blob: 65cd0e98115fc0bf20b879e3aeebf5552bd55814 [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/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
florian99dd03e2013-01-29 03:56:06 +0000243 return IRExpr_ITE(condition, iftrue, iffalse);
sewardj2019a972011-03-07 16:04:07 +0000244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
sewardj05f5e012014-05-04 10:52:11 +0000420 stmt(IRStmt_Exit(condition, Ijk_InvalICache,
421 IRConst_U64(guest_IA_curr_instr),
florian6820ba52012-07-26 02:01:50 +0000422 S390X_GUEST_OFFSET(guest_IA)));
423}
424
425/* Convenience function to yield to thread scheduler */
426static void
427yield_if(IRExpr *condition)
428{
429 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
430 S390X_GUEST_OFFSET(guest_IA)));
431}
432
sewardj2019a972011-03-07 16:04:07 +0000433static __inline__ IRExpr *get_fpr_dw0(UInt);
434static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000435static __inline__ IRExpr *get_dpr_dw0(UInt);
436static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000437
438/* Read a floating point register pair and combine their contents into a
439 128-bit value */
440static IRExpr *
441get_fpr_pair(UInt archreg)
442{
443 IRExpr *high = get_fpr_dw0(archreg);
444 IRExpr *low = get_fpr_dw0(archreg + 2);
445
446 return binop(Iop_F64HLtoF128, high, low);
447}
448
449/* Write a 128-bit floating point value into a register pair. */
450static void
451put_fpr_pair(UInt archreg, IRExpr *expr)
452{
453 IRExpr *high = unop(Iop_F128HItoF64, expr);
454 IRExpr *low = unop(Iop_F128LOtoF64, expr);
455
456 put_fpr_dw0(archreg, high);
457 put_fpr_dw0(archreg + 2, low);
458}
459
floriane38f6412012-12-21 17:32:12 +0000460/* Read a floating point register pair cointaining DFP value
461 and combine their contents into a 128-bit value */
462
463static IRExpr *
464get_dpr_pair(UInt archreg)
465{
466 IRExpr *high = get_dpr_dw0(archreg);
467 IRExpr *low = get_dpr_dw0(archreg + 2);
468
469 return binop(Iop_D64HLtoD128, high, low);
470}
471
472/* Write a 128-bit decimal floating point value into a register pair. */
473static void
474put_dpr_pair(UInt archreg, IRExpr *expr)
475{
476 IRExpr *high = unop(Iop_D128HItoD64, expr);
477 IRExpr *low = unop(Iop_D128LOtoD64, expr);
478
479 put_dpr_dw0(archreg, high);
480 put_dpr_dw0(archreg + 2, low);
481}
482
floriane75dafa2012-09-01 17:54:09 +0000483/* Terminate the current IRSB with an emulation failure. */
484static void
florianafa3f042014-09-06 21:43:28 +0000485emulation_failure_with_expr(IRExpr *emfailure)
floriane75dafa2012-09-01 17:54:09 +0000486{
florianafa3f042014-09-06 21:43:28 +0000487 vassert(typeOfIRExpr(irsb->tyenv, emfailure) == Ity_I32);
488
489 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emfailure));
floriane75dafa2012-09-01 17:54:09 +0000490 dis_res->whatNext = Dis_StopHere;
491 dis_res->jk_StopHere = Ijk_EmFail;
492}
sewardj2019a972011-03-07 16:04:07 +0000493
florianafa3f042014-09-06 21:43:28 +0000494static void
495emulation_failure(VexEmNote fail_kind)
496{
497 emulation_failure_with_expr(mkU32(fail_kind));
498}
499
florian4b8efad2012-09-02 18:07:08 +0000500/* Terminate the current IRSB with an emulation warning. */
501static void
florianafa3f042014-09-06 21:43:28 +0000502emulation_warning_with_expr(IRExpr *emwarning)
503{
504 vassert(typeOfIRExpr(irsb->tyenv, emwarning) == Ity_I32);
505
506 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), emwarning));
507 dis_res->whatNext = Dis_StopHere;
508 dis_res->jk_StopHere = Ijk_EmWarn;
509}
510
511static void
florian4b8efad2012-09-02 18:07:08 +0000512emulation_warning(VexEmNote warn_kind)
513{
florianafa3f042014-09-06 21:43:28 +0000514 emulation_warning_with_expr(mkU32(warn_kind));
florian4b8efad2012-09-02 18:07:08 +0000515}
516
sewardj2019a972011-03-07 16:04:07 +0000517/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000518/*--- IR Debugging aids. ---*/
519/*------------------------------------------------------------*/
520#if 0
521
522static ULong
523s390_do_print(HChar *text, ULong value)
524{
525 vex_printf("%s %llu\n", text, value);
526 return 0;
527}
528
529static void
530s390_print(HChar *text, IRExpr *value)
531{
532 IRDirty *d;
533
534 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
535 mkIRExprVec_2(mkU64((ULong)text), value));
536 stmt(IRStmt_Dirty(d));
537}
538#endif
539
540
541/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000542/*--- Build the flags thunk. ---*/
543/*------------------------------------------------------------*/
544
545/* Completely fill the flags thunk. We're always filling all fields.
546 Apparently, that is better for redundant PUT elimination. */
547static void
548s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
549{
550 UInt op_off, dep1_off, dep2_off, ndep_off;
551
florian428dfdd2012-03-27 03:09:49 +0000552 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
553 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
554 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
555 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000556
557 stmt(IRStmt_Put(op_off, op));
558 stmt(IRStmt_Put(dep1_off, dep1));
559 stmt(IRStmt_Put(dep2_off, dep2));
560 stmt(IRStmt_Put(ndep_off, ndep));
561}
562
563
564/* Create an expression for V and widen the result to 64 bit. */
565static IRExpr *
566s390_cc_widen(IRTemp v, Bool sign_extend)
567{
568 IRExpr *expr;
569
570 expr = mkexpr(v);
571
572 switch (typeOfIRTemp(irsb->tyenv, v)) {
573 case Ity_I64:
574 break;
575 case Ity_I32:
576 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
577 break;
578 case Ity_I16:
579 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
580 break;
581 case Ity_I8:
582 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
583 break;
584 default:
585 vpanic("s390_cc_widen");
586 }
587
588 return expr;
589}
590
591static void
592s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
593{
594 IRExpr *op, *dep1, *dep2, *ndep;
595
596 op = mkU64(opc);
597 dep1 = s390_cc_widen(d1, sign_extend);
598 dep2 = mkU64(0);
599 ndep = mkU64(0);
600
601 s390_cc_thunk_fill(op, dep1, dep2, ndep);
602}
603
604
605static void
606s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
607{
608 IRExpr *op, *dep1, *dep2, *ndep;
609
610 op = mkU64(opc);
611 dep1 = s390_cc_widen(d1, sign_extend);
612 dep2 = s390_cc_widen(d2, sign_extend);
613 ndep = mkU64(0);
614
615 s390_cc_thunk_fill(op, dep1, dep2, ndep);
616}
617
618
619/* memcheck believes that the NDEP field in the flags thunk is always
620 defined. But for some flag computations (e.g. add with carry) that is
621 just not true. We therefore need to convey to memcheck that the value
622 of the ndep field does matter and therefore we make the DEP2 field
623 depend on it:
624
625 DEP2 = original_DEP2 ^ NDEP
626
627 In s390_calculate_cc we exploit that (a^b)^b == a
628 I.e. we xor the DEP2 value with the NDEP value to recover the
629 original_DEP2 value. */
630static void
631s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
632{
633 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
634
635 op = mkU64(opc);
636 dep1 = s390_cc_widen(d1, sign_extend);
637 dep2 = s390_cc_widen(d2, sign_extend);
638 ndep = s390_cc_widen(nd, sign_extend);
639
640 dep2x = binop(Iop_Xor64, dep2, ndep);
641
642 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
643}
644
645
646/* Write one floating point value into the flags thunk */
647static void
648s390_cc_thunk_put1f(UInt opc, IRTemp d1)
649{
650 IRExpr *op, *dep1, *dep2, *ndep;
651
florianbafb8262013-05-31 15:41:55 +0000652 /* Make the CC_DEP1 slot appear completely defined.
653 Otherwise, assigning a 32-bit value will cause memcheck
654 to trigger an undefinedness error.
655 */
656 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
657 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
658 stmt(IRStmt_Put(dep1_off, mkU64(0)));
659 }
sewardj2019a972011-03-07 16:04:07 +0000660 op = mkU64(opc);
661 dep1 = mkexpr(d1);
662 dep2 = mkU64(0);
663 ndep = mkU64(0);
664
665 s390_cc_thunk_fill(op, dep1, dep2, ndep);
666}
667
668
669/* Write a floating point value and an integer into the flags thunk. The
670 integer value is zero-extended first. */
671static void
672s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
673{
674 IRExpr *op, *dep1, *dep2, *ndep;
675
florianbafb8262013-05-31 15:41:55 +0000676 /* Make the CC_DEP1 slot appear completely defined.
677 Otherwise, assigning a 32-bit value will cause memcheck
678 to trigger an undefinedness error.
679 */
680 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
681 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
682 stmt(IRStmt_Put(dep1_off, mkU64(0)));
683 }
sewardj2019a972011-03-07 16:04:07 +0000684 op = mkU64(opc);
685 dep1 = mkexpr(d1);
686 dep2 = s390_cc_widen(d2, False);
687 ndep = mkU64(0);
688
689 s390_cc_thunk_fill(op, dep1, dep2, ndep);
690}
691
692
693/* Write a 128-bit floating point value into the flags thunk. This is
694 done by splitting the value into two 64-bits values. */
695static void
696s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
697{
698 IRExpr *op, *hi, *lo, *ndep;
699
700 op = mkU64(opc);
701 hi = unop(Iop_F128HItoF64, mkexpr(d1));
702 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
703 ndep = mkU64(0);
704
705 s390_cc_thunk_fill(op, hi, lo, ndep);
706}
707
708
709/* Write a 128-bit floating point value and an integer into the flags thunk.
710 The integer value is zero-extended first. */
711static void
712s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
713{
714 IRExpr *op, *hi, *lo, *lox, *ndep;
715
716 op = mkU64(opc);
717 hi = unop(Iop_F128HItoF64, mkexpr(d1));
718 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
719 ndep = s390_cc_widen(nd, False);
720
721 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
722
723 s390_cc_thunk_fill(op, hi, lox, ndep);
724}
725
726
floriane38f6412012-12-21 17:32:12 +0000727/* Write a 128-bit decimal floating point value into the flags thunk.
728 This is done by splitting the value into two 64-bits values. */
729static void
730s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
731{
732 IRExpr *op, *hi, *lo, *ndep;
733
734 op = mkU64(opc);
735 hi = unop(Iop_D128HItoD64, mkexpr(d1));
736 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
737 ndep = mkU64(0);
738
739 s390_cc_thunk_fill(op, hi, lo, ndep);
740}
741
742
floriance9e3db2012-12-27 20:14:03 +0000743/* Write a 128-bit decimal floating point value and an integer into the flags
744 thunk. The integer value is zero-extended first. */
745static void
746s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
747{
748 IRExpr *op, *hi, *lo, *lox, *ndep;
749
750 op = mkU64(opc);
751 hi = unop(Iop_D128HItoD64, mkexpr(d1));
752 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
753 ndep = s390_cc_widen(nd, False);
754
755 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
756
757 s390_cc_thunk_fill(op, hi, lox, ndep);
758}
759
760
sewardj2019a972011-03-07 16:04:07 +0000761static void
762s390_cc_set(UInt val)
763{
764 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
765 mkU64(val), mkU64(0), mkU64(0));
766}
767
768/* Build IR to calculate the condition code from flags thunk.
769 Returns an expression of type Ity_I32 */
770static IRExpr *
771s390_call_calculate_cc(void)
772{
773 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
774
florian428dfdd2012-03-27 03:09:49 +0000775 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
776 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
777 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
778 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000779
780 args = mkIRExprVec_4(op, dep1, dep2, ndep);
781 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
782 "s390_calculate_cc", &s390_calculate_cc, args);
783
784 /* Exclude OP and NDEP from definedness checking. We're only
785 interested in DEP1 and DEP2. */
786 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
787
788 return call;
789}
790
791/* Build IR to calculate the internal condition code for a "compare and branch"
792 insn. Returns an expression of type Ity_I32 */
793static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000794s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000795{
florianff9613f2012-05-12 15:26:44 +0000796 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000797
florianff9613f2012-05-12 15:26:44 +0000798 switch (opc) {
799 case S390_CC_OP_SIGNED_COMPARE:
800 dep1 = s390_cc_widen(op1, True);
801 dep2 = s390_cc_widen(op2, True);
802 break;
803
804 case S390_CC_OP_UNSIGNED_COMPARE:
805 dep1 = s390_cc_widen(op1, False);
806 dep2 = s390_cc_widen(op2, False);
807 break;
808
809 default:
810 vpanic("s390_call_calculate_icc");
811 }
812
813 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000814 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000815
florianff9613f2012-05-12 15:26:44 +0000816 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000817 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000818 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000819
florianff9613f2012-05-12 15:26:44 +0000820 /* Exclude the requested condition, OP and NDEP from definedness
821 checking. We're only interested in DEP1 and DEP2. */
822 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000823
824 return call;
825}
826
827/* Build IR to calculate the condition code from flags thunk.
828 Returns an expression of type Ity_I32 */
829static IRExpr *
830s390_call_calculate_cond(UInt m)
831{
832 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
833
834 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000835 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
836 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
837 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
838 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000839
840 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
841 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
842 "s390_calculate_cond", &s390_calculate_cond, args);
843
844 /* Exclude the requested condition, OP and NDEP from definedness
845 checking. We're only interested in DEP1 and DEP2. */
846 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
847
848 return call;
849}
850
851#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
852#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
853#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
854#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
855#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
856#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
857#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
858 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
859#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
860 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000861
862
sewardj2019a972011-03-07 16:04:07 +0000863
864
865/*------------------------------------------------------------*/
866/*--- Guest register access ---*/
867/*------------------------------------------------------------*/
868
869
870/*------------------------------------------------------------*/
871/*--- ar registers ---*/
872/*------------------------------------------------------------*/
873
874/* Return the guest state offset of a ar register. */
875static UInt
876ar_offset(UInt archreg)
877{
878 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000879 S390X_GUEST_OFFSET(guest_a0),
880 S390X_GUEST_OFFSET(guest_a1),
881 S390X_GUEST_OFFSET(guest_a2),
882 S390X_GUEST_OFFSET(guest_a3),
883 S390X_GUEST_OFFSET(guest_a4),
884 S390X_GUEST_OFFSET(guest_a5),
885 S390X_GUEST_OFFSET(guest_a6),
886 S390X_GUEST_OFFSET(guest_a7),
887 S390X_GUEST_OFFSET(guest_a8),
888 S390X_GUEST_OFFSET(guest_a9),
889 S390X_GUEST_OFFSET(guest_a10),
890 S390X_GUEST_OFFSET(guest_a11),
891 S390X_GUEST_OFFSET(guest_a12),
892 S390X_GUEST_OFFSET(guest_a13),
893 S390X_GUEST_OFFSET(guest_a14),
894 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000895 };
896
897 vassert(archreg < 16);
898
899 return offset[archreg];
900}
901
902
903/* Return the guest state offset of word #0 of a ar register. */
904static __inline__ UInt
905ar_w0_offset(UInt archreg)
906{
907 return ar_offset(archreg) + 0;
908}
909
910/* Write word #0 of a ar to the guest state. */
911static __inline__ void
912put_ar_w0(UInt archreg, IRExpr *expr)
913{
914 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
915
916 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
917}
918
919/* Read word #0 of a ar register. */
920static __inline__ IRExpr *
921get_ar_w0(UInt archreg)
922{
923 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
924}
925
926
927/*------------------------------------------------------------*/
928/*--- fpr registers ---*/
929/*------------------------------------------------------------*/
930
931/* Return the guest state offset of a fpr register. */
932static UInt
933fpr_offset(UInt archreg)
934{
935 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000936 S390X_GUEST_OFFSET(guest_f0),
937 S390X_GUEST_OFFSET(guest_f1),
938 S390X_GUEST_OFFSET(guest_f2),
939 S390X_GUEST_OFFSET(guest_f3),
940 S390X_GUEST_OFFSET(guest_f4),
941 S390X_GUEST_OFFSET(guest_f5),
942 S390X_GUEST_OFFSET(guest_f6),
943 S390X_GUEST_OFFSET(guest_f7),
944 S390X_GUEST_OFFSET(guest_f8),
945 S390X_GUEST_OFFSET(guest_f9),
946 S390X_GUEST_OFFSET(guest_f10),
947 S390X_GUEST_OFFSET(guest_f11),
948 S390X_GUEST_OFFSET(guest_f12),
949 S390X_GUEST_OFFSET(guest_f13),
950 S390X_GUEST_OFFSET(guest_f14),
951 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000952 };
953
954 vassert(archreg < 16);
955
956 return offset[archreg];
957}
958
959
960/* Return the guest state offset of word #0 of a fpr register. */
961static __inline__ UInt
962fpr_w0_offset(UInt archreg)
963{
964 return fpr_offset(archreg) + 0;
965}
966
967/* Write word #0 of a fpr to the guest state. */
968static __inline__ void
969put_fpr_w0(UInt archreg, IRExpr *expr)
970{
971 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
972
973 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
974}
975
976/* Read word #0 of a fpr register. */
977static __inline__ IRExpr *
978get_fpr_w0(UInt archreg)
979{
980 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
981}
982
983/* Return the guest state offset of double word #0 of a fpr register. */
984static __inline__ UInt
985fpr_dw0_offset(UInt archreg)
986{
987 return fpr_offset(archreg) + 0;
988}
989
990/* Write double word #0 of a fpr to the guest state. */
991static __inline__ void
992put_fpr_dw0(UInt archreg, IRExpr *expr)
993{
994 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
995
996 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
997}
998
999/* Read double word #0 of a fpr register. */
1000static __inline__ IRExpr *
1001get_fpr_dw0(UInt archreg)
1002{
1003 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
1004}
1005
floriane38f6412012-12-21 17:32:12 +00001006/* Write word #0 of a dpr to the guest state. */
1007static __inline__ void
1008put_dpr_w0(UInt archreg, IRExpr *expr)
1009{
1010 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
1011
1012 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
1013}
1014
1015/* Read word #0 of a dpr register. */
1016static __inline__ IRExpr *
1017get_dpr_w0(UInt archreg)
1018{
1019 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1020}
1021
florian12390202012-11-10 22:34:14 +00001022/* Write double word #0 of a fpr containg DFP value to the guest state. */
1023static __inline__ void
1024put_dpr_dw0(UInt archreg, IRExpr *expr)
1025{
1026 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1027
1028 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1029}
1030
1031/* Read double word #0 of a fpr register containing DFP value. */
1032static __inline__ IRExpr *
1033get_dpr_dw0(UInt archreg)
1034{
1035 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1036}
sewardj2019a972011-03-07 16:04:07 +00001037
1038/*------------------------------------------------------------*/
1039/*--- gpr registers ---*/
1040/*------------------------------------------------------------*/
1041
1042/* Return the guest state offset of a gpr register. */
1043static UInt
1044gpr_offset(UInt archreg)
1045{
1046 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001047 S390X_GUEST_OFFSET(guest_r0),
1048 S390X_GUEST_OFFSET(guest_r1),
1049 S390X_GUEST_OFFSET(guest_r2),
1050 S390X_GUEST_OFFSET(guest_r3),
1051 S390X_GUEST_OFFSET(guest_r4),
1052 S390X_GUEST_OFFSET(guest_r5),
1053 S390X_GUEST_OFFSET(guest_r6),
1054 S390X_GUEST_OFFSET(guest_r7),
1055 S390X_GUEST_OFFSET(guest_r8),
1056 S390X_GUEST_OFFSET(guest_r9),
1057 S390X_GUEST_OFFSET(guest_r10),
1058 S390X_GUEST_OFFSET(guest_r11),
1059 S390X_GUEST_OFFSET(guest_r12),
1060 S390X_GUEST_OFFSET(guest_r13),
1061 S390X_GUEST_OFFSET(guest_r14),
1062 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001063 };
1064
1065 vassert(archreg < 16);
1066
1067 return offset[archreg];
1068}
1069
1070
1071/* Return the guest state offset of word #0 of a gpr register. */
1072static __inline__ UInt
1073gpr_w0_offset(UInt archreg)
1074{
1075 return gpr_offset(archreg) + 0;
1076}
1077
1078/* Write word #0 of a gpr to the guest state. */
1079static __inline__ void
1080put_gpr_w0(UInt archreg, IRExpr *expr)
1081{
1082 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1083
1084 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1085}
1086
1087/* Read word #0 of a gpr register. */
1088static __inline__ IRExpr *
1089get_gpr_w0(UInt archreg)
1090{
1091 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1092}
1093
1094/* Return the guest state offset of double word #0 of a gpr register. */
1095static __inline__ UInt
1096gpr_dw0_offset(UInt archreg)
1097{
1098 return gpr_offset(archreg) + 0;
1099}
1100
1101/* Write double word #0 of a gpr to the guest state. */
1102static __inline__ void
1103put_gpr_dw0(UInt archreg, IRExpr *expr)
1104{
1105 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1106
1107 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1108}
1109
1110/* Read double word #0 of a gpr register. */
1111static __inline__ IRExpr *
1112get_gpr_dw0(UInt archreg)
1113{
1114 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1115}
1116
1117/* Return the guest state offset of half word #1 of a gpr register. */
1118static __inline__ UInt
1119gpr_hw1_offset(UInt archreg)
1120{
1121 return gpr_offset(archreg) + 2;
1122}
1123
1124/* Write half word #1 of a gpr to the guest state. */
1125static __inline__ void
1126put_gpr_hw1(UInt archreg, IRExpr *expr)
1127{
1128 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1129
1130 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1131}
1132
1133/* Read half word #1 of a gpr register. */
1134static __inline__ IRExpr *
1135get_gpr_hw1(UInt archreg)
1136{
1137 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1138}
1139
1140/* Return the guest state offset of byte #6 of a gpr register. */
1141static __inline__ UInt
1142gpr_b6_offset(UInt archreg)
1143{
1144 return gpr_offset(archreg) + 6;
1145}
1146
1147/* Write byte #6 of a gpr to the guest state. */
1148static __inline__ void
1149put_gpr_b6(UInt archreg, IRExpr *expr)
1150{
1151 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1152
1153 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1154}
1155
1156/* Read byte #6 of a gpr register. */
1157static __inline__ IRExpr *
1158get_gpr_b6(UInt archreg)
1159{
1160 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1161}
1162
1163/* Return the guest state offset of byte #3 of a gpr register. */
1164static __inline__ UInt
1165gpr_b3_offset(UInt archreg)
1166{
1167 return gpr_offset(archreg) + 3;
1168}
1169
1170/* Write byte #3 of a gpr to the guest state. */
1171static __inline__ void
1172put_gpr_b3(UInt archreg, IRExpr *expr)
1173{
1174 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1175
1176 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1177}
1178
1179/* Read byte #3 of a gpr register. */
1180static __inline__ IRExpr *
1181get_gpr_b3(UInt archreg)
1182{
1183 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1184}
1185
1186/* Return the guest state offset of byte #0 of a gpr register. */
1187static __inline__ UInt
1188gpr_b0_offset(UInt archreg)
1189{
1190 return gpr_offset(archreg) + 0;
1191}
1192
1193/* Write byte #0 of a gpr to the guest state. */
1194static __inline__ void
1195put_gpr_b0(UInt archreg, IRExpr *expr)
1196{
1197 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1198
1199 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1200}
1201
1202/* Read byte #0 of a gpr register. */
1203static __inline__ IRExpr *
1204get_gpr_b0(UInt archreg)
1205{
1206 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1207}
1208
1209/* Return the guest state offset of word #1 of a gpr register. */
1210static __inline__ UInt
1211gpr_w1_offset(UInt archreg)
1212{
1213 return gpr_offset(archreg) + 4;
1214}
1215
1216/* Write word #1 of a gpr to the guest state. */
1217static __inline__ void
1218put_gpr_w1(UInt archreg, IRExpr *expr)
1219{
1220 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1221
1222 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1223}
1224
1225/* Read word #1 of a gpr register. */
1226static __inline__ IRExpr *
1227get_gpr_w1(UInt archreg)
1228{
1229 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1230}
1231
1232/* Return the guest state offset of half word #3 of a gpr register. */
1233static __inline__ UInt
1234gpr_hw3_offset(UInt archreg)
1235{
1236 return gpr_offset(archreg) + 6;
1237}
1238
1239/* Write half word #3 of a gpr to the guest state. */
1240static __inline__ void
1241put_gpr_hw3(UInt archreg, IRExpr *expr)
1242{
1243 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1244
1245 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1246}
1247
1248/* Read half word #3 of a gpr register. */
1249static __inline__ IRExpr *
1250get_gpr_hw3(UInt archreg)
1251{
1252 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1253}
1254
1255/* Return the guest state offset of byte #7 of a gpr register. */
1256static __inline__ UInt
1257gpr_b7_offset(UInt archreg)
1258{
1259 return gpr_offset(archreg) + 7;
1260}
1261
1262/* Write byte #7 of a gpr to the guest state. */
1263static __inline__ void
1264put_gpr_b7(UInt archreg, IRExpr *expr)
1265{
1266 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1267
1268 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1269}
1270
1271/* Read byte #7 of a gpr register. */
1272static __inline__ IRExpr *
1273get_gpr_b7(UInt archreg)
1274{
1275 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1276}
1277
1278/* Return the guest state offset of half word #0 of a gpr register. */
1279static __inline__ UInt
1280gpr_hw0_offset(UInt archreg)
1281{
1282 return gpr_offset(archreg) + 0;
1283}
1284
1285/* Write half word #0 of a gpr to the guest state. */
1286static __inline__ void
1287put_gpr_hw0(UInt archreg, IRExpr *expr)
1288{
1289 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1290
1291 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1292}
1293
1294/* Read half word #0 of a gpr register. */
1295static __inline__ IRExpr *
1296get_gpr_hw0(UInt archreg)
1297{
1298 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1299}
1300
1301/* Return the guest state offset of byte #4 of a gpr register. */
1302static __inline__ UInt
1303gpr_b4_offset(UInt archreg)
1304{
1305 return gpr_offset(archreg) + 4;
1306}
1307
1308/* Write byte #4 of a gpr to the guest state. */
1309static __inline__ void
1310put_gpr_b4(UInt archreg, IRExpr *expr)
1311{
1312 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1313
1314 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1315}
1316
1317/* Read byte #4 of a gpr register. */
1318static __inline__ IRExpr *
1319get_gpr_b4(UInt archreg)
1320{
1321 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1322}
1323
1324/* Return the guest state offset of byte #1 of a gpr register. */
1325static __inline__ UInt
1326gpr_b1_offset(UInt archreg)
1327{
1328 return gpr_offset(archreg) + 1;
1329}
1330
1331/* Write byte #1 of a gpr to the guest state. */
1332static __inline__ void
1333put_gpr_b1(UInt archreg, IRExpr *expr)
1334{
1335 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1336
1337 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1338}
1339
1340/* Read byte #1 of a gpr register. */
1341static __inline__ IRExpr *
1342get_gpr_b1(UInt archreg)
1343{
1344 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1345}
1346
1347/* Return the guest state offset of half word #2 of a gpr register. */
1348static __inline__ UInt
1349gpr_hw2_offset(UInt archreg)
1350{
1351 return gpr_offset(archreg) + 4;
1352}
1353
1354/* Write half word #2 of a gpr to the guest state. */
1355static __inline__ void
1356put_gpr_hw2(UInt archreg, IRExpr *expr)
1357{
1358 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1359
1360 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1361}
1362
1363/* Read half word #2 of a gpr register. */
1364static __inline__ IRExpr *
1365get_gpr_hw2(UInt archreg)
1366{
1367 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1368}
1369
1370/* Return the guest state offset of byte #5 of a gpr register. */
1371static __inline__ UInt
1372gpr_b5_offset(UInt archreg)
1373{
1374 return gpr_offset(archreg) + 5;
1375}
1376
1377/* Write byte #5 of a gpr to the guest state. */
1378static __inline__ void
1379put_gpr_b5(UInt archreg, IRExpr *expr)
1380{
1381 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1382
1383 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1384}
1385
1386/* Read byte #5 of a gpr register. */
1387static __inline__ IRExpr *
1388get_gpr_b5(UInt archreg)
1389{
1390 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1391}
1392
1393/* Return the guest state offset of byte #2 of a gpr register. */
1394static __inline__ UInt
1395gpr_b2_offset(UInt archreg)
1396{
1397 return gpr_offset(archreg) + 2;
1398}
1399
1400/* Write byte #2 of a gpr to the guest state. */
1401static __inline__ void
1402put_gpr_b2(UInt archreg, IRExpr *expr)
1403{
1404 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1405
1406 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1407}
1408
1409/* Read byte #2 of a gpr register. */
1410static __inline__ IRExpr *
1411get_gpr_b2(UInt archreg)
1412{
1413 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1414}
1415
1416/* Return the guest state offset of the counter register. */
1417static UInt
1418counter_offset(void)
1419{
floriane88b3c92011-07-05 02:48:39 +00001420 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001421}
1422
1423/* Return the guest state offset of double word #0 of the counter register. */
1424static __inline__ UInt
1425counter_dw0_offset(void)
1426{
1427 return counter_offset() + 0;
1428}
1429
1430/* Write double word #0 of the counter to the guest state. */
1431static __inline__ void
1432put_counter_dw0(IRExpr *expr)
1433{
1434 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1435
1436 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1437}
1438
1439/* Read double word #0 of the counter register. */
1440static __inline__ IRExpr *
1441get_counter_dw0(void)
1442{
1443 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1444}
1445
1446/* Return the guest state offset of word #0 of the counter register. */
1447static __inline__ UInt
1448counter_w0_offset(void)
1449{
1450 return counter_offset() + 0;
1451}
1452
1453/* Return the guest state offset of word #1 of the counter register. */
1454static __inline__ UInt
1455counter_w1_offset(void)
1456{
1457 return counter_offset() + 4;
1458}
1459
1460/* Write word #0 of the counter to the guest state. */
1461static __inline__ void
1462put_counter_w0(IRExpr *expr)
1463{
1464 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1465
1466 stmt(IRStmt_Put(counter_w0_offset(), expr));
1467}
1468
1469/* Read word #0 of the counter register. */
1470static __inline__ IRExpr *
1471get_counter_w0(void)
1472{
1473 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1474}
1475
1476/* Write word #1 of the counter to the guest state. */
1477static __inline__ void
1478put_counter_w1(IRExpr *expr)
1479{
1480 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1481
1482 stmt(IRStmt_Put(counter_w1_offset(), expr));
1483}
1484
1485/* Read word #1 of the counter register. */
1486static __inline__ IRExpr *
1487get_counter_w1(void)
1488{
1489 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1490}
1491
1492/* Return the guest state offset of the fpc register. */
1493static UInt
1494fpc_offset(void)
1495{
floriane88b3c92011-07-05 02:48:39 +00001496 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001497}
1498
1499/* Return the guest state offset of word #0 of the fpc register. */
1500static __inline__ UInt
1501fpc_w0_offset(void)
1502{
1503 return fpc_offset() + 0;
1504}
1505
1506/* Write word #0 of the fpc to the guest state. */
1507static __inline__ void
1508put_fpc_w0(IRExpr *expr)
1509{
1510 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1511
1512 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1513}
1514
1515/* Read word #0 of the fpc register. */
1516static __inline__ IRExpr *
1517get_fpc_w0(void)
1518{
1519 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1520}
1521
1522
1523/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001524/*--- Rounding modes ---*/
1525/*------------------------------------------------------------*/
1526
florian125e20d2012-10-07 15:42:37 +00001527/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001528 IRRoundingMode:
1529
1530 rounding mode | s390 | IR
1531 -------------------------
1532 to nearest | 00 | 00
1533 to zero | 01 | 11
1534 to +infinity | 10 | 10
1535 to -infinity | 11 | 01
1536
1537 So: IR = (4 - s390) & 3
1538*/
1539static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001540get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001541{
1542 IRTemp fpc_bits = newTemp(Ity_I32);
1543
1544 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1545 Prior to that bits [30:31] contained the bfp rounding mode with
1546 bit 29 being unused and having a value of 0. So we can always
1547 extract the least significant 3 bits. */
1548 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1549
1550 /* fixs390:
1551
1552
1553 if (! s390_host_has_fpext && rounding_mode > 3) {
1554 emulation warning @ runtime and
1555 set fpc to round nearest
1556 }
1557 */
1558
1559 /* For now silently adjust an unsupported rounding mode to "nearest" */
1560 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1561 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001562 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001563
1564 // rm_IR = (4 - rm_s390) & 3;
1565 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1566}
1567
1568/* Encode the s390 rounding mode as it appears in the m3 field of certain
1569 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1570 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1571 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1572 considers the default rounding mode (4.3.3). */
1573static IRTemp
1574encode_bfp_rounding_mode(UChar mode)
1575{
1576 IRExpr *rm;
1577
1578 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001579 case S390_BFP_ROUND_PER_FPC:
1580 rm = get_bfp_rounding_mode_from_fpc();
1581 break;
1582 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1583 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1584 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1585 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1586 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1587 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001588 default:
1589 vpanic("encode_bfp_rounding_mode");
1590 }
1591
1592 return mktemp(Ity_I32, rm);
1593}
1594
florianc8e4f562012-10-27 16:19:31 +00001595/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1596 IRRoundingMode:
1597
1598 rounding mode | s390 | IR
1599 ------------------------------------------------
1600 to nearest, ties to even | 000 | 000
1601 to zero | 001 | 011
1602 to +infinity | 010 | 010
1603 to -infinity | 011 | 001
1604 to nearest, ties away from 0 | 100 | 100
1605 to nearest, ties toward 0 | 101 | 111
1606 to away from 0 | 110 | 110
1607 to prepare for shorter precision | 111 | 101
1608
1609 So: IR = (s390 ^ ((s390 << 1) & 2))
1610*/
florianc8e4f562012-10-27 16:19:31 +00001611static IRExpr *
1612get_dfp_rounding_mode_from_fpc(void)
1613{
1614 IRTemp fpc_bits = newTemp(Ity_I32);
1615
1616 /* The dfp rounding mode is stored in bits [25:27].
1617 extract the bits at 25:27 and right shift 4 times. */
1618 assign(fpc_bits, binop(Iop_Shr32,
1619 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1620 mkU8(4)));
1621
1622 IRExpr *rm_s390 = mkexpr(fpc_bits);
1623 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1624
1625 return binop(Iop_Xor32, rm_s390,
1626 binop( Iop_And32,
1627 binop(Iop_Shl32, rm_s390, mkU8(1)),
1628 mkU32(2)));
1629}
1630
1631/* Encode the s390 rounding mode as it appears in the m3 field of certain
1632 instructions to VEX's IRRoundingMode. */
1633static IRTemp
1634encode_dfp_rounding_mode(UChar mode)
1635{
1636 IRExpr *rm;
1637
1638 switch (mode) {
1639 case S390_DFP_ROUND_PER_FPC_0:
1640 case S390_DFP_ROUND_PER_FPC_2:
1641 rm = get_dfp_rounding_mode_from_fpc(); break;
1642 case S390_DFP_ROUND_NEAREST_EVEN_4:
1643 case S390_DFP_ROUND_NEAREST_EVEN_8:
florian79e5a482013-06-06 19:12:46 +00001644 rm = mkU32(Irrm_NEAREST); break;
florianc8e4f562012-10-27 16:19:31 +00001645 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1646 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
florian79e5a482013-06-06 19:12:46 +00001647 rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
florianc8e4f562012-10-27 16:19:31 +00001648 case S390_DFP_ROUND_PREPARE_SHORT_3:
1649 case S390_DFP_ROUND_PREPARE_SHORT_15:
florian79e5a482013-06-06 19:12:46 +00001650 rm = mkU32(Irrm_PREPARE_SHORTER); break;
florianc8e4f562012-10-27 16:19:31 +00001651 case S390_DFP_ROUND_ZERO_5:
1652 case S390_DFP_ROUND_ZERO_9:
florian79e5a482013-06-06 19:12:46 +00001653 rm = mkU32(Irrm_ZERO ); break;
florianc8e4f562012-10-27 16:19:31 +00001654 case S390_DFP_ROUND_POSINF_6:
1655 case S390_DFP_ROUND_POSINF_10:
florian79e5a482013-06-06 19:12:46 +00001656 rm = mkU32(Irrm_PosINF); break;
florianc8e4f562012-10-27 16:19:31 +00001657 case S390_DFP_ROUND_NEGINF_7:
1658 case S390_DFP_ROUND_NEGINF_11:
florian79e5a482013-06-06 19:12:46 +00001659 rm = mkU32(Irrm_NegINF); break;
florianc8e4f562012-10-27 16:19:31 +00001660 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
florian79e5a482013-06-06 19:12:46 +00001661 rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
florianc8e4f562012-10-27 16:19:31 +00001662 case S390_DFP_ROUND_AWAY_0:
florian79e5a482013-06-06 19:12:46 +00001663 rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
florianc8e4f562012-10-27 16:19:31 +00001664 default:
1665 vpanic("encode_dfp_rounding_mode");
1666 }
1667
1668 return mktemp(Ity_I32, rm);
1669}
florian12390202012-11-10 22:34:14 +00001670
florianc8e4f562012-10-27 16:19:31 +00001671
florian2c74d242012-09-12 19:38:42 +00001672/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001673/*--- Condition code helpers ---*/
1674/*------------------------------------------------------------*/
1675
1676/* The result of a Iop_CmpFxx operation is a condition code. It is
1677 encoded using the values defined in type IRCmpFxxResult.
1678 Before we can store the condition code into the guest state (or do
1679 anything else with it for that matter) we need to convert it to
1680 the encoding that s390 uses. This is what this function does.
1681
1682 s390 VEX b6 b2 b0 cc.1 cc.0
1683 0 0x40 EQ 1 0 0 0 0
1684 1 0x01 LT 0 0 1 0 1
1685 2 0x00 GT 0 0 0 1 0
1686 3 0x45 Unordered 1 1 1 1 1
1687
1688 The following bits from the VEX encoding are interesting:
1689 b0, b2, b6 with b0 being the LSB. We observe:
1690
1691 cc.0 = b0;
1692 cc.1 = b2 | (~b0 & ~b6)
1693
1694 with cc being the s390 condition code.
1695*/
1696static IRExpr *
1697convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1698{
1699 IRTemp cc0 = newTemp(Ity_I32);
1700 IRTemp cc1 = newTemp(Ity_I32);
1701 IRTemp b0 = newTemp(Ity_I32);
1702 IRTemp b2 = newTemp(Ity_I32);
1703 IRTemp b6 = newTemp(Ity_I32);
1704
1705 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1706 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1707 mkU32(1)));
1708 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1709 mkU32(1)));
1710
1711 assign(cc0, mkexpr(b0));
1712 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1713 binop(Iop_And32,
1714 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1715 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1716 )));
1717
1718 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1719}
1720
1721
1722/* The result of a Iop_CmpDxx operation is a condition code. It is
1723 encoded using the values defined in type IRCmpDxxResult.
1724 Before we can store the condition code into the guest state (or do
1725 anything else with it for that matter) we need to convert it to
1726 the encoding that s390 uses. This is what this function does. */
1727static IRExpr *
1728convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1729{
1730 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1731 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001732 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001733}
1734
1735
1736/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001737/*--- Build IR for formats ---*/
1738/*------------------------------------------------------------*/
1739static void
florian55085f82012-11-21 00:36:55 +00001740s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001741 UChar i)
1742{
florian55085f82012-11-21 00:36:55 +00001743 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001744
sewardj7ee97522011-05-09 21:45:04 +00001745 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001746 s390_disasm(ENC2(MNM, UINT), mnm, i);
1747}
1748
1749static void
florian78d5ef72013-05-11 15:02:58 +00001750s390_format_E(const HChar *(*irgen)(void))
1751{
1752 const HChar *mnm = irgen();
1753
1754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1755 s390_disasm(ENC1(MNM), mnm);
1756}
1757
1758static void
florian55085f82012-11-21 00:36:55 +00001759s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001760 UChar r1, UShort i2)
1761{
1762 irgen(r1, i2);
1763}
1764
1765static void
florian55085f82012-11-21 00:36:55 +00001766s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001767 UChar r1, UShort i2)
1768{
florian55085f82012-11-21 00:36:55 +00001769 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001770
sewardj7ee97522011-05-09 21:45:04 +00001771 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001772 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1773}
1774
1775static void
florian55085f82012-11-21 00:36:55 +00001776s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001777 UChar r1, UShort i2)
1778{
florian55085f82012-11-21 00:36:55 +00001779 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001780
sewardj7ee97522011-05-09 21:45:04 +00001781 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001782 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1783}
1784
1785static void
florian55085f82012-11-21 00:36:55 +00001786s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001787 UChar r1, UShort i2)
1788{
florian55085f82012-11-21 00:36:55 +00001789 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001790
sewardj7ee97522011-05-09 21:45:04 +00001791 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001792 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1793}
1794
1795static void
florian55085f82012-11-21 00:36:55 +00001796s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001797 UChar r1, UChar r3, UShort i2)
1798{
florian55085f82012-11-21 00:36:55 +00001799 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001800
sewardj7ee97522011-05-09 21:45:04 +00001801 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001802 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1803}
1804
1805static void
florian55085f82012-11-21 00:36:55 +00001806s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001807 UChar r1, UChar r3, UShort i2)
1808{
florian55085f82012-11-21 00:36:55 +00001809 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001810
sewardj7ee97522011-05-09 21:45:04 +00001811 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001812 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1813}
1814
1815static void
florian55085f82012-11-21 00:36:55 +00001816s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1817 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001818 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1819{
florian55085f82012-11-21 00:36:55 +00001820 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001821
sewardj7ee97522011-05-09 21:45:04 +00001822 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001823 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1824 i5);
1825}
1826
1827static void
florian55085f82012-11-21 00:36:55 +00001828s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1829 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001830 UChar r1, UChar r2, UShort i4, UChar m3)
1831{
florian55085f82012-11-21 00:36:55 +00001832 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001833
sewardj7ee97522011-05-09 21:45:04 +00001834 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001835 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1836 r2, m3, (Int)(Short)i4);
1837}
1838
1839static void
florian55085f82012-11-21 00:36:55 +00001840s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1841 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001842 UChar r1, UChar m3, UShort i4, UChar i2)
1843{
florian55085f82012-11-21 00:36:55 +00001844 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001845
sewardj7ee97522011-05-09 21:45:04 +00001846 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001847 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1848 r1, i2, m3, (Int)(Short)i4);
1849}
1850
1851static void
florian55085f82012-11-21 00:36:55 +00001852s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1853 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001854 UChar r1, UChar m3, UShort i4, UChar i2)
1855{
florian55085f82012-11-21 00:36:55 +00001856 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001857
sewardj7ee97522011-05-09 21:45:04 +00001858 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001859 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1860 (Int)(Char)i2, m3, (Int)(Short)i4);
1861}
1862
1863static void
florian55085f82012-11-21 00:36:55 +00001864s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001865 UChar r1, UInt i2)
1866{
1867 irgen(r1, i2);
1868}
1869
1870static void
florian55085f82012-11-21 00:36:55 +00001871s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001872 UChar r1, UInt i2)
1873{
florian55085f82012-11-21 00:36:55 +00001874 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001875
sewardj7ee97522011-05-09 21:45:04 +00001876 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001877 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1878}
1879
1880static void
florian55085f82012-11-21 00:36:55 +00001881s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001882 UChar r1, UInt i2)
1883{
florian55085f82012-11-21 00:36:55 +00001884 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001885
sewardj7ee97522011-05-09 21:45:04 +00001886 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001887 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1888}
1889
1890static void
florian55085f82012-11-21 00:36:55 +00001891s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001892 UChar r1, UInt i2)
1893{
florian55085f82012-11-21 00:36:55 +00001894 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001895
sewardj7ee97522011-05-09 21:45:04 +00001896 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001897 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1898}
1899
1900static void
florian55085f82012-11-21 00:36:55 +00001901s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001902 UChar r1, UInt i2)
1903{
florian55085f82012-11-21 00:36:55 +00001904 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001905
sewardj7ee97522011-05-09 21:45:04 +00001906 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001907 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1908}
1909
1910static void
florian55085f82012-11-21 00:36:55 +00001911s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001912 IRTemp op4addr),
1913 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1914{
florian55085f82012-11-21 00:36:55 +00001915 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001916 IRTemp op4addr = newTemp(Ity_I64);
1917
1918 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1919 mkU64(0)));
1920
1921 mnm = irgen(r1, m3, i2, op4addr);
1922
sewardj7ee97522011-05-09 21:45:04 +00001923 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001924 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1925 (Int)(Char)i2, m3, d4, 0, b4);
1926}
1927
1928static void
florian55085f82012-11-21 00:36:55 +00001929s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001930 IRTemp op4addr),
1931 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1932{
florian55085f82012-11-21 00:36:55 +00001933 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001934 IRTemp op4addr = newTemp(Ity_I64);
1935
1936 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1937 mkU64(0)));
1938
1939 mnm = irgen(r1, m3, i2, op4addr);
1940
sewardj7ee97522011-05-09 21:45:04 +00001941 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001942 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1943 i2, m3, d4, 0, b4);
1944}
1945
1946static void
florian55085f82012-11-21 00:36:55 +00001947s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001948 UChar r1, UChar r2)
1949{
1950 irgen(r1, r2);
1951}
1952
1953static void
florian55085f82012-11-21 00:36:55 +00001954s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001955 UChar r1, UChar r2)
1956{
florian55085f82012-11-21 00:36:55 +00001957 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001958
sewardj7ee97522011-05-09 21:45:04 +00001959 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001960 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1961}
1962
1963static void
florian55085f82012-11-21 00:36:55 +00001964s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001965 UChar r1, UChar r2)
1966{
florian55085f82012-11-21 00:36:55 +00001967 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001968
sewardj7ee97522011-05-09 21:45:04 +00001969 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001970 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1971}
1972
1973static void
florian55085f82012-11-21 00:36:55 +00001974s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001975 UChar r1, UChar r2)
1976{
1977 irgen(r1, r2);
1978}
1979
1980static void
florian55085f82012-11-21 00:36:55 +00001981s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001982 UChar r1, UChar r2)
1983{
florian55085f82012-11-21 00:36:55 +00001984 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001985
sewardj7ee97522011-05-09 21:45:04 +00001986 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001987 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1988}
1989
1990static void
florian55085f82012-11-21 00:36:55 +00001991s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001992 UChar r1, UChar r2)
1993{
florian55085f82012-11-21 00:36:55 +00001994 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001995
sewardj7ee97522011-05-09 21:45:04 +00001996 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001997 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1998}
1999
2000static void
florian55085f82012-11-21 00:36:55 +00002001s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002002 UChar r1, UChar r2)
2003{
florian55085f82012-11-21 00:36:55 +00002004 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002005
sewardj7ee97522011-05-09 21:45:04 +00002006 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002007 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
2008}
2009
2010static void
florian55085f82012-11-21 00:36:55 +00002011s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002012 UChar r1, UChar r2)
2013{
florian55085f82012-11-21 00:36:55 +00002014 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002015
sewardj7ee97522011-05-09 21:45:04 +00002016 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002017 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2018}
2019
2020static void
florian55085f82012-11-21 00:36:55 +00002021s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002022 UChar r1)
2023{
florian55085f82012-11-21 00:36:55 +00002024 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002025
sewardj7ee97522011-05-09 21:45:04 +00002026 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002027 s390_disasm(ENC2(MNM, GPR), mnm, r1);
2028}
2029
2030static void
florian55085f82012-11-21 00:36:55 +00002031s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002032 UChar r1)
2033{
florian55085f82012-11-21 00:36:55 +00002034 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002035
sewardj7ee97522011-05-09 21:45:04 +00002036 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002037 s390_disasm(ENC2(MNM, FPR), mnm, r1);
2038}
2039
2040static void
florian55085f82012-11-21 00:36:55 +00002041s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002042 UChar m3, UChar r1, UChar r2)
2043{
florian55085f82012-11-21 00:36:55 +00002044 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002045
2046 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002047 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002048}
2049
2050static void
florian55085f82012-11-21 00:36:55 +00002051s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002052 UChar r1, UChar r3, UChar r2)
2053{
florian55085f82012-11-21 00:36:55 +00002054 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002055
sewardj7ee97522011-05-09 21:45:04 +00002056 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002057 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2058}
2059
2060static void
florian5c539732013-02-14 14:27:12 +00002061s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2062 UChar r3, UChar r1, UChar r2)
2063{
2064 const HChar *mnm = irgen(r3, r1, r2);
2065
2066 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2067 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2068}
2069
2070static void
florian55085f82012-11-21 00:36:55 +00002071s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2072 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002073 UChar m3, UChar m4, UChar r1, UChar r2)
2074{
florian55085f82012-11-21 00:36:55 +00002075 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002076
2077 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2078 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2079}
2080
2081static void
floriane38f6412012-12-21 17:32:12 +00002082s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2083 UChar m4, UChar r1, UChar r2)
2084{
2085 const HChar *mnm = irgen(m4, r1, r2);
2086
2087 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2088 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2089}
2090
2091static void
florian55085f82012-11-21 00:36:55 +00002092s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2093 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002094 UChar m3, UChar m4, UChar r1, UChar r2)
2095{
florian55085f82012-11-21 00:36:55 +00002096 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002097
2098 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2099 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2100}
2101
2102static void
florian55085f82012-11-21 00:36:55 +00002103s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2104 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002105 UChar m3, UChar m4, UChar r1, UChar r2)
2106{
florian55085f82012-11-21 00:36:55 +00002107 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002108
2109 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2110 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2111}
2112
2113
2114static void
florian55085f82012-11-21 00:36:55 +00002115s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002116 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2117{
2118 irgen(m3, r1, r2);
2119
sewardj7ee97522011-05-09 21:45:04 +00002120 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002121 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2122}
2123
2124static void
florian55085f82012-11-21 00:36:55 +00002125s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002126 UChar r3, UChar r1, UChar r2)
2127{
florian55085f82012-11-21 00:36:55 +00002128 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002129
sewardj7ee97522011-05-09 21:45:04 +00002130 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002131 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2132}
2133
2134static void
florian5c539732013-02-14 14:27:12 +00002135s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2136 UChar r3, UChar m4, UChar r1, UChar r2)
2137{
2138 const HChar *mnm = irgen(r3, m4, r1, r2);
2139
2140 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2141 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2142}
2143
2144static void
2145s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2146 UChar r3, UChar m4, UChar r1, UChar r2)
2147{
2148 const HChar *mnm = irgen(r3, m4, r1, r2);
2149
2150 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2151 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2152}
2153
2154static void
florian55085f82012-11-21 00:36:55 +00002155s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002156 UChar r3, UChar m4, UChar r1, UChar r2)
2157{
florian55085f82012-11-21 00:36:55 +00002158 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002159
2160 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2161 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2162}
2163
2164static void
florian55085f82012-11-21 00:36:55 +00002165s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002166 UChar r3, UChar r1, UChar r2)
2167{
florian55085f82012-11-21 00:36:55 +00002168 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002169
sewardj7ee97522011-05-09 21:45:04 +00002170 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002171 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2172}
2173
2174static void
florian55085f82012-11-21 00:36:55 +00002175s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2176 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002177 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2178{
florian55085f82012-11-21 00:36:55 +00002179 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002180 IRTemp op4addr = newTemp(Ity_I64);
2181
2182 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2183 mkU64(0)));
2184
2185 mnm = irgen(r1, r2, m3, op4addr);
2186
sewardj7ee97522011-05-09 21:45:04 +00002187 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002188 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2189 r2, m3, d4, 0, b4);
2190}
2191
2192static void
florian55085f82012-11-21 00:36:55 +00002193s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002194 UChar r1, UChar b2, UShort d2)
2195{
florian55085f82012-11-21 00:36:55 +00002196 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002197 IRTemp op2addr = newTemp(Ity_I64);
2198
2199 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2200 mkU64(0)));
2201
2202 mnm = irgen(r1, op2addr);
2203
sewardj7ee97522011-05-09 21:45:04 +00002204 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002205 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2206}
2207
2208static void
florian55085f82012-11-21 00:36:55 +00002209s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002210 UChar r1, UChar r3, UChar b2, UShort d2)
2211{
florian55085f82012-11-21 00:36:55 +00002212 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002213 IRTemp op2addr = newTemp(Ity_I64);
2214
2215 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2216 mkU64(0)));
2217
2218 mnm = irgen(r1, r3, op2addr);
2219
sewardj7ee97522011-05-09 21:45:04 +00002220 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002221 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2222}
2223
2224static void
florian55085f82012-11-21 00:36:55 +00002225s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002226 UChar r1, UChar r3, UChar b2, UShort d2)
2227{
florian55085f82012-11-21 00:36:55 +00002228 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002229 IRTemp op2addr = newTemp(Ity_I64);
2230
2231 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2232 mkU64(0)));
2233
2234 mnm = irgen(r1, r3, op2addr);
2235
sewardj7ee97522011-05-09 21:45:04 +00002236 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002237 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2238}
2239
2240static void
florian55085f82012-11-21 00:36:55 +00002241s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002242 UChar r1, UChar r3, UChar b2, UShort d2)
2243{
florian55085f82012-11-21 00:36:55 +00002244 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002245 IRTemp op2addr = newTemp(Ity_I64);
2246
2247 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2248 mkU64(0)));
2249
2250 mnm = irgen(r1, r3, op2addr);
2251
sewardj7ee97522011-05-09 21:45:04 +00002252 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002253 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2254}
2255
2256static void
florian55085f82012-11-21 00:36:55 +00002257s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002258 UChar r1, UChar r3, UShort i2)
2259{
florian55085f82012-11-21 00:36:55 +00002260 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002261
sewardj7ee97522011-05-09 21:45:04 +00002262 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002263 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2264}
2265
2266static void
florian55085f82012-11-21 00:36:55 +00002267s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002268 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2269{
florian55085f82012-11-21 00:36:55 +00002270 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002271 IRTemp op2addr = newTemp(Ity_I64);
2272 IRTemp d2 = newTemp(Ity_I64);
2273
2274 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2275 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2276 mkU64(0)));
2277
2278 mnm = irgen(r1, r3, op2addr);
2279
sewardj7ee97522011-05-09 21:45:04 +00002280 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002281 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2282}
2283
2284static void
florian55085f82012-11-21 00:36:55 +00002285s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002286 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2287{
florian55085f82012-11-21 00:36:55 +00002288 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002289 IRTemp op2addr = newTemp(Ity_I64);
2290 IRTemp d2 = newTemp(Ity_I64);
2291
2292 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2293 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2294 mkU64(0)));
2295
2296 mnm = irgen(r1, r3, op2addr);
2297
sewardj7ee97522011-05-09 21:45:04 +00002298 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002299 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2300}
2301
2302static void
florian55085f82012-11-21 00:36:55 +00002303s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002304 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2305{
florian55085f82012-11-21 00:36:55 +00002306 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002307 IRTemp op2addr = newTemp(Ity_I64);
2308 IRTemp d2 = newTemp(Ity_I64);
2309
2310 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2311 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2312 mkU64(0)));
2313
2314 mnm = irgen(r1, r3, op2addr);
2315
sewardj7ee97522011-05-09 21:45:04 +00002316 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002317 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2318}
2319
2320static void
florian55085f82012-11-21 00:36:55 +00002321s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002322 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2323 Int xmnm_kind)
2324{
2325 IRTemp op2addr = newTemp(Ity_I64);
2326 IRTemp d2 = newTemp(Ity_I64);
2327
florian6820ba52012-07-26 02:01:50 +00002328 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2329
sewardjd7bde722011-04-05 13:19:33 +00002330 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2331 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2332 mkU64(0)));
2333
2334 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002335
2336 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002337
sewardj7ee97522011-05-09 21:45:04 +00002338 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002339 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2340}
2341
2342static void
florian55085f82012-11-21 00:36:55 +00002343s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002344 IRTemp op2addr),
2345 UChar r1, UChar x2, UChar b2, UShort d2)
2346{
2347 IRTemp op2addr = newTemp(Ity_I64);
2348
2349 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2350 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2351 mkU64(0)));
2352
2353 irgen(r1, x2, b2, d2, op2addr);
2354}
2355
2356static void
florian55085f82012-11-21 00:36:55 +00002357s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002358 UChar r1, UChar x2, UChar b2, UShort d2)
2359{
florian55085f82012-11-21 00:36:55 +00002360 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002361 IRTemp op2addr = newTemp(Ity_I64);
2362
2363 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2364 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2365 mkU64(0)));
2366
2367 mnm = irgen(r1, op2addr);
2368
sewardj7ee97522011-05-09 21:45:04 +00002369 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002370 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2371}
2372
2373static void
florian55085f82012-11-21 00:36:55 +00002374s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002375 UChar r1, UChar x2, UChar b2, UShort d2)
2376{
florian55085f82012-11-21 00:36:55 +00002377 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002378 IRTemp op2addr = newTemp(Ity_I64);
2379
2380 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2381 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2382 mkU64(0)));
2383
2384 mnm = irgen(r1, op2addr);
2385
sewardj7ee97522011-05-09 21:45:04 +00002386 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002387 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2388}
2389
2390static void
florian55085f82012-11-21 00:36:55 +00002391s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002392 UChar r1, UChar x2, UChar b2, UShort d2)
2393{
florian55085f82012-11-21 00:36:55 +00002394 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002395 IRTemp op2addr = newTemp(Ity_I64);
2396
2397 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2398 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2399 mkU64(0)));
2400
2401 mnm = irgen(r1, op2addr);
2402
sewardj7ee97522011-05-09 21:45:04 +00002403 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002404 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2405}
2406
2407static void
florian55085f82012-11-21 00:36:55 +00002408s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002409 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2410{
florian55085f82012-11-21 00:36:55 +00002411 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002412 IRTemp op2addr = newTemp(Ity_I64);
2413
2414 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2415 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2416 mkU64(0)));
2417
2418 mnm = irgen(r3, op2addr, r1);
2419
sewardj7ee97522011-05-09 21:45:04 +00002420 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002421 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2422}
2423
2424static void
florian55085f82012-11-21 00:36:55 +00002425s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002426 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2427{
florian55085f82012-11-21 00:36:55 +00002428 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002429 IRTemp op2addr = newTemp(Ity_I64);
2430 IRTemp d2 = newTemp(Ity_I64);
2431
2432 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2433 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2434 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2435 mkU64(0)));
2436
2437 mnm = irgen(r1, op2addr);
2438
sewardj7ee97522011-05-09 21:45:04 +00002439 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002440 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2441}
2442
2443static void
florian55085f82012-11-21 00:36:55 +00002444s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002445 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2446{
florian55085f82012-11-21 00:36:55 +00002447 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002448 IRTemp op2addr = newTemp(Ity_I64);
2449 IRTemp d2 = newTemp(Ity_I64);
2450
2451 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2452 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2453 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2454 mkU64(0)));
2455
2456 mnm = irgen(r1, op2addr);
2457
sewardj7ee97522011-05-09 21:45:04 +00002458 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002459 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2460}
2461
2462static void
florian55085f82012-11-21 00:36:55 +00002463s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002464 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2465{
florian55085f82012-11-21 00:36:55 +00002466 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002467 IRTemp op2addr = newTemp(Ity_I64);
2468 IRTemp d2 = newTemp(Ity_I64);
2469
2470 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2471 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2472 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2473 mkU64(0)));
2474
2475 mnm = irgen();
2476
sewardj7ee97522011-05-09 21:45:04 +00002477 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002478 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2479}
2480
2481static void
florian55085f82012-11-21 00:36:55 +00002482s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002483 UChar b2, UShort d2)
2484{
florian55085f82012-11-21 00:36:55 +00002485 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002486 IRTemp op2addr = newTemp(Ity_I64);
2487
2488 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2489 mkU64(0)));
2490
2491 mnm = irgen(op2addr);
2492
sewardj7ee97522011-05-09 21:45:04 +00002493 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002494 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2495}
2496
2497static void
florian55085f82012-11-21 00:36:55 +00002498s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002499 UChar i2, UChar b1, UShort d1)
2500{
florian55085f82012-11-21 00:36:55 +00002501 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002502 IRTemp op1addr = newTemp(Ity_I64);
2503
2504 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2505 mkU64(0)));
2506
2507 mnm = irgen(i2, op1addr);
2508
sewardj7ee97522011-05-09 21:45:04 +00002509 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002510 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2511}
2512
2513static void
florian55085f82012-11-21 00:36:55 +00002514s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002515 UChar i2, UChar b1, UShort dl1, UChar dh1)
2516{
florian55085f82012-11-21 00:36:55 +00002517 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002518 IRTemp op1addr = newTemp(Ity_I64);
2519 IRTemp d1 = newTemp(Ity_I64);
2520
2521 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2522 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2523 mkU64(0)));
2524
2525 mnm = irgen(i2, op1addr);
2526
sewardj7ee97522011-05-09 21:45:04 +00002527 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002528 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2529}
2530
2531static void
florian55085f82012-11-21 00:36:55 +00002532s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002533 UChar i2, UChar b1, UShort dl1, UChar dh1)
2534{
florian55085f82012-11-21 00:36:55 +00002535 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002536 IRTemp op1addr = newTemp(Ity_I64);
2537 IRTemp d1 = newTemp(Ity_I64);
2538
2539 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2540 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2541 mkU64(0)));
2542
2543 mnm = irgen(i2, op1addr);
2544
sewardj7ee97522011-05-09 21:45:04 +00002545 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002546 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2547}
2548
2549static void
florian55085f82012-11-21 00:36:55 +00002550s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002551 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2552{
florian55085f82012-11-21 00:36:55 +00002553 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002554 IRTemp op1addr = newTemp(Ity_I64);
2555 IRTemp op2addr = newTemp(Ity_I64);
2556
2557 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2558 mkU64(0)));
2559 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2560 mkU64(0)));
2561
2562 mnm = irgen(l, op1addr, op2addr);
2563
sewardj7ee97522011-05-09 21:45:04 +00002564 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002565 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2566}
2567
2568static void
florian55085f82012-11-21 00:36:55 +00002569s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002570 UChar b1, UShort d1, UShort i2)
2571{
florian55085f82012-11-21 00:36:55 +00002572 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002573 IRTemp op1addr = newTemp(Ity_I64);
2574
2575 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2576 mkU64(0)));
2577
2578 mnm = irgen(i2, op1addr);
2579
sewardj7ee97522011-05-09 21:45:04 +00002580 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002581 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2582}
2583
2584static void
florian55085f82012-11-21 00:36:55 +00002585s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002586 UChar b1, UShort d1, UShort i2)
2587{
florian55085f82012-11-21 00:36:55 +00002588 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002589 IRTemp op1addr = newTemp(Ity_I64);
2590
2591 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2592 mkU64(0)));
2593
2594 mnm = irgen(i2, op1addr);
2595
sewardj7ee97522011-05-09 21:45:04 +00002596 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002597 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2598}
2599
2600
2601
2602/*------------------------------------------------------------*/
2603/*--- Build IR for opcodes ---*/
2604/*------------------------------------------------------------*/
2605
florian55085f82012-11-21 00:36:55 +00002606static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002607s390_irgen_AR(UChar r1, UChar r2)
2608{
2609 IRTemp op1 = newTemp(Ity_I32);
2610 IRTemp op2 = newTemp(Ity_I32);
2611 IRTemp result = newTemp(Ity_I32);
2612
2613 assign(op1, get_gpr_w1(r1));
2614 assign(op2, get_gpr_w1(r2));
2615 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2616 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2617 put_gpr_w1(r1, mkexpr(result));
2618
2619 return "ar";
2620}
2621
florian55085f82012-11-21 00:36:55 +00002622static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002623s390_irgen_AGR(UChar r1, UChar r2)
2624{
2625 IRTemp op1 = newTemp(Ity_I64);
2626 IRTemp op2 = newTemp(Ity_I64);
2627 IRTemp result = newTemp(Ity_I64);
2628
2629 assign(op1, get_gpr_dw0(r1));
2630 assign(op2, get_gpr_dw0(r2));
2631 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2632 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2633 put_gpr_dw0(r1, mkexpr(result));
2634
2635 return "agr";
2636}
2637
florian55085f82012-11-21 00:36:55 +00002638static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002639s390_irgen_AGFR(UChar r1, UChar r2)
2640{
2641 IRTemp op1 = newTemp(Ity_I64);
2642 IRTemp op2 = newTemp(Ity_I64);
2643 IRTemp result = newTemp(Ity_I64);
2644
2645 assign(op1, get_gpr_dw0(r1));
2646 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2647 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2648 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2649 put_gpr_dw0(r1, mkexpr(result));
2650
2651 return "agfr";
2652}
2653
florian55085f82012-11-21 00:36:55 +00002654static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002655s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2656{
2657 IRTemp op2 = newTemp(Ity_I32);
2658 IRTemp op3 = newTemp(Ity_I32);
2659 IRTemp result = newTemp(Ity_I32);
2660
2661 assign(op2, get_gpr_w1(r2));
2662 assign(op3, get_gpr_w1(r3));
2663 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2664 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2665 put_gpr_w1(r1, mkexpr(result));
2666
2667 return "ark";
2668}
2669
florian55085f82012-11-21 00:36:55 +00002670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002671s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2672{
2673 IRTemp op2 = newTemp(Ity_I64);
2674 IRTemp op3 = newTemp(Ity_I64);
2675 IRTemp result = newTemp(Ity_I64);
2676
2677 assign(op2, get_gpr_dw0(r2));
2678 assign(op3, get_gpr_dw0(r3));
2679 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2680 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2681 put_gpr_dw0(r1, mkexpr(result));
2682
2683 return "agrk";
2684}
2685
florian55085f82012-11-21 00:36:55 +00002686static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002687s390_irgen_A(UChar r1, IRTemp op2addr)
2688{
2689 IRTemp op1 = newTemp(Ity_I32);
2690 IRTemp op2 = newTemp(Ity_I32);
2691 IRTemp result = newTemp(Ity_I32);
2692
2693 assign(op1, get_gpr_w1(r1));
2694 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2695 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2696 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2697 put_gpr_w1(r1, mkexpr(result));
2698
2699 return "a";
2700}
2701
florian55085f82012-11-21 00:36:55 +00002702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002703s390_irgen_AY(UChar r1, IRTemp op2addr)
2704{
2705 IRTemp op1 = newTemp(Ity_I32);
2706 IRTemp op2 = newTemp(Ity_I32);
2707 IRTemp result = newTemp(Ity_I32);
2708
2709 assign(op1, get_gpr_w1(r1));
2710 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2711 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2712 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2713 put_gpr_w1(r1, mkexpr(result));
2714
2715 return "ay";
2716}
2717
florian55085f82012-11-21 00:36:55 +00002718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002719s390_irgen_AG(UChar r1, IRTemp op2addr)
2720{
2721 IRTemp op1 = newTemp(Ity_I64);
2722 IRTemp op2 = newTemp(Ity_I64);
2723 IRTemp result = newTemp(Ity_I64);
2724
2725 assign(op1, get_gpr_dw0(r1));
2726 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2727 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2728 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2729 put_gpr_dw0(r1, mkexpr(result));
2730
2731 return "ag";
2732}
2733
florian55085f82012-11-21 00:36:55 +00002734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002735s390_irgen_AGF(UChar r1, IRTemp op2addr)
2736{
2737 IRTemp op1 = newTemp(Ity_I64);
2738 IRTemp op2 = newTemp(Ity_I64);
2739 IRTemp result = newTemp(Ity_I64);
2740
2741 assign(op1, get_gpr_dw0(r1));
2742 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2743 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2744 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2745 put_gpr_dw0(r1, mkexpr(result));
2746
2747 return "agf";
2748}
2749
florian55085f82012-11-21 00:36:55 +00002750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002751s390_irgen_AFI(UChar r1, UInt i2)
2752{
2753 IRTemp op1 = newTemp(Ity_I32);
2754 Int op2;
2755 IRTemp result = newTemp(Ity_I32);
2756
2757 assign(op1, get_gpr_w1(r1));
2758 op2 = (Int)i2;
2759 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2760 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2761 mkU32((UInt)op2)));
2762 put_gpr_w1(r1, mkexpr(result));
2763
2764 return "afi";
2765}
2766
florian55085f82012-11-21 00:36:55 +00002767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002768s390_irgen_AGFI(UChar r1, UInt i2)
2769{
2770 IRTemp op1 = newTemp(Ity_I64);
2771 Long op2;
2772 IRTemp result = newTemp(Ity_I64);
2773
2774 assign(op1, get_gpr_dw0(r1));
2775 op2 = (Long)(Int)i2;
2776 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2777 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2778 mkU64((ULong)op2)));
2779 put_gpr_dw0(r1, mkexpr(result));
2780
2781 return "agfi";
2782}
2783
florian55085f82012-11-21 00:36:55 +00002784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002785s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2786{
2787 Int op2;
2788 IRTemp op3 = newTemp(Ity_I32);
2789 IRTemp result = newTemp(Ity_I32);
2790
2791 op2 = (Int)(Short)i2;
2792 assign(op3, get_gpr_w1(r3));
2793 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2794 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2795 op2)), op3);
2796 put_gpr_w1(r1, mkexpr(result));
2797
2798 return "ahik";
2799}
2800
florian55085f82012-11-21 00:36:55 +00002801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002802s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2803{
2804 Long op2;
2805 IRTemp op3 = newTemp(Ity_I64);
2806 IRTemp result = newTemp(Ity_I64);
2807
2808 op2 = (Long)(Short)i2;
2809 assign(op3, get_gpr_dw0(r3));
2810 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2811 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2812 op2)), op3);
2813 put_gpr_dw0(r1, mkexpr(result));
2814
2815 return "aghik";
2816}
2817
florian55085f82012-11-21 00:36:55 +00002818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002819s390_irgen_ASI(UChar i2, IRTemp op1addr)
2820{
2821 IRTemp op1 = newTemp(Ity_I32);
2822 Int op2;
2823 IRTemp result = newTemp(Ity_I32);
2824
2825 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2826 op2 = (Int)(Char)i2;
2827 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2828 store(mkexpr(op1addr), mkexpr(result));
2829 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2830 mkU32((UInt)op2)));
2831
2832 return "asi";
2833}
2834
florian55085f82012-11-21 00:36:55 +00002835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002836s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2837{
2838 IRTemp op1 = newTemp(Ity_I64);
2839 Long op2;
2840 IRTemp result = newTemp(Ity_I64);
2841
2842 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2843 op2 = (Long)(Char)i2;
2844 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2845 store(mkexpr(op1addr), mkexpr(result));
2846 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2847 mkU64((ULong)op2)));
2848
2849 return "agsi";
2850}
2851
florian55085f82012-11-21 00:36:55 +00002852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002853s390_irgen_AH(UChar r1, IRTemp op2addr)
2854{
2855 IRTemp op1 = newTemp(Ity_I32);
2856 IRTemp op2 = newTemp(Ity_I32);
2857 IRTemp result = newTemp(Ity_I32);
2858
2859 assign(op1, get_gpr_w1(r1));
2860 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2861 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2862 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2863 put_gpr_w1(r1, mkexpr(result));
2864
2865 return "ah";
2866}
2867
florian55085f82012-11-21 00:36:55 +00002868static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002869s390_irgen_AHY(UChar r1, IRTemp op2addr)
2870{
2871 IRTemp op1 = newTemp(Ity_I32);
2872 IRTemp op2 = newTemp(Ity_I32);
2873 IRTemp result = newTemp(Ity_I32);
2874
2875 assign(op1, get_gpr_w1(r1));
2876 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2877 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2878 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2879 put_gpr_w1(r1, mkexpr(result));
2880
2881 return "ahy";
2882}
2883
florian55085f82012-11-21 00:36:55 +00002884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002885s390_irgen_AHI(UChar r1, UShort i2)
2886{
2887 IRTemp op1 = newTemp(Ity_I32);
2888 Int op2;
2889 IRTemp result = newTemp(Ity_I32);
2890
2891 assign(op1, get_gpr_w1(r1));
2892 op2 = (Int)(Short)i2;
2893 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2894 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2895 mkU32((UInt)op2)));
2896 put_gpr_w1(r1, mkexpr(result));
2897
2898 return "ahi";
2899}
2900
florian55085f82012-11-21 00:36:55 +00002901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002902s390_irgen_AGHI(UChar r1, UShort i2)
2903{
2904 IRTemp op1 = newTemp(Ity_I64);
2905 Long op2;
2906 IRTemp result = newTemp(Ity_I64);
2907
2908 assign(op1, get_gpr_dw0(r1));
2909 op2 = (Long)(Short)i2;
2910 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2911 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2912 mkU64((ULong)op2)));
2913 put_gpr_dw0(r1, mkexpr(result));
2914
2915 return "aghi";
2916}
2917
florian55085f82012-11-21 00:36:55 +00002918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002919s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2920{
2921 IRTemp op2 = newTemp(Ity_I32);
2922 IRTemp op3 = newTemp(Ity_I32);
2923 IRTemp result = newTemp(Ity_I32);
2924
2925 assign(op2, get_gpr_w0(r2));
2926 assign(op3, get_gpr_w0(r3));
2927 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2928 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2929 put_gpr_w0(r1, mkexpr(result));
2930
2931 return "ahhhr";
2932}
2933
florian55085f82012-11-21 00:36:55 +00002934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002935s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2936{
2937 IRTemp op2 = newTemp(Ity_I32);
2938 IRTemp op3 = newTemp(Ity_I32);
2939 IRTemp result = newTemp(Ity_I32);
2940
2941 assign(op2, get_gpr_w0(r2));
2942 assign(op3, get_gpr_w1(r3));
2943 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2944 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2945 put_gpr_w0(r1, mkexpr(result));
2946
2947 return "ahhlr";
2948}
2949
florian55085f82012-11-21 00:36:55 +00002950static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002951s390_irgen_AIH(UChar r1, UInt i2)
2952{
2953 IRTemp op1 = newTemp(Ity_I32);
2954 Int op2;
2955 IRTemp result = newTemp(Ity_I32);
2956
2957 assign(op1, get_gpr_w0(r1));
2958 op2 = (Int)i2;
2959 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2960 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2961 mkU32((UInt)op2)));
2962 put_gpr_w0(r1, mkexpr(result));
2963
2964 return "aih";
2965}
2966
florian55085f82012-11-21 00:36:55 +00002967static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002968s390_irgen_ALR(UChar r1, UChar r2)
2969{
2970 IRTemp op1 = newTemp(Ity_I32);
2971 IRTemp op2 = newTemp(Ity_I32);
2972 IRTemp result = newTemp(Ity_I32);
2973
2974 assign(op1, get_gpr_w1(r1));
2975 assign(op2, get_gpr_w1(r2));
2976 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2977 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2978 put_gpr_w1(r1, mkexpr(result));
2979
2980 return "alr";
2981}
2982
florian55085f82012-11-21 00:36:55 +00002983static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002984s390_irgen_ALGR(UChar r1, UChar r2)
2985{
2986 IRTemp op1 = newTemp(Ity_I64);
2987 IRTemp op2 = newTemp(Ity_I64);
2988 IRTemp result = newTemp(Ity_I64);
2989
2990 assign(op1, get_gpr_dw0(r1));
2991 assign(op2, get_gpr_dw0(r2));
2992 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2993 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2994 put_gpr_dw0(r1, mkexpr(result));
2995
2996 return "algr";
2997}
2998
florian55085f82012-11-21 00:36:55 +00002999static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003000s390_irgen_ALGFR(UChar r1, UChar r2)
3001{
3002 IRTemp op1 = newTemp(Ity_I64);
3003 IRTemp op2 = newTemp(Ity_I64);
3004 IRTemp result = newTemp(Ity_I64);
3005
3006 assign(op1, get_gpr_dw0(r1));
3007 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
3008 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3009 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3010 put_gpr_dw0(r1, mkexpr(result));
3011
3012 return "algfr";
3013}
3014
florian55085f82012-11-21 00:36:55 +00003015static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003016s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
3017{
3018 IRTemp op2 = newTemp(Ity_I32);
3019 IRTemp op3 = newTemp(Ity_I32);
3020 IRTemp result = newTemp(Ity_I32);
3021
3022 assign(op2, get_gpr_w1(r2));
3023 assign(op3, get_gpr_w1(r3));
3024 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3025 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3026 put_gpr_w1(r1, mkexpr(result));
3027
3028 return "alrk";
3029}
3030
florian55085f82012-11-21 00:36:55 +00003031static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003032s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
3033{
3034 IRTemp op2 = newTemp(Ity_I64);
3035 IRTemp op3 = newTemp(Ity_I64);
3036 IRTemp result = newTemp(Ity_I64);
3037
3038 assign(op2, get_gpr_dw0(r2));
3039 assign(op3, get_gpr_dw0(r3));
3040 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
3041 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3042 put_gpr_dw0(r1, mkexpr(result));
3043
3044 return "algrk";
3045}
3046
florian55085f82012-11-21 00:36:55 +00003047static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003048s390_irgen_AL(UChar r1, IRTemp op2addr)
3049{
3050 IRTemp op1 = newTemp(Ity_I32);
3051 IRTemp op2 = newTemp(Ity_I32);
3052 IRTemp result = newTemp(Ity_I32);
3053
3054 assign(op1, get_gpr_w1(r1));
3055 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3056 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3057 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3058 put_gpr_w1(r1, mkexpr(result));
3059
3060 return "al";
3061}
3062
florian55085f82012-11-21 00:36:55 +00003063static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003064s390_irgen_ALY(UChar r1, IRTemp op2addr)
3065{
3066 IRTemp op1 = newTemp(Ity_I32);
3067 IRTemp op2 = newTemp(Ity_I32);
3068 IRTemp result = newTemp(Ity_I32);
3069
3070 assign(op1, get_gpr_w1(r1));
3071 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3072 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3073 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3074 put_gpr_w1(r1, mkexpr(result));
3075
3076 return "aly";
3077}
3078
florian55085f82012-11-21 00:36:55 +00003079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003080s390_irgen_ALG(UChar r1, IRTemp op2addr)
3081{
3082 IRTemp op1 = newTemp(Ity_I64);
3083 IRTemp op2 = newTemp(Ity_I64);
3084 IRTemp result = newTemp(Ity_I64);
3085
3086 assign(op1, get_gpr_dw0(r1));
3087 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3088 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3089 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3090 put_gpr_dw0(r1, mkexpr(result));
3091
3092 return "alg";
3093}
3094
florian55085f82012-11-21 00:36:55 +00003095static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003096s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3097{
3098 IRTemp op1 = newTemp(Ity_I64);
3099 IRTemp op2 = newTemp(Ity_I64);
3100 IRTemp result = newTemp(Ity_I64);
3101
3102 assign(op1, get_gpr_dw0(r1));
3103 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3104 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3105 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3106 put_gpr_dw0(r1, mkexpr(result));
3107
3108 return "algf";
3109}
3110
florian55085f82012-11-21 00:36:55 +00003111static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003112s390_irgen_ALFI(UChar r1, UInt i2)
3113{
3114 IRTemp op1 = newTemp(Ity_I32);
3115 UInt op2;
3116 IRTemp result = newTemp(Ity_I32);
3117
3118 assign(op1, get_gpr_w1(r1));
3119 op2 = i2;
3120 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3121 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3122 mkU32(op2)));
3123 put_gpr_w1(r1, mkexpr(result));
3124
3125 return "alfi";
3126}
3127
florian55085f82012-11-21 00:36:55 +00003128static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003129s390_irgen_ALGFI(UChar r1, UInt i2)
3130{
3131 IRTemp op1 = newTemp(Ity_I64);
3132 ULong op2;
3133 IRTemp result = newTemp(Ity_I64);
3134
3135 assign(op1, get_gpr_dw0(r1));
3136 op2 = (ULong)i2;
3137 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3138 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3139 mkU64(op2)));
3140 put_gpr_dw0(r1, mkexpr(result));
3141
3142 return "algfi";
3143}
3144
florian55085f82012-11-21 00:36:55 +00003145static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003146s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3147{
3148 IRTemp op2 = newTemp(Ity_I32);
3149 IRTemp op3 = newTemp(Ity_I32);
3150 IRTemp result = newTemp(Ity_I32);
3151
3152 assign(op2, get_gpr_w0(r2));
3153 assign(op3, get_gpr_w0(r3));
3154 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3155 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3156 put_gpr_w0(r1, mkexpr(result));
3157
3158 return "alhhhr";
3159}
3160
florian55085f82012-11-21 00:36:55 +00003161static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003162s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3163{
3164 IRTemp op2 = newTemp(Ity_I32);
3165 IRTemp op3 = newTemp(Ity_I32);
3166 IRTemp result = newTemp(Ity_I32);
3167
3168 assign(op2, get_gpr_w0(r2));
3169 assign(op3, get_gpr_w1(r3));
3170 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3171 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3172 put_gpr_w0(r1, mkexpr(result));
3173
3174 return "alhhlr";
3175}
3176
florian55085f82012-11-21 00:36:55 +00003177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003178s390_irgen_ALCR(UChar r1, UChar r2)
3179{
3180 IRTemp op1 = newTemp(Ity_I32);
3181 IRTemp op2 = newTemp(Ity_I32);
3182 IRTemp result = newTemp(Ity_I32);
3183 IRTemp carry_in = newTemp(Ity_I32);
3184
3185 assign(op1, get_gpr_w1(r1));
3186 assign(op2, get_gpr_w1(r2));
3187 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3188 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3189 mkexpr(carry_in)));
3190 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3191 put_gpr_w1(r1, mkexpr(result));
3192
3193 return "alcr";
3194}
3195
florian55085f82012-11-21 00:36:55 +00003196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003197s390_irgen_ALCGR(UChar r1, UChar r2)
3198{
3199 IRTemp op1 = newTemp(Ity_I64);
3200 IRTemp op2 = newTemp(Ity_I64);
3201 IRTemp result = newTemp(Ity_I64);
3202 IRTemp carry_in = newTemp(Ity_I64);
3203
3204 assign(op1, get_gpr_dw0(r1));
3205 assign(op2, get_gpr_dw0(r2));
3206 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3207 mkU8(1))));
3208 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3209 mkexpr(carry_in)));
3210 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3211 put_gpr_dw0(r1, mkexpr(result));
3212
3213 return "alcgr";
3214}
3215
florian55085f82012-11-21 00:36:55 +00003216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003217s390_irgen_ALC(UChar r1, IRTemp op2addr)
3218{
3219 IRTemp op1 = newTemp(Ity_I32);
3220 IRTemp op2 = newTemp(Ity_I32);
3221 IRTemp result = newTemp(Ity_I32);
3222 IRTemp carry_in = newTemp(Ity_I32);
3223
3224 assign(op1, get_gpr_w1(r1));
3225 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3226 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3227 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3228 mkexpr(carry_in)));
3229 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3230 put_gpr_w1(r1, mkexpr(result));
3231
3232 return "alc";
3233}
3234
florian55085f82012-11-21 00:36:55 +00003235static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003236s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3237{
3238 IRTemp op1 = newTemp(Ity_I64);
3239 IRTemp op2 = newTemp(Ity_I64);
3240 IRTemp result = newTemp(Ity_I64);
3241 IRTemp carry_in = newTemp(Ity_I64);
3242
3243 assign(op1, get_gpr_dw0(r1));
3244 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3245 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3246 mkU8(1))));
3247 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3248 mkexpr(carry_in)));
3249 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3250 put_gpr_dw0(r1, mkexpr(result));
3251
3252 return "alcg";
3253}
3254
florian55085f82012-11-21 00:36:55 +00003255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003256s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3257{
3258 IRTemp op1 = newTemp(Ity_I32);
3259 UInt op2;
3260 IRTemp result = newTemp(Ity_I32);
3261
3262 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3263 op2 = (UInt)(Int)(Char)i2;
3264 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3265 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3266 mkU32(op2)));
3267 store(mkexpr(op1addr), mkexpr(result));
3268
3269 return "alsi";
3270}
3271
florian55085f82012-11-21 00:36:55 +00003272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003273s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3274{
3275 IRTemp op1 = newTemp(Ity_I64);
3276 ULong op2;
3277 IRTemp result = newTemp(Ity_I64);
3278
3279 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3280 op2 = (ULong)(Long)(Char)i2;
3281 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3282 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3283 mkU64(op2)));
3284 store(mkexpr(op1addr), mkexpr(result));
3285
3286 return "algsi";
3287}
3288
florian55085f82012-11-21 00:36:55 +00003289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003290s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3291{
3292 UInt op2;
3293 IRTemp op3 = newTemp(Ity_I32);
3294 IRTemp result = newTemp(Ity_I32);
3295
3296 op2 = (UInt)(Int)(Short)i2;
3297 assign(op3, get_gpr_w1(r3));
3298 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3299 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3300 op3);
3301 put_gpr_w1(r1, mkexpr(result));
3302
3303 return "alhsik";
3304}
3305
florian55085f82012-11-21 00:36:55 +00003306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003307s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3308{
3309 ULong op2;
3310 IRTemp op3 = newTemp(Ity_I64);
3311 IRTemp result = newTemp(Ity_I64);
3312
3313 op2 = (ULong)(Long)(Short)i2;
3314 assign(op3, get_gpr_dw0(r3));
3315 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3316 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3317 op3);
3318 put_gpr_dw0(r1, mkexpr(result));
3319
3320 return "alghsik";
3321}
3322
florian55085f82012-11-21 00:36:55 +00003323static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003324s390_irgen_ALSIH(UChar r1, UInt i2)
3325{
3326 IRTemp op1 = newTemp(Ity_I32);
3327 UInt op2;
3328 IRTemp result = newTemp(Ity_I32);
3329
3330 assign(op1, get_gpr_w0(r1));
3331 op2 = i2;
3332 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3333 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3334 mkU32(op2)));
3335 put_gpr_w0(r1, mkexpr(result));
3336
3337 return "alsih";
3338}
3339
florian55085f82012-11-21 00:36:55 +00003340static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003341s390_irgen_ALSIHN(UChar r1, UInt i2)
3342{
3343 IRTemp op1 = newTemp(Ity_I32);
3344 UInt op2;
3345 IRTemp result = newTemp(Ity_I32);
3346
3347 assign(op1, get_gpr_w0(r1));
3348 op2 = i2;
3349 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3350 put_gpr_w0(r1, mkexpr(result));
3351
3352 return "alsihn";
3353}
3354
florian55085f82012-11-21 00:36:55 +00003355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003356s390_irgen_NR(UChar r1, UChar r2)
3357{
3358 IRTemp op1 = newTemp(Ity_I32);
3359 IRTemp op2 = newTemp(Ity_I32);
3360 IRTemp result = newTemp(Ity_I32);
3361
3362 assign(op1, get_gpr_w1(r1));
3363 assign(op2, get_gpr_w1(r2));
3364 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3365 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3366 put_gpr_w1(r1, mkexpr(result));
3367
3368 return "nr";
3369}
3370
florian55085f82012-11-21 00:36:55 +00003371static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003372s390_irgen_NGR(UChar r1, UChar r2)
3373{
3374 IRTemp op1 = newTemp(Ity_I64);
3375 IRTemp op2 = newTemp(Ity_I64);
3376 IRTemp result = newTemp(Ity_I64);
3377
3378 assign(op1, get_gpr_dw0(r1));
3379 assign(op2, get_gpr_dw0(r2));
3380 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3381 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3382 put_gpr_dw0(r1, mkexpr(result));
3383
3384 return "ngr";
3385}
3386
florian55085f82012-11-21 00:36:55 +00003387static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003388s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3389{
3390 IRTemp op2 = newTemp(Ity_I32);
3391 IRTemp op3 = newTemp(Ity_I32);
3392 IRTemp result = newTemp(Ity_I32);
3393
3394 assign(op2, get_gpr_w1(r2));
3395 assign(op3, get_gpr_w1(r3));
3396 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3397 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3398 put_gpr_w1(r1, mkexpr(result));
3399
3400 return "nrk";
3401}
3402
florian55085f82012-11-21 00:36:55 +00003403static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003404s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3405{
3406 IRTemp op2 = newTemp(Ity_I64);
3407 IRTemp op3 = newTemp(Ity_I64);
3408 IRTemp result = newTemp(Ity_I64);
3409
3410 assign(op2, get_gpr_dw0(r2));
3411 assign(op3, get_gpr_dw0(r3));
3412 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3413 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3414 put_gpr_dw0(r1, mkexpr(result));
3415
3416 return "ngrk";
3417}
3418
florian55085f82012-11-21 00:36:55 +00003419static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003420s390_irgen_N(UChar r1, IRTemp op2addr)
3421{
3422 IRTemp op1 = newTemp(Ity_I32);
3423 IRTemp op2 = newTemp(Ity_I32);
3424 IRTemp result = newTemp(Ity_I32);
3425
3426 assign(op1, get_gpr_w1(r1));
3427 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3428 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3429 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3430 put_gpr_w1(r1, mkexpr(result));
3431
3432 return "n";
3433}
3434
florian55085f82012-11-21 00:36:55 +00003435static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003436s390_irgen_NY(UChar r1, IRTemp op2addr)
3437{
3438 IRTemp op1 = newTemp(Ity_I32);
3439 IRTemp op2 = newTemp(Ity_I32);
3440 IRTemp result = newTemp(Ity_I32);
3441
3442 assign(op1, get_gpr_w1(r1));
3443 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3444 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3445 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3446 put_gpr_w1(r1, mkexpr(result));
3447
3448 return "ny";
3449}
3450
florian55085f82012-11-21 00:36:55 +00003451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003452s390_irgen_NG(UChar r1, IRTemp op2addr)
3453{
3454 IRTemp op1 = newTemp(Ity_I64);
3455 IRTemp op2 = newTemp(Ity_I64);
3456 IRTemp result = newTemp(Ity_I64);
3457
3458 assign(op1, get_gpr_dw0(r1));
3459 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3460 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3461 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3462 put_gpr_dw0(r1, mkexpr(result));
3463
3464 return "ng";
3465}
3466
florian55085f82012-11-21 00:36:55 +00003467static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003468s390_irgen_NI(UChar i2, IRTemp op1addr)
3469{
3470 IRTemp op1 = newTemp(Ity_I8);
3471 UChar op2;
3472 IRTemp result = newTemp(Ity_I8);
3473
3474 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3475 op2 = i2;
3476 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3477 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3478 store(mkexpr(op1addr), mkexpr(result));
3479
3480 return "ni";
3481}
3482
florian55085f82012-11-21 00:36:55 +00003483static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003484s390_irgen_NIY(UChar i2, IRTemp op1addr)
3485{
3486 IRTemp op1 = newTemp(Ity_I8);
3487 UChar op2;
3488 IRTemp result = newTemp(Ity_I8);
3489
3490 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3491 op2 = i2;
3492 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3493 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3494 store(mkexpr(op1addr), mkexpr(result));
3495
3496 return "niy";
3497}
3498
florian55085f82012-11-21 00:36:55 +00003499static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003500s390_irgen_NIHF(UChar r1, UInt i2)
3501{
3502 IRTemp op1 = newTemp(Ity_I32);
3503 UInt op2;
3504 IRTemp result = newTemp(Ity_I32);
3505
3506 assign(op1, get_gpr_w0(r1));
3507 op2 = i2;
3508 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3509 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3510 put_gpr_w0(r1, mkexpr(result));
3511
3512 return "nihf";
3513}
3514
florian55085f82012-11-21 00:36:55 +00003515static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003516s390_irgen_NIHH(UChar r1, UShort i2)
3517{
3518 IRTemp op1 = newTemp(Ity_I16);
3519 UShort op2;
3520 IRTemp result = newTemp(Ity_I16);
3521
3522 assign(op1, get_gpr_hw0(r1));
3523 op2 = i2;
3524 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3525 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3526 put_gpr_hw0(r1, mkexpr(result));
3527
3528 return "nihh";
3529}
3530
florian55085f82012-11-21 00:36:55 +00003531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003532s390_irgen_NIHL(UChar r1, UShort i2)
3533{
3534 IRTemp op1 = newTemp(Ity_I16);
3535 UShort op2;
3536 IRTemp result = newTemp(Ity_I16);
3537
3538 assign(op1, get_gpr_hw1(r1));
3539 op2 = i2;
3540 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3541 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3542 put_gpr_hw1(r1, mkexpr(result));
3543
3544 return "nihl";
3545}
3546
florian55085f82012-11-21 00:36:55 +00003547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003548s390_irgen_NILF(UChar r1, UInt i2)
3549{
3550 IRTemp op1 = newTemp(Ity_I32);
3551 UInt op2;
3552 IRTemp result = newTemp(Ity_I32);
3553
3554 assign(op1, get_gpr_w1(r1));
3555 op2 = i2;
3556 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3557 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3558 put_gpr_w1(r1, mkexpr(result));
3559
3560 return "nilf";
3561}
3562
florian55085f82012-11-21 00:36:55 +00003563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003564s390_irgen_NILH(UChar r1, UShort i2)
3565{
3566 IRTemp op1 = newTemp(Ity_I16);
3567 UShort op2;
3568 IRTemp result = newTemp(Ity_I16);
3569
3570 assign(op1, get_gpr_hw2(r1));
3571 op2 = i2;
3572 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3573 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3574 put_gpr_hw2(r1, mkexpr(result));
3575
3576 return "nilh";
3577}
3578
florian55085f82012-11-21 00:36:55 +00003579static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003580s390_irgen_NILL(UChar r1, UShort i2)
3581{
3582 IRTemp op1 = newTemp(Ity_I16);
3583 UShort op2;
3584 IRTemp result = newTemp(Ity_I16);
3585
3586 assign(op1, get_gpr_hw3(r1));
3587 op2 = i2;
3588 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3589 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3590 put_gpr_hw3(r1, mkexpr(result));
3591
3592 return "nill";
3593}
3594
florian55085f82012-11-21 00:36:55 +00003595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003596s390_irgen_BASR(UChar r1, UChar r2)
3597{
3598 IRTemp target = newTemp(Ity_I64);
3599
3600 if (r2 == 0) {
3601 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3602 } else {
3603 if (r1 != r2) {
3604 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3605 call_function(get_gpr_dw0(r2));
3606 } else {
3607 assign(target, get_gpr_dw0(r2));
3608 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3609 call_function(mkexpr(target));
3610 }
3611 }
3612
3613 return "basr";
3614}
3615
florian55085f82012-11-21 00:36:55 +00003616static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003617s390_irgen_BAS(UChar r1, IRTemp op2addr)
3618{
3619 IRTemp target = newTemp(Ity_I64);
3620
3621 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3622 assign(target, mkexpr(op2addr));
3623 call_function(mkexpr(target));
3624
3625 return "bas";
3626}
3627
florian55085f82012-11-21 00:36:55 +00003628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003629s390_irgen_BCR(UChar r1, UChar r2)
3630{
3631 IRTemp cond = newTemp(Ity_I32);
3632
sewardja52e37e2011-04-28 18:48:06 +00003633 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3634 stmt(IRStmt_MBE(Imbe_Fence));
3635 }
3636
sewardj2019a972011-03-07 16:04:07 +00003637 if ((r2 == 0) || (r1 == 0)) {
3638 } else {
3639 if (r1 == 15) {
3640 return_from_function(get_gpr_dw0(r2));
3641 } else {
3642 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003643 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3644 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003645 }
3646 }
sewardj7ee97522011-05-09 21:45:04 +00003647 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003648 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3649
3650 return "bcr";
3651}
3652
florian55085f82012-11-21 00:36:55 +00003653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003654s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3655{
3656 IRTemp cond = newTemp(Ity_I32);
3657
3658 if (r1 == 0) {
3659 } else {
3660 if (r1 == 15) {
3661 always_goto(mkexpr(op2addr));
3662 } else {
3663 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003664 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3665 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003666 }
3667 }
sewardj7ee97522011-05-09 21:45:04 +00003668 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003669 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3670
3671 return "bc";
3672}
3673
florian55085f82012-11-21 00:36:55 +00003674static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003675s390_irgen_BCTR(UChar r1, UChar r2)
3676{
3677 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3678 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003679 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3680 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003681 }
3682
3683 return "bctr";
3684}
3685
florian55085f82012-11-21 00:36:55 +00003686static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003687s390_irgen_BCTGR(UChar r1, UChar r2)
3688{
3689 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3690 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003691 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3692 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003693 }
3694
3695 return "bctgr";
3696}
3697
florian55085f82012-11-21 00:36:55 +00003698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003699s390_irgen_BCT(UChar r1, IRTemp op2addr)
3700{
3701 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003702 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3703 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003704
3705 return "bct";
3706}
3707
florian55085f82012-11-21 00:36:55 +00003708static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003709s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3710{
3711 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003712 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3713 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003714
3715 return "bctg";
3716}
3717
florian55085f82012-11-21 00:36:55 +00003718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003719s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3720{
3721 IRTemp value = newTemp(Ity_I32);
3722
3723 assign(value, get_gpr_w1(r3 | 1));
3724 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003725 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3726 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003727
3728 return "bxh";
3729}
3730
florian55085f82012-11-21 00:36:55 +00003731static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003732s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3733{
3734 IRTemp value = newTemp(Ity_I64);
3735
3736 assign(value, get_gpr_dw0(r3 | 1));
3737 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003738 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3739 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003740
3741 return "bxhg";
3742}
3743
florian55085f82012-11-21 00:36:55 +00003744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003745s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3746{
3747 IRTemp value = newTemp(Ity_I32);
3748
3749 assign(value, get_gpr_w1(r3 | 1));
3750 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003751 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3752 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003753
3754 return "bxle";
3755}
3756
florian55085f82012-11-21 00:36:55 +00003757static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003758s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3759{
3760 IRTemp value = newTemp(Ity_I64);
3761
3762 assign(value, get_gpr_dw0(r3 | 1));
3763 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003764 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3765 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003766
3767 return "bxleg";
3768}
3769
florian55085f82012-11-21 00:36:55 +00003770static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003771s390_irgen_BRAS(UChar r1, UShort i2)
3772{
3773 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003774 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003775
3776 return "bras";
3777}
3778
florian55085f82012-11-21 00:36:55 +00003779static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003780s390_irgen_BRASL(UChar r1, UInt i2)
3781{
3782 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003783 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003784
3785 return "brasl";
3786}
3787
florian55085f82012-11-21 00:36:55 +00003788static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003789s390_irgen_BRC(UChar r1, UShort i2)
3790{
3791 IRTemp cond = newTemp(Ity_I32);
3792
3793 if (r1 == 0) {
3794 } else {
3795 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003796 always_goto_and_chase(
3797 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003798 } else {
3799 assign(cond, s390_call_calculate_cond(r1));
3800 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3801 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3802
3803 }
3804 }
sewardj7ee97522011-05-09 21:45:04 +00003805 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003806 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3807
3808 return "brc";
3809}
3810
florian55085f82012-11-21 00:36:55 +00003811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003812s390_irgen_BRCL(UChar r1, UInt i2)
3813{
3814 IRTemp cond = newTemp(Ity_I32);
3815
3816 if (r1 == 0) {
3817 } else {
3818 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003819 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003820 } else {
3821 assign(cond, s390_call_calculate_cond(r1));
3822 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3823 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3824 }
3825 }
sewardj7ee97522011-05-09 21:45:04 +00003826 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003827 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3828
3829 return "brcl";
3830}
3831
florian55085f82012-11-21 00:36:55 +00003832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003833s390_irgen_BRCT(UChar r1, UShort i2)
3834{
3835 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3836 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3837 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3838
3839 return "brct";
3840}
3841
florian55085f82012-11-21 00:36:55 +00003842static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003843s390_irgen_BRCTG(UChar r1, UShort i2)
3844{
3845 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3846 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3847 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3848
3849 return "brctg";
3850}
3851
florian55085f82012-11-21 00:36:55 +00003852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003853s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3854{
3855 IRTemp value = newTemp(Ity_I32);
3856
3857 assign(value, get_gpr_w1(r3 | 1));
3858 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3859 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3860 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3861
3862 return "brxh";
3863}
3864
florian55085f82012-11-21 00:36:55 +00003865static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003866s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3867{
3868 IRTemp value = newTemp(Ity_I64);
3869
3870 assign(value, get_gpr_dw0(r3 | 1));
3871 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3872 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3873 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3874
3875 return "brxhg";
3876}
3877
florian55085f82012-11-21 00:36:55 +00003878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003879s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3880{
3881 IRTemp value = newTemp(Ity_I32);
3882
3883 assign(value, get_gpr_w1(r3 | 1));
3884 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3885 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3886 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3887
3888 return "brxle";
3889}
3890
florian55085f82012-11-21 00:36:55 +00003891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003892s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3893{
3894 IRTemp value = newTemp(Ity_I64);
3895
3896 assign(value, get_gpr_dw0(r3 | 1));
3897 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3898 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3899 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3900
3901 return "brxlg";
3902}
3903
florian55085f82012-11-21 00:36:55 +00003904static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003905s390_irgen_CR(UChar r1, UChar r2)
3906{
3907 IRTemp op1 = newTemp(Ity_I32);
3908 IRTemp op2 = newTemp(Ity_I32);
3909
3910 assign(op1, get_gpr_w1(r1));
3911 assign(op2, get_gpr_w1(r2));
3912 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3913
3914 return "cr";
3915}
3916
florian55085f82012-11-21 00:36:55 +00003917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003918s390_irgen_CGR(UChar r1, UChar r2)
3919{
3920 IRTemp op1 = newTemp(Ity_I64);
3921 IRTemp op2 = newTemp(Ity_I64);
3922
3923 assign(op1, get_gpr_dw0(r1));
3924 assign(op2, get_gpr_dw0(r2));
3925 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3926
3927 return "cgr";
3928}
3929
florian55085f82012-11-21 00:36:55 +00003930static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003931s390_irgen_CGFR(UChar r1, UChar r2)
3932{
3933 IRTemp op1 = newTemp(Ity_I64);
3934 IRTemp op2 = newTemp(Ity_I64);
3935
3936 assign(op1, get_gpr_dw0(r1));
3937 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3938 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3939
3940 return "cgfr";
3941}
3942
florian55085f82012-11-21 00:36:55 +00003943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003944s390_irgen_C(UChar r1, IRTemp op2addr)
3945{
3946 IRTemp op1 = newTemp(Ity_I32);
3947 IRTemp op2 = newTemp(Ity_I32);
3948
3949 assign(op1, get_gpr_w1(r1));
3950 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3951 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3952
3953 return "c";
3954}
3955
florian55085f82012-11-21 00:36:55 +00003956static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003957s390_irgen_CY(UChar r1, IRTemp op2addr)
3958{
3959 IRTemp op1 = newTemp(Ity_I32);
3960 IRTemp op2 = newTemp(Ity_I32);
3961
3962 assign(op1, get_gpr_w1(r1));
3963 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3964 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3965
3966 return "cy";
3967}
3968
florian55085f82012-11-21 00:36:55 +00003969static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003970s390_irgen_CG(UChar r1, IRTemp op2addr)
3971{
3972 IRTemp op1 = newTemp(Ity_I64);
3973 IRTemp op2 = newTemp(Ity_I64);
3974
3975 assign(op1, get_gpr_dw0(r1));
3976 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3977 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3978
3979 return "cg";
3980}
3981
florian55085f82012-11-21 00:36:55 +00003982static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003983s390_irgen_CGF(UChar r1, IRTemp op2addr)
3984{
3985 IRTemp op1 = newTemp(Ity_I64);
3986 IRTemp op2 = newTemp(Ity_I64);
3987
3988 assign(op1, get_gpr_dw0(r1));
3989 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3990 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3991
3992 return "cgf";
3993}
3994
florian55085f82012-11-21 00:36:55 +00003995static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003996s390_irgen_CFI(UChar r1, UInt i2)
3997{
3998 IRTemp op1 = newTemp(Ity_I32);
3999 Int op2;
4000
4001 assign(op1, get_gpr_w1(r1));
4002 op2 = (Int)i2;
4003 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4004 mkU32((UInt)op2)));
4005
4006 return "cfi";
4007}
4008
florian55085f82012-11-21 00:36:55 +00004009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004010s390_irgen_CGFI(UChar r1, UInt i2)
4011{
4012 IRTemp op1 = newTemp(Ity_I64);
4013 Long op2;
4014
4015 assign(op1, get_gpr_dw0(r1));
4016 op2 = (Long)(Int)i2;
4017 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4018 mkU64((ULong)op2)));
4019
4020 return "cgfi";
4021}
4022
florian55085f82012-11-21 00:36:55 +00004023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004024s390_irgen_CRL(UChar r1, UInt i2)
4025{
4026 IRTemp op1 = newTemp(Ity_I32);
4027 IRTemp op2 = newTemp(Ity_I32);
4028
4029 assign(op1, get_gpr_w1(r1));
4030 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4031 i2 << 1))));
4032 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4033
4034 return "crl";
4035}
4036
florian55085f82012-11-21 00:36:55 +00004037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004038s390_irgen_CGRL(UChar r1, UInt i2)
4039{
4040 IRTemp op1 = newTemp(Ity_I64);
4041 IRTemp op2 = newTemp(Ity_I64);
4042
4043 assign(op1, get_gpr_dw0(r1));
4044 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4045 i2 << 1))));
4046 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4047
4048 return "cgrl";
4049}
4050
florian55085f82012-11-21 00:36:55 +00004051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004052s390_irgen_CGFRL(UChar r1, UInt i2)
4053{
4054 IRTemp op1 = newTemp(Ity_I64);
4055 IRTemp op2 = newTemp(Ity_I64);
4056
4057 assign(op1, get_gpr_dw0(r1));
4058 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4059 ((ULong)(Long)(Int)i2 << 1)))));
4060 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4061
4062 return "cgfrl";
4063}
4064
florian55085f82012-11-21 00:36:55 +00004065static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004066s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4067{
4068 IRTemp op1 = newTemp(Ity_I32);
4069 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004070 IRTemp cond = newTemp(Ity_I32);
4071
4072 if (m3 == 0) {
4073 } else {
4074 if (m3 == 14) {
4075 always_goto(mkexpr(op4addr));
4076 } else {
4077 assign(op1, get_gpr_w1(r1));
4078 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004079 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4080 op1, op2));
florianf321da72012-07-21 20:32:57 +00004081 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4082 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004083 }
4084 }
4085
4086 return "crb";
4087}
4088
florian55085f82012-11-21 00:36:55 +00004089static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004090s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4091{
4092 IRTemp op1 = newTemp(Ity_I64);
4093 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004094 IRTemp cond = newTemp(Ity_I32);
4095
4096 if (m3 == 0) {
4097 } else {
4098 if (m3 == 14) {
4099 always_goto(mkexpr(op4addr));
4100 } else {
4101 assign(op1, get_gpr_dw0(r1));
4102 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004103 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4104 op1, op2));
florianf321da72012-07-21 20:32:57 +00004105 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4106 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004107 }
4108 }
4109
4110 return "cgrb";
4111}
4112
florian55085f82012-11-21 00:36:55 +00004113static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004114s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4115{
4116 IRTemp op1 = newTemp(Ity_I32);
4117 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004118 IRTemp cond = newTemp(Ity_I32);
4119
4120 if (m3 == 0) {
4121 } else {
4122 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004123 always_goto_and_chase(
4124 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004125 } else {
4126 assign(op1, get_gpr_w1(r1));
4127 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004128 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4129 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004130 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4131 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4132
4133 }
4134 }
4135
4136 return "crj";
4137}
4138
florian55085f82012-11-21 00:36:55 +00004139static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004140s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4141{
4142 IRTemp op1 = newTemp(Ity_I64);
4143 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004144 IRTemp cond = newTemp(Ity_I32);
4145
4146 if (m3 == 0) {
4147 } else {
4148 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004149 always_goto_and_chase(
4150 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004151 } else {
4152 assign(op1, get_gpr_dw0(r1));
4153 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004154 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4155 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004156 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4157 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4158
4159 }
4160 }
4161
4162 return "cgrj";
4163}
4164
florian55085f82012-11-21 00:36:55 +00004165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004166s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4167{
4168 IRTemp op1 = newTemp(Ity_I32);
4169 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004170 IRTemp cond = newTemp(Ity_I32);
4171
4172 if (m3 == 0) {
4173 } else {
4174 if (m3 == 14) {
4175 always_goto(mkexpr(op4addr));
4176 } else {
4177 assign(op1, get_gpr_w1(r1));
4178 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004179 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4180 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004181 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4182 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004183 }
4184 }
4185
4186 return "cib";
4187}
4188
florian55085f82012-11-21 00:36:55 +00004189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004190s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4191{
4192 IRTemp op1 = newTemp(Ity_I64);
4193 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004194 IRTemp cond = newTemp(Ity_I32);
4195
4196 if (m3 == 0) {
4197 } else {
4198 if (m3 == 14) {
4199 always_goto(mkexpr(op4addr));
4200 } else {
4201 assign(op1, get_gpr_dw0(r1));
4202 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004203 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4204 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004205 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4206 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004207 }
4208 }
4209
4210 return "cgib";
4211}
4212
florian55085f82012-11-21 00:36:55 +00004213static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004214s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4215{
4216 IRTemp op1 = newTemp(Ity_I32);
4217 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004218 IRTemp cond = newTemp(Ity_I32);
4219
4220 if (m3 == 0) {
4221 } else {
4222 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004223 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004224 } else {
4225 assign(op1, get_gpr_w1(r1));
4226 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004227 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4228 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004229 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4230 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4231
4232 }
4233 }
4234
4235 return "cij";
4236}
4237
florian55085f82012-11-21 00:36:55 +00004238static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004239s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4240{
4241 IRTemp op1 = newTemp(Ity_I64);
4242 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004243 IRTemp cond = newTemp(Ity_I32);
4244
4245 if (m3 == 0) {
4246 } else {
4247 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004248 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004249 } else {
4250 assign(op1, get_gpr_dw0(r1));
4251 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004252 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4253 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004254 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4255 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4256
4257 }
4258 }
4259
4260 return "cgij";
4261}
4262
florian55085f82012-11-21 00:36:55 +00004263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004264s390_irgen_CH(UChar r1, IRTemp op2addr)
4265{
4266 IRTemp op1 = newTemp(Ity_I32);
4267 IRTemp op2 = newTemp(Ity_I32);
4268
4269 assign(op1, get_gpr_w1(r1));
4270 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4271 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4272
4273 return "ch";
4274}
4275
florian55085f82012-11-21 00:36:55 +00004276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004277s390_irgen_CHY(UChar r1, IRTemp op2addr)
4278{
4279 IRTemp op1 = newTemp(Ity_I32);
4280 IRTemp op2 = newTemp(Ity_I32);
4281
4282 assign(op1, get_gpr_w1(r1));
4283 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4284 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4285
4286 return "chy";
4287}
4288
florian55085f82012-11-21 00:36:55 +00004289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004290s390_irgen_CGH(UChar r1, IRTemp op2addr)
4291{
4292 IRTemp op1 = newTemp(Ity_I64);
4293 IRTemp op2 = newTemp(Ity_I64);
4294
4295 assign(op1, get_gpr_dw0(r1));
4296 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4297 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4298
4299 return "cgh";
4300}
4301
florian55085f82012-11-21 00:36:55 +00004302static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004303s390_irgen_CHI(UChar r1, UShort i2)
4304{
4305 IRTemp op1 = newTemp(Ity_I32);
4306 Int op2;
4307
4308 assign(op1, get_gpr_w1(r1));
4309 op2 = (Int)(Short)i2;
4310 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4311 mkU32((UInt)op2)));
4312
4313 return "chi";
4314}
4315
florian55085f82012-11-21 00:36:55 +00004316static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004317s390_irgen_CGHI(UChar r1, UShort i2)
4318{
4319 IRTemp op1 = newTemp(Ity_I64);
4320 Long op2;
4321
4322 assign(op1, get_gpr_dw0(r1));
4323 op2 = (Long)(Short)i2;
4324 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4325 mkU64((ULong)op2)));
4326
4327 return "cghi";
4328}
4329
florian55085f82012-11-21 00:36:55 +00004330static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004331s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4332{
4333 IRTemp op1 = newTemp(Ity_I16);
4334 Short op2;
4335
4336 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4337 op2 = (Short)i2;
4338 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4339 mkU16((UShort)op2)));
4340
4341 return "chhsi";
4342}
4343
florian55085f82012-11-21 00:36:55 +00004344static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004345s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4346{
4347 IRTemp op1 = newTemp(Ity_I32);
4348 Int op2;
4349
4350 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4351 op2 = (Int)(Short)i2;
4352 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4353 mkU32((UInt)op2)));
4354
4355 return "chsi";
4356}
4357
florian55085f82012-11-21 00:36:55 +00004358static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004359s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4360{
4361 IRTemp op1 = newTemp(Ity_I64);
4362 Long op2;
4363
4364 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4365 op2 = (Long)(Short)i2;
4366 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4367 mkU64((ULong)op2)));
4368
4369 return "cghsi";
4370}
4371
florian55085f82012-11-21 00:36:55 +00004372static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004373s390_irgen_CHRL(UChar r1, UInt i2)
4374{
4375 IRTemp op1 = newTemp(Ity_I32);
4376 IRTemp op2 = newTemp(Ity_I32);
4377
4378 assign(op1, get_gpr_w1(r1));
4379 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4380 ((ULong)(Long)(Int)i2 << 1)))));
4381 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4382
4383 return "chrl";
4384}
4385
florian55085f82012-11-21 00:36:55 +00004386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004387s390_irgen_CGHRL(UChar r1, UInt i2)
4388{
4389 IRTemp op1 = newTemp(Ity_I64);
4390 IRTemp op2 = newTemp(Ity_I64);
4391
4392 assign(op1, get_gpr_dw0(r1));
4393 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4394 ((ULong)(Long)(Int)i2 << 1)))));
4395 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4396
4397 return "cghrl";
4398}
4399
florian55085f82012-11-21 00:36:55 +00004400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004401s390_irgen_CHHR(UChar r1, UChar r2)
4402{
4403 IRTemp op1 = newTemp(Ity_I32);
4404 IRTemp op2 = newTemp(Ity_I32);
4405
4406 assign(op1, get_gpr_w0(r1));
4407 assign(op2, get_gpr_w0(r2));
4408 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4409
4410 return "chhr";
4411}
4412
florian55085f82012-11-21 00:36:55 +00004413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004414s390_irgen_CHLR(UChar r1, UChar r2)
4415{
4416 IRTemp op1 = newTemp(Ity_I32);
4417 IRTemp op2 = newTemp(Ity_I32);
4418
4419 assign(op1, get_gpr_w0(r1));
4420 assign(op2, get_gpr_w1(r2));
4421 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4422
4423 return "chlr";
4424}
4425
florian55085f82012-11-21 00:36:55 +00004426static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004427s390_irgen_CHF(UChar r1, IRTemp op2addr)
4428{
4429 IRTemp op1 = newTemp(Ity_I32);
4430 IRTemp op2 = newTemp(Ity_I32);
4431
4432 assign(op1, get_gpr_w0(r1));
4433 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4434 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4435
4436 return "chf";
4437}
4438
florian55085f82012-11-21 00:36:55 +00004439static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004440s390_irgen_CIH(UChar r1, UInt i2)
4441{
4442 IRTemp op1 = newTemp(Ity_I32);
4443 Int op2;
4444
4445 assign(op1, get_gpr_w0(r1));
4446 op2 = (Int)i2;
4447 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4448 mkU32((UInt)op2)));
4449
4450 return "cih";
4451}
4452
florian55085f82012-11-21 00:36:55 +00004453static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004454s390_irgen_CLR(UChar r1, UChar r2)
4455{
4456 IRTemp op1 = newTemp(Ity_I32);
4457 IRTemp op2 = newTemp(Ity_I32);
4458
4459 assign(op1, get_gpr_w1(r1));
4460 assign(op2, get_gpr_w1(r2));
4461 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4462
4463 return "clr";
4464}
4465
florian55085f82012-11-21 00:36:55 +00004466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004467s390_irgen_CLGR(UChar r1, UChar r2)
4468{
4469 IRTemp op1 = newTemp(Ity_I64);
4470 IRTemp op2 = newTemp(Ity_I64);
4471
4472 assign(op1, get_gpr_dw0(r1));
4473 assign(op2, get_gpr_dw0(r2));
4474 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4475
4476 return "clgr";
4477}
4478
florian55085f82012-11-21 00:36:55 +00004479static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004480s390_irgen_CLGFR(UChar r1, UChar r2)
4481{
4482 IRTemp op1 = newTemp(Ity_I64);
4483 IRTemp op2 = newTemp(Ity_I64);
4484
4485 assign(op1, get_gpr_dw0(r1));
4486 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4487 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4488
4489 return "clgfr";
4490}
4491
florian55085f82012-11-21 00:36:55 +00004492static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004493s390_irgen_CL(UChar r1, IRTemp op2addr)
4494{
4495 IRTemp op1 = newTemp(Ity_I32);
4496 IRTemp op2 = newTemp(Ity_I32);
4497
4498 assign(op1, get_gpr_w1(r1));
4499 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4500 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4501
4502 return "cl";
4503}
4504
florian55085f82012-11-21 00:36:55 +00004505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004506s390_irgen_CLY(UChar r1, IRTemp op2addr)
4507{
4508 IRTemp op1 = newTemp(Ity_I32);
4509 IRTemp op2 = newTemp(Ity_I32);
4510
4511 assign(op1, get_gpr_w1(r1));
4512 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4513 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4514
4515 return "cly";
4516}
4517
florian55085f82012-11-21 00:36:55 +00004518static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004519s390_irgen_CLG(UChar r1, IRTemp op2addr)
4520{
4521 IRTemp op1 = newTemp(Ity_I64);
4522 IRTemp op2 = newTemp(Ity_I64);
4523
4524 assign(op1, get_gpr_dw0(r1));
4525 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4526 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4527
4528 return "clg";
4529}
4530
florian55085f82012-11-21 00:36:55 +00004531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004532s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4533{
4534 IRTemp op1 = newTemp(Ity_I64);
4535 IRTemp op2 = newTemp(Ity_I64);
4536
4537 assign(op1, get_gpr_dw0(r1));
4538 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4539 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4540
4541 return "clgf";
4542}
4543
florian55085f82012-11-21 00:36:55 +00004544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004545s390_irgen_CLFI(UChar r1, UInt i2)
4546{
4547 IRTemp op1 = newTemp(Ity_I32);
4548 UInt op2;
4549
4550 assign(op1, get_gpr_w1(r1));
4551 op2 = i2;
4552 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4553 mkU32(op2)));
4554
4555 return "clfi";
4556}
4557
florian55085f82012-11-21 00:36:55 +00004558static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004559s390_irgen_CLGFI(UChar r1, UInt i2)
4560{
4561 IRTemp op1 = newTemp(Ity_I64);
4562 ULong op2;
4563
4564 assign(op1, get_gpr_dw0(r1));
4565 op2 = (ULong)i2;
4566 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4567 mkU64(op2)));
4568
4569 return "clgfi";
4570}
4571
florian55085f82012-11-21 00:36:55 +00004572static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004573s390_irgen_CLI(UChar i2, IRTemp op1addr)
4574{
4575 IRTemp op1 = newTemp(Ity_I8);
4576 UChar op2;
4577
4578 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4579 op2 = i2;
4580 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4581 mkU8(op2)));
4582
4583 return "cli";
4584}
4585
florian55085f82012-11-21 00:36:55 +00004586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004587s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4588{
4589 IRTemp op1 = newTemp(Ity_I8);
4590 UChar op2;
4591
4592 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4593 op2 = i2;
4594 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4595 mkU8(op2)));
4596
4597 return "cliy";
4598}
4599
florian55085f82012-11-21 00:36:55 +00004600static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004601s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4602{
4603 IRTemp op1 = newTemp(Ity_I32);
4604 UInt op2;
4605
4606 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4607 op2 = (UInt)i2;
4608 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4609 mkU32(op2)));
4610
4611 return "clfhsi";
4612}
4613
florian55085f82012-11-21 00:36:55 +00004614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004615s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4616{
4617 IRTemp op1 = newTemp(Ity_I64);
4618 ULong op2;
4619
4620 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4621 op2 = (ULong)i2;
4622 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4623 mkU64(op2)));
4624
4625 return "clghsi";
4626}
4627
florian55085f82012-11-21 00:36:55 +00004628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004629s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4630{
4631 IRTemp op1 = newTemp(Ity_I16);
4632 UShort op2;
4633
4634 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4635 op2 = i2;
4636 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4637 mkU16(op2)));
4638
4639 return "clhhsi";
4640}
4641
florian55085f82012-11-21 00:36:55 +00004642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004643s390_irgen_CLRL(UChar r1, UInt i2)
4644{
4645 IRTemp op1 = newTemp(Ity_I32);
4646 IRTemp op2 = newTemp(Ity_I32);
4647
4648 assign(op1, get_gpr_w1(r1));
4649 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4650 i2 << 1))));
4651 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4652
4653 return "clrl";
4654}
4655
florian55085f82012-11-21 00:36:55 +00004656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004657s390_irgen_CLGRL(UChar r1, UInt i2)
4658{
4659 IRTemp op1 = newTemp(Ity_I64);
4660 IRTemp op2 = newTemp(Ity_I64);
4661
4662 assign(op1, get_gpr_dw0(r1));
4663 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4664 i2 << 1))));
4665 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4666
4667 return "clgrl";
4668}
4669
florian55085f82012-11-21 00:36:55 +00004670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004671s390_irgen_CLGFRL(UChar r1, UInt i2)
4672{
4673 IRTemp op1 = newTemp(Ity_I64);
4674 IRTemp op2 = newTemp(Ity_I64);
4675
4676 assign(op1, get_gpr_dw0(r1));
4677 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4678 ((ULong)(Long)(Int)i2 << 1)))));
4679 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4680
4681 return "clgfrl";
4682}
4683
florian55085f82012-11-21 00:36:55 +00004684static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004685s390_irgen_CLHRL(UChar r1, UInt i2)
4686{
4687 IRTemp op1 = newTemp(Ity_I32);
4688 IRTemp op2 = newTemp(Ity_I32);
4689
4690 assign(op1, get_gpr_w1(r1));
4691 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4692 ((ULong)(Long)(Int)i2 << 1)))));
4693 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4694
4695 return "clhrl";
4696}
4697
florian55085f82012-11-21 00:36:55 +00004698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004699s390_irgen_CLGHRL(UChar r1, UInt i2)
4700{
4701 IRTemp op1 = newTemp(Ity_I64);
4702 IRTemp op2 = newTemp(Ity_I64);
4703
4704 assign(op1, get_gpr_dw0(r1));
4705 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4706 ((ULong)(Long)(Int)i2 << 1)))));
4707 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4708
4709 return "clghrl";
4710}
4711
florian55085f82012-11-21 00:36:55 +00004712static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004713s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4714{
4715 IRTemp op1 = newTemp(Ity_I32);
4716 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004717 IRTemp cond = newTemp(Ity_I32);
4718
4719 if (m3 == 0) {
4720 } else {
4721 if (m3 == 14) {
4722 always_goto(mkexpr(op4addr));
4723 } else {
4724 assign(op1, get_gpr_w1(r1));
4725 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004726 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4727 op1, op2));
florianf321da72012-07-21 20:32:57 +00004728 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4729 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004730 }
4731 }
4732
4733 return "clrb";
4734}
4735
florian55085f82012-11-21 00:36:55 +00004736static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004737s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4738{
4739 IRTemp op1 = newTemp(Ity_I64);
4740 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004741 IRTemp cond = newTemp(Ity_I32);
4742
4743 if (m3 == 0) {
4744 } else {
4745 if (m3 == 14) {
4746 always_goto(mkexpr(op4addr));
4747 } else {
4748 assign(op1, get_gpr_dw0(r1));
4749 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004750 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4751 op1, op2));
florianf321da72012-07-21 20:32:57 +00004752 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4753 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004754 }
4755 }
4756
4757 return "clgrb";
4758}
4759
florian55085f82012-11-21 00:36:55 +00004760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004761s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4762{
4763 IRTemp op1 = newTemp(Ity_I32);
4764 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004765 IRTemp cond = newTemp(Ity_I32);
4766
4767 if (m3 == 0) {
4768 } else {
4769 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004770 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004771 } else {
4772 assign(op1, get_gpr_w1(r1));
4773 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004774 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4775 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004776 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4777 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4778
4779 }
4780 }
4781
4782 return "clrj";
4783}
4784
florian55085f82012-11-21 00:36:55 +00004785static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004786s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4787{
4788 IRTemp op1 = newTemp(Ity_I64);
4789 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004790 IRTemp cond = newTemp(Ity_I32);
4791
4792 if (m3 == 0) {
4793 } else {
4794 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004795 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004796 } else {
4797 assign(op1, get_gpr_dw0(r1));
4798 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004799 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4800 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004801 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4802 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4803
4804 }
4805 }
4806
4807 return "clgrj";
4808}
4809
florian55085f82012-11-21 00:36:55 +00004810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004811s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4812{
4813 IRTemp op1 = newTemp(Ity_I32);
4814 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004815 IRTemp cond = newTemp(Ity_I32);
4816
4817 if (m3 == 0) {
4818 } else {
4819 if (m3 == 14) {
4820 always_goto(mkexpr(op4addr));
4821 } else {
4822 assign(op1, get_gpr_w1(r1));
4823 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004824 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4825 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004826 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4827 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004828 }
4829 }
4830
4831 return "clib";
4832}
4833
florian55085f82012-11-21 00:36:55 +00004834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004835s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4836{
4837 IRTemp op1 = newTemp(Ity_I64);
4838 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004839 IRTemp cond = newTemp(Ity_I32);
4840
4841 if (m3 == 0) {
4842 } else {
4843 if (m3 == 14) {
4844 always_goto(mkexpr(op4addr));
4845 } else {
4846 assign(op1, get_gpr_dw0(r1));
4847 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004848 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4849 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004850 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4851 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004852 }
4853 }
4854
4855 return "clgib";
4856}
4857
florian55085f82012-11-21 00:36:55 +00004858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004859s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4860{
4861 IRTemp op1 = newTemp(Ity_I32);
4862 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004863 IRTemp cond = newTemp(Ity_I32);
4864
4865 if (m3 == 0) {
4866 } else {
4867 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004868 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004869 } else {
4870 assign(op1, get_gpr_w1(r1));
4871 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004872 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4873 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004874 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4875 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4876
4877 }
4878 }
4879
4880 return "clij";
4881}
4882
florian55085f82012-11-21 00:36:55 +00004883static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004884s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4885{
4886 IRTemp op1 = newTemp(Ity_I64);
4887 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004888 IRTemp cond = newTemp(Ity_I32);
4889
4890 if (m3 == 0) {
4891 } else {
4892 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004893 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004894 } else {
4895 assign(op1, get_gpr_dw0(r1));
4896 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004897 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4898 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004899 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4900 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4901
4902 }
4903 }
4904
4905 return "clgij";
4906}
4907
florian55085f82012-11-21 00:36:55 +00004908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004909s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4910{
4911 IRTemp op1 = newTemp(Ity_I32);
4912 IRTemp op2 = newTemp(Ity_I32);
4913 IRTemp b0 = newTemp(Ity_I32);
4914 IRTemp b1 = newTemp(Ity_I32);
4915 IRTemp b2 = newTemp(Ity_I32);
4916 IRTemp b3 = newTemp(Ity_I32);
4917 IRTemp c0 = newTemp(Ity_I32);
4918 IRTemp c1 = newTemp(Ity_I32);
4919 IRTemp c2 = newTemp(Ity_I32);
4920 IRTemp c3 = newTemp(Ity_I32);
4921 UChar n;
4922
4923 n = 0;
4924 if ((r3 & 8) != 0) {
4925 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4926 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4927 n = n + 1;
4928 } else {
4929 assign(b0, mkU32(0));
4930 assign(c0, mkU32(0));
4931 }
4932 if ((r3 & 4) != 0) {
4933 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4934 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4935 mkU64(n)))));
4936 n = n + 1;
4937 } else {
4938 assign(b1, mkU32(0));
4939 assign(c1, mkU32(0));
4940 }
4941 if ((r3 & 2) != 0) {
4942 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4943 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4944 mkU64(n)))));
4945 n = n + 1;
4946 } else {
4947 assign(b2, mkU32(0));
4948 assign(c2, mkU32(0));
4949 }
4950 if ((r3 & 1) != 0) {
4951 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4952 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4953 mkU64(n)))));
4954 n = n + 1;
4955 } else {
4956 assign(b3, mkU32(0));
4957 assign(c3, mkU32(0));
4958 }
4959 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4960 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4961 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4962 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4963 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4964 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4965 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4966
4967 return "clm";
4968}
4969
florian55085f82012-11-21 00:36:55 +00004970static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004971s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4972{
4973 IRTemp op1 = newTemp(Ity_I32);
4974 IRTemp op2 = newTemp(Ity_I32);
4975 IRTemp b0 = newTemp(Ity_I32);
4976 IRTemp b1 = newTemp(Ity_I32);
4977 IRTemp b2 = newTemp(Ity_I32);
4978 IRTemp b3 = newTemp(Ity_I32);
4979 IRTemp c0 = newTemp(Ity_I32);
4980 IRTemp c1 = newTemp(Ity_I32);
4981 IRTemp c2 = newTemp(Ity_I32);
4982 IRTemp c3 = newTemp(Ity_I32);
4983 UChar n;
4984
4985 n = 0;
4986 if ((r3 & 8) != 0) {
4987 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4988 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4989 n = n + 1;
4990 } else {
4991 assign(b0, mkU32(0));
4992 assign(c0, mkU32(0));
4993 }
4994 if ((r3 & 4) != 0) {
4995 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4996 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4997 mkU64(n)))));
4998 n = n + 1;
4999 } else {
5000 assign(b1, mkU32(0));
5001 assign(c1, mkU32(0));
5002 }
5003 if ((r3 & 2) != 0) {
5004 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
5005 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5006 mkU64(n)))));
5007 n = n + 1;
5008 } else {
5009 assign(b2, mkU32(0));
5010 assign(c2, mkU32(0));
5011 }
5012 if ((r3 & 1) != 0) {
5013 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
5014 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5015 mkU64(n)))));
5016 n = n + 1;
5017 } else {
5018 assign(b3, mkU32(0));
5019 assign(c3, mkU32(0));
5020 }
5021 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5022 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5023 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5024 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5025 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5026 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5027 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5028
5029 return "clmy";
5030}
5031
florian55085f82012-11-21 00:36:55 +00005032static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005033s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5034{
5035 IRTemp op1 = newTemp(Ity_I32);
5036 IRTemp op2 = newTemp(Ity_I32);
5037 IRTemp b0 = newTemp(Ity_I32);
5038 IRTemp b1 = newTemp(Ity_I32);
5039 IRTemp b2 = newTemp(Ity_I32);
5040 IRTemp b3 = newTemp(Ity_I32);
5041 IRTemp c0 = newTemp(Ity_I32);
5042 IRTemp c1 = newTemp(Ity_I32);
5043 IRTemp c2 = newTemp(Ity_I32);
5044 IRTemp c3 = newTemp(Ity_I32);
5045 UChar n;
5046
5047 n = 0;
5048 if ((r3 & 8) != 0) {
5049 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5050 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5051 n = n + 1;
5052 } else {
5053 assign(b0, mkU32(0));
5054 assign(c0, mkU32(0));
5055 }
5056 if ((r3 & 4) != 0) {
5057 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5058 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5059 mkU64(n)))));
5060 n = n + 1;
5061 } else {
5062 assign(b1, mkU32(0));
5063 assign(c1, mkU32(0));
5064 }
5065 if ((r3 & 2) != 0) {
5066 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5067 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5068 mkU64(n)))));
5069 n = n + 1;
5070 } else {
5071 assign(b2, mkU32(0));
5072 assign(c2, mkU32(0));
5073 }
5074 if ((r3 & 1) != 0) {
5075 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5076 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5077 mkU64(n)))));
5078 n = n + 1;
5079 } else {
5080 assign(b3, mkU32(0));
5081 assign(c3, mkU32(0));
5082 }
5083 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5084 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5085 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5086 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5087 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5088 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5089 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5090
5091 return "clmh";
5092}
5093
florian55085f82012-11-21 00:36:55 +00005094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005095s390_irgen_CLHHR(UChar r1, UChar r2)
5096{
5097 IRTemp op1 = newTemp(Ity_I32);
5098 IRTemp op2 = newTemp(Ity_I32);
5099
5100 assign(op1, get_gpr_w0(r1));
5101 assign(op2, get_gpr_w0(r2));
5102 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5103
5104 return "clhhr";
5105}
5106
florian55085f82012-11-21 00:36:55 +00005107static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005108s390_irgen_CLHLR(UChar r1, UChar r2)
5109{
5110 IRTemp op1 = newTemp(Ity_I32);
5111 IRTemp op2 = newTemp(Ity_I32);
5112
5113 assign(op1, get_gpr_w0(r1));
5114 assign(op2, get_gpr_w1(r2));
5115 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5116
5117 return "clhlr";
5118}
5119
florian55085f82012-11-21 00:36:55 +00005120static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005121s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5122{
5123 IRTemp op1 = newTemp(Ity_I32);
5124 IRTemp op2 = newTemp(Ity_I32);
5125
5126 assign(op1, get_gpr_w0(r1));
5127 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5128 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5129
5130 return "clhf";
5131}
5132
florian55085f82012-11-21 00:36:55 +00005133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005134s390_irgen_CLIH(UChar r1, UInt i2)
5135{
5136 IRTemp op1 = newTemp(Ity_I32);
5137 UInt op2;
5138
5139 assign(op1, get_gpr_w0(r1));
5140 op2 = i2;
5141 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5142 mkU32(op2)));
5143
5144 return "clih";
5145}
5146
florian55085f82012-11-21 00:36:55 +00005147static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005148s390_irgen_CPYA(UChar r1, UChar r2)
5149{
5150 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005151 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005152 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5153
5154 return "cpya";
5155}
5156
florian55085f82012-11-21 00:36:55 +00005157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005158s390_irgen_XR(UChar r1, UChar r2)
5159{
5160 IRTemp op1 = newTemp(Ity_I32);
5161 IRTemp op2 = newTemp(Ity_I32);
5162 IRTemp result = newTemp(Ity_I32);
5163
5164 if (r1 == r2) {
5165 assign(result, mkU32(0));
5166 } else {
5167 assign(op1, get_gpr_w1(r1));
5168 assign(op2, get_gpr_w1(r2));
5169 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5170 }
5171 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5172 put_gpr_w1(r1, mkexpr(result));
5173
5174 return "xr";
5175}
5176
florian55085f82012-11-21 00:36:55 +00005177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005178s390_irgen_XGR(UChar r1, UChar r2)
5179{
5180 IRTemp op1 = newTemp(Ity_I64);
5181 IRTemp op2 = newTemp(Ity_I64);
5182 IRTemp result = newTemp(Ity_I64);
5183
5184 if (r1 == r2) {
5185 assign(result, mkU64(0));
5186 } else {
5187 assign(op1, get_gpr_dw0(r1));
5188 assign(op2, get_gpr_dw0(r2));
5189 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5190 }
5191 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5192 put_gpr_dw0(r1, mkexpr(result));
5193
5194 return "xgr";
5195}
5196
florian55085f82012-11-21 00:36:55 +00005197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005198s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5199{
5200 IRTemp op2 = newTemp(Ity_I32);
5201 IRTemp op3 = newTemp(Ity_I32);
5202 IRTemp result = newTemp(Ity_I32);
5203
5204 assign(op2, get_gpr_w1(r2));
5205 assign(op3, get_gpr_w1(r3));
5206 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5207 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5208 put_gpr_w1(r1, mkexpr(result));
5209
5210 return "xrk";
5211}
5212
florian55085f82012-11-21 00:36:55 +00005213static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005214s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5215{
5216 IRTemp op2 = newTemp(Ity_I64);
5217 IRTemp op3 = newTemp(Ity_I64);
5218 IRTemp result = newTemp(Ity_I64);
5219
5220 assign(op2, get_gpr_dw0(r2));
5221 assign(op3, get_gpr_dw0(r3));
5222 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5223 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5224 put_gpr_dw0(r1, mkexpr(result));
5225
5226 return "xgrk";
5227}
5228
florian55085f82012-11-21 00:36:55 +00005229static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005230s390_irgen_X(UChar r1, IRTemp op2addr)
5231{
5232 IRTemp op1 = newTemp(Ity_I32);
5233 IRTemp op2 = newTemp(Ity_I32);
5234 IRTemp result = newTemp(Ity_I32);
5235
5236 assign(op1, get_gpr_w1(r1));
5237 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5238 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5239 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5240 put_gpr_w1(r1, mkexpr(result));
5241
5242 return "x";
5243}
5244
florian55085f82012-11-21 00:36:55 +00005245static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005246s390_irgen_XY(UChar r1, IRTemp op2addr)
5247{
5248 IRTemp op1 = newTemp(Ity_I32);
5249 IRTemp op2 = newTemp(Ity_I32);
5250 IRTemp result = newTemp(Ity_I32);
5251
5252 assign(op1, get_gpr_w1(r1));
5253 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5254 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5255 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5256 put_gpr_w1(r1, mkexpr(result));
5257
5258 return "xy";
5259}
5260
florian55085f82012-11-21 00:36:55 +00005261static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005262s390_irgen_XG(UChar r1, IRTemp op2addr)
5263{
5264 IRTemp op1 = newTemp(Ity_I64);
5265 IRTemp op2 = newTemp(Ity_I64);
5266 IRTemp result = newTemp(Ity_I64);
5267
5268 assign(op1, get_gpr_dw0(r1));
5269 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5270 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5271 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5272 put_gpr_dw0(r1, mkexpr(result));
5273
5274 return "xg";
5275}
5276
florian55085f82012-11-21 00:36:55 +00005277static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005278s390_irgen_XI(UChar i2, IRTemp op1addr)
5279{
5280 IRTemp op1 = newTemp(Ity_I8);
5281 UChar op2;
5282 IRTemp result = newTemp(Ity_I8);
5283
5284 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5285 op2 = i2;
5286 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5287 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5288 store(mkexpr(op1addr), mkexpr(result));
5289
5290 return "xi";
5291}
5292
florian55085f82012-11-21 00:36:55 +00005293static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005294s390_irgen_XIY(UChar i2, IRTemp op1addr)
5295{
5296 IRTemp op1 = newTemp(Ity_I8);
5297 UChar op2;
5298 IRTemp result = newTemp(Ity_I8);
5299
5300 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5301 op2 = i2;
5302 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5303 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5304 store(mkexpr(op1addr), mkexpr(result));
5305
5306 return "xiy";
5307}
5308
florian55085f82012-11-21 00:36:55 +00005309static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005310s390_irgen_XIHF(UChar r1, UInt i2)
5311{
5312 IRTemp op1 = newTemp(Ity_I32);
5313 UInt op2;
5314 IRTemp result = newTemp(Ity_I32);
5315
5316 assign(op1, get_gpr_w0(r1));
5317 op2 = i2;
5318 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5319 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5320 put_gpr_w0(r1, mkexpr(result));
5321
5322 return "xihf";
5323}
5324
florian55085f82012-11-21 00:36:55 +00005325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005326s390_irgen_XILF(UChar r1, UInt i2)
5327{
5328 IRTemp op1 = newTemp(Ity_I32);
5329 UInt op2;
5330 IRTemp result = newTemp(Ity_I32);
5331
5332 assign(op1, get_gpr_w1(r1));
5333 op2 = i2;
5334 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5335 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5336 put_gpr_w1(r1, mkexpr(result));
5337
5338 return "xilf";
5339}
5340
florian55085f82012-11-21 00:36:55 +00005341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005342s390_irgen_EAR(UChar r1, UChar r2)
5343{
5344 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005345 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005346 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5347
5348 return "ear";
5349}
5350
florian55085f82012-11-21 00:36:55 +00005351static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005352s390_irgen_IC(UChar r1, IRTemp op2addr)
5353{
5354 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5355
5356 return "ic";
5357}
5358
florian55085f82012-11-21 00:36:55 +00005359static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005360s390_irgen_ICY(UChar r1, IRTemp op2addr)
5361{
5362 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5363
5364 return "icy";
5365}
5366
florian55085f82012-11-21 00:36:55 +00005367static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005368s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5369{
5370 UChar n;
5371 IRTemp result = newTemp(Ity_I32);
5372 UInt mask;
5373
5374 n = 0;
5375 mask = (UInt)r3;
5376 if ((mask & 8) != 0) {
5377 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5378 n = n + 1;
5379 }
5380 if ((mask & 4) != 0) {
5381 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5382
5383 n = n + 1;
5384 }
5385 if ((mask & 2) != 0) {
5386 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5387
5388 n = n + 1;
5389 }
5390 if ((mask & 1) != 0) {
5391 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5392
5393 n = n + 1;
5394 }
5395 assign(result, get_gpr_w1(r1));
5396 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5397 mkU32(mask)));
5398
5399 return "icm";
5400}
5401
florian55085f82012-11-21 00:36:55 +00005402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005403s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5404{
5405 UChar n;
5406 IRTemp result = newTemp(Ity_I32);
5407 UInt mask;
5408
5409 n = 0;
5410 mask = (UInt)r3;
5411 if ((mask & 8) != 0) {
5412 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5413 n = n + 1;
5414 }
5415 if ((mask & 4) != 0) {
5416 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5417
5418 n = n + 1;
5419 }
5420 if ((mask & 2) != 0) {
5421 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5422
5423 n = n + 1;
5424 }
5425 if ((mask & 1) != 0) {
5426 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5427
5428 n = n + 1;
5429 }
5430 assign(result, get_gpr_w1(r1));
5431 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5432 mkU32(mask)));
5433
5434 return "icmy";
5435}
5436
florian55085f82012-11-21 00:36:55 +00005437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005438s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5439{
5440 UChar n;
5441 IRTemp result = newTemp(Ity_I32);
5442 UInt mask;
5443
5444 n = 0;
5445 mask = (UInt)r3;
5446 if ((mask & 8) != 0) {
5447 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5448 n = n + 1;
5449 }
5450 if ((mask & 4) != 0) {
5451 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5452
5453 n = n + 1;
5454 }
5455 if ((mask & 2) != 0) {
5456 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5457
5458 n = n + 1;
5459 }
5460 if ((mask & 1) != 0) {
5461 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5462
5463 n = n + 1;
5464 }
5465 assign(result, get_gpr_w0(r1));
5466 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5467 mkU32(mask)));
5468
5469 return "icmh";
5470}
5471
florian55085f82012-11-21 00:36:55 +00005472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005473s390_irgen_IIHF(UChar r1, UInt i2)
5474{
5475 put_gpr_w0(r1, mkU32(i2));
5476
5477 return "iihf";
5478}
5479
florian55085f82012-11-21 00:36:55 +00005480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005481s390_irgen_IIHH(UChar r1, UShort i2)
5482{
5483 put_gpr_hw0(r1, mkU16(i2));
5484
5485 return "iihh";
5486}
5487
florian55085f82012-11-21 00:36:55 +00005488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005489s390_irgen_IIHL(UChar r1, UShort i2)
5490{
5491 put_gpr_hw1(r1, mkU16(i2));
5492
5493 return "iihl";
5494}
5495
florian55085f82012-11-21 00:36:55 +00005496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005497s390_irgen_IILF(UChar r1, UInt i2)
5498{
5499 put_gpr_w1(r1, mkU32(i2));
5500
5501 return "iilf";
5502}
5503
florian55085f82012-11-21 00:36:55 +00005504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005505s390_irgen_IILH(UChar r1, UShort i2)
5506{
5507 put_gpr_hw2(r1, mkU16(i2));
5508
5509 return "iilh";
5510}
5511
florian55085f82012-11-21 00:36:55 +00005512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005513s390_irgen_IILL(UChar r1, UShort i2)
5514{
5515 put_gpr_hw3(r1, mkU16(i2));
5516
5517 return "iill";
5518}
5519
florian55085f82012-11-21 00:36:55 +00005520static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005521s390_irgen_LR(UChar r1, UChar r2)
5522{
5523 put_gpr_w1(r1, get_gpr_w1(r2));
5524
5525 return "lr";
5526}
5527
florian55085f82012-11-21 00:36:55 +00005528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005529s390_irgen_LGR(UChar r1, UChar r2)
5530{
5531 put_gpr_dw0(r1, get_gpr_dw0(r2));
5532
5533 return "lgr";
5534}
5535
florian55085f82012-11-21 00:36:55 +00005536static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005537s390_irgen_LGFR(UChar r1, UChar r2)
5538{
5539 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5540
5541 return "lgfr";
5542}
5543
florian55085f82012-11-21 00:36:55 +00005544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005545s390_irgen_L(UChar r1, IRTemp op2addr)
5546{
5547 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5548
5549 return "l";
5550}
5551
florian55085f82012-11-21 00:36:55 +00005552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005553s390_irgen_LY(UChar r1, IRTemp op2addr)
5554{
5555 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5556
5557 return "ly";
5558}
5559
florian55085f82012-11-21 00:36:55 +00005560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005561s390_irgen_LG(UChar r1, IRTemp op2addr)
5562{
5563 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5564
5565 return "lg";
5566}
5567
florian55085f82012-11-21 00:36:55 +00005568static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005569s390_irgen_LGF(UChar r1, IRTemp op2addr)
5570{
5571 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5572
5573 return "lgf";
5574}
5575
florian55085f82012-11-21 00:36:55 +00005576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005577s390_irgen_LGFI(UChar r1, UInt i2)
5578{
5579 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5580
5581 return "lgfi";
5582}
5583
florian55085f82012-11-21 00:36:55 +00005584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005585s390_irgen_LRL(UChar r1, UInt i2)
5586{
5587 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5588 i2 << 1))));
5589
5590 return "lrl";
5591}
5592
florian55085f82012-11-21 00:36:55 +00005593static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005594s390_irgen_LGRL(UChar r1, UInt i2)
5595{
5596 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5597 i2 << 1))));
5598
5599 return "lgrl";
5600}
5601
florian55085f82012-11-21 00:36:55 +00005602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005603s390_irgen_LGFRL(UChar r1, UInt i2)
5604{
5605 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5606 ((ULong)(Long)(Int)i2 << 1)))));
5607
5608 return "lgfrl";
5609}
5610
florian55085f82012-11-21 00:36:55 +00005611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005612s390_irgen_LA(UChar r1, IRTemp op2addr)
5613{
5614 put_gpr_dw0(r1, mkexpr(op2addr));
5615
5616 return "la";
5617}
5618
florian55085f82012-11-21 00:36:55 +00005619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005620s390_irgen_LAY(UChar r1, IRTemp op2addr)
5621{
5622 put_gpr_dw0(r1, mkexpr(op2addr));
5623
5624 return "lay";
5625}
5626
florian55085f82012-11-21 00:36:55 +00005627static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005628s390_irgen_LAE(UChar r1, IRTemp op2addr)
5629{
5630 put_gpr_dw0(r1, mkexpr(op2addr));
5631
5632 return "lae";
5633}
5634
florian55085f82012-11-21 00:36:55 +00005635static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005636s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5637{
5638 put_gpr_dw0(r1, mkexpr(op2addr));
5639
5640 return "laey";
5641}
5642
florian55085f82012-11-21 00:36:55 +00005643static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005644s390_irgen_LARL(UChar r1, UInt i2)
5645{
5646 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5647
5648 return "larl";
5649}
5650
floriana265ee72012-12-02 20:58:17 +00005651/* The IR representation of LAA and friends is an approximation of what
5652 happens natively. Essentially a loop containing a compare-and-swap is
5653 constructed which will iterate until the CAS succeeds. As a consequence,
5654 instrumenters may see more memory accesses than happen natively. See also
5655 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005656static void
5657s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005658{
floriana265ee72012-12-02 20:58:17 +00005659 IRCAS *cas;
5660 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005661 IRTemp op2 = newTemp(Ity_I32);
5662 IRTemp op3 = newTemp(Ity_I32);
5663 IRTemp result = newTemp(Ity_I32);
5664
5665 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5666 assign(op3, get_gpr_w1(r3));
5667 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005668
5669 /* Place the addition of second operand and third operand at the
5670 second-operand location everytime */
5671 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5672 Iend_BE, mkexpr(op2addr),
5673 NULL, mkexpr(op2), /* expected value */
5674 NULL, mkexpr(result) /* new value */);
5675 stmt(IRStmt_CAS(cas));
5676
florianffc94012012-12-02 21:31:15 +00005677 /* Set CC according to 32-bit addition */
5678 if (is_signed) {
5679 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5680 } else {
5681 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5682 }
floriana265ee72012-12-02 20:58:17 +00005683
5684 /* If old_mem contains the expected value, then the CAS succeeded.
5685 Otherwise, it did not */
5686 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5687 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005688}
5689
5690static void
5691s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5692{
5693 IRCAS *cas;
5694 IRTemp old_mem = newTemp(Ity_I64);
5695 IRTemp op2 = newTemp(Ity_I64);
5696 IRTemp op3 = newTemp(Ity_I64);
5697 IRTemp result = newTemp(Ity_I64);
5698
5699 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5700 assign(op3, get_gpr_dw0(r3));
5701 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5702
5703 /* Place the addition of second operand and third operand at the
5704 second-operand location everytime */
5705 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5706 Iend_BE, mkexpr(op2addr),
5707 NULL, mkexpr(op2), /* expected value */
5708 NULL, mkexpr(result) /* new value */);
5709 stmt(IRStmt_CAS(cas));
5710
5711 /* Set CC according to 64-bit addition */
5712 if (is_signed) {
5713 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5714 } else {
5715 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5716 }
5717
5718 /* If old_mem contains the expected value, then the CAS succeeded.
5719 Otherwise, it did not */
5720 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5721 put_gpr_dw0(r1, mkexpr(old_mem));
5722}
5723
5724static void
5725s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5726{
5727 IRCAS *cas;
5728 IRTemp old_mem = newTemp(Ity_I32);
5729 IRTemp op2 = newTemp(Ity_I32);
5730 IRTemp op3 = newTemp(Ity_I32);
5731 IRTemp result = newTemp(Ity_I32);
5732
5733 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5734 assign(op3, get_gpr_w1(r3));
5735 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5736
5737 /* Place the addition of second operand and third operand at the
5738 second-operand location everytime */
5739 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5740 Iend_BE, mkexpr(op2addr),
5741 NULL, mkexpr(op2), /* expected value */
5742 NULL, mkexpr(result) /* new value */);
5743 stmt(IRStmt_CAS(cas));
5744
5745 /* Set CC according to bitwise operation */
5746 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5747
5748 /* If old_mem contains the expected value, then the CAS succeeded.
5749 Otherwise, it did not */
5750 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5751 put_gpr_w1(r1, mkexpr(old_mem));
5752}
5753
5754static void
5755s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5756{
5757 IRCAS *cas;
5758 IRTemp old_mem = newTemp(Ity_I64);
5759 IRTemp op2 = newTemp(Ity_I64);
5760 IRTemp op3 = newTemp(Ity_I64);
5761 IRTemp result = newTemp(Ity_I64);
5762
5763 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5764 assign(op3, get_gpr_dw0(r3));
5765 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5766
5767 /* Place the addition of second operand and third operand at the
5768 second-operand location everytime */
5769 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5770 Iend_BE, mkexpr(op2addr),
5771 NULL, mkexpr(op2), /* expected value */
5772 NULL, mkexpr(result) /* new value */);
5773 stmt(IRStmt_CAS(cas));
5774
5775 /* Set CC according to bitwise operation */
5776 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5777
5778 /* If old_mem contains the expected value, then the CAS succeeded.
5779 Otherwise, it did not */
5780 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5781 put_gpr_dw0(r1, mkexpr(old_mem));
5782}
5783
5784static const HChar *
5785s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5786{
5787 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005788
5789 return "laa";
5790}
5791
florian55085f82012-11-21 00:36:55 +00005792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005793s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5794{
florianffc94012012-12-02 21:31:15 +00005795 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005796
5797 return "laag";
5798}
5799
florian55085f82012-11-21 00:36:55 +00005800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005801s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5802{
florianffc94012012-12-02 21:31:15 +00005803 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005804
5805 return "laal";
5806}
5807
florian55085f82012-11-21 00:36:55 +00005808static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005809s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5810{
florianffc94012012-12-02 21:31:15 +00005811 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005812
5813 return "laalg";
5814}
5815
florian55085f82012-11-21 00:36:55 +00005816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005817s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5818{
florianffc94012012-12-02 21:31:15 +00005819 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005820
5821 return "lan";
5822}
5823
florian55085f82012-11-21 00:36:55 +00005824static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005825s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5826{
florianffc94012012-12-02 21:31:15 +00005827 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005828
5829 return "lang";
5830}
5831
florian55085f82012-11-21 00:36:55 +00005832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005833s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5834{
florianffc94012012-12-02 21:31:15 +00005835 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005836
5837 return "lax";
5838}
5839
florian55085f82012-11-21 00:36:55 +00005840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005841s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5842{
florianffc94012012-12-02 21:31:15 +00005843 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005844
5845 return "laxg";
5846}
5847
florian55085f82012-11-21 00:36:55 +00005848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005849s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5850{
florianffc94012012-12-02 21:31:15 +00005851 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005852
5853 return "lao";
5854}
5855
florian55085f82012-11-21 00:36:55 +00005856static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005857s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5858{
florianffc94012012-12-02 21:31:15 +00005859 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005860
5861 return "laog";
5862}
5863
florian55085f82012-11-21 00:36:55 +00005864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005865s390_irgen_LTR(UChar r1, UChar r2)
5866{
5867 IRTemp op2 = newTemp(Ity_I32);
5868
5869 assign(op2, get_gpr_w1(r2));
5870 put_gpr_w1(r1, mkexpr(op2));
5871 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5872
5873 return "ltr";
5874}
5875
florian55085f82012-11-21 00:36:55 +00005876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005877s390_irgen_LTGR(UChar r1, UChar r2)
5878{
5879 IRTemp op2 = newTemp(Ity_I64);
5880
5881 assign(op2, get_gpr_dw0(r2));
5882 put_gpr_dw0(r1, mkexpr(op2));
5883 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5884
5885 return "ltgr";
5886}
5887
florian55085f82012-11-21 00:36:55 +00005888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005889s390_irgen_LTGFR(UChar r1, UChar r2)
5890{
5891 IRTemp op2 = newTemp(Ity_I64);
5892
5893 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5894 put_gpr_dw0(r1, mkexpr(op2));
5895 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5896
5897 return "ltgfr";
5898}
5899
florian55085f82012-11-21 00:36:55 +00005900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005901s390_irgen_LT(UChar r1, IRTemp op2addr)
5902{
5903 IRTemp op2 = newTemp(Ity_I32);
5904
5905 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5906 put_gpr_w1(r1, mkexpr(op2));
5907 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5908
5909 return "lt";
5910}
5911
florian55085f82012-11-21 00:36:55 +00005912static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005913s390_irgen_LTG(UChar r1, IRTemp op2addr)
5914{
5915 IRTemp op2 = newTemp(Ity_I64);
5916
5917 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5918 put_gpr_dw0(r1, mkexpr(op2));
5919 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5920
5921 return "ltg";
5922}
5923
florian55085f82012-11-21 00:36:55 +00005924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005925s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5926{
5927 IRTemp op2 = newTemp(Ity_I64);
5928
5929 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5930 put_gpr_dw0(r1, mkexpr(op2));
5931 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5932
5933 return "ltgf";
5934}
5935
florian55085f82012-11-21 00:36:55 +00005936static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005937s390_irgen_LBR(UChar r1, UChar r2)
5938{
5939 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5940
5941 return "lbr";
5942}
5943
florian55085f82012-11-21 00:36:55 +00005944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005945s390_irgen_LGBR(UChar r1, UChar r2)
5946{
5947 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5948
5949 return "lgbr";
5950}
5951
florian55085f82012-11-21 00:36:55 +00005952static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005953s390_irgen_LB(UChar r1, IRTemp op2addr)
5954{
5955 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5956
5957 return "lb";
5958}
5959
florian55085f82012-11-21 00:36:55 +00005960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005961s390_irgen_LGB(UChar r1, IRTemp op2addr)
5962{
5963 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5964
5965 return "lgb";
5966}
5967
florian55085f82012-11-21 00:36:55 +00005968static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005969s390_irgen_LBH(UChar r1, IRTemp op2addr)
5970{
5971 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5972
5973 return "lbh";
5974}
5975
florian55085f82012-11-21 00:36:55 +00005976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005977s390_irgen_LCR(UChar r1, UChar r2)
5978{
5979 Int op1;
5980 IRTemp op2 = newTemp(Ity_I32);
5981 IRTemp result = newTemp(Ity_I32);
5982
5983 op1 = 0;
5984 assign(op2, get_gpr_w1(r2));
5985 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5986 put_gpr_w1(r1, mkexpr(result));
5987 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5988 op1)), op2);
5989
5990 return "lcr";
5991}
5992
florian55085f82012-11-21 00:36:55 +00005993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005994s390_irgen_LCGR(UChar r1, UChar r2)
5995{
5996 Long op1;
5997 IRTemp op2 = newTemp(Ity_I64);
5998 IRTemp result = newTemp(Ity_I64);
5999
6000 op1 = 0ULL;
6001 assign(op2, get_gpr_dw0(r2));
6002 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6003 put_gpr_dw0(r1, mkexpr(result));
6004 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6005 op1)), op2);
6006
6007 return "lcgr";
6008}
6009
florian55085f82012-11-21 00:36:55 +00006010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006011s390_irgen_LCGFR(UChar r1, UChar r2)
6012{
6013 Long op1;
6014 IRTemp op2 = newTemp(Ity_I64);
6015 IRTemp result = newTemp(Ity_I64);
6016
6017 op1 = 0ULL;
6018 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6019 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6020 put_gpr_dw0(r1, mkexpr(result));
6021 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6022 op1)), op2);
6023
6024 return "lcgfr";
6025}
6026
florian55085f82012-11-21 00:36:55 +00006027static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006028s390_irgen_LHR(UChar r1, UChar r2)
6029{
6030 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6031
6032 return "lhr";
6033}
6034
florian55085f82012-11-21 00:36:55 +00006035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006036s390_irgen_LGHR(UChar r1, UChar r2)
6037{
6038 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6039
6040 return "lghr";
6041}
6042
florian55085f82012-11-21 00:36:55 +00006043static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006044s390_irgen_LH(UChar r1, IRTemp op2addr)
6045{
6046 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6047
6048 return "lh";
6049}
6050
florian55085f82012-11-21 00:36:55 +00006051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006052s390_irgen_LHY(UChar r1, IRTemp op2addr)
6053{
6054 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6055
6056 return "lhy";
6057}
6058
florian55085f82012-11-21 00:36:55 +00006059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006060s390_irgen_LGH(UChar r1, IRTemp op2addr)
6061{
6062 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6063
6064 return "lgh";
6065}
6066
florian55085f82012-11-21 00:36:55 +00006067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006068s390_irgen_LHI(UChar r1, UShort i2)
6069{
6070 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6071
6072 return "lhi";
6073}
6074
florian55085f82012-11-21 00:36:55 +00006075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006076s390_irgen_LGHI(UChar r1, UShort i2)
6077{
6078 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6079
6080 return "lghi";
6081}
6082
florian55085f82012-11-21 00:36:55 +00006083static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006084s390_irgen_LHRL(UChar r1, UInt i2)
6085{
6086 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6087 ((ULong)(Long)(Int)i2 << 1)))));
6088
6089 return "lhrl";
6090}
6091
florian55085f82012-11-21 00:36:55 +00006092static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006093s390_irgen_LGHRL(UChar r1, UInt i2)
6094{
6095 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6096 ((ULong)(Long)(Int)i2 << 1)))));
6097
6098 return "lghrl";
6099}
6100
florian55085f82012-11-21 00:36:55 +00006101static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006102s390_irgen_LHH(UChar r1, IRTemp op2addr)
6103{
6104 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6105
6106 return "lhh";
6107}
6108
florian55085f82012-11-21 00:36:55 +00006109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006110s390_irgen_LFH(UChar r1, IRTemp op2addr)
6111{
6112 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6113
6114 return "lfh";
6115}
6116
florian55085f82012-11-21 00:36:55 +00006117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006118s390_irgen_LLGFR(UChar r1, UChar r2)
6119{
6120 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6121
6122 return "llgfr";
6123}
6124
florian55085f82012-11-21 00:36:55 +00006125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006126s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6127{
6128 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6129
6130 return "llgf";
6131}
6132
florian55085f82012-11-21 00:36:55 +00006133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006134s390_irgen_LLGFRL(UChar r1, UInt i2)
6135{
6136 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6137 ((ULong)(Long)(Int)i2 << 1)))));
6138
6139 return "llgfrl";
6140}
6141
florian55085f82012-11-21 00:36:55 +00006142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006143s390_irgen_LLCR(UChar r1, UChar r2)
6144{
6145 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6146
6147 return "llcr";
6148}
6149
florian55085f82012-11-21 00:36:55 +00006150static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006151s390_irgen_LLGCR(UChar r1, UChar r2)
6152{
6153 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6154
6155 return "llgcr";
6156}
6157
florian55085f82012-11-21 00:36:55 +00006158static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006159s390_irgen_LLC(UChar r1, IRTemp op2addr)
6160{
6161 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6162
6163 return "llc";
6164}
6165
florian55085f82012-11-21 00:36:55 +00006166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006167s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6168{
6169 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6170
6171 return "llgc";
6172}
6173
florian55085f82012-11-21 00:36:55 +00006174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006175s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6176{
6177 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6178
6179 return "llch";
6180}
6181
florian55085f82012-11-21 00:36:55 +00006182static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006183s390_irgen_LLHR(UChar r1, UChar r2)
6184{
6185 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6186
6187 return "llhr";
6188}
6189
florian55085f82012-11-21 00:36:55 +00006190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006191s390_irgen_LLGHR(UChar r1, UChar r2)
6192{
6193 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6194
6195 return "llghr";
6196}
6197
florian55085f82012-11-21 00:36:55 +00006198static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006199s390_irgen_LLH(UChar r1, IRTemp op2addr)
6200{
6201 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6202
6203 return "llh";
6204}
6205
florian55085f82012-11-21 00:36:55 +00006206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006207s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6208{
6209 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6210
6211 return "llgh";
6212}
6213
florian55085f82012-11-21 00:36:55 +00006214static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006215s390_irgen_LLHRL(UChar r1, UInt i2)
6216{
6217 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6218 ((ULong)(Long)(Int)i2 << 1)))));
6219
6220 return "llhrl";
6221}
6222
florian55085f82012-11-21 00:36:55 +00006223static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006224s390_irgen_LLGHRL(UChar r1, UInt i2)
6225{
6226 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6227 ((ULong)(Long)(Int)i2 << 1)))));
6228
6229 return "llghrl";
6230}
6231
florian55085f82012-11-21 00:36:55 +00006232static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006233s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6234{
6235 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6236
6237 return "llhh";
6238}
6239
florian55085f82012-11-21 00:36:55 +00006240static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006241s390_irgen_LLIHF(UChar r1, UInt i2)
6242{
6243 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6244
6245 return "llihf";
6246}
6247
florian55085f82012-11-21 00:36:55 +00006248static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006249s390_irgen_LLIHH(UChar r1, UShort i2)
6250{
6251 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6252
6253 return "llihh";
6254}
6255
florian55085f82012-11-21 00:36:55 +00006256static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006257s390_irgen_LLIHL(UChar r1, UShort i2)
6258{
6259 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6260
6261 return "llihl";
6262}
6263
florian55085f82012-11-21 00:36:55 +00006264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006265s390_irgen_LLILF(UChar r1, UInt i2)
6266{
6267 put_gpr_dw0(r1, mkU64(i2));
6268
6269 return "llilf";
6270}
6271
florian55085f82012-11-21 00:36:55 +00006272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006273s390_irgen_LLILH(UChar r1, UShort i2)
6274{
6275 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6276
6277 return "llilh";
6278}
6279
florian55085f82012-11-21 00:36:55 +00006280static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006281s390_irgen_LLILL(UChar r1, UShort i2)
6282{
6283 put_gpr_dw0(r1, mkU64(i2));
6284
6285 return "llill";
6286}
6287
florian55085f82012-11-21 00:36:55 +00006288static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006289s390_irgen_LLGTR(UChar r1, UChar r2)
6290{
6291 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6292 mkU32(2147483647))));
6293
6294 return "llgtr";
6295}
6296
florian55085f82012-11-21 00:36:55 +00006297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006298s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6299{
6300 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6301 mkexpr(op2addr)), mkU32(2147483647))));
6302
6303 return "llgt";
6304}
6305
florian55085f82012-11-21 00:36:55 +00006306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006307s390_irgen_LNR(UChar r1, UChar r2)
6308{
6309 IRTemp op2 = newTemp(Ity_I32);
6310 IRTemp result = newTemp(Ity_I32);
6311
6312 assign(op2, get_gpr_w1(r2));
6313 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6314 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6315 put_gpr_w1(r1, mkexpr(result));
6316 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6317
6318 return "lnr";
6319}
6320
florian55085f82012-11-21 00:36:55 +00006321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006322s390_irgen_LNGR(UChar r1, UChar r2)
6323{
6324 IRTemp op2 = newTemp(Ity_I64);
6325 IRTemp result = newTemp(Ity_I64);
6326
6327 assign(op2, get_gpr_dw0(r2));
6328 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6329 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6330 put_gpr_dw0(r1, mkexpr(result));
6331 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6332
6333 return "lngr";
6334}
6335
florian55085f82012-11-21 00:36:55 +00006336static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006337s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6338{
6339 IRTemp op2 = newTemp(Ity_I64);
6340 IRTemp result = newTemp(Ity_I64);
6341
6342 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6343 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6344 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6345 put_gpr_dw0(r1, mkexpr(result));
6346 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6347
6348 return "lngfr";
6349}
6350
florian55085f82012-11-21 00:36:55 +00006351static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006352s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6353{
florian6820ba52012-07-26 02:01:50 +00006354 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006355 put_gpr_w1(r1, get_gpr_w1(r2));
6356
6357 return "locr";
6358}
6359
florian55085f82012-11-21 00:36:55 +00006360static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006361s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6362{
florian6820ba52012-07-26 02:01:50 +00006363 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006364 put_gpr_dw0(r1, get_gpr_dw0(r2));
6365
6366 return "locgr";
6367}
6368
florian55085f82012-11-21 00:36:55 +00006369static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006370s390_irgen_LOC(UChar r1, IRTemp op2addr)
6371{
6372 /* condition is checked in format handler */
6373 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6374
6375 return "loc";
6376}
6377
florian55085f82012-11-21 00:36:55 +00006378static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006379s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6380{
6381 /* condition is checked in format handler */
6382 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6383
6384 return "locg";
6385}
6386
florian55085f82012-11-21 00:36:55 +00006387static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006388s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6389{
6390 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6391 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6392 ));
6393
6394 return "lpq";
6395}
6396
florian55085f82012-11-21 00:36:55 +00006397static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006398s390_irgen_LPR(UChar r1, UChar r2)
6399{
6400 IRTemp op2 = newTemp(Ity_I32);
6401 IRTemp result = newTemp(Ity_I32);
6402
6403 assign(op2, get_gpr_w1(r2));
6404 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6405 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6406 put_gpr_w1(r1, mkexpr(result));
6407 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6408
6409 return "lpr";
6410}
6411
florian55085f82012-11-21 00:36:55 +00006412static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006413s390_irgen_LPGR(UChar r1, UChar r2)
6414{
6415 IRTemp op2 = newTemp(Ity_I64);
6416 IRTemp result = newTemp(Ity_I64);
6417
6418 assign(op2, get_gpr_dw0(r2));
6419 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6420 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6421 put_gpr_dw0(r1, mkexpr(result));
6422 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6423
6424 return "lpgr";
6425}
6426
florian55085f82012-11-21 00:36:55 +00006427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006428s390_irgen_LPGFR(UChar r1, UChar r2)
6429{
6430 IRTemp op2 = newTemp(Ity_I64);
6431 IRTemp result = newTemp(Ity_I64);
6432
6433 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6434 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6435 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6436 put_gpr_dw0(r1, mkexpr(result));
6437 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6438
6439 return "lpgfr";
6440}
6441
florian55085f82012-11-21 00:36:55 +00006442static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006443s390_irgen_LRVR(UChar r1, UChar r2)
6444{
6445 IRTemp b0 = newTemp(Ity_I8);
6446 IRTemp b1 = newTemp(Ity_I8);
6447 IRTemp b2 = newTemp(Ity_I8);
6448 IRTemp b3 = newTemp(Ity_I8);
6449
6450 assign(b3, get_gpr_b7(r2));
6451 assign(b2, get_gpr_b6(r2));
6452 assign(b1, get_gpr_b5(r2));
6453 assign(b0, get_gpr_b4(r2));
6454 put_gpr_b4(r1, mkexpr(b3));
6455 put_gpr_b5(r1, mkexpr(b2));
6456 put_gpr_b6(r1, mkexpr(b1));
6457 put_gpr_b7(r1, mkexpr(b0));
6458
6459 return "lrvr";
6460}
6461
florian55085f82012-11-21 00:36:55 +00006462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006463s390_irgen_LRVGR(UChar r1, UChar r2)
6464{
6465 IRTemp b0 = newTemp(Ity_I8);
6466 IRTemp b1 = newTemp(Ity_I8);
6467 IRTemp b2 = newTemp(Ity_I8);
6468 IRTemp b3 = newTemp(Ity_I8);
6469 IRTemp b4 = newTemp(Ity_I8);
6470 IRTemp b5 = newTemp(Ity_I8);
6471 IRTemp b6 = newTemp(Ity_I8);
6472 IRTemp b7 = newTemp(Ity_I8);
6473
6474 assign(b7, get_gpr_b7(r2));
6475 assign(b6, get_gpr_b6(r2));
6476 assign(b5, get_gpr_b5(r2));
6477 assign(b4, get_gpr_b4(r2));
6478 assign(b3, get_gpr_b3(r2));
6479 assign(b2, get_gpr_b2(r2));
6480 assign(b1, get_gpr_b1(r2));
6481 assign(b0, get_gpr_b0(r2));
6482 put_gpr_b0(r1, mkexpr(b7));
6483 put_gpr_b1(r1, mkexpr(b6));
6484 put_gpr_b2(r1, mkexpr(b5));
6485 put_gpr_b3(r1, mkexpr(b4));
6486 put_gpr_b4(r1, mkexpr(b3));
6487 put_gpr_b5(r1, mkexpr(b2));
6488 put_gpr_b6(r1, mkexpr(b1));
6489 put_gpr_b7(r1, mkexpr(b0));
6490
6491 return "lrvgr";
6492}
6493
florian55085f82012-11-21 00:36:55 +00006494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006495s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6496{
6497 IRTemp op2 = newTemp(Ity_I16);
6498
6499 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6500 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6501 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6502
6503 return "lrvh";
6504}
6505
florian55085f82012-11-21 00:36:55 +00006506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006507s390_irgen_LRV(UChar r1, IRTemp op2addr)
6508{
6509 IRTemp op2 = newTemp(Ity_I32);
6510
6511 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6512 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6513 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6514 mkU8(8)), mkU32(255))));
6515 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6516 mkU8(16)), mkU32(255))));
6517 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6518 mkU8(24)), mkU32(255))));
6519
6520 return "lrv";
6521}
6522
florian55085f82012-11-21 00:36:55 +00006523static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006524s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6525{
6526 IRTemp op2 = newTemp(Ity_I64);
6527
6528 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6529 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6530 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6531 mkU8(8)), mkU64(255))));
6532 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6533 mkU8(16)), mkU64(255))));
6534 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6535 mkU8(24)), mkU64(255))));
6536 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6537 mkU8(32)), mkU64(255))));
6538 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6539 mkU8(40)), mkU64(255))));
6540 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6541 mkU8(48)), mkU64(255))));
6542 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6543 mkU8(56)), mkU64(255))));
6544
6545 return "lrvg";
6546}
6547
florian55085f82012-11-21 00:36:55 +00006548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006549s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6550{
6551 store(mkexpr(op1addr), mkU16(i2));
6552
6553 return "mvhhi";
6554}
6555
florian55085f82012-11-21 00:36:55 +00006556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006557s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6558{
6559 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6560
6561 return "mvhi";
6562}
6563
florian55085f82012-11-21 00:36:55 +00006564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006565s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6566{
6567 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6568
6569 return "mvghi";
6570}
6571
florian55085f82012-11-21 00:36:55 +00006572static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006573s390_irgen_MVI(UChar i2, IRTemp op1addr)
6574{
6575 store(mkexpr(op1addr), mkU8(i2));
6576
6577 return "mvi";
6578}
6579
florian55085f82012-11-21 00:36:55 +00006580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006581s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6582{
6583 store(mkexpr(op1addr), mkU8(i2));
6584
6585 return "mviy";
6586}
6587
florian55085f82012-11-21 00:36:55 +00006588static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006589s390_irgen_MR(UChar r1, UChar r2)
6590{
6591 IRTemp op1 = newTemp(Ity_I32);
6592 IRTemp op2 = newTemp(Ity_I32);
6593 IRTemp result = newTemp(Ity_I64);
6594
6595 assign(op1, get_gpr_w1(r1 + 1));
6596 assign(op2, get_gpr_w1(r2));
6597 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6598 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6599 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6600
6601 return "mr";
6602}
6603
florian55085f82012-11-21 00:36:55 +00006604static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006605s390_irgen_M(UChar r1, IRTemp op2addr)
6606{
6607 IRTemp op1 = newTemp(Ity_I32);
6608 IRTemp op2 = newTemp(Ity_I32);
6609 IRTemp result = newTemp(Ity_I64);
6610
6611 assign(op1, get_gpr_w1(r1 + 1));
6612 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6613 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6614 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6615 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6616
6617 return "m";
6618}
6619
florian55085f82012-11-21 00:36:55 +00006620static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006621s390_irgen_MFY(UChar r1, IRTemp op2addr)
6622{
6623 IRTemp op1 = newTemp(Ity_I32);
6624 IRTemp op2 = newTemp(Ity_I32);
6625 IRTemp result = newTemp(Ity_I64);
6626
6627 assign(op1, get_gpr_w1(r1 + 1));
6628 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6629 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6630 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6631 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6632
6633 return "mfy";
6634}
6635
florian55085f82012-11-21 00:36:55 +00006636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006637s390_irgen_MH(UChar r1, IRTemp op2addr)
6638{
6639 IRTemp op1 = newTemp(Ity_I32);
6640 IRTemp op2 = newTemp(Ity_I16);
6641 IRTemp result = newTemp(Ity_I64);
6642
6643 assign(op1, get_gpr_w1(r1));
6644 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6645 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6646 ));
6647 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6648
6649 return "mh";
6650}
6651
florian55085f82012-11-21 00:36:55 +00006652static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006653s390_irgen_MHY(UChar r1, IRTemp op2addr)
6654{
6655 IRTemp op1 = newTemp(Ity_I32);
6656 IRTemp op2 = newTemp(Ity_I16);
6657 IRTemp result = newTemp(Ity_I64);
6658
6659 assign(op1, get_gpr_w1(r1));
6660 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6661 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6662 ));
6663 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6664
6665 return "mhy";
6666}
6667
florian55085f82012-11-21 00:36:55 +00006668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006669s390_irgen_MHI(UChar r1, UShort i2)
6670{
6671 IRTemp op1 = newTemp(Ity_I32);
6672 Short op2;
6673 IRTemp result = newTemp(Ity_I64);
6674
6675 assign(op1, get_gpr_w1(r1));
6676 op2 = (Short)i2;
6677 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6678 mkU16((UShort)op2))));
6679 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6680
6681 return "mhi";
6682}
6683
florian55085f82012-11-21 00:36:55 +00006684static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006685s390_irgen_MGHI(UChar r1, UShort i2)
6686{
6687 IRTemp op1 = newTemp(Ity_I64);
6688 Short op2;
6689 IRTemp result = newTemp(Ity_I128);
6690
6691 assign(op1, get_gpr_dw0(r1));
6692 op2 = (Short)i2;
6693 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6694 mkU16((UShort)op2))));
6695 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6696
6697 return "mghi";
6698}
6699
florian55085f82012-11-21 00:36:55 +00006700static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006701s390_irgen_MLR(UChar r1, UChar r2)
6702{
6703 IRTemp op1 = newTemp(Ity_I32);
6704 IRTemp op2 = newTemp(Ity_I32);
6705 IRTemp result = newTemp(Ity_I64);
6706
6707 assign(op1, get_gpr_w1(r1 + 1));
6708 assign(op2, get_gpr_w1(r2));
6709 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6710 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6711 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6712
6713 return "mlr";
6714}
6715
florian55085f82012-11-21 00:36:55 +00006716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006717s390_irgen_MLGR(UChar r1, UChar r2)
6718{
6719 IRTemp op1 = newTemp(Ity_I64);
6720 IRTemp op2 = newTemp(Ity_I64);
6721 IRTemp result = newTemp(Ity_I128);
6722
6723 assign(op1, get_gpr_dw0(r1 + 1));
6724 assign(op2, get_gpr_dw0(r2));
6725 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6726 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6727 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6728
6729 return "mlgr";
6730}
6731
florian55085f82012-11-21 00:36:55 +00006732static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006733s390_irgen_ML(UChar r1, IRTemp op2addr)
6734{
6735 IRTemp op1 = newTemp(Ity_I32);
6736 IRTemp op2 = newTemp(Ity_I32);
6737 IRTemp result = newTemp(Ity_I64);
6738
6739 assign(op1, get_gpr_w1(r1 + 1));
6740 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6741 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6742 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6743 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6744
6745 return "ml";
6746}
6747
florian55085f82012-11-21 00:36:55 +00006748static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006749s390_irgen_MLG(UChar r1, IRTemp op2addr)
6750{
6751 IRTemp op1 = newTemp(Ity_I64);
6752 IRTemp op2 = newTemp(Ity_I64);
6753 IRTemp result = newTemp(Ity_I128);
6754
6755 assign(op1, get_gpr_dw0(r1 + 1));
6756 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6757 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6758 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6759 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6760
6761 return "mlg";
6762}
6763
florian55085f82012-11-21 00:36:55 +00006764static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006765s390_irgen_MSR(UChar r1, UChar r2)
6766{
6767 IRTemp op1 = newTemp(Ity_I32);
6768 IRTemp op2 = newTemp(Ity_I32);
6769 IRTemp result = newTemp(Ity_I64);
6770
6771 assign(op1, get_gpr_w1(r1));
6772 assign(op2, get_gpr_w1(r2));
6773 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6774 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6775
6776 return "msr";
6777}
6778
florian55085f82012-11-21 00:36:55 +00006779static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006780s390_irgen_MSGR(UChar r1, UChar r2)
6781{
6782 IRTemp op1 = newTemp(Ity_I64);
6783 IRTemp op2 = newTemp(Ity_I64);
6784 IRTemp result = newTemp(Ity_I128);
6785
6786 assign(op1, get_gpr_dw0(r1));
6787 assign(op2, get_gpr_dw0(r2));
6788 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6789 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6790
6791 return "msgr";
6792}
6793
florian55085f82012-11-21 00:36:55 +00006794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006795s390_irgen_MSGFR(UChar r1, UChar r2)
6796{
6797 IRTemp op1 = newTemp(Ity_I64);
6798 IRTemp op2 = newTemp(Ity_I32);
6799 IRTemp result = newTemp(Ity_I128);
6800
6801 assign(op1, get_gpr_dw0(r1));
6802 assign(op2, get_gpr_w1(r2));
6803 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6804 ));
6805 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6806
6807 return "msgfr";
6808}
6809
florian55085f82012-11-21 00:36:55 +00006810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006811s390_irgen_MS(UChar r1, IRTemp op2addr)
6812{
6813 IRTemp op1 = newTemp(Ity_I32);
6814 IRTemp op2 = newTemp(Ity_I32);
6815 IRTemp result = newTemp(Ity_I64);
6816
6817 assign(op1, get_gpr_w1(r1));
6818 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6819 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6820 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6821
6822 return "ms";
6823}
6824
florian55085f82012-11-21 00:36:55 +00006825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006826s390_irgen_MSY(UChar r1, IRTemp op2addr)
6827{
6828 IRTemp op1 = newTemp(Ity_I32);
6829 IRTemp op2 = newTemp(Ity_I32);
6830 IRTemp result = newTemp(Ity_I64);
6831
6832 assign(op1, get_gpr_w1(r1));
6833 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6834 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6835 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6836
6837 return "msy";
6838}
6839
florian55085f82012-11-21 00:36:55 +00006840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006841s390_irgen_MSG(UChar r1, IRTemp op2addr)
6842{
6843 IRTemp op1 = newTemp(Ity_I64);
6844 IRTemp op2 = newTemp(Ity_I64);
6845 IRTemp result = newTemp(Ity_I128);
6846
6847 assign(op1, get_gpr_dw0(r1));
6848 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6849 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6850 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6851
6852 return "msg";
6853}
6854
florian55085f82012-11-21 00:36:55 +00006855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006856s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6857{
6858 IRTemp op1 = newTemp(Ity_I64);
6859 IRTemp op2 = newTemp(Ity_I32);
6860 IRTemp result = newTemp(Ity_I128);
6861
6862 assign(op1, get_gpr_dw0(r1));
6863 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6864 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6865 ));
6866 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6867
6868 return "msgf";
6869}
6870
florian55085f82012-11-21 00:36:55 +00006871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006872s390_irgen_MSFI(UChar r1, UInt i2)
6873{
6874 IRTemp op1 = newTemp(Ity_I32);
6875 Int op2;
6876 IRTemp result = newTemp(Ity_I64);
6877
6878 assign(op1, get_gpr_w1(r1));
6879 op2 = (Int)i2;
6880 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6881 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6882
6883 return "msfi";
6884}
6885
florian55085f82012-11-21 00:36:55 +00006886static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006887s390_irgen_MSGFI(UChar r1, UInt i2)
6888{
6889 IRTemp op1 = newTemp(Ity_I64);
6890 Int op2;
6891 IRTemp result = newTemp(Ity_I128);
6892
6893 assign(op1, get_gpr_dw0(r1));
6894 op2 = (Int)i2;
6895 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6896 op2))));
6897 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6898
6899 return "msgfi";
6900}
6901
florian55085f82012-11-21 00:36:55 +00006902static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006903s390_irgen_OR(UChar r1, UChar r2)
6904{
6905 IRTemp op1 = newTemp(Ity_I32);
6906 IRTemp op2 = newTemp(Ity_I32);
6907 IRTemp result = newTemp(Ity_I32);
6908
6909 assign(op1, get_gpr_w1(r1));
6910 assign(op2, get_gpr_w1(r2));
6911 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6912 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6913 put_gpr_w1(r1, mkexpr(result));
6914
6915 return "or";
6916}
6917
florian55085f82012-11-21 00:36:55 +00006918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006919s390_irgen_OGR(UChar r1, UChar r2)
6920{
6921 IRTemp op1 = newTemp(Ity_I64);
6922 IRTemp op2 = newTemp(Ity_I64);
6923 IRTemp result = newTemp(Ity_I64);
6924
6925 assign(op1, get_gpr_dw0(r1));
6926 assign(op2, get_gpr_dw0(r2));
6927 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6928 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6929 put_gpr_dw0(r1, mkexpr(result));
6930
6931 return "ogr";
6932}
6933
florian55085f82012-11-21 00:36:55 +00006934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006935s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6936{
6937 IRTemp op2 = newTemp(Ity_I32);
6938 IRTemp op3 = newTemp(Ity_I32);
6939 IRTemp result = newTemp(Ity_I32);
6940
6941 assign(op2, get_gpr_w1(r2));
6942 assign(op3, get_gpr_w1(r3));
6943 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6944 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6945 put_gpr_w1(r1, mkexpr(result));
6946
6947 return "ork";
6948}
6949
florian55085f82012-11-21 00:36:55 +00006950static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006951s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6952{
6953 IRTemp op2 = newTemp(Ity_I64);
6954 IRTemp op3 = newTemp(Ity_I64);
6955 IRTemp result = newTemp(Ity_I64);
6956
6957 assign(op2, get_gpr_dw0(r2));
6958 assign(op3, get_gpr_dw0(r3));
6959 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6960 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6961 put_gpr_dw0(r1, mkexpr(result));
6962
6963 return "ogrk";
6964}
6965
florian55085f82012-11-21 00:36:55 +00006966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006967s390_irgen_O(UChar r1, IRTemp op2addr)
6968{
6969 IRTemp op1 = newTemp(Ity_I32);
6970 IRTemp op2 = newTemp(Ity_I32);
6971 IRTemp result = newTemp(Ity_I32);
6972
6973 assign(op1, get_gpr_w1(r1));
6974 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6975 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6976 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6977 put_gpr_w1(r1, mkexpr(result));
6978
6979 return "o";
6980}
6981
florian55085f82012-11-21 00:36:55 +00006982static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006983s390_irgen_OY(UChar r1, IRTemp op2addr)
6984{
6985 IRTemp op1 = newTemp(Ity_I32);
6986 IRTemp op2 = newTemp(Ity_I32);
6987 IRTemp result = newTemp(Ity_I32);
6988
6989 assign(op1, get_gpr_w1(r1));
6990 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6991 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6992 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6993 put_gpr_w1(r1, mkexpr(result));
6994
6995 return "oy";
6996}
6997
florian55085f82012-11-21 00:36:55 +00006998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006999s390_irgen_OG(UChar r1, IRTemp op2addr)
7000{
7001 IRTemp op1 = newTemp(Ity_I64);
7002 IRTemp op2 = newTemp(Ity_I64);
7003 IRTemp result = newTemp(Ity_I64);
7004
7005 assign(op1, get_gpr_dw0(r1));
7006 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7007 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
7008 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7009 put_gpr_dw0(r1, mkexpr(result));
7010
7011 return "og";
7012}
7013
florian55085f82012-11-21 00:36:55 +00007014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007015s390_irgen_OI(UChar i2, IRTemp op1addr)
7016{
7017 IRTemp op1 = newTemp(Ity_I8);
7018 UChar op2;
7019 IRTemp result = newTemp(Ity_I8);
7020
7021 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7022 op2 = i2;
7023 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7024 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7025 store(mkexpr(op1addr), mkexpr(result));
7026
7027 return "oi";
7028}
7029
florian55085f82012-11-21 00:36:55 +00007030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007031s390_irgen_OIY(UChar i2, IRTemp op1addr)
7032{
7033 IRTemp op1 = newTemp(Ity_I8);
7034 UChar op2;
7035 IRTemp result = newTemp(Ity_I8);
7036
7037 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7038 op2 = i2;
7039 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7040 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7041 store(mkexpr(op1addr), mkexpr(result));
7042
7043 return "oiy";
7044}
7045
florian55085f82012-11-21 00:36:55 +00007046static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007047s390_irgen_OIHF(UChar r1, UInt i2)
7048{
7049 IRTemp op1 = newTemp(Ity_I32);
7050 UInt op2;
7051 IRTemp result = newTemp(Ity_I32);
7052
7053 assign(op1, get_gpr_w0(r1));
7054 op2 = i2;
7055 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7056 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7057 put_gpr_w0(r1, mkexpr(result));
7058
7059 return "oihf";
7060}
7061
florian55085f82012-11-21 00:36:55 +00007062static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007063s390_irgen_OIHH(UChar r1, UShort i2)
7064{
7065 IRTemp op1 = newTemp(Ity_I16);
7066 UShort op2;
7067 IRTemp result = newTemp(Ity_I16);
7068
7069 assign(op1, get_gpr_hw0(r1));
7070 op2 = i2;
7071 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7072 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7073 put_gpr_hw0(r1, mkexpr(result));
7074
7075 return "oihh";
7076}
7077
florian55085f82012-11-21 00:36:55 +00007078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007079s390_irgen_OIHL(UChar r1, UShort i2)
7080{
7081 IRTemp op1 = newTemp(Ity_I16);
7082 UShort op2;
7083 IRTemp result = newTemp(Ity_I16);
7084
7085 assign(op1, get_gpr_hw1(r1));
7086 op2 = i2;
7087 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7088 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7089 put_gpr_hw1(r1, mkexpr(result));
7090
7091 return "oihl";
7092}
7093
florian55085f82012-11-21 00:36:55 +00007094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007095s390_irgen_OILF(UChar r1, UInt i2)
7096{
7097 IRTemp op1 = newTemp(Ity_I32);
7098 UInt op2;
7099 IRTemp result = newTemp(Ity_I32);
7100
7101 assign(op1, get_gpr_w1(r1));
7102 op2 = i2;
7103 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7104 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7105 put_gpr_w1(r1, mkexpr(result));
7106
7107 return "oilf";
7108}
7109
florian55085f82012-11-21 00:36:55 +00007110static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007111s390_irgen_OILH(UChar r1, UShort i2)
7112{
7113 IRTemp op1 = newTemp(Ity_I16);
7114 UShort op2;
7115 IRTemp result = newTemp(Ity_I16);
7116
7117 assign(op1, get_gpr_hw2(r1));
7118 op2 = i2;
7119 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7120 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7121 put_gpr_hw2(r1, mkexpr(result));
7122
7123 return "oilh";
7124}
7125
florian55085f82012-11-21 00:36:55 +00007126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007127s390_irgen_OILL(UChar r1, UShort i2)
7128{
7129 IRTemp op1 = newTemp(Ity_I16);
7130 UShort op2;
7131 IRTemp result = newTemp(Ity_I16);
7132
7133 assign(op1, get_gpr_hw3(r1));
7134 op2 = i2;
7135 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7136 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7137 put_gpr_hw3(r1, mkexpr(result));
7138
7139 return "oill";
7140}
7141
florian55085f82012-11-21 00:36:55 +00007142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007143s390_irgen_PFD(void)
7144{
7145
7146 return "pfd";
7147}
7148
florian55085f82012-11-21 00:36:55 +00007149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007150s390_irgen_PFDRL(void)
7151{
7152
7153 return "pfdrl";
7154}
7155
florian78d5ef72013-05-11 15:02:58 +00007156static IRExpr *
7157get_rounding_mode_from_gr0(void)
7158{
7159 IRTemp rm_bits = newTemp(Ity_I32);
7160 IRExpr *s390rm;
7161 IRExpr *irrm;
7162
7163 vassert(s390_host_has_pfpo);
7164 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7165 when PFPO insn is called. So, extract the bits at [60:63] */
7166 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7167 s390rm = mkexpr(rm_bits);
7168 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7169 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7170 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7171 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7172 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7173 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7174 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7175 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7176 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7177 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7178 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7179 mkexpr(encode_dfp_rounding_mode(
7180 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7181 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7182 mkexpr(encode_dfp_rounding_mode(
7183 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7184 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7185 mkexpr(encode_dfp_rounding_mode(
7186 S390_DFP_ROUND_AWAY_0)),
7187 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7188 mkexpr(encode_dfp_rounding_mode(
7189 S390_DFP_ROUND_PREPARE_SHORT_15)),
7190 /* if rounding mode is 0 or invalid (2-7)
7191 set S390_DFP_ROUND_PER_FPC_0 */
7192 mkexpr(encode_dfp_rounding_mode(
7193 S390_DFP_ROUND_PER_FPC_0)))))))))));
7194
7195 return irrm;
7196}
7197
7198static IRExpr *
7199s390_call_pfpo_helper(IRExpr *gr0)
7200{
7201 IRExpr **args, *call;
7202
7203 args = mkIRExprVec_1(gr0);
7204 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7205 "s390_do_pfpo", &s390_do_pfpo, args);
7206 /* Nothing is excluded from definedness checking. */
7207 call->Iex.CCall.cee->mcx_mask = 0;
7208
7209 return call;
7210}
7211
7212static const HChar *
7213s390_irgen_PFPO(void)
7214{
7215 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
7216 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7217 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
7218 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
florian7ab421d2013-06-17 21:03:56 +00007219 IRTemp src1 = newTemp(Ity_F32);
7220 IRTemp dst1 = newTemp(Ity_D32);
7221 IRTemp src2 = newTemp(Ity_F32);
7222 IRTemp dst2 = newTemp(Ity_D64);
7223 IRTemp src3 = newTemp(Ity_F32);
florian78d5ef72013-05-11 15:02:58 +00007224 IRTemp dst3 = newTemp(Ity_D128);
florian7ab421d2013-06-17 21:03:56 +00007225 IRTemp src4 = newTemp(Ity_F64);
7226 IRTemp dst4 = newTemp(Ity_D32);
7227 IRTemp src5 = newTemp(Ity_F64);
7228 IRTemp dst5 = newTemp(Ity_D64);
7229 IRTemp src6 = newTemp(Ity_F64);
7230 IRTemp dst6 = newTemp(Ity_D128);
7231 IRTemp src7 = newTemp(Ity_F128);
7232 IRTemp dst7 = newTemp(Ity_D32);
7233 IRTemp src8 = newTemp(Ity_F128);
7234 IRTemp dst8 = newTemp(Ity_D64);
7235 IRTemp src9 = newTemp(Ity_F128);
7236 IRTemp dst9 = newTemp(Ity_D128);
7237 IRTemp src10 = newTemp(Ity_D32);
7238 IRTemp dst10 = newTemp(Ity_F32);
7239 IRTemp src11 = newTemp(Ity_D32);
7240 IRTemp dst11 = newTemp(Ity_F64);
7241 IRTemp src12 = newTemp(Ity_D32);
7242 IRTemp dst12 = newTemp(Ity_F128);
7243 IRTemp src13 = newTemp(Ity_D64);
7244 IRTemp dst13 = newTemp(Ity_F32);
7245 IRTemp src14 = newTemp(Ity_D64);
7246 IRTemp dst14 = newTemp(Ity_F64);
7247 IRTemp src15 = newTemp(Ity_D64);
7248 IRTemp dst15 = newTemp(Ity_F128);
7249 IRTemp src16 = newTemp(Ity_D128);
7250 IRTemp dst16 = newTemp(Ity_F32);
7251 IRTemp src17 = newTemp(Ity_D128);
7252 IRTemp dst17 = newTemp(Ity_F64);
7253 IRTemp src18 = newTemp(Ity_D128);
7254 IRTemp dst18 = newTemp(Ity_F128);
florian78d5ef72013-05-11 15:02:58 +00007255 IRExpr *irrm;
7256
7257 vassert(s390_host_has_pfpo);
7258
7259 assign(gr0, get_gpr_w1(0));
7260 /* get function code */
7261 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7262 mkU32(0x7fffff)));
7263 /* get validity test bit */
7264 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7265 mkU32(0x1)));
7266 irrm = get_rounding_mode_from_gr0();
7267
7268 /* test_bit is 1 */
florian7ab421d2013-06-17 21:03:56 +00007269 assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
florian78d5ef72013-05-11 15:02:58 +00007270 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7271
7272 /* Return code set in GR1 is usually 0. Non-zero value is set only
7273 when exceptions are raised. See Programming Notes point 5 in the
7274 instrcution description of pfpo in POP. Since valgrind does not
7275 model exception, it might be safe to just set 0 to GR 1. */
7276 put_gpr_w1(1, mkU32(0x0));
7277 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7278
7279 /* Check validity of function code in GR 0 */
7280 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
florianafa3f042014-09-06 21:43:28 +00007281 emulation_failure_with_expr(mkexpr(ef));
florian78d5ef72013-05-11 15:02:58 +00007282
7283 stmt(
7284 IRStmt_Exit(
7285 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7286 Ijk_EmFail,
7287 IRConst_U64(guest_IA_next_instr),
7288 S390X_GUEST_OFFSET(guest_IA)
7289 )
7290 );
7291
florian7ab421d2013-06-17 21:03:56 +00007292 /* F32 -> D32 */
florian78d5ef72013-05-11 15:02:58 +00007293 /* get source from FPR 4,6 - already set in src1 */
florian7ab421d2013-06-17 21:03:56 +00007294 assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7295 put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007296 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007297 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7298 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
florian78d5ef72013-05-11 15:02:58 +00007299
florian7ab421d2013-06-17 21:03:56 +00007300 /* F32 -> D64 */
7301 assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7302 assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7303 put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007304 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007305 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7306 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007307
florian7ab421d2013-06-17 21:03:56 +00007308 /* F32 -> D128 */
7309 assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7310 assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
florian78d5ef72013-05-11 15:02:58 +00007311 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7312 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007313 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7314 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7315
7316 /* F64 -> D32 */
7317 assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7318 assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7319 put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7320 put_gpr_w1(1, mkU32(0x0));
7321 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7322 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7323
7324 /* F64 -> D64 */
7325 assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7326 assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7327 put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7328 put_gpr_w1(1, mkU32(0x0));
7329 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7330 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7331
7332 /* F64 -> D128 */
7333 assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7334 assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7335 put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7336 put_gpr_w1(1, mkU32(0x0));
7337 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
florian78d5ef72013-05-11 15:02:58 +00007338 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7339
florian7ab421d2013-06-17 21:03:56 +00007340 /* F128 -> D32 */
7341 assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7342 assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7343 put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007344 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007345 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7346 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7347
7348 /* F128 -> D64 */
7349 assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7350 assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7351 put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7352 put_gpr_w1(1, mkU32(0x0));
7353 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7354 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007355
7356 /* F128 -> D128 */
florian7ab421d2013-06-17 21:03:56 +00007357 assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7358 assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7359 put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007360 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007361 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
florian78d5ef72013-05-11 15:02:58 +00007362 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7363
florian7ab421d2013-06-17 21:03:56 +00007364 /* D32 -> F32 */
7365 assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7366 assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7367 put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007368 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007369 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7370 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7371
7372 /* D32 -> F64 */
7373 assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7374 assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7375 put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7376 put_gpr_w1(1, mkU32(0x0));
7377 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7378 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7379
7380 /* D32 -> F128 */
7381 assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7382 assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7383 put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7384 put_gpr_w1(1, mkU32(0x0));
7385 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7386 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7387
7388 /* D64 -> F32 */
7389 assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7390 assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7391 put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7392 put_gpr_w1(1, mkU32(0x0));
7393 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7394 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7395
7396 /* D64 -> F64 */
7397 assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7398 assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7399 put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7400 put_gpr_w1(1, mkU32(0x0));
7401 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7402 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7403
7404 /* D64 -> F128 */
7405 assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7406 assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7407 put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7408 put_gpr_w1(1, mkU32(0x0));
7409 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7410 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7411
7412 /* D128 -> F32 */
7413 assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7414 assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7415 put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7416 put_gpr_w1(1, mkU32(0x0));
7417 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7418 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7419
7420 /* D128 -> F64 */
7421 assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7422 assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7423 put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7424 put_gpr_w1(1, mkU32(0x0));
7425 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7426 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7427
7428 /* D128 -> F128 */
7429 assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7430 assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7431 put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7432 put_gpr_w1(1, mkU32(0x0));
7433 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
florian78d5ef72013-05-11 15:02:58 +00007434 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7435
7436 return "pfpo";
7437}
7438
florian55085f82012-11-21 00:36:55 +00007439static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007440s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7441{
7442 IRTemp amount = newTemp(Ity_I64);
7443 IRTemp op = newTemp(Ity_I32);
7444
7445 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7446 assign(op, get_gpr_w1(r3));
7447 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7448 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7449 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7450
7451 return "rll";
7452}
7453
florian55085f82012-11-21 00:36:55 +00007454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007455s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7456{
7457 IRTemp amount = newTemp(Ity_I64);
7458 IRTemp op = newTemp(Ity_I64);
7459
7460 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7461 assign(op, get_gpr_dw0(r3));
7462 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7463 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7464 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7465
7466 return "rllg";
7467}
7468
florian55085f82012-11-21 00:36:55 +00007469static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007470s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7471{
7472 UChar from;
7473 UChar to;
7474 UChar rot;
7475 UChar t_bit;
7476 ULong mask;
7477 ULong maskc;
7478 IRTemp result = newTemp(Ity_I64);
7479 IRTemp op2 = newTemp(Ity_I64);
7480
7481 from = i3 & 63;
7482 to = i4 & 63;
7483 rot = i5 & 63;
7484 t_bit = i3 & 128;
7485 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7486 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7487 mkU8(64 - rot))));
7488 if (from <= to) {
7489 mask = ~0ULL;
7490 mask = (mask >> from) & (mask << (63 - to));
7491 maskc = ~mask;
7492 } else {
7493 maskc = ~0ULL;
7494 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7495 mask = ~maskc;
7496 }
7497 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7498 ), mkU64(mask)));
7499 if (t_bit == 0) {
7500 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7501 mkU64(maskc)), mkexpr(result)));
7502 }
7503 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7504
7505 return "rnsbg";
7506}
7507
florian55085f82012-11-21 00:36:55 +00007508static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007509s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7510{
7511 UChar from;
7512 UChar to;
7513 UChar rot;
7514 UChar t_bit;
7515 ULong mask;
7516 ULong maskc;
7517 IRTemp result = newTemp(Ity_I64);
7518 IRTemp op2 = newTemp(Ity_I64);
7519
7520 from = i3 & 63;
7521 to = i4 & 63;
7522 rot = i5 & 63;
7523 t_bit = i3 & 128;
7524 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7525 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7526 mkU8(64 - rot))));
7527 if (from <= to) {
7528 mask = ~0ULL;
7529 mask = (mask >> from) & (mask << (63 - to));
7530 maskc = ~mask;
7531 } else {
7532 maskc = ~0ULL;
7533 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7534 mask = ~maskc;
7535 }
7536 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7537 ), mkU64(mask)));
7538 if (t_bit == 0) {
7539 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7540 mkU64(maskc)), mkexpr(result)));
7541 }
7542 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7543
7544 return "rxsbg";
7545}
7546
florian55085f82012-11-21 00:36:55 +00007547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007548s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7549{
7550 UChar from;
7551 UChar to;
7552 UChar rot;
7553 UChar t_bit;
7554 ULong mask;
7555 ULong maskc;
7556 IRTemp result = newTemp(Ity_I64);
7557 IRTemp op2 = newTemp(Ity_I64);
7558
7559 from = i3 & 63;
7560 to = i4 & 63;
7561 rot = i5 & 63;
7562 t_bit = i3 & 128;
7563 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7564 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7565 mkU8(64 - rot))));
7566 if (from <= to) {
7567 mask = ~0ULL;
7568 mask = (mask >> from) & (mask << (63 - to));
7569 maskc = ~mask;
7570 } else {
7571 maskc = ~0ULL;
7572 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7573 mask = ~maskc;
7574 }
7575 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7576 ), mkU64(mask)));
7577 if (t_bit == 0) {
7578 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7579 mkU64(maskc)), mkexpr(result)));
7580 }
7581 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7582
7583 return "rosbg";
7584}
7585
florian55085f82012-11-21 00:36:55 +00007586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007587s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7588{
7589 UChar from;
7590 UChar to;
7591 UChar rot;
7592 UChar z_bit;
7593 ULong mask;
7594 ULong maskc;
7595 IRTemp op2 = newTemp(Ity_I64);
7596 IRTemp result = newTemp(Ity_I64);
7597
7598 from = i3 & 63;
7599 to = i4 & 63;
7600 rot = i5 & 63;
7601 z_bit = i4 & 128;
7602 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7603 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7604 mkU8(64 - rot))));
7605 if (from <= to) {
7606 mask = ~0ULL;
7607 mask = (mask >> from) & (mask << (63 - to));
7608 maskc = ~mask;
7609 } else {
7610 maskc = ~0ULL;
7611 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7612 mask = ~maskc;
7613 }
7614 if (z_bit == 0) {
7615 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7616 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7617 } else {
7618 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7619 }
7620 assign(result, get_gpr_dw0(r1));
cborntrae03b6002013-11-07 21:37:28 +00007621 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
sewardj2019a972011-03-07 16:04:07 +00007622
7623 return "risbg";
7624}
7625
florian55085f82012-11-21 00:36:55 +00007626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007627s390_irgen_SAR(UChar r1, UChar r2)
7628{
7629 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007630 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007631 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7632
7633 return "sar";
7634}
7635
florian55085f82012-11-21 00:36:55 +00007636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007637s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7638{
7639 IRTemp p1 = newTemp(Ity_I64);
7640 IRTemp p2 = newTemp(Ity_I64);
7641 IRTemp op = newTemp(Ity_I64);
7642 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007643 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007644 IRTemp shift_amount = newTemp(Ity_I64);
7645
7646 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7647 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7648 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7649 ));
7650 sign_mask = 1ULL << 63;
7651 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7652 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007653 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7654 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007655 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7656 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7657 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7658
7659 return "slda";
7660}
7661
florian55085f82012-11-21 00:36:55 +00007662static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007663s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7664{
7665 IRTemp p1 = newTemp(Ity_I64);
7666 IRTemp p2 = newTemp(Ity_I64);
7667 IRTemp result = newTemp(Ity_I64);
7668
7669 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7670 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7671 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7672 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7673 mkexpr(op2addr), mkU64(63)))));
7674 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7675 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7676
7677 return "sldl";
7678}
7679
florian55085f82012-11-21 00:36:55 +00007680static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007681s390_irgen_SLA(UChar r1, IRTemp op2addr)
7682{
7683 IRTemp uop = newTemp(Ity_I32);
7684 IRTemp result = newTemp(Ity_I32);
7685 UInt sign_mask;
7686 IRTemp shift_amount = newTemp(Ity_I64);
7687 IRTemp op = newTemp(Ity_I32);
7688
7689 assign(op, get_gpr_w1(r1));
7690 assign(uop, get_gpr_w1(r1));
7691 sign_mask = 2147483648U;
7692 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7693 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7694 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7695 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7696 put_gpr_w1(r1, mkexpr(result));
7697 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7698
7699 return "sla";
7700}
7701
florian55085f82012-11-21 00:36:55 +00007702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007703s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7704{
7705 IRTemp uop = newTemp(Ity_I32);
7706 IRTemp result = newTemp(Ity_I32);
7707 UInt sign_mask;
7708 IRTemp shift_amount = newTemp(Ity_I64);
7709 IRTemp op = newTemp(Ity_I32);
7710
7711 assign(op, get_gpr_w1(r3));
7712 assign(uop, get_gpr_w1(r3));
7713 sign_mask = 2147483648U;
7714 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7715 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7716 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7717 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7718 put_gpr_w1(r1, mkexpr(result));
7719 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7720
7721 return "slak";
7722}
7723
florian55085f82012-11-21 00:36:55 +00007724static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007725s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7726{
7727 IRTemp uop = newTemp(Ity_I64);
7728 IRTemp result = newTemp(Ity_I64);
7729 ULong sign_mask;
7730 IRTemp shift_amount = newTemp(Ity_I64);
7731 IRTemp op = newTemp(Ity_I64);
7732
7733 assign(op, get_gpr_dw0(r3));
7734 assign(uop, get_gpr_dw0(r3));
7735 sign_mask = 9223372036854775808ULL;
7736 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7737 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7738 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7739 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7740 put_gpr_dw0(r1, mkexpr(result));
7741 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7742
7743 return "slag";
7744}
7745
florian55085f82012-11-21 00:36:55 +00007746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007747s390_irgen_SLL(UChar r1, IRTemp op2addr)
7748{
7749 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7750 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7751
7752 return "sll";
7753}
7754
florian55085f82012-11-21 00:36:55 +00007755static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007756s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7757{
7758 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7759 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7760
7761 return "sllk";
7762}
7763
florian55085f82012-11-21 00:36:55 +00007764static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007765s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7766{
7767 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7768 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7769
7770 return "sllg";
7771}
7772
florian55085f82012-11-21 00:36:55 +00007773static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007774s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7775{
7776 IRTemp p1 = newTemp(Ity_I64);
7777 IRTemp p2 = newTemp(Ity_I64);
7778 IRTemp result = newTemp(Ity_I64);
7779
7780 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7781 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7782 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7783 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7784 mkexpr(op2addr), mkU64(63)))));
7785 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7786 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7787 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7788
7789 return "srda";
7790}
7791
florian55085f82012-11-21 00:36:55 +00007792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007793s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7794{
7795 IRTemp p1 = newTemp(Ity_I64);
7796 IRTemp p2 = newTemp(Ity_I64);
7797 IRTemp result = newTemp(Ity_I64);
7798
7799 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7800 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7801 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7802 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7803 mkexpr(op2addr), mkU64(63)))));
7804 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7805 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7806
7807 return "srdl";
7808}
7809
florian55085f82012-11-21 00:36:55 +00007810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007811s390_irgen_SRA(UChar r1, IRTemp op2addr)
7812{
7813 IRTemp result = newTemp(Ity_I32);
7814 IRTemp op = newTemp(Ity_I32);
7815
7816 assign(op, get_gpr_w1(r1));
7817 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7818 mkexpr(op2addr), mkU64(63)))));
7819 put_gpr_w1(r1, mkexpr(result));
7820 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7821
7822 return "sra";
7823}
7824
florian55085f82012-11-21 00:36:55 +00007825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007826s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7827{
7828 IRTemp result = newTemp(Ity_I32);
7829 IRTemp op = newTemp(Ity_I32);
7830
7831 assign(op, get_gpr_w1(r3));
7832 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7833 mkexpr(op2addr), mkU64(63)))));
7834 put_gpr_w1(r1, mkexpr(result));
7835 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7836
7837 return "srak";
7838}
7839
florian55085f82012-11-21 00:36:55 +00007840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007841s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7842{
7843 IRTemp result = newTemp(Ity_I64);
7844 IRTemp op = newTemp(Ity_I64);
7845
7846 assign(op, get_gpr_dw0(r3));
7847 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7848 mkexpr(op2addr), mkU64(63)))));
7849 put_gpr_dw0(r1, mkexpr(result));
7850 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7851
7852 return "srag";
7853}
7854
florian55085f82012-11-21 00:36:55 +00007855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007856s390_irgen_SRL(UChar r1, IRTemp op2addr)
7857{
7858 IRTemp op = newTemp(Ity_I32);
7859
7860 assign(op, get_gpr_w1(r1));
7861 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7862 mkexpr(op2addr), mkU64(63)))));
7863
7864 return "srl";
7865}
7866
florian55085f82012-11-21 00:36:55 +00007867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007868s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7869{
7870 IRTemp op = newTemp(Ity_I32);
7871
7872 assign(op, get_gpr_w1(r3));
7873 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7874 mkexpr(op2addr), mkU64(63)))));
7875
7876 return "srlk";
7877}
7878
florian55085f82012-11-21 00:36:55 +00007879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007880s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7881{
7882 IRTemp op = newTemp(Ity_I64);
7883
7884 assign(op, get_gpr_dw0(r3));
7885 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7886 mkexpr(op2addr), mkU64(63)))));
7887
7888 return "srlg";
7889}
7890
florian55085f82012-11-21 00:36:55 +00007891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007892s390_irgen_ST(UChar r1, IRTemp op2addr)
7893{
7894 store(mkexpr(op2addr), get_gpr_w1(r1));
7895
7896 return "st";
7897}
7898
florian55085f82012-11-21 00:36:55 +00007899static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007900s390_irgen_STY(UChar r1, IRTemp op2addr)
7901{
7902 store(mkexpr(op2addr), get_gpr_w1(r1));
7903
7904 return "sty";
7905}
7906
florian55085f82012-11-21 00:36:55 +00007907static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007908s390_irgen_STG(UChar r1, IRTemp op2addr)
7909{
7910 store(mkexpr(op2addr), get_gpr_dw0(r1));
7911
7912 return "stg";
7913}
7914
florian55085f82012-11-21 00:36:55 +00007915static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007916s390_irgen_STRL(UChar r1, UInt i2)
7917{
7918 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7919 get_gpr_w1(r1));
7920
7921 return "strl";
7922}
7923
florian55085f82012-11-21 00:36:55 +00007924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007925s390_irgen_STGRL(UChar r1, UInt i2)
7926{
7927 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7928 get_gpr_dw0(r1));
7929
7930 return "stgrl";
7931}
7932
florian55085f82012-11-21 00:36:55 +00007933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007934s390_irgen_STC(UChar r1, IRTemp op2addr)
7935{
7936 store(mkexpr(op2addr), get_gpr_b7(r1));
7937
7938 return "stc";
7939}
7940
florian55085f82012-11-21 00:36:55 +00007941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007942s390_irgen_STCY(UChar r1, IRTemp op2addr)
7943{
7944 store(mkexpr(op2addr), get_gpr_b7(r1));
7945
7946 return "stcy";
7947}
7948
florian55085f82012-11-21 00:36:55 +00007949static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007950s390_irgen_STCH(UChar r1, IRTemp op2addr)
7951{
7952 store(mkexpr(op2addr), get_gpr_b3(r1));
7953
7954 return "stch";
7955}
7956
florian55085f82012-11-21 00:36:55 +00007957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007958s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7959{
7960 UChar mask;
7961 UChar n;
7962
7963 mask = (UChar)r3;
7964 n = 0;
7965 if ((mask & 8) != 0) {
7966 store(mkexpr(op2addr), get_gpr_b4(r1));
7967 n = n + 1;
7968 }
7969 if ((mask & 4) != 0) {
7970 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7971 n = n + 1;
7972 }
7973 if ((mask & 2) != 0) {
7974 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7975 n = n + 1;
7976 }
7977 if ((mask & 1) != 0) {
7978 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7979 }
7980
7981 return "stcm";
7982}
7983
florian55085f82012-11-21 00:36:55 +00007984static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007985s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7986{
7987 UChar mask;
7988 UChar n;
7989
7990 mask = (UChar)r3;
7991 n = 0;
7992 if ((mask & 8) != 0) {
7993 store(mkexpr(op2addr), get_gpr_b4(r1));
7994 n = n + 1;
7995 }
7996 if ((mask & 4) != 0) {
7997 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7998 n = n + 1;
7999 }
8000 if ((mask & 2) != 0) {
8001 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
8002 n = n + 1;
8003 }
8004 if ((mask & 1) != 0) {
8005 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
8006 }
8007
8008 return "stcmy";
8009}
8010
florian55085f82012-11-21 00:36:55 +00008011static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008012s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8013{
8014 UChar mask;
8015 UChar n;
8016
8017 mask = (UChar)r3;
8018 n = 0;
8019 if ((mask & 8) != 0) {
8020 store(mkexpr(op2addr), get_gpr_b0(r1));
8021 n = n + 1;
8022 }
8023 if ((mask & 4) != 0) {
8024 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8025 n = n + 1;
8026 }
8027 if ((mask & 2) != 0) {
8028 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8029 n = n + 1;
8030 }
8031 if ((mask & 1) != 0) {
8032 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8033 }
8034
8035 return "stcmh";
8036}
8037
florian55085f82012-11-21 00:36:55 +00008038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008039s390_irgen_STH(UChar r1, IRTemp op2addr)
8040{
8041 store(mkexpr(op2addr), get_gpr_hw3(r1));
8042
8043 return "sth";
8044}
8045
florian55085f82012-11-21 00:36:55 +00008046static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008047s390_irgen_STHY(UChar r1, IRTemp op2addr)
8048{
8049 store(mkexpr(op2addr), get_gpr_hw3(r1));
8050
8051 return "sthy";
8052}
8053
florian55085f82012-11-21 00:36:55 +00008054static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008055s390_irgen_STHRL(UChar r1, UInt i2)
8056{
8057 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8058 get_gpr_hw3(r1));
8059
8060 return "sthrl";
8061}
8062
florian55085f82012-11-21 00:36:55 +00008063static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008064s390_irgen_STHH(UChar r1, IRTemp op2addr)
8065{
8066 store(mkexpr(op2addr), get_gpr_hw1(r1));
8067
8068 return "sthh";
8069}
8070
florian55085f82012-11-21 00:36:55 +00008071static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008072s390_irgen_STFH(UChar r1, IRTemp op2addr)
8073{
8074 store(mkexpr(op2addr), get_gpr_w0(r1));
8075
8076 return "stfh";
8077}
8078
florian55085f82012-11-21 00:36:55 +00008079static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008080s390_irgen_STOC(UChar r1, IRTemp op2addr)
8081{
8082 /* condition is checked in format handler */
8083 store(mkexpr(op2addr), get_gpr_w1(r1));
8084
8085 return "stoc";
8086}
8087
florian55085f82012-11-21 00:36:55 +00008088static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008089s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8090{
8091 /* condition is checked in format handler */
8092 store(mkexpr(op2addr), get_gpr_dw0(r1));
8093
8094 return "stocg";
8095}
8096
florian55085f82012-11-21 00:36:55 +00008097static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008098s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8099{
8100 store(mkexpr(op2addr), get_gpr_dw0(r1));
8101 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8102
8103 return "stpq";
8104}
8105
florian55085f82012-11-21 00:36:55 +00008106static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008107s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8108{
8109 store(mkexpr(op2addr), get_gpr_b7(r1));
8110 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8111
8112 return "strvh";
8113}
8114
florian55085f82012-11-21 00:36:55 +00008115static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008116s390_irgen_STRV(UChar r1, IRTemp op2addr)
8117{
8118 store(mkexpr(op2addr), get_gpr_b7(r1));
8119 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8120 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8121 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8122
8123 return "strv";
8124}
8125
florian55085f82012-11-21 00:36:55 +00008126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008127s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8128{
8129 store(mkexpr(op2addr), get_gpr_b7(r1));
8130 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8131 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8132 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8133 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8134 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8135 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8136 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8137
8138 return "strvg";
8139}
8140
florian55085f82012-11-21 00:36:55 +00008141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008142s390_irgen_SR(UChar r1, UChar r2)
8143{
8144 IRTemp op1 = newTemp(Ity_I32);
8145 IRTemp op2 = newTemp(Ity_I32);
8146 IRTemp result = newTemp(Ity_I32);
8147
8148 assign(op1, get_gpr_w1(r1));
8149 assign(op2, get_gpr_w1(r2));
8150 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8151 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8152 put_gpr_w1(r1, mkexpr(result));
8153
8154 return "sr";
8155}
8156
florian55085f82012-11-21 00:36:55 +00008157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008158s390_irgen_SGR(UChar r1, UChar r2)
8159{
8160 IRTemp op1 = newTemp(Ity_I64);
8161 IRTemp op2 = newTemp(Ity_I64);
8162 IRTemp result = newTemp(Ity_I64);
8163
8164 assign(op1, get_gpr_dw0(r1));
8165 assign(op2, get_gpr_dw0(r2));
8166 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8167 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8168 put_gpr_dw0(r1, mkexpr(result));
8169
8170 return "sgr";
8171}
8172
florian55085f82012-11-21 00:36:55 +00008173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008174s390_irgen_SGFR(UChar r1, UChar r2)
8175{
8176 IRTemp op1 = newTemp(Ity_I64);
8177 IRTemp op2 = newTemp(Ity_I64);
8178 IRTemp result = newTemp(Ity_I64);
8179
8180 assign(op1, get_gpr_dw0(r1));
8181 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8182 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8183 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8184 put_gpr_dw0(r1, mkexpr(result));
8185
8186 return "sgfr";
8187}
8188
florian55085f82012-11-21 00:36:55 +00008189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008190s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8191{
8192 IRTemp op2 = newTemp(Ity_I32);
8193 IRTemp op3 = newTemp(Ity_I32);
8194 IRTemp result = newTemp(Ity_I32);
8195
8196 assign(op2, get_gpr_w1(r2));
8197 assign(op3, get_gpr_w1(r3));
8198 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8199 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8200 put_gpr_w1(r1, mkexpr(result));
8201
8202 return "srk";
8203}
8204
florian55085f82012-11-21 00:36:55 +00008205static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008206s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8207{
8208 IRTemp op2 = newTemp(Ity_I64);
8209 IRTemp op3 = newTemp(Ity_I64);
8210 IRTemp result = newTemp(Ity_I64);
8211
8212 assign(op2, get_gpr_dw0(r2));
8213 assign(op3, get_gpr_dw0(r3));
8214 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8215 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8216 put_gpr_dw0(r1, mkexpr(result));
8217
8218 return "sgrk";
8219}
8220
florian55085f82012-11-21 00:36:55 +00008221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008222s390_irgen_S(UChar r1, IRTemp op2addr)
8223{
8224 IRTemp op1 = newTemp(Ity_I32);
8225 IRTemp op2 = newTemp(Ity_I32);
8226 IRTemp result = newTemp(Ity_I32);
8227
8228 assign(op1, get_gpr_w1(r1));
8229 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8230 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8231 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8232 put_gpr_w1(r1, mkexpr(result));
8233
8234 return "s";
8235}
8236
florian55085f82012-11-21 00:36:55 +00008237static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008238s390_irgen_SY(UChar r1, IRTemp op2addr)
8239{
8240 IRTemp op1 = newTemp(Ity_I32);
8241 IRTemp op2 = newTemp(Ity_I32);
8242 IRTemp result = newTemp(Ity_I32);
8243
8244 assign(op1, get_gpr_w1(r1));
8245 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8246 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8247 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8248 put_gpr_w1(r1, mkexpr(result));
8249
8250 return "sy";
8251}
8252
florian55085f82012-11-21 00:36:55 +00008253static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008254s390_irgen_SG(UChar r1, IRTemp op2addr)
8255{
8256 IRTemp op1 = newTemp(Ity_I64);
8257 IRTemp op2 = newTemp(Ity_I64);
8258 IRTemp result = newTemp(Ity_I64);
8259
8260 assign(op1, get_gpr_dw0(r1));
8261 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8262 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8263 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8264 put_gpr_dw0(r1, mkexpr(result));
8265
8266 return "sg";
8267}
8268
florian55085f82012-11-21 00:36:55 +00008269static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008270s390_irgen_SGF(UChar r1, IRTemp op2addr)
8271{
8272 IRTemp op1 = newTemp(Ity_I64);
8273 IRTemp op2 = newTemp(Ity_I64);
8274 IRTemp result = newTemp(Ity_I64);
8275
8276 assign(op1, get_gpr_dw0(r1));
8277 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8278 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8279 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8280 put_gpr_dw0(r1, mkexpr(result));
8281
8282 return "sgf";
8283}
8284
florian55085f82012-11-21 00:36:55 +00008285static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008286s390_irgen_SH(UChar r1, IRTemp op2addr)
8287{
8288 IRTemp op1 = newTemp(Ity_I32);
8289 IRTemp op2 = newTemp(Ity_I32);
8290 IRTemp result = newTemp(Ity_I32);
8291
8292 assign(op1, get_gpr_w1(r1));
8293 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8294 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8295 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8296 put_gpr_w1(r1, mkexpr(result));
8297
8298 return "sh";
8299}
8300
florian55085f82012-11-21 00:36:55 +00008301static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008302s390_irgen_SHY(UChar r1, IRTemp op2addr)
8303{
8304 IRTemp op1 = newTemp(Ity_I32);
8305 IRTemp op2 = newTemp(Ity_I32);
8306 IRTemp result = newTemp(Ity_I32);
8307
8308 assign(op1, get_gpr_w1(r1));
8309 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8310 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8311 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8312 put_gpr_w1(r1, mkexpr(result));
8313
8314 return "shy";
8315}
8316
florian55085f82012-11-21 00:36:55 +00008317static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008318s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8319{
8320 IRTemp op2 = newTemp(Ity_I32);
8321 IRTemp op3 = newTemp(Ity_I32);
8322 IRTemp result = newTemp(Ity_I32);
8323
8324 assign(op2, get_gpr_w0(r1));
8325 assign(op3, get_gpr_w0(r2));
8326 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8327 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8328 put_gpr_w0(r1, mkexpr(result));
8329
8330 return "shhhr";
8331}
8332
florian55085f82012-11-21 00:36:55 +00008333static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008334s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8335{
8336 IRTemp op2 = newTemp(Ity_I32);
8337 IRTemp op3 = newTemp(Ity_I32);
8338 IRTemp result = newTemp(Ity_I32);
8339
8340 assign(op2, get_gpr_w0(r1));
8341 assign(op3, get_gpr_w1(r2));
8342 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8343 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8344 put_gpr_w0(r1, mkexpr(result));
8345
8346 return "shhlr";
8347}
8348
florian55085f82012-11-21 00:36:55 +00008349static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008350s390_irgen_SLR(UChar r1, UChar r2)
8351{
8352 IRTemp op1 = newTemp(Ity_I32);
8353 IRTemp op2 = newTemp(Ity_I32);
8354 IRTemp result = newTemp(Ity_I32);
8355
8356 assign(op1, get_gpr_w1(r1));
8357 assign(op2, get_gpr_w1(r2));
8358 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8359 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8360 put_gpr_w1(r1, mkexpr(result));
8361
8362 return "slr";
8363}
8364
florian55085f82012-11-21 00:36:55 +00008365static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008366s390_irgen_SLGR(UChar r1, UChar r2)
8367{
8368 IRTemp op1 = newTemp(Ity_I64);
8369 IRTemp op2 = newTemp(Ity_I64);
8370 IRTemp result = newTemp(Ity_I64);
8371
8372 assign(op1, get_gpr_dw0(r1));
8373 assign(op2, get_gpr_dw0(r2));
8374 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8375 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8376 put_gpr_dw0(r1, mkexpr(result));
8377
8378 return "slgr";
8379}
8380
florian55085f82012-11-21 00:36:55 +00008381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008382s390_irgen_SLGFR(UChar r1, UChar r2)
8383{
8384 IRTemp op1 = newTemp(Ity_I64);
8385 IRTemp op2 = newTemp(Ity_I64);
8386 IRTemp result = newTemp(Ity_I64);
8387
8388 assign(op1, get_gpr_dw0(r1));
8389 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8390 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8391 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8392 put_gpr_dw0(r1, mkexpr(result));
8393
8394 return "slgfr";
8395}
8396
florian55085f82012-11-21 00:36:55 +00008397static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008398s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8399{
8400 IRTemp op2 = newTemp(Ity_I32);
8401 IRTemp op3 = newTemp(Ity_I32);
8402 IRTemp result = newTemp(Ity_I32);
8403
8404 assign(op2, get_gpr_w1(r2));
8405 assign(op3, get_gpr_w1(r3));
8406 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8407 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8408 put_gpr_w1(r1, mkexpr(result));
8409
8410 return "slrk";
8411}
8412
florian55085f82012-11-21 00:36:55 +00008413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008414s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8415{
8416 IRTemp op2 = newTemp(Ity_I64);
8417 IRTemp op3 = newTemp(Ity_I64);
8418 IRTemp result = newTemp(Ity_I64);
8419
8420 assign(op2, get_gpr_dw0(r2));
8421 assign(op3, get_gpr_dw0(r3));
8422 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8423 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8424 put_gpr_dw0(r1, mkexpr(result));
8425
8426 return "slgrk";
8427}
8428
florian55085f82012-11-21 00:36:55 +00008429static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008430s390_irgen_SL(UChar r1, IRTemp op2addr)
8431{
8432 IRTemp op1 = newTemp(Ity_I32);
8433 IRTemp op2 = newTemp(Ity_I32);
8434 IRTemp result = newTemp(Ity_I32);
8435
8436 assign(op1, get_gpr_w1(r1));
8437 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8438 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8439 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8440 put_gpr_w1(r1, mkexpr(result));
8441
8442 return "sl";
8443}
8444
florian55085f82012-11-21 00:36:55 +00008445static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008446s390_irgen_SLY(UChar r1, IRTemp op2addr)
8447{
8448 IRTemp op1 = newTemp(Ity_I32);
8449 IRTemp op2 = newTemp(Ity_I32);
8450 IRTemp result = newTemp(Ity_I32);
8451
8452 assign(op1, get_gpr_w1(r1));
8453 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8454 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8455 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8456 put_gpr_w1(r1, mkexpr(result));
8457
8458 return "sly";
8459}
8460
florian55085f82012-11-21 00:36:55 +00008461static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008462s390_irgen_SLG(UChar r1, IRTemp op2addr)
8463{
8464 IRTemp op1 = newTemp(Ity_I64);
8465 IRTemp op2 = newTemp(Ity_I64);
8466 IRTemp result = newTemp(Ity_I64);
8467
8468 assign(op1, get_gpr_dw0(r1));
8469 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8470 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8471 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8472 put_gpr_dw0(r1, mkexpr(result));
8473
8474 return "slg";
8475}
8476
florian55085f82012-11-21 00:36:55 +00008477static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008478s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8479{
8480 IRTemp op1 = newTemp(Ity_I64);
8481 IRTemp op2 = newTemp(Ity_I64);
8482 IRTemp result = newTemp(Ity_I64);
8483
8484 assign(op1, get_gpr_dw0(r1));
8485 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8486 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8487 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8488 put_gpr_dw0(r1, mkexpr(result));
8489
8490 return "slgf";
8491}
8492
florian55085f82012-11-21 00:36:55 +00008493static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008494s390_irgen_SLFI(UChar r1, UInt i2)
8495{
8496 IRTemp op1 = newTemp(Ity_I32);
8497 UInt op2;
8498 IRTemp result = newTemp(Ity_I32);
8499
8500 assign(op1, get_gpr_w1(r1));
8501 op2 = i2;
8502 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8503 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8504 mkU32(op2)));
8505 put_gpr_w1(r1, mkexpr(result));
8506
8507 return "slfi";
8508}
8509
florian55085f82012-11-21 00:36:55 +00008510static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008511s390_irgen_SLGFI(UChar r1, UInt i2)
8512{
8513 IRTemp op1 = newTemp(Ity_I64);
8514 ULong op2;
8515 IRTemp result = newTemp(Ity_I64);
8516
8517 assign(op1, get_gpr_dw0(r1));
8518 op2 = (ULong)i2;
8519 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8520 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8521 mkU64(op2)));
8522 put_gpr_dw0(r1, mkexpr(result));
8523
8524 return "slgfi";
8525}
8526
florian55085f82012-11-21 00:36:55 +00008527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008528s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8529{
8530 IRTemp op2 = newTemp(Ity_I32);
8531 IRTemp op3 = newTemp(Ity_I32);
8532 IRTemp result = newTemp(Ity_I32);
8533
8534 assign(op2, get_gpr_w0(r1));
8535 assign(op3, get_gpr_w0(r2));
8536 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8537 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8538 put_gpr_w0(r1, mkexpr(result));
8539
8540 return "slhhhr";
8541}
8542
florian55085f82012-11-21 00:36:55 +00008543static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008544s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8545{
8546 IRTemp op2 = newTemp(Ity_I32);
8547 IRTemp op3 = newTemp(Ity_I32);
8548 IRTemp result = newTemp(Ity_I32);
8549
8550 assign(op2, get_gpr_w0(r1));
8551 assign(op3, get_gpr_w1(r2));
8552 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8553 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8554 put_gpr_w0(r1, mkexpr(result));
8555
8556 return "slhhlr";
8557}
8558
florian55085f82012-11-21 00:36:55 +00008559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008560s390_irgen_SLBR(UChar r1, UChar r2)
8561{
8562 IRTemp op1 = newTemp(Ity_I32);
8563 IRTemp op2 = newTemp(Ity_I32);
8564 IRTemp result = newTemp(Ity_I32);
8565 IRTemp borrow_in = newTemp(Ity_I32);
8566
8567 assign(op1, get_gpr_w1(r1));
8568 assign(op2, get_gpr_w1(r2));
8569 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8570 s390_call_calculate_cc(), mkU8(1))));
8571 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8572 mkexpr(borrow_in)));
8573 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8574 put_gpr_w1(r1, mkexpr(result));
8575
8576 return "slbr";
8577}
8578
florian55085f82012-11-21 00:36:55 +00008579static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008580s390_irgen_SLBGR(UChar r1, UChar r2)
8581{
8582 IRTemp op1 = newTemp(Ity_I64);
8583 IRTemp op2 = newTemp(Ity_I64);
8584 IRTemp result = newTemp(Ity_I64);
8585 IRTemp borrow_in = newTemp(Ity_I64);
8586
8587 assign(op1, get_gpr_dw0(r1));
8588 assign(op2, get_gpr_dw0(r2));
8589 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8590 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8591 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8592 mkexpr(borrow_in)));
8593 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8594 put_gpr_dw0(r1, mkexpr(result));
8595
8596 return "slbgr";
8597}
8598
florian55085f82012-11-21 00:36:55 +00008599static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008600s390_irgen_SLB(UChar r1, IRTemp op2addr)
8601{
8602 IRTemp op1 = newTemp(Ity_I32);
8603 IRTemp op2 = newTemp(Ity_I32);
8604 IRTemp result = newTemp(Ity_I32);
8605 IRTemp borrow_in = newTemp(Ity_I32);
8606
8607 assign(op1, get_gpr_w1(r1));
8608 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8609 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8610 s390_call_calculate_cc(), mkU8(1))));
8611 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8612 mkexpr(borrow_in)));
8613 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8614 put_gpr_w1(r1, mkexpr(result));
8615
8616 return "slb";
8617}
8618
florian55085f82012-11-21 00:36:55 +00008619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008620s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8621{
8622 IRTemp op1 = newTemp(Ity_I64);
8623 IRTemp op2 = newTemp(Ity_I64);
8624 IRTemp result = newTemp(Ity_I64);
8625 IRTemp borrow_in = newTemp(Ity_I64);
8626
8627 assign(op1, get_gpr_dw0(r1));
8628 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8629 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8630 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8631 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8632 mkexpr(borrow_in)));
8633 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8634 put_gpr_dw0(r1, mkexpr(result));
8635
8636 return "slbg";
8637}
8638
florian55085f82012-11-21 00:36:55 +00008639static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008640s390_irgen_SVC(UChar i)
8641{
8642 IRTemp sysno = newTemp(Ity_I64);
8643
8644 if (i != 0) {
8645 assign(sysno, mkU64(i));
8646 } else {
8647 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8648 }
8649 system_call(mkexpr(sysno));
8650
8651 return "svc";
8652}
8653
florian55085f82012-11-21 00:36:55 +00008654static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008655s390_irgen_TM(UChar i2, IRTemp op1addr)
8656{
8657 UChar mask;
8658 IRTemp value = newTemp(Ity_I8);
8659
8660 mask = i2;
8661 assign(value, load(Ity_I8, mkexpr(op1addr)));
8662 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8663 mkU8(mask)));
8664
8665 return "tm";
8666}
8667
florian55085f82012-11-21 00:36:55 +00008668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008669s390_irgen_TMY(UChar i2, IRTemp op1addr)
8670{
8671 UChar mask;
8672 IRTemp value = newTemp(Ity_I8);
8673
8674 mask = i2;
8675 assign(value, load(Ity_I8, mkexpr(op1addr)));
8676 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8677 mkU8(mask)));
8678
8679 return "tmy";
8680}
8681
florian55085f82012-11-21 00:36:55 +00008682static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008683s390_irgen_TMHH(UChar r1, UShort i2)
8684{
8685 UShort mask;
8686 IRTemp value = newTemp(Ity_I16);
8687
8688 mask = i2;
8689 assign(value, get_gpr_hw0(r1));
8690 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8691 mkU16(mask)));
8692
8693 return "tmhh";
8694}
8695
florian55085f82012-11-21 00:36:55 +00008696static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008697s390_irgen_TMHL(UChar r1, UShort i2)
8698{
8699 UShort mask;
8700 IRTemp value = newTemp(Ity_I16);
8701
8702 mask = i2;
8703 assign(value, get_gpr_hw1(r1));
8704 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8705 mkU16(mask)));
8706
8707 return "tmhl";
8708}
8709
florian55085f82012-11-21 00:36:55 +00008710static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008711s390_irgen_TMLH(UChar r1, UShort i2)
8712{
8713 UShort mask;
8714 IRTemp value = newTemp(Ity_I16);
8715
8716 mask = i2;
8717 assign(value, get_gpr_hw2(r1));
8718 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8719 mkU16(mask)));
8720
8721 return "tmlh";
8722}
8723
florian55085f82012-11-21 00:36:55 +00008724static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008725s390_irgen_TMLL(UChar r1, UShort i2)
8726{
8727 UShort mask;
8728 IRTemp value = newTemp(Ity_I16);
8729
8730 mask = i2;
8731 assign(value, get_gpr_hw3(r1));
8732 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8733 mkU16(mask)));
8734
8735 return "tmll";
8736}
8737
florian55085f82012-11-21 00:36:55 +00008738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008739s390_irgen_EFPC(UChar r1)
8740{
8741 put_gpr_w1(r1, get_fpc_w0());
8742
8743 return "efpc";
8744}
8745
florian55085f82012-11-21 00:36:55 +00008746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008747s390_irgen_LER(UChar r1, UChar r2)
8748{
8749 put_fpr_w0(r1, get_fpr_w0(r2));
8750
8751 return "ler";
8752}
8753
florian55085f82012-11-21 00:36:55 +00008754static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008755s390_irgen_LDR(UChar r1, UChar r2)
8756{
8757 put_fpr_dw0(r1, get_fpr_dw0(r2));
8758
8759 return "ldr";
8760}
8761
florian55085f82012-11-21 00:36:55 +00008762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008763s390_irgen_LXR(UChar r1, UChar r2)
8764{
8765 put_fpr_dw0(r1, get_fpr_dw0(r2));
8766 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8767
8768 return "lxr";
8769}
8770
florian55085f82012-11-21 00:36:55 +00008771static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008772s390_irgen_LE(UChar r1, IRTemp op2addr)
8773{
8774 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8775
8776 return "le";
8777}
8778
florian55085f82012-11-21 00:36:55 +00008779static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008780s390_irgen_LD(UChar r1, IRTemp op2addr)
8781{
8782 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8783
8784 return "ld";
8785}
8786
florian55085f82012-11-21 00:36:55 +00008787static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008788s390_irgen_LEY(UChar r1, IRTemp op2addr)
8789{
8790 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8791
8792 return "ley";
8793}
8794
florian55085f82012-11-21 00:36:55 +00008795static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008796s390_irgen_LDY(UChar r1, IRTemp op2addr)
8797{
8798 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8799
8800 return "ldy";
8801}
8802
florian55085f82012-11-21 00:36:55 +00008803static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008804s390_irgen_LFPC(IRTemp op2addr)
8805{
8806 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8807
8808 return "lfpc";
8809}
8810
florian55085f82012-11-21 00:36:55 +00008811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008812s390_irgen_LZER(UChar r1)
8813{
8814 put_fpr_w0(r1, mkF32i(0x0));
8815
8816 return "lzer";
8817}
8818
florian55085f82012-11-21 00:36:55 +00008819static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008820s390_irgen_LZDR(UChar r1)
8821{
8822 put_fpr_dw0(r1, mkF64i(0x0));
8823
8824 return "lzdr";
8825}
8826
florian55085f82012-11-21 00:36:55 +00008827static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008828s390_irgen_LZXR(UChar r1)
8829{
8830 put_fpr_dw0(r1, mkF64i(0x0));
8831 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8832
8833 return "lzxr";
8834}
8835
florian55085f82012-11-21 00:36:55 +00008836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008837s390_irgen_SRNM(IRTemp op2addr)
8838{
florianf0fa1be2012-09-18 20:24:38 +00008839 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008840
florianf0fa1be2012-09-18 20:24:38 +00008841 input_mask = 3;
8842 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008843
florianf0fa1be2012-09-18 20:24:38 +00008844 put_fpc_w0(binop(Iop_Or32,
8845 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8846 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8847 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008848 return "srnm";
8849}
8850
florian55085f82012-11-21 00:36:55 +00008851static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008852s390_irgen_SRNMB(IRTemp op2addr)
8853{
8854 UInt input_mask, fpc_mask;
8855
8856 input_mask = 7;
8857 fpc_mask = 7;
8858
8859 put_fpc_w0(binop(Iop_Or32,
8860 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8861 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8862 mkU32(input_mask))));
8863 return "srnmb";
8864}
8865
florian81a4bfe2012-09-20 01:25:28 +00008866static void
florianf0fa1be2012-09-18 20:24:38 +00008867s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8868{
8869 if (b2 == 0) { /* This is the typical case */
8870 if (d2 > 3) {
8871 if (s390_host_has_fpext && d2 == 7) {
8872 /* ok */
8873 } else {
8874 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008875 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008876 }
8877 }
8878 }
8879
8880 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8881}
8882
florian82cdba62013-03-12 01:31:24 +00008883/* Wrapper to validate the parameter as in SRNMB is not required, as all
8884 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8885static const HChar *
8886s390_irgen_SRNMT(IRTemp op2addr)
8887{
8888 UInt input_mask, fpc_mask;
8889
8890 input_mask = 7;
8891 fpc_mask = 0x70;
8892
8893 /* fpc[25:27] <- op2addr[61:63]
8894 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8895 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8896 binop(Iop_Shl32, binop(Iop_And32,
8897 unop(Iop_64to32, mkexpr(op2addr)),
8898 mkU32(input_mask)), mkU8(4))));
8899 return "srnmt";
8900}
8901
florianf0fa1be2012-09-18 20:24:38 +00008902
florian55085f82012-11-21 00:36:55 +00008903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008904s390_irgen_SFPC(UChar r1)
8905{
8906 put_fpc_w0(get_gpr_w1(r1));
8907
8908 return "sfpc";
8909}
8910
florian55085f82012-11-21 00:36:55 +00008911static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008912s390_irgen_STE(UChar r1, IRTemp op2addr)
8913{
8914 store(mkexpr(op2addr), get_fpr_w0(r1));
8915
8916 return "ste";
8917}
8918
florian55085f82012-11-21 00:36:55 +00008919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008920s390_irgen_STD(UChar r1, IRTemp op2addr)
8921{
8922 store(mkexpr(op2addr), get_fpr_dw0(r1));
8923
8924 return "std";
8925}
8926
florian55085f82012-11-21 00:36:55 +00008927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008928s390_irgen_STEY(UChar r1, IRTemp op2addr)
8929{
8930 store(mkexpr(op2addr), get_fpr_w0(r1));
8931
8932 return "stey";
8933}
8934
florian55085f82012-11-21 00:36:55 +00008935static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008936s390_irgen_STDY(UChar r1, IRTemp op2addr)
8937{
8938 store(mkexpr(op2addr), get_fpr_dw0(r1));
8939
8940 return "stdy";
8941}
8942
florian55085f82012-11-21 00:36:55 +00008943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008944s390_irgen_STFPC(IRTemp op2addr)
8945{
8946 store(mkexpr(op2addr), get_fpc_w0());
8947
8948 return "stfpc";
8949}
8950
florian55085f82012-11-21 00:36:55 +00008951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008952s390_irgen_AEBR(UChar r1, UChar r2)
8953{
8954 IRTemp op1 = newTemp(Ity_F32);
8955 IRTemp op2 = newTemp(Ity_F32);
8956 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008957 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008958
8959 assign(op1, get_fpr_w0(r1));
8960 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008961 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008962 mkexpr(op2)));
8963 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8964 put_fpr_w0(r1, mkexpr(result));
8965
8966 return "aebr";
8967}
8968
florian55085f82012-11-21 00:36:55 +00008969static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008970s390_irgen_ADBR(UChar r1, UChar r2)
8971{
8972 IRTemp op1 = newTemp(Ity_F64);
8973 IRTemp op2 = newTemp(Ity_F64);
8974 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008975 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008976
8977 assign(op1, get_fpr_dw0(r1));
8978 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008979 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008980 mkexpr(op2)));
8981 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8982 put_fpr_dw0(r1, mkexpr(result));
8983
8984 return "adbr";
8985}
8986
florian55085f82012-11-21 00:36:55 +00008987static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008988s390_irgen_AEB(UChar r1, IRTemp op2addr)
8989{
8990 IRTemp op1 = newTemp(Ity_F32);
8991 IRTemp op2 = newTemp(Ity_F32);
8992 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008993 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008994
8995 assign(op1, get_fpr_w0(r1));
8996 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008997 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008998 mkexpr(op2)));
8999 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9000 put_fpr_w0(r1, mkexpr(result));
9001
9002 return "aeb";
9003}
9004
florian55085f82012-11-21 00:36:55 +00009005static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009006s390_irgen_ADB(UChar r1, IRTemp op2addr)
9007{
9008 IRTemp op1 = newTemp(Ity_F64);
9009 IRTemp op2 = newTemp(Ity_F64);
9010 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009011 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009012
9013 assign(op1, get_fpr_dw0(r1));
9014 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009015 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009016 mkexpr(op2)));
9017 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9018 put_fpr_dw0(r1, mkexpr(result));
9019
9020 return "adb";
9021}
9022
florian55085f82012-11-21 00:36:55 +00009023static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009024s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9025 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009026{
florian125e20d2012-10-07 15:42:37 +00009027 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009028 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009029 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009030 }
sewardj2019a972011-03-07 16:04:07 +00009031 IRTemp op2 = newTemp(Ity_I32);
9032
9033 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009034 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009035 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009036
9037 return "cefbr";
9038}
9039
florian55085f82012-11-21 00:36:55 +00009040static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009041s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9042 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009043{
9044 IRTemp op2 = newTemp(Ity_I32);
9045
9046 assign(op2, get_gpr_w1(r2));
9047 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9048
9049 return "cdfbr";
9050}
9051
florian55085f82012-11-21 00:36:55 +00009052static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009053s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9054 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009055{
florian125e20d2012-10-07 15:42:37 +00009056 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009057 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009058 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009059 }
sewardj2019a972011-03-07 16:04:07 +00009060 IRTemp op2 = newTemp(Ity_I64);
9061
9062 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009063 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009064 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009065
9066 return "cegbr";
9067}
9068
florian55085f82012-11-21 00:36:55 +00009069static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009070s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9071 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009072{
florian125e20d2012-10-07 15:42:37 +00009073 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009074 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009075 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009076 }
sewardj2019a972011-03-07 16:04:07 +00009077 IRTemp op2 = newTemp(Ity_I64);
9078
9079 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009080 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009081 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009082
9083 return "cdgbr";
9084}
9085
florian55085f82012-11-21 00:36:55 +00009086static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009087s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9088 UChar r1, UChar r2)
9089{
floriane75dafa2012-09-01 17:54:09 +00009090 if (! s390_host_has_fpext) {
9091 emulation_failure(EmFail_S390X_fpext);
9092 } else {
9093 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009094
floriane75dafa2012-09-01 17:54:09 +00009095 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009096 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009097 mkexpr(op2)));
9098 }
florian1c8f7ff2012-09-01 00:12:11 +00009099 return "celfbr";
9100}
9101
florian55085f82012-11-21 00:36:55 +00009102static const HChar *
floriand2129202012-09-01 20:01:39 +00009103s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9104 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00009105{
floriane75dafa2012-09-01 17:54:09 +00009106 if (! s390_host_has_fpext) {
9107 emulation_failure(EmFail_S390X_fpext);
9108 } else {
9109 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009110
floriane75dafa2012-09-01 17:54:09 +00009111 assign(op2, get_gpr_w1(r2));
9112 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9113 }
florian1c8f7ff2012-09-01 00:12:11 +00009114 return "cdlfbr";
9115}
9116
florian55085f82012-11-21 00:36:55 +00009117static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009118s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9119 UChar r1, UChar r2)
9120{
floriane75dafa2012-09-01 17:54:09 +00009121 if (! s390_host_has_fpext) {
9122 emulation_failure(EmFail_S390X_fpext);
9123 } else {
9124 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009125
floriane75dafa2012-09-01 17:54:09 +00009126 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009127 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009128 mkexpr(op2)));
9129 }
florian1c8f7ff2012-09-01 00:12:11 +00009130 return "celgbr";
9131}
9132
florian55085f82012-11-21 00:36:55 +00009133static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009134s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9135 UChar r1, UChar r2)
9136{
floriane75dafa2012-09-01 17:54:09 +00009137 if (! s390_host_has_fpext) {
9138 emulation_failure(EmFail_S390X_fpext);
9139 } else {
9140 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009141
floriane75dafa2012-09-01 17:54:09 +00009142 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009143 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9144 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009145 mkexpr(op2)));
9146 }
florian1c8f7ff2012-09-01 00:12:11 +00009147 return "cdlgbr";
9148}
9149
florian55085f82012-11-21 00:36:55 +00009150static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009151s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9152 UChar r1, UChar r2)
9153{
floriane75dafa2012-09-01 17:54:09 +00009154 if (! s390_host_has_fpext) {
9155 emulation_failure(EmFail_S390X_fpext);
9156 } else {
9157 IRTemp op = newTemp(Ity_F32);
9158 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009159 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009160
floriane75dafa2012-09-01 17:54:09 +00009161 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009162 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009163 mkexpr(op)));
9164 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009165 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009166 }
florian1c8f7ff2012-09-01 00:12:11 +00009167 return "clfebr";
9168}
9169
florian55085f82012-11-21 00:36:55 +00009170static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009171s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9172 UChar r1, UChar r2)
9173{
floriane75dafa2012-09-01 17:54:09 +00009174 if (! s390_host_has_fpext) {
9175 emulation_failure(EmFail_S390X_fpext);
9176 } else {
9177 IRTemp op = newTemp(Ity_F64);
9178 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009179 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009180
floriane75dafa2012-09-01 17:54:09 +00009181 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009182 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009183 mkexpr(op)));
9184 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009185 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009186 }
florian1c8f7ff2012-09-01 00:12:11 +00009187 return "clfdbr";
9188}
9189
florian55085f82012-11-21 00:36:55 +00009190static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009191s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9192 UChar r1, UChar r2)
9193{
floriane75dafa2012-09-01 17:54:09 +00009194 if (! s390_host_has_fpext) {
9195 emulation_failure(EmFail_S390X_fpext);
9196 } else {
9197 IRTemp op = newTemp(Ity_F32);
9198 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009199 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009200
floriane75dafa2012-09-01 17:54:09 +00009201 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009202 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009203 mkexpr(op)));
9204 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009205 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009206 }
florian1c8f7ff2012-09-01 00:12:11 +00009207 return "clgebr";
9208}
9209
florian55085f82012-11-21 00:36:55 +00009210static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009211s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9212 UChar r1, UChar r2)
9213{
floriane75dafa2012-09-01 17:54:09 +00009214 if (! s390_host_has_fpext) {
9215 emulation_failure(EmFail_S390X_fpext);
9216 } else {
9217 IRTemp op = newTemp(Ity_F64);
9218 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009219 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009220
floriane75dafa2012-09-01 17:54:09 +00009221 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009222 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009223 mkexpr(op)));
9224 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009225 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009226 }
florian1c8f7ff2012-09-01 00:12:11 +00009227 return "clgdbr";
9228}
9229
florian55085f82012-11-21 00:36:55 +00009230static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009231s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9232 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009233{
9234 IRTemp op = newTemp(Ity_F32);
9235 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009236 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009237
9238 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009239 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009240 mkexpr(op)));
9241 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009242 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009243
9244 return "cfebr";
9245}
9246
florian55085f82012-11-21 00:36:55 +00009247static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009248s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9249 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009250{
9251 IRTemp op = newTemp(Ity_F64);
9252 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009253 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009254
9255 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009256 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009257 mkexpr(op)));
9258 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009259 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009260
9261 return "cfdbr";
9262}
9263
florian55085f82012-11-21 00:36:55 +00009264static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009265s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9266 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009267{
9268 IRTemp op = newTemp(Ity_F32);
9269 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009270 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009271
9272 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009273 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009274 mkexpr(op)));
9275 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009276 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009277
9278 return "cgebr";
9279}
9280
florian55085f82012-11-21 00:36:55 +00009281static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009282s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9283 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009284{
9285 IRTemp op = newTemp(Ity_F64);
9286 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009287 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009288
9289 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009290 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009291 mkexpr(op)));
9292 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009293 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009294
9295 return "cgdbr";
9296}
9297
florian55085f82012-11-21 00:36:55 +00009298static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009299s390_irgen_DEBR(UChar r1, UChar r2)
9300{
9301 IRTemp op1 = newTemp(Ity_F32);
9302 IRTemp op2 = newTemp(Ity_F32);
9303 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009304 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009305
9306 assign(op1, get_fpr_w0(r1));
9307 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009308 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009309 mkexpr(op2)));
9310 put_fpr_w0(r1, mkexpr(result));
9311
9312 return "debr";
9313}
9314
florian55085f82012-11-21 00:36:55 +00009315static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009316s390_irgen_DDBR(UChar r1, UChar r2)
9317{
9318 IRTemp op1 = newTemp(Ity_F64);
9319 IRTemp op2 = newTemp(Ity_F64);
9320 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009321 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009322
9323 assign(op1, get_fpr_dw0(r1));
9324 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009325 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009326 mkexpr(op2)));
9327 put_fpr_dw0(r1, mkexpr(result));
9328
9329 return "ddbr";
9330}
9331
florian55085f82012-11-21 00:36:55 +00009332static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009333s390_irgen_DEB(UChar r1, IRTemp op2addr)
9334{
9335 IRTemp op1 = newTemp(Ity_F32);
9336 IRTemp op2 = newTemp(Ity_F32);
9337 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009338 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009339
9340 assign(op1, get_fpr_w0(r1));
9341 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009342 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009343 mkexpr(op2)));
9344 put_fpr_w0(r1, mkexpr(result));
9345
9346 return "deb";
9347}
9348
florian55085f82012-11-21 00:36:55 +00009349static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009350s390_irgen_DDB(UChar r1, IRTemp op2addr)
9351{
9352 IRTemp op1 = newTemp(Ity_F64);
9353 IRTemp op2 = newTemp(Ity_F64);
9354 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009355 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009356
9357 assign(op1, get_fpr_dw0(r1));
9358 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009359 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009360 mkexpr(op2)));
9361 put_fpr_dw0(r1, mkexpr(result));
9362
9363 return "ddb";
9364}
9365
florian55085f82012-11-21 00:36:55 +00009366static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009367s390_irgen_LTEBR(UChar r1, UChar r2)
9368{
9369 IRTemp result = newTemp(Ity_F32);
9370
9371 assign(result, get_fpr_w0(r2));
9372 put_fpr_w0(r1, mkexpr(result));
9373 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9374
9375 return "ltebr";
9376}
9377
florian55085f82012-11-21 00:36:55 +00009378static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009379s390_irgen_LTDBR(UChar r1, UChar r2)
9380{
9381 IRTemp result = newTemp(Ity_F64);
9382
9383 assign(result, get_fpr_dw0(r2));
9384 put_fpr_dw0(r1, mkexpr(result));
9385 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9386
9387 return "ltdbr";
9388}
9389
florian55085f82012-11-21 00:36:55 +00009390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009391s390_irgen_LCEBR(UChar r1, UChar r2)
9392{
9393 IRTemp result = newTemp(Ity_F32);
9394
9395 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9396 put_fpr_w0(r1, mkexpr(result));
9397 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9398
9399 return "lcebr";
9400}
9401
florian55085f82012-11-21 00:36:55 +00009402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009403s390_irgen_LCDBR(UChar r1, UChar r2)
9404{
9405 IRTemp result = newTemp(Ity_F64);
9406
9407 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9408 put_fpr_dw0(r1, mkexpr(result));
9409 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9410
9411 return "lcdbr";
9412}
9413
florian55085f82012-11-21 00:36:55 +00009414static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009415s390_irgen_LDEBR(UChar r1, UChar r2)
9416{
9417 IRTemp op = newTemp(Ity_F32);
9418
9419 assign(op, get_fpr_w0(r2));
9420 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9421
9422 return "ldebr";
9423}
9424
florian55085f82012-11-21 00:36:55 +00009425static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009426s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9427{
9428 IRTemp op = newTemp(Ity_F32);
9429
9430 assign(op, load(Ity_F32, mkexpr(op2addr)));
9431 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9432
9433 return "ldeb";
9434}
9435
florian55085f82012-11-21 00:36:55 +00009436static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009437s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9438 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009439{
florian125e20d2012-10-07 15:42:37 +00009440 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009441 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009442 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009443 }
sewardj2019a972011-03-07 16:04:07 +00009444 IRTemp op = newTemp(Ity_F64);
9445
9446 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009447 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009448 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009449
9450 return "ledbr";
9451}
9452
florian55085f82012-11-21 00:36:55 +00009453static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009454s390_irgen_MEEBR(UChar r1, UChar r2)
9455{
9456 IRTemp op1 = newTemp(Ity_F32);
9457 IRTemp op2 = newTemp(Ity_F32);
9458 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009459 IRRoundingMode rounding_mode =
9460 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009461
9462 assign(op1, get_fpr_w0(r1));
9463 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009464 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009465 mkexpr(op2)));
9466 put_fpr_w0(r1, mkexpr(result));
9467
9468 return "meebr";
9469}
9470
florian55085f82012-11-21 00:36:55 +00009471static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009472s390_irgen_MDBR(UChar r1, UChar r2)
9473{
9474 IRTemp op1 = newTemp(Ity_F64);
9475 IRTemp op2 = newTemp(Ity_F64);
9476 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009477 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009478
9479 assign(op1, get_fpr_dw0(r1));
9480 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009481 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009482 mkexpr(op2)));
9483 put_fpr_dw0(r1, mkexpr(result));
9484
9485 return "mdbr";
9486}
9487
florian55085f82012-11-21 00:36:55 +00009488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009489s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9490{
9491 IRTemp op1 = newTemp(Ity_F32);
9492 IRTemp op2 = newTemp(Ity_F32);
9493 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009494 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009495
9496 assign(op1, get_fpr_w0(r1));
9497 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009498 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009499 mkexpr(op2)));
9500 put_fpr_w0(r1, mkexpr(result));
9501
9502 return "meeb";
9503}
9504
florian55085f82012-11-21 00:36:55 +00009505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009506s390_irgen_MDB(UChar r1, IRTemp op2addr)
9507{
9508 IRTemp op1 = newTemp(Ity_F64);
9509 IRTemp op2 = newTemp(Ity_F64);
9510 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009511 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009512
9513 assign(op1, get_fpr_dw0(r1));
9514 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009515 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009516 mkexpr(op2)));
9517 put_fpr_dw0(r1, mkexpr(result));
9518
9519 return "mdb";
9520}
9521
florian55085f82012-11-21 00:36:55 +00009522static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009523s390_irgen_SEBR(UChar r1, UChar r2)
9524{
9525 IRTemp op1 = newTemp(Ity_F32);
9526 IRTemp op2 = newTemp(Ity_F32);
9527 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009528 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009529
9530 assign(op1, get_fpr_w0(r1));
9531 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009532 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009533 mkexpr(op2)));
9534 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9535 put_fpr_w0(r1, mkexpr(result));
9536
9537 return "sebr";
9538}
9539
florian55085f82012-11-21 00:36:55 +00009540static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009541s390_irgen_SDBR(UChar r1, UChar r2)
9542{
9543 IRTemp op1 = newTemp(Ity_F64);
9544 IRTemp op2 = newTemp(Ity_F64);
9545 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009546 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009547
9548 assign(op1, get_fpr_dw0(r1));
9549 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009550 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009551 mkexpr(op2)));
9552 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9553 put_fpr_dw0(r1, mkexpr(result));
9554
9555 return "sdbr";
9556}
9557
florian55085f82012-11-21 00:36:55 +00009558static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009559s390_irgen_SEB(UChar r1, IRTemp op2addr)
9560{
9561 IRTemp op1 = newTemp(Ity_F32);
9562 IRTemp op2 = newTemp(Ity_F32);
9563 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009564 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009565
9566 assign(op1, get_fpr_w0(r1));
9567 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009568 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009569 mkexpr(op2)));
9570 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9571 put_fpr_w0(r1, mkexpr(result));
9572
9573 return "seb";
9574}
9575
florian55085f82012-11-21 00:36:55 +00009576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009577s390_irgen_SDB(UChar r1, IRTemp op2addr)
9578{
9579 IRTemp op1 = newTemp(Ity_F64);
9580 IRTemp op2 = newTemp(Ity_F64);
9581 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009582 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009583
9584 assign(op1, get_fpr_dw0(r1));
9585 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009586 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009587 mkexpr(op2)));
9588 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9589 put_fpr_dw0(r1, mkexpr(result));
9590
9591 return "sdb";
9592}
9593
florian55085f82012-11-21 00:36:55 +00009594static const HChar *
florian12390202012-11-10 22:34:14 +00009595s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9596{
9597 IRTemp op1 = newTemp(Ity_D64);
9598 IRTemp op2 = newTemp(Ity_D64);
9599 IRTemp result = newTemp(Ity_D64);
9600 IRTemp rounding_mode;
9601
9602 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009603
9604 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9605 emulation_warning(EmWarn_S390X_fpext_rounding);
9606 m4 = S390_DFP_ROUND_PER_FPC_0;
9607 }
9608
florian12390202012-11-10 22:34:14 +00009609 rounding_mode = encode_dfp_rounding_mode(m4);
9610 assign(op1, get_dpr_dw0(r2));
9611 assign(op2, get_dpr_dw0(r3));
9612 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9613 mkexpr(op2)));
9614 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9615 put_dpr_dw0(r1, mkexpr(result));
9616
9617 return (m4 == 0) ? "adtr" : "adtra";
9618}
9619
florian55085f82012-11-21 00:36:55 +00009620static const HChar *
floriane38f6412012-12-21 17:32:12 +00009621s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9622{
9623 IRTemp op1 = newTemp(Ity_D128);
9624 IRTemp op2 = newTemp(Ity_D128);
9625 IRTemp result = newTemp(Ity_D128);
9626 IRTemp rounding_mode;
9627
9628 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009629
9630 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9631 emulation_warning(EmWarn_S390X_fpext_rounding);
9632 m4 = S390_DFP_ROUND_PER_FPC_0;
9633 }
9634
floriane38f6412012-12-21 17:32:12 +00009635 rounding_mode = encode_dfp_rounding_mode(m4);
9636 assign(op1, get_dpr_pair(r2));
9637 assign(op2, get_dpr_pair(r3));
9638 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9639 mkexpr(op2)));
9640 put_dpr_pair(r1, mkexpr(result));
9641
9642 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9643
9644 return (m4 == 0) ? "axtr" : "axtra";
9645}
9646
9647static const HChar *
9648s390_irgen_CDTR(UChar r1, UChar r2)
9649{
9650 IRTemp op1 = newTemp(Ity_D64);
9651 IRTemp op2 = newTemp(Ity_D64);
9652 IRTemp cc_vex = newTemp(Ity_I32);
9653 IRTemp cc_s390 = newTemp(Ity_I32);
9654
9655 assign(op1, get_dpr_dw0(r1));
9656 assign(op2, get_dpr_dw0(r2));
9657 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9658
florian2d3d87f2012-12-21 21:05:17 +00009659 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009660 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9661
9662 return "cdtr";
9663}
9664
9665static const HChar *
9666s390_irgen_CXTR(UChar r1, UChar r2)
9667{
9668 IRTemp op1 = newTemp(Ity_D128);
9669 IRTemp op2 = newTemp(Ity_D128);
9670 IRTemp cc_vex = newTemp(Ity_I32);
9671 IRTemp cc_s390 = newTemp(Ity_I32);
9672
9673 assign(op1, get_dpr_pair(r1));
9674 assign(op2, get_dpr_pair(r2));
9675 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9676
florian2d3d87f2012-12-21 21:05:17 +00009677 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009678 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9679
9680 return "cxtr";
9681}
9682
9683static const HChar *
florian5f034622013-01-13 02:29:05 +00009684s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9685 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9686{
9687 vassert(s390_host_has_dfp);
9688
9689 if (! s390_host_has_fpext) {
9690 emulation_failure(EmFail_S390X_fpext);
9691 } else {
9692 IRTemp op2 = newTemp(Ity_I32);
9693
9694 assign(op2, get_gpr_w1(r2));
9695 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9696 }
9697 return "cdftr";
9698}
9699
9700static const HChar *
9701s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9702 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9703{
9704 vassert(s390_host_has_dfp);
9705
9706 if (! s390_host_has_fpext) {
9707 emulation_failure(EmFail_S390X_fpext);
9708 } else {
9709 IRTemp op2 = newTemp(Ity_I32);
9710
9711 assign(op2, get_gpr_w1(r2));
9712 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9713 }
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{
9721 IRTemp op2 = newTemp(Ity_I64);
9722
9723 vassert(s390_host_has_dfp);
9724 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9725 emulation_warning(EmWarn_S390X_fpext_rounding);
9726 m3 = S390_DFP_ROUND_PER_FPC_0;
9727 }
9728
9729 assign(op2, get_gpr_dw0(r2));
9730 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9731 mkexpr(op2)));
9732
9733 return (m3 == 0) ? "cdgtr" : "cdgtra";
9734}
9735
9736static const HChar *
9737s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9738 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9739{
9740 IRTemp op2 = newTemp(Ity_I64);
9741
9742 vassert(s390_host_has_dfp);
9743
florian1bb7f6f2013-02-11 00:03:27 +00009744 /* No emulation warning here about an non-zero m3 on hosts without
9745 floating point extension facility. No rounding is performed */
9746
floriana887acd2013-02-08 23:32:54 +00009747 assign(op2, get_gpr_dw0(r2));
9748 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9749
9750 return "cxgtr";
9751}
9752
9753static const HChar *
florian5f034622013-01-13 02:29:05 +00009754s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9755 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9756{
9757 vassert(s390_host_has_dfp);
9758
9759 if (! s390_host_has_fpext) {
9760 emulation_failure(EmFail_S390X_fpext);
9761 } else {
9762 IRTemp op2 = newTemp(Ity_I32);
9763
9764 assign(op2, get_gpr_w1(r2));
9765 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9766 }
9767 return "cdlftr";
9768}
9769
9770static const HChar *
9771s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9772 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9773{
9774 vassert(s390_host_has_dfp);
9775
9776 if (! s390_host_has_fpext) {
9777 emulation_failure(EmFail_S390X_fpext);
9778 } else {
9779 IRTemp op2 = newTemp(Ity_I32);
9780
9781 assign(op2, get_gpr_w1(r2));
9782 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9783 }
9784 return "cxlftr";
9785}
9786
9787static const HChar *
9788s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9789 UChar r1, UChar r2)
9790{
9791 vassert(s390_host_has_dfp);
9792
9793 if (! s390_host_has_fpext) {
9794 emulation_failure(EmFail_S390X_fpext);
9795 } else {
9796 IRTemp op2 = newTemp(Ity_I64);
9797
9798 assign(op2, get_gpr_dw0(r2));
9799 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9800 mkexpr(encode_dfp_rounding_mode(m3)),
9801 mkexpr(op2)));
9802 }
9803 return "cdlgtr";
9804}
9805
9806static const HChar *
9807s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9808 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9809{
9810 vassert(s390_host_has_dfp);
9811
9812 if (! s390_host_has_fpext) {
9813 emulation_failure(EmFail_S390X_fpext);
9814 } else {
9815 IRTemp op2 = newTemp(Ity_I64);
9816
9817 assign(op2, get_gpr_dw0(r2));
9818 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9819 }
9820 return "cxlgtr";
9821}
9822
9823static const HChar *
9824s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9825 UChar r1, UChar r2)
9826{
9827 vassert(s390_host_has_dfp);
9828
9829 if (! s390_host_has_fpext) {
9830 emulation_failure(EmFail_S390X_fpext);
9831 } else {
9832 IRTemp op = newTemp(Ity_D64);
9833 IRTemp result = newTemp(Ity_I32);
9834 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9835
9836 assign(op, get_dpr_dw0(r2));
9837 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9838 mkexpr(op)));
9839 put_gpr_w1(r1, mkexpr(result));
9840 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9841 }
9842 return "cfdtr";
9843}
9844
9845static const HChar *
9846s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9847 UChar r1, UChar r2)
9848{
9849 vassert(s390_host_has_dfp);
9850
9851 if (! s390_host_has_fpext) {
9852 emulation_failure(EmFail_S390X_fpext);
9853 } else {
9854 IRTemp op = newTemp(Ity_D128);
9855 IRTemp result = newTemp(Ity_I32);
9856 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9857
9858 assign(op, get_dpr_pair(r2));
9859 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9860 mkexpr(op)));
9861 put_gpr_w1(r1, mkexpr(result));
9862 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9863 }
9864 return "cfxtr";
9865}
9866
9867static const HChar *
floriana887acd2013-02-08 23:32:54 +00009868s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9869 UChar r1, UChar r2)
9870{
9871 IRTemp op = newTemp(Ity_D64);
9872 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9873
9874 vassert(s390_host_has_dfp);
9875
9876 /* If fpext is not installed and m3 is in 1:7,
9877 rounding mode performed is unpredictable */
9878 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9879 emulation_warning(EmWarn_S390X_fpext_rounding);
9880 m3 = S390_DFP_ROUND_PER_FPC_0;
9881 }
9882
9883 assign(op, get_dpr_dw0(r2));
9884 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9885 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9886
9887 return "cgdtr";
9888}
9889
9890static const HChar *
9891s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9892 UChar r1, UChar r2)
9893{
9894 IRTemp op = newTemp(Ity_D128);
9895 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9896
9897 vassert(s390_host_has_dfp);
9898
9899 /* If fpext is not installed and m3 is in 1:7,
9900 rounding mode performed is unpredictable */
9901 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9902 emulation_warning(EmWarn_S390X_fpext_rounding);
9903 m3 = S390_DFP_ROUND_PER_FPC_0;
9904 }
9905 assign(op, get_dpr_pair(r2));
9906 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9907 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9908
9909 return "cgxtr";
9910}
9911
9912static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009913s390_irgen_CEDTR(UChar r1, UChar r2)
9914{
9915 IRTemp op1 = newTemp(Ity_D64);
9916 IRTemp op2 = newTemp(Ity_D64);
9917 IRTemp cc_vex = newTemp(Ity_I32);
9918 IRTemp cc_s390 = newTemp(Ity_I32);
9919
9920 vassert(s390_host_has_dfp);
9921 assign(op1, get_dpr_dw0(r1));
9922 assign(op2, get_dpr_dw0(r2));
9923 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9924
9925 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9926 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9927
9928 return "cedtr";
9929}
9930
9931static const HChar *
9932s390_irgen_CEXTR(UChar r1, UChar r2)
9933{
9934 IRTemp op1 = newTemp(Ity_D128);
9935 IRTemp op2 = newTemp(Ity_D128);
9936 IRTemp cc_vex = newTemp(Ity_I32);
9937 IRTemp cc_s390 = newTemp(Ity_I32);
9938
9939 vassert(s390_host_has_dfp);
9940 assign(op1, get_dpr_pair(r1));
9941 assign(op2, get_dpr_pair(r2));
9942 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9943
9944 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9945 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9946
9947 return "cextr";
9948}
9949
9950static const HChar *
florian5f034622013-01-13 02:29:05 +00009951s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9952 UChar r1, UChar r2)
9953{
9954 vassert(s390_host_has_dfp);
9955
9956 if (! s390_host_has_fpext) {
9957 emulation_failure(EmFail_S390X_fpext);
9958 } else {
9959 IRTemp op = newTemp(Ity_D64);
9960 IRTemp result = newTemp(Ity_I32);
9961 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9962
9963 assign(op, get_dpr_dw0(r2));
9964 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9965 mkexpr(op)));
9966 put_gpr_w1(r1, mkexpr(result));
9967 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9968 }
9969 return "clfdtr";
9970}
9971
9972static const HChar *
9973s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9974 UChar r1, UChar r2)
9975{
9976 vassert(s390_host_has_dfp);
9977
9978 if (! s390_host_has_fpext) {
9979 emulation_failure(EmFail_S390X_fpext);
9980 } else {
9981 IRTemp op = newTemp(Ity_D128);
9982 IRTemp result = newTemp(Ity_I32);
9983 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9984
9985 assign(op, get_dpr_pair(r2));
9986 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9987 mkexpr(op)));
9988 put_gpr_w1(r1, mkexpr(result));
9989 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9990 }
9991 return "clfxtr";
9992}
9993
9994static const HChar *
9995s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9996 UChar r1, UChar r2)
9997{
9998 vassert(s390_host_has_dfp);
9999
10000 if (! s390_host_has_fpext) {
10001 emulation_failure(EmFail_S390X_fpext);
10002 } else {
10003 IRTemp op = newTemp(Ity_D64);
10004 IRTemp result = newTemp(Ity_I64);
10005 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10006
10007 assign(op, get_dpr_dw0(r2));
10008 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
10009 mkexpr(op)));
10010 put_gpr_dw0(r1, mkexpr(result));
10011 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10012 }
10013 return "clgdtr";
10014}
10015
10016static const HChar *
10017s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10018 UChar r1, UChar r2)
10019{
10020 vassert(s390_host_has_dfp);
10021
10022 if (! s390_host_has_fpext) {
10023 emulation_failure(EmFail_S390X_fpext);
10024 } else {
10025 IRTemp op = newTemp(Ity_D128);
10026 IRTemp result = newTemp(Ity_I64);
10027 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10028
10029 assign(op, get_dpr_pair(r2));
10030 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10031 mkexpr(op)));
10032 put_gpr_dw0(r1, mkexpr(result));
10033 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10034 rounding_mode);
10035 }
10036 return "clgxtr";
10037}
10038
10039static const HChar *
florian12390202012-11-10 22:34:14 +000010040s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10041{
10042 IRTemp op1 = newTemp(Ity_D64);
10043 IRTemp op2 = newTemp(Ity_D64);
10044 IRTemp result = newTemp(Ity_D64);
10045 IRTemp rounding_mode;
10046
10047 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010048
10049 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10050 emulation_warning(EmWarn_S390X_fpext_rounding);
10051 m4 = S390_DFP_ROUND_PER_FPC_0;
10052 }
10053
florian12390202012-11-10 22:34:14 +000010054 rounding_mode = encode_dfp_rounding_mode(m4);
10055 assign(op1, get_dpr_dw0(r2));
10056 assign(op2, get_dpr_dw0(r3));
10057 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10058 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010059 put_dpr_dw0(r1, mkexpr(result));
10060
10061 return (m4 == 0) ? "ddtr" : "ddtra";
10062}
10063
florian55085f82012-11-21 00:36:55 +000010064static const HChar *
floriane38f6412012-12-21 17:32:12 +000010065s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10066{
10067 IRTemp op1 = newTemp(Ity_D128);
10068 IRTemp op2 = newTemp(Ity_D128);
10069 IRTemp result = newTemp(Ity_D128);
10070 IRTemp rounding_mode;
10071
10072 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010073
10074 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10075 emulation_warning(EmWarn_S390X_fpext_rounding);
10076 m4 = S390_DFP_ROUND_PER_FPC_0;
10077 }
10078
floriane38f6412012-12-21 17:32:12 +000010079 rounding_mode = encode_dfp_rounding_mode(m4);
10080 assign(op1, get_dpr_pair(r2));
10081 assign(op2, get_dpr_pair(r3));
10082 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10083 mkexpr(op2)));
10084 put_dpr_pair(r1, mkexpr(result));
10085
10086 return (m4 == 0) ? "dxtr" : "dxtra";
10087}
10088
10089static const HChar *
florian5c539732013-02-14 14:27:12 +000010090s390_irgen_EEDTR(UChar r1, UChar r2)
10091{
10092 vassert(s390_host_has_dfp);
10093
10094 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10095 return "eedtr";
10096}
10097
10098static const HChar *
10099s390_irgen_EEXTR(UChar r1, UChar r2)
10100{
10101 vassert(s390_host_has_dfp);
10102
10103 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10104 return "eextr";
10105}
10106
10107static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010108s390_irgen_ESDTR(UChar r1, UChar r2)
10109{
10110 vassert(s390_host_has_dfp);
10111 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10112 return "esdtr";
10113}
10114
10115static const HChar *
10116s390_irgen_ESXTR(UChar r1, UChar r2)
10117{
10118 vassert(s390_host_has_dfp);
10119 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10120 return "esxtr";
10121}
10122
10123static const HChar *
florian5c539732013-02-14 14:27:12 +000010124s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10125{
10126 IRTemp op1 = newTemp(Ity_I64);
10127 IRTemp op2 = newTemp(Ity_D64);
10128 IRTemp result = newTemp(Ity_D64);
10129
10130 vassert(s390_host_has_dfp);
10131
10132 assign(op1, get_gpr_dw0(r2));
10133 assign(op2, get_dpr_dw0(r3));
10134 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10135 put_dpr_dw0(r1, mkexpr(result));
10136
10137 return "iedtr";
10138}
10139
10140static const HChar *
10141s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10142{
10143 IRTemp op1 = newTemp(Ity_I64);
10144 IRTemp op2 = newTemp(Ity_D128);
10145 IRTemp result = newTemp(Ity_D128);
10146
10147 vassert(s390_host_has_dfp);
10148
10149 assign(op1, get_gpr_dw0(r2));
10150 assign(op2, get_dpr_pair(r3));
10151 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10152 put_dpr_pair(r1, mkexpr(result));
10153
10154 return "iextr";
10155}
10156
10157static const HChar *
floriane38f6412012-12-21 17:32:12 +000010158s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10159{
10160 IRTemp op = newTemp(Ity_D32);
10161
10162 vassert(s390_host_has_dfp);
10163
10164 assign(op, get_dpr_w0(r2));
10165 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10166
10167 return "ldetr";
10168}
10169
10170static const HChar *
10171s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10172{
10173 IRTemp op = newTemp(Ity_D64);
10174
10175 assign(op, get_dpr_dw0(r2));
10176 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10177
10178 return "lxdtr";
10179}
10180
10181static const HChar *
10182s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10183 UChar r1, UChar r2)
10184{
10185 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010186
10187 /* If fpext is not installed and m3 is in 1:7,
10188 rounding mode performed is unpredictable */
10189 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010190 emulation_warning(EmWarn_S390X_fpext_rounding);
10191 m3 = S390_DFP_ROUND_PER_FPC_0;
10192 }
10193 IRTemp result = newTemp(Ity_D64);
10194
10195 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10196 get_dpr_pair(r2)));
10197 put_dpr_dw0(r1, mkexpr(result));
10198
10199 return "ldxtr";
10200}
10201
10202static const HChar *
10203s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10204 UChar r1, UChar r2)
10205{
10206 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010207
10208 /* If fpext is not installed and m3 is in 1:7,
10209 rounding mode performed is unpredictable */
10210 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010211 emulation_warning(EmWarn_S390X_fpext_rounding);
10212 m3 = S390_DFP_ROUND_PER_FPC_0;
10213 }
10214 IRTemp op = newTemp(Ity_D64);
10215
10216 assign(op, get_dpr_dw0(r2));
10217 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10218 mkexpr(op)));
10219
10220 return "ledtr";
10221}
10222
10223static const HChar *
10224s390_irgen_LTDTR(UChar r1, UChar r2)
10225{
10226 IRTemp result = newTemp(Ity_D64);
10227
10228 assign(result, get_dpr_dw0(r2));
10229 put_dpr_dw0(r1, mkexpr(result));
10230 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10231
10232 return "ltdtr";
10233}
10234
10235static const HChar *
10236s390_irgen_LTXTR(UChar r1, UChar r2)
10237{
10238 IRTemp result = newTemp(Ity_D128);
10239
10240 assign(result, get_dpr_pair(r2));
10241 put_dpr_pair(r1, mkexpr(result));
10242 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10243
10244 return "ltxtr";
10245}
10246
10247static const HChar *
florian12390202012-11-10 22:34:14 +000010248s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10249{
10250 IRTemp op1 = newTemp(Ity_D64);
10251 IRTemp op2 = newTemp(Ity_D64);
10252 IRTemp result = newTemp(Ity_D64);
10253 IRTemp rounding_mode;
10254
10255 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010256
10257 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10258 emulation_warning(EmWarn_S390X_fpext_rounding);
10259 m4 = S390_DFP_ROUND_PER_FPC_0;
10260 }
10261
florian12390202012-11-10 22:34:14 +000010262 rounding_mode = encode_dfp_rounding_mode(m4);
10263 assign(op1, get_dpr_dw0(r2));
10264 assign(op2, get_dpr_dw0(r3));
10265 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10266 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010267 put_dpr_dw0(r1, mkexpr(result));
10268
10269 return (m4 == 0) ? "mdtr" : "mdtra";
10270}
10271
florian55085f82012-11-21 00:36:55 +000010272static const HChar *
floriane38f6412012-12-21 17:32:12 +000010273s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10274{
10275 IRTemp op1 = newTemp(Ity_D128);
10276 IRTemp op2 = newTemp(Ity_D128);
10277 IRTemp result = newTemp(Ity_D128);
10278 IRTemp rounding_mode;
10279
10280 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010281
10282 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10283 emulation_warning(EmWarn_S390X_fpext_rounding);
10284 m4 = S390_DFP_ROUND_PER_FPC_0;
10285 }
10286
floriane38f6412012-12-21 17:32:12 +000010287 rounding_mode = encode_dfp_rounding_mode(m4);
10288 assign(op1, get_dpr_pair(r2));
10289 assign(op2, get_dpr_pair(r3));
10290 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10291 mkexpr(op2)));
10292 put_dpr_pair(r1, mkexpr(result));
10293
10294 return (m4 == 0) ? "mxtr" : "mxtra";
10295}
10296
10297static const HChar *
florian5c539732013-02-14 14:27:12 +000010298s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10299{
10300 IRTemp op1 = newTemp(Ity_D64);
10301 IRTemp op2 = newTemp(Ity_D64);
10302 IRTemp result = newTemp(Ity_D64);
10303 IRTemp rounding_mode;
10304
10305 vassert(s390_host_has_dfp);
10306 /* If fpext is not installed and m4 is in 1:7,
10307 rounding mode performed is unpredictable */
10308 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10309 emulation_warning(EmWarn_S390X_fpext_rounding);
10310 m4 = S390_DFP_ROUND_PER_FPC_0;
10311 }
10312
10313 rounding_mode = encode_dfp_rounding_mode(m4);
10314 assign(op1, get_dpr_dw0(r2));
10315 assign(op2, get_dpr_dw0(r3));
10316 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10317 mkexpr(op2)));
10318 put_dpr_dw0(r1, mkexpr(result));
10319
10320 return "qadtr";
10321}
10322
10323static const HChar *
10324s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10325{
10326 IRTemp op1 = newTemp(Ity_D128);
10327 IRTemp op2 = newTemp(Ity_D128);
10328 IRTemp result = newTemp(Ity_D128);
10329 IRTemp rounding_mode;
10330
10331 vassert(s390_host_has_dfp);
10332 /* If fpext is not installed and m4 is in 1:7,
10333 rounding mode performed is unpredictable */
10334 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10335 emulation_warning(EmWarn_S390X_fpext_rounding);
10336 m4 = S390_DFP_ROUND_PER_FPC_0;
10337 }
10338
10339 rounding_mode = encode_dfp_rounding_mode(m4);
10340 assign(op1, get_dpr_pair(r2));
10341 assign(op2, get_dpr_pair(r3));
10342 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10343 mkexpr(op2)));
10344 put_dpr_pair(r1, mkexpr(result));
10345
10346 return "qaxtr";
10347}
10348
10349static const HChar *
10350s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10351{
10352 IRTemp op1 = newTemp(Ity_I8);
10353 IRTemp op2 = newTemp(Ity_D64);
10354 IRTemp result = newTemp(Ity_D64);
10355 IRTemp rounding_mode;
10356
10357 vassert(s390_host_has_dfp);
10358 /* 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_gpr_b7(r2));
10367 assign(op2, get_dpr_dw0(r3));
10368 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10369 mkexpr(op1), mkexpr(op2)));
10370 put_dpr_dw0(r1, mkexpr(result));
10371
10372 return "rrdtr";
10373}
10374
10375static const HChar *
10376s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10377{
10378 IRTemp op1 = newTemp(Ity_I8);
10379 IRTemp op2 = newTemp(Ity_D128);
10380 IRTemp result = newTemp(Ity_D128);
10381 IRTemp rounding_mode;
10382
10383 vassert(s390_host_has_dfp);
10384 /* If fpext is not installed and m4 is in 1:7,
10385 rounding mode performed is unpredictable */
10386 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10387 emulation_warning(EmWarn_S390X_fpext_rounding);
10388 m4 = S390_DFP_ROUND_PER_FPC_0;
10389 }
10390
10391 rounding_mode = encode_dfp_rounding_mode(m4);
10392 assign(op1, get_gpr_b7(r2));
10393 assign(op2, get_dpr_pair(r3));
10394 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10395 mkexpr(op1), mkexpr(op2)));
10396 put_dpr_pair(r1, mkexpr(result));
10397
10398 return "rrxtr";
10399}
10400
10401static const HChar *
florian12390202012-11-10 22:34:14 +000010402s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10403{
10404 IRTemp op1 = newTemp(Ity_D64);
10405 IRTemp op2 = newTemp(Ity_D64);
10406 IRTemp result = newTemp(Ity_D64);
10407 IRTemp rounding_mode;
10408
10409 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010410
10411 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10412 emulation_warning(EmWarn_S390X_fpext_rounding);
10413 m4 = S390_DFP_ROUND_PER_FPC_0;
10414 }
10415
florian12390202012-11-10 22:34:14 +000010416 rounding_mode = encode_dfp_rounding_mode(m4);
10417 assign(op1, get_dpr_dw0(r2));
10418 assign(op2, get_dpr_dw0(r3));
10419 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10420 mkexpr(op2)));
10421 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10422 put_dpr_dw0(r1, mkexpr(result));
10423
10424 return (m4 == 0) ? "sdtr" : "sdtra";
10425}
10426
floriane38f6412012-12-21 17:32:12 +000010427static const HChar *
10428s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10429{
10430 IRTemp op1 = newTemp(Ity_D128);
10431 IRTemp op2 = newTemp(Ity_D128);
10432 IRTemp result = newTemp(Ity_D128);
10433 IRTemp rounding_mode;
10434
10435 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010436
10437 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10438 emulation_warning(EmWarn_S390X_fpext_rounding);
10439 m4 = S390_DFP_ROUND_PER_FPC_0;
10440 }
10441
floriane38f6412012-12-21 17:32:12 +000010442 rounding_mode = encode_dfp_rounding_mode(m4);
10443 assign(op1, get_dpr_pair(r2));
10444 assign(op2, get_dpr_pair(r3));
10445 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10446 mkexpr(op2)));
10447 put_dpr_pair(r1, mkexpr(result));
10448
10449 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10450
10451 return (m4 == 0) ? "sxtr" : "sxtra";
10452}
sewardj2019a972011-03-07 16:04:07 +000010453
florian55085f82012-11-21 00:36:55 +000010454static const HChar *
florian1b901d42013-01-01 22:19:24 +000010455s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10456{
10457 IRTemp op = newTemp(Ity_D64);
10458
10459 vassert(s390_host_has_dfp);
10460
10461 assign(op, get_dpr_dw0(r3));
10462 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
10463 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10464
10465 return "sldt";
10466}
10467
10468static const HChar *
10469s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10470{
10471 IRTemp op = newTemp(Ity_D128);
10472
10473 vassert(s390_host_has_dfp);
10474
10475 assign(op, get_dpr_pair(r3));
10476 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
10477 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10478
10479 return "slxt";
10480}
10481
10482static const HChar *
10483s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10484{
10485 IRTemp op = newTemp(Ity_D64);
10486
10487 vassert(s390_host_has_dfp);
10488
10489 assign(op, get_dpr_dw0(r3));
10490 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
10491 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10492
10493 return "srdt";
10494}
10495
10496static const HChar *
10497s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10498{
10499 IRTemp op = newTemp(Ity_D128);
10500
10501 vassert(s390_host_has_dfp);
10502
10503 assign(op, get_dpr_pair(r3));
10504 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
10505 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10506
10507 return "srxt";
10508}
10509
10510static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010511s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10512{
10513 IRTemp value = newTemp(Ity_D32);
10514
10515 vassert(s390_host_has_dfp);
10516 assign(value, get_dpr_w0(r1));
10517
10518 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10519
10520 return "tdcet";
10521}
10522
10523static const HChar *
10524s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10525{
10526 IRTemp value = newTemp(Ity_D64);
10527
10528 vassert(s390_host_has_dfp);
10529 assign(value, get_dpr_dw0(r1));
10530
10531 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10532
10533 return "tdcdt";
10534}
10535
10536static const HChar *
10537s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10538{
10539 IRTemp value = newTemp(Ity_D128);
10540
10541 vassert(s390_host_has_dfp);
10542 assign(value, get_dpr_pair(r1));
10543
10544 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10545
10546 return "tdcxt";
10547}
10548
10549static const HChar *
10550s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10551{
10552 IRTemp value = newTemp(Ity_D32);
10553
10554 vassert(s390_host_has_dfp);
10555 assign(value, get_dpr_w0(r1));
10556
10557 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10558
10559 return "tdget";
10560}
10561
10562static const HChar *
10563s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10564{
10565 IRTemp value = newTemp(Ity_D64);
10566
10567 vassert(s390_host_has_dfp);
10568 assign(value, get_dpr_dw0(r1));
10569
10570 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10571
10572 return "tdgdt";
10573}
10574
10575static const HChar *
10576s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10577{
10578 IRTemp value = newTemp(Ity_D128);
10579
10580 vassert(s390_host_has_dfp);
10581 assign(value, get_dpr_pair(r1));
10582
10583 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10584
10585 return "tdgxt";
10586}
10587
10588static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010589s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10590{
florian79e839e2012-05-05 02:20:30 +000010591 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010592
florian79e839e2012-05-05 02:20:30 +000010593 assign(len, mkU64(length));
10594 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010595
10596 return "clc";
10597}
10598
florian55085f82012-11-21 00:36:55 +000010599static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010600s390_irgen_CLCL(UChar r1, UChar r2)
10601{
10602 IRTemp addr1 = newTemp(Ity_I64);
10603 IRTemp addr2 = newTemp(Ity_I64);
10604 IRTemp addr1_load = newTemp(Ity_I64);
10605 IRTemp addr2_load = newTemp(Ity_I64);
10606 IRTemp len1 = newTemp(Ity_I32);
10607 IRTemp len2 = newTemp(Ity_I32);
10608 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10609 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10610 IRTemp single1 = newTemp(Ity_I8);
10611 IRTemp single2 = newTemp(Ity_I8);
10612 IRTemp pad = newTemp(Ity_I8);
10613
10614 assign(addr1, get_gpr_dw0(r1));
10615 assign(r1p1, get_gpr_w1(r1 + 1));
10616 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10617 assign(addr2, get_gpr_dw0(r2));
10618 assign(r2p1, get_gpr_w1(r2 + 1));
10619 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10620 assign(pad, get_gpr_b4(r2 + 1));
10621
10622 /* len1 == 0 and len2 == 0? Exit */
10623 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010624 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10625 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010626
10627 /* Because mkite evaluates both the then-clause and the else-clause
10628 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10629 may be NULL and loading from there would segfault. So we provide a
10630 valid dummy address in that case. Loading from there does no harm and
10631 the value will be discarded at runtime. */
10632 assign(addr1_load,
10633 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10634 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10635 assign(single1,
10636 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10637 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10638
10639 assign(addr2_load,
10640 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10641 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10642 assign(single2,
10643 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10644 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10645
10646 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10647 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010648 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010649
10650 /* Update len1 and addr1, unless len1 == 0. */
10651 put_gpr_dw0(r1,
10652 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10653 mkexpr(addr1),
10654 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10655
10656 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10657 put_gpr_w1(r1 + 1,
10658 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10659 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10660 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10661
10662 /* Update len2 and addr2, unless len2 == 0. */
10663 put_gpr_dw0(r2,
10664 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10665 mkexpr(addr2),
10666 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10667
10668 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10669 put_gpr_w1(r2 + 1,
10670 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10671 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10672 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10673
florian6820ba52012-07-26 02:01:50 +000010674 iterate();
florianb0c9a132011-09-08 15:37:39 +000010675
10676 return "clcl";
10677}
10678
florian55085f82012-11-21 00:36:55 +000010679static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010680s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10681{
10682 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10683
10684 addr1 = newTemp(Ity_I64);
10685 addr3 = newTemp(Ity_I64);
10686 addr1_load = newTemp(Ity_I64);
10687 addr3_load = newTemp(Ity_I64);
10688 len1 = newTemp(Ity_I64);
10689 len3 = newTemp(Ity_I64);
10690 single1 = newTemp(Ity_I8);
10691 single3 = newTemp(Ity_I8);
10692
10693 assign(addr1, get_gpr_dw0(r1));
10694 assign(len1, get_gpr_dw0(r1 + 1));
10695 assign(addr3, get_gpr_dw0(r3));
10696 assign(len3, get_gpr_dw0(r3 + 1));
10697
10698 /* len1 == 0 and len3 == 0? Exit */
10699 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010700 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10701 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010702
10703 /* A mux requires both ways to be possible. This is a way to prevent clcle
10704 from reading from addr1 if it should read from the pad. Since the pad
10705 has no address, just read from the instruction, we discard that anyway */
10706 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010707 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10708 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010709
10710 /* same for addr3 */
10711 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010712 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10713 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010714
10715 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010716 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10717 unop(Iop_64to8, mkexpr(pad2)),
10718 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010719
10720 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010721 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10722 unop(Iop_64to8, mkexpr(pad2)),
10723 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010724
10725 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10726 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010727 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010728
10729 /* If a length in 0 we must not change this length and the address */
10730 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010731 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10732 mkexpr(addr1),
10733 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010734
10735 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010736 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10737 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010738
10739 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010740 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10741 mkexpr(addr3),
10742 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010743
10744 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010745 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10746 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010747
florian6820ba52012-07-26 02:01:50 +000010748 iterate();
sewardj2019a972011-03-07 16:04:07 +000010749
10750 return "clcle";
10751}
floriana64c2432011-07-16 02:11:50 +000010752
florianb0bf6602012-05-05 00:01:16 +000010753
sewardj2019a972011-03-07 16:04:07 +000010754static void
10755s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10756{
florianb0bf6602012-05-05 00:01:16 +000010757 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10758}
sewardj2019a972011-03-07 16:04:07 +000010759
sewardj2019a972011-03-07 16:04:07 +000010760
florianb0bf6602012-05-05 00:01:16 +000010761static void
10762s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10763{
10764 s390_irgen_xonc(Iop_And8, length, start1, start2);
10765}
sewardj2019a972011-03-07 16:04:07 +000010766
sewardj2019a972011-03-07 16:04:07 +000010767
florianb0bf6602012-05-05 00:01:16 +000010768static void
10769s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10770{
10771 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010772}
10773
10774
10775static void
10776s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10777{
10778 IRTemp current1 = newTemp(Ity_I8);
10779 IRTemp current2 = newTemp(Ity_I8);
10780 IRTemp counter = newTemp(Ity_I64);
10781
10782 assign(counter, get_counter_dw0());
10783 put_counter_dw0(mkU64(0));
10784
10785 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10786 mkexpr(counter))));
10787 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10788 mkexpr(counter))));
10789 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10790 False);
10791
10792 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010793 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010794
10795 /* Check for end of field */
10796 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010797 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010798 put_counter_dw0(mkU64(0));
10799}
10800
10801static void
10802s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10803{
10804 IRTemp counter = newTemp(Ity_I64);
10805
10806 assign(counter, get_counter_dw0());
10807
10808 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10809 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10810
10811 /* Check for end of field */
10812 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010813 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010814 put_counter_dw0(mkU64(0));
10815}
10816
florianf87d4fb2012-05-05 02:55:24 +000010817static void
10818s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10819{
10820 IRTemp op = newTemp(Ity_I8);
10821 IRTemp op1 = newTemp(Ity_I8);
10822 IRTemp result = newTemp(Ity_I64);
10823 IRTemp counter = newTemp(Ity_I64);
10824
10825 assign(counter, get_counter_dw0());
10826
10827 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10828
10829 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10830
10831 assign(op1, load(Ity_I8, mkexpr(result)));
10832 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10833
10834 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010835 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010836 put_counter_dw0(mkU64(0));
10837}
sewardj2019a972011-03-07 16:04:07 +000010838
10839
10840static void
10841s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010842 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010843 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010844{
10845 struct SS {
10846 unsigned int op : 8;
10847 unsigned int l : 8;
10848 unsigned int b1 : 4;
10849 unsigned int d1 : 12;
10850 unsigned int b2 : 4;
10851 unsigned int d2 : 12;
10852 };
10853 union {
10854 struct SS dec;
10855 unsigned long bytes;
10856 } ss;
10857 IRTemp cond;
10858 IRDirty *d;
10859 IRTemp torun;
10860
10861 IRTemp start1 = newTemp(Ity_I64);
10862 IRTemp start2 = newTemp(Ity_I64);
10863 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10864 cond = newTemp(Ity_I1);
10865 torun = newTemp(Ity_I64);
10866
10867 assign(torun, load(Ity_I64, mkexpr(addr2)));
10868 /* Start with a check that the saved code is still correct */
10869 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10870 /* If not, save the new value */
10871 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10872 mkIRExprVec_1(mkexpr(torun)));
10873 d->guard = mkexpr(cond);
10874 stmt(IRStmt_Dirty(d));
10875
10876 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010877 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian428dfdd2012-03-27 03:09:49 +000010878 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000010879 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010880 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010881
10882 ss.bytes = last_execute_target;
10883 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10884 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10885 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10886 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10887 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10888 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10889 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010890
sewardj2019a972011-03-07 16:04:07 +000010891 last_execute_target = 0;
10892}
10893
florian55085f82012-11-21 00:36:55 +000010894static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010895s390_irgen_EX(UChar r1, IRTemp addr2)
10896{
10897 switch(last_execute_target & 0xff00000000000000ULL) {
10898 case 0:
10899 {
10900 /* no code information yet */
10901 IRDirty *d;
10902
10903 /* so safe the code... */
10904 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10905 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10906 stmt(IRStmt_Dirty(d));
10907 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010908 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian428dfdd2012-03-27 03:09:49 +000010909 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000010910 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010911 restart_if(IRExpr_Const(IRConst_U1(True)));
10912
sewardj2019a972011-03-07 16:04:07 +000010913 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010914 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010915 dis_res->whatNext = Dis_StopHere;
sewardj05f5e012014-05-04 10:52:11 +000010916 dis_res->jk_StopHere = Ijk_InvalICache;
sewardj2019a972011-03-07 16:04:07 +000010917 break;
10918 }
10919
10920 case 0xd200000000000000ULL:
10921 /* special case MVC */
10922 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010923 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010924
10925 case 0xd500000000000000ULL:
10926 /* special case CLC */
10927 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010928 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010929
10930 case 0xd700000000000000ULL:
10931 /* special case XC */
10932 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010933 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010934
florianb0bf6602012-05-05 00:01:16 +000010935 case 0xd600000000000000ULL:
10936 /* special case OC */
10937 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010938 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010939
10940 case 0xd400000000000000ULL:
10941 /* special case NC */
10942 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010943 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010944
florianf87d4fb2012-05-05 02:55:24 +000010945 case 0xdc00000000000000ULL:
10946 /* special case TR */
10947 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010948 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010949
sewardj2019a972011-03-07 16:04:07 +000010950 default:
10951 {
10952 /* everything else will get a self checking prefix that also checks the
10953 register content */
10954 IRDirty *d;
10955 UChar *bytes;
10956 IRTemp cond;
10957 IRTemp orperand;
10958 IRTemp torun;
10959
10960 cond = newTemp(Ity_I1);
10961 orperand = newTemp(Ity_I64);
10962 torun = newTemp(Ity_I64);
10963
10964 if (r1 == 0)
10965 assign(orperand, mkU64(0));
10966 else
10967 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10968 /* This code is going to be translated */
10969 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10970 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10971
10972 /* Start with a check that saved code is still correct */
10973 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10974 mkU64(last_execute_target)));
10975 /* If not, save the new value */
10976 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10977 mkIRExprVec_1(mkexpr(torun)));
10978 d->guard = mkexpr(cond);
10979 stmt(IRStmt_Dirty(d));
10980
10981 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010982 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
10983 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010984 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010985
10986 /* Now comes the actual translation */
10987 bytes = (UChar *) &last_execute_target;
10988 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10989 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010990 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010991 vex_printf(" which was executed by\n");
10992 /* dont make useless translations in the next execute */
10993 last_execute_target = 0;
10994 }
10995 }
10996 return "ex";
10997}
10998
florian55085f82012-11-21 00:36:55 +000010999static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011000s390_irgen_EXRL(UChar r1, UInt offset)
11001{
11002 IRTemp addr = newTemp(Ity_I64);
11003 /* we might save one round trip because we know the target */
11004 if (!last_execute_target)
11005 last_execute_target = *(ULong *)(HWord)
11006 (guest_IA_curr_instr + offset * 2UL);
11007 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
11008 s390_irgen_EX(r1, addr);
11009 return "exrl";
11010}
11011
florian55085f82012-11-21 00:36:55 +000011012static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011013s390_irgen_IPM(UChar r1)
11014{
11015 // As long as we dont support SPM, lets just assume 0 as program mask
11016 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11017 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11018
11019 return "ipm";
11020}
11021
11022
florian55085f82012-11-21 00:36:55 +000011023static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011024s390_irgen_SRST(UChar r1, UChar r2)
11025{
11026 IRTemp address = newTemp(Ity_I64);
11027 IRTemp next = newTemp(Ity_I64);
11028 IRTemp delim = newTemp(Ity_I8);
11029 IRTemp counter = newTemp(Ity_I64);
11030 IRTemp byte = newTemp(Ity_I8);
11031
11032 assign(address, get_gpr_dw0(r2));
11033 assign(next, get_gpr_dw0(r1));
11034
11035 assign(counter, get_counter_dw0());
11036 put_counter_dw0(mkU64(0));
11037
11038 // start = next? CC=2 and out r1 and r2 unchanged
11039 s390_cc_set(2);
11040 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011041 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000011042
11043 assign(byte, load(Ity_I8, mkexpr(address)));
11044 assign(delim, get_gpr_b7(0));
11045
11046 // byte = delim? CC=1, R1=address
11047 s390_cc_set(1);
11048 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000011049 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011050
11051 // else: all equal, no end yet, loop
11052 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11053 put_gpr_dw0(r1, mkexpr(next));
11054 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011055
florian6820ba52012-07-26 02:01:50 +000011056 iterate();
sewardj2019a972011-03-07 16:04:07 +000011057
11058 return "srst";
11059}
11060
florian55085f82012-11-21 00:36:55 +000011061static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011062s390_irgen_CLST(UChar r1, UChar r2)
11063{
11064 IRTemp address1 = newTemp(Ity_I64);
11065 IRTemp address2 = newTemp(Ity_I64);
11066 IRTemp end = newTemp(Ity_I8);
11067 IRTemp counter = newTemp(Ity_I64);
11068 IRTemp byte1 = newTemp(Ity_I8);
11069 IRTemp byte2 = newTemp(Ity_I8);
11070
11071 assign(address1, get_gpr_dw0(r1));
11072 assign(address2, get_gpr_dw0(r2));
11073 assign(end, get_gpr_b7(0));
11074 assign(counter, get_counter_dw0());
11075 put_counter_dw0(mkU64(0));
11076 assign(byte1, load(Ity_I8, mkexpr(address1)));
11077 assign(byte2, load(Ity_I8, mkexpr(address2)));
11078
11079 // end in both? all equal, reset r1 and r2 to start values
11080 s390_cc_set(0);
11081 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11082 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011083 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11084 binop(Iop_Or8,
11085 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11086 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000011087
11088 put_gpr_dw0(r1, mkexpr(address1));
11089 put_gpr_dw0(r2, mkexpr(address2));
11090
11091 // End found in string1
11092 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011093 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000011094
11095 // End found in string2
11096 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011097 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000011098
11099 // string1 < string2
11100 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011101 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11102 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000011103
11104 // string2 < string1
11105 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011106 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11107 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000011108
11109 // else: all equal, no end yet, loop
11110 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11111 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11112 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011113
florian6820ba52012-07-26 02:01:50 +000011114 iterate();
sewardj2019a972011-03-07 16:04:07 +000011115
11116 return "clst";
11117}
11118
11119static void
11120s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11121{
11122 UChar reg;
11123 IRTemp addr = newTemp(Ity_I64);
11124
11125 assign(addr, mkexpr(op2addr));
11126 reg = r1;
11127 do {
11128 IRTemp old = addr;
11129
11130 reg %= 16;
11131 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11132 addr = newTemp(Ity_I64);
11133 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11134 reg++;
11135 } while (reg != (r3 + 1));
11136}
11137
florian55085f82012-11-21 00:36:55 +000011138static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011139s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11140{
11141 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11142
11143 return "lm";
11144}
11145
florian55085f82012-11-21 00:36:55 +000011146static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011147s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11148{
11149 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11150
11151 return "lmy";
11152}
11153
florian55085f82012-11-21 00:36:55 +000011154static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011155s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11156{
11157 UChar reg;
11158 IRTemp addr = newTemp(Ity_I64);
11159
11160 assign(addr, mkexpr(op2addr));
11161 reg = r1;
11162 do {
11163 IRTemp old = addr;
11164
11165 reg %= 16;
11166 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11167 addr = newTemp(Ity_I64);
11168 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11169 reg++;
11170 } while (reg != (r3 + 1));
11171
11172 return "lmh";
11173}
11174
florian55085f82012-11-21 00:36:55 +000011175static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011176s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11177{
11178 UChar reg;
11179 IRTemp addr = newTemp(Ity_I64);
11180
11181 assign(addr, mkexpr(op2addr));
11182 reg = r1;
11183 do {
11184 IRTemp old = addr;
11185
11186 reg %= 16;
11187 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11188 addr = newTemp(Ity_I64);
11189 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11190 reg++;
11191 } while (reg != (r3 + 1));
11192
11193 return "lmg";
11194}
11195
11196static void
11197s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11198{
11199 UChar reg;
11200 IRTemp addr = newTemp(Ity_I64);
11201
11202 assign(addr, mkexpr(op2addr));
11203 reg = r1;
11204 do {
11205 IRTemp old = addr;
11206
11207 reg %= 16;
11208 store(mkexpr(addr), get_gpr_w1(reg));
11209 addr = newTemp(Ity_I64);
11210 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11211 reg++;
11212 } while( reg != (r3 + 1));
11213}
11214
florian55085f82012-11-21 00:36:55 +000011215static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011216s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11217{
11218 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11219
11220 return "stm";
11221}
11222
florian55085f82012-11-21 00:36:55 +000011223static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011224s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11225{
11226 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11227
11228 return "stmy";
11229}
11230
florian55085f82012-11-21 00:36:55 +000011231static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011232s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11233{
11234 UChar reg;
11235 IRTemp addr = newTemp(Ity_I64);
11236
11237 assign(addr, mkexpr(op2addr));
11238 reg = r1;
11239 do {
11240 IRTemp old = addr;
11241
11242 reg %= 16;
11243 store(mkexpr(addr), get_gpr_w0(reg));
11244 addr = newTemp(Ity_I64);
11245 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11246 reg++;
11247 } while( reg != (r3 + 1));
11248
11249 return "stmh";
11250}
11251
florian55085f82012-11-21 00:36:55 +000011252static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011253s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11254{
11255 UChar reg;
11256 IRTemp addr = newTemp(Ity_I64);
11257
11258 assign(addr, mkexpr(op2addr));
11259 reg = r1;
11260 do {
11261 IRTemp old = addr;
11262
11263 reg %= 16;
11264 store(mkexpr(addr), get_gpr_dw0(reg));
11265 addr = newTemp(Ity_I64);
11266 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11267 reg++;
11268 } while( reg != (r3 + 1));
11269
11270 return "stmg";
11271}
11272
11273static void
florianb0bf6602012-05-05 00:01:16 +000011274s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000011275{
11276 IRTemp old1 = newTemp(Ity_I8);
11277 IRTemp old2 = newTemp(Ity_I8);
11278 IRTemp new1 = newTemp(Ity_I8);
11279 IRTemp counter = newTemp(Ity_I32);
11280 IRTemp addr1 = newTemp(Ity_I64);
11281
11282 assign(counter, get_counter_w0());
11283
11284 assign(addr1, binop(Iop_Add64, mkexpr(start1),
11285 unop(Iop_32Uto64, mkexpr(counter))));
11286
11287 assign(old1, load(Ity_I8, mkexpr(addr1)));
11288 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11289 unop(Iop_32Uto64,mkexpr(counter)))));
11290 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11291
11292 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000011293 if (op == Iop_Xor8) {
11294 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000011295 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11296 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000011297 } else
11298 store(mkexpr(addr1), mkexpr(new1));
11299 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11300 get_counter_w1()));
11301
11302 /* Check for end of field */
11303 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011304 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000011305 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11306 False);
11307 put_counter_dw0(mkU64(0));
11308}
11309
florian55085f82012-11-21 00:36:55 +000011310static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011311s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11312{
florianb0bf6602012-05-05 00:01:16 +000011313 IRTemp len = newTemp(Ity_I32);
11314
11315 assign(len, mkU32(length));
11316 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011317
11318 return "xc";
11319}
11320
sewardjb63967e2011-03-24 08:50:04 +000011321static void
11322s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11323{
11324 IRTemp counter = newTemp(Ity_I32);
11325 IRTemp start = newTemp(Ity_I64);
11326 IRTemp addr = newTemp(Ity_I64);
11327
11328 assign(start,
11329 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11330
11331 if (length < 8) {
11332 UInt i;
11333
11334 for (i = 0; i <= length; ++i) {
11335 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11336 }
11337 } else {
11338 assign(counter, get_counter_w0());
11339
11340 assign(addr, binop(Iop_Add64, mkexpr(start),
11341 unop(Iop_32Uto64, mkexpr(counter))));
11342
11343 store(mkexpr(addr), mkU8(0));
11344
11345 /* Check for end of field */
11346 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011347 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011348
11349 /* Reset counter */
11350 put_counter_dw0(mkU64(0));
11351 }
11352
11353 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11354
sewardj7ee97522011-05-09 21:45:04 +000011355 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011356 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11357}
11358
florian55085f82012-11-21 00:36:55 +000011359static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011360s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11361{
florianb0bf6602012-05-05 00:01:16 +000011362 IRTemp len = newTemp(Ity_I32);
11363
11364 assign(len, mkU32(length));
11365 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011366
11367 return "nc";
11368}
11369
florian55085f82012-11-21 00:36:55 +000011370static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011371s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11372{
florianb0bf6602012-05-05 00:01:16 +000011373 IRTemp len = newTemp(Ity_I32);
11374
11375 assign(len, mkU32(length));
11376 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011377
11378 return "oc";
11379}
11380
11381
florian55085f82012-11-21 00:36:55 +000011382static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011383s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11384{
florian79e839e2012-05-05 02:20:30 +000011385 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011386
florian79e839e2012-05-05 02:20:30 +000011387 assign(len, mkU64(length));
11388 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011389
11390 return "mvc";
11391}
11392
florian55085f82012-11-21 00:36:55 +000011393static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011394s390_irgen_MVCL(UChar r1, UChar r2)
11395{
11396 IRTemp addr1 = newTemp(Ity_I64);
11397 IRTemp addr2 = newTemp(Ity_I64);
11398 IRTemp addr2_load = newTemp(Ity_I64);
11399 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11400 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11401 IRTemp len1 = newTemp(Ity_I32);
11402 IRTemp len2 = newTemp(Ity_I32);
11403 IRTemp pad = newTemp(Ity_I8);
11404 IRTemp single = newTemp(Ity_I8);
11405
11406 assign(addr1, get_gpr_dw0(r1));
11407 assign(r1p1, get_gpr_w1(r1 + 1));
11408 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11409 assign(addr2, get_gpr_dw0(r2));
11410 assign(r2p1, get_gpr_w1(r2 + 1));
11411 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11412 assign(pad, get_gpr_b4(r2 + 1));
11413
11414 /* len1 == 0 ? */
11415 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011416 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011417
11418 /* Check for destructive overlap:
11419 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11420 s390_cc_set(3);
11421 IRTemp cond1 = newTemp(Ity_I32);
11422 assign(cond1, unop(Iop_1Uto32,
11423 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11424 IRTemp cond2 = newTemp(Ity_I32);
11425 assign(cond2, unop(Iop_1Uto32,
11426 binop(Iop_CmpLT64U, mkexpr(addr1),
11427 binop(Iop_Add64, mkexpr(addr2),
11428 unop(Iop_32Uto64, mkexpr(len1))))));
11429 IRTemp cond3 = newTemp(Ity_I32);
11430 assign(cond3, unop(Iop_1Uto32,
11431 binop(Iop_CmpLT64U,
11432 mkexpr(addr1),
11433 binop(Iop_Add64, mkexpr(addr2),
11434 unop(Iop_32Uto64, mkexpr(len2))))));
11435
florian6820ba52012-07-26 02:01:50 +000011436 next_insn_if(binop(Iop_CmpEQ32,
11437 binop(Iop_And32,
11438 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11439 mkexpr(cond3)),
11440 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011441
11442 /* See s390_irgen_CLCL for explanation why we cannot load directly
11443 and need two steps. */
11444 assign(addr2_load,
11445 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11446 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11447 assign(single,
11448 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11449 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11450
11451 store(mkexpr(addr1), mkexpr(single));
11452
11453 /* Update addr1 and len1 */
11454 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11455 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11456
11457 /* Update addr2 and len2 */
11458 put_gpr_dw0(r2,
11459 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11460 mkexpr(addr2),
11461 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11462
11463 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11464 put_gpr_w1(r2 + 1,
11465 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11466 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11467 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11468
11469 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011470 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011471
11472 return "mvcl";
11473}
11474
11475
florian55085f82012-11-21 00:36:55 +000011476static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011477s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11478{
11479 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11480
11481 addr1 = newTemp(Ity_I64);
11482 addr3 = newTemp(Ity_I64);
11483 addr3_load = newTemp(Ity_I64);
11484 len1 = newTemp(Ity_I64);
11485 len3 = newTemp(Ity_I64);
11486 single = newTemp(Ity_I8);
11487
11488 assign(addr1, get_gpr_dw0(r1));
11489 assign(len1, get_gpr_dw0(r1 + 1));
11490 assign(addr3, get_gpr_dw0(r3));
11491 assign(len3, get_gpr_dw0(r3 + 1));
11492
11493 // len1 == 0 ?
11494 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011495 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011496
11497 /* This is a hack to prevent mvcle from reading from addr3 if it
11498 should read from the pad. Since the pad has no address, just
11499 read from the instruction, we discard that anyway */
11500 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011501 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11502 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011503
11504 assign(single,
florian6ad49522011-09-09 02:38:55 +000011505 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11506 unop(Iop_64to8, mkexpr(pad2)),
11507 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011508 store(mkexpr(addr1), mkexpr(single));
11509
11510 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11511
11512 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11513
11514 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011515 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11516 mkexpr(addr3),
11517 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011518
11519 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011520 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11521 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011522
sewardj2019a972011-03-07 16:04:07 +000011523 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011524 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011525
11526 return "mvcle";
11527}
11528
florian55085f82012-11-21 00:36:55 +000011529static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011530s390_irgen_MVST(UChar r1, UChar r2)
11531{
11532 IRTemp addr1 = newTemp(Ity_I64);
11533 IRTemp addr2 = newTemp(Ity_I64);
11534 IRTemp end = newTemp(Ity_I8);
11535 IRTemp byte = newTemp(Ity_I8);
11536 IRTemp counter = newTemp(Ity_I64);
11537
11538 assign(addr1, get_gpr_dw0(r1));
11539 assign(addr2, get_gpr_dw0(r2));
11540 assign(counter, get_counter_dw0());
11541 assign(end, get_gpr_b7(0));
11542 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11543 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11544
11545 // We use unlimited as cpu-determined number
11546 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011547 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011548
11549 // and always set cc=1 at the end + update r1
11550 s390_cc_set(1);
11551 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11552 put_counter_dw0(mkU64(0));
11553
11554 return "mvst";
11555}
11556
11557static void
11558s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11559{
11560 IRTemp op1 = newTemp(Ity_I64);
11561 IRTemp result = newTemp(Ity_I64);
11562
11563 assign(op1, binop(Iop_32HLto64,
11564 get_gpr_w1(r1), // high 32 bits
11565 get_gpr_w1(r1 + 1))); // low 32 bits
11566 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11567 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11568 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11569}
11570
11571static void
11572s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11573{
11574 IRTemp op1 = newTemp(Ity_I128);
11575 IRTemp result = newTemp(Ity_I128);
11576
11577 assign(op1, binop(Iop_64HLto128,
11578 get_gpr_dw0(r1), // high 64 bits
11579 get_gpr_dw0(r1 + 1))); // low 64 bits
11580 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11581 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11582 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11583}
11584
11585static void
11586s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11587{
11588 IRTemp op1 = newTemp(Ity_I64);
11589 IRTemp result = newTemp(Ity_I128);
11590
11591 assign(op1, get_gpr_dw0(r1 + 1));
11592 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11593 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11594 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11595}
11596
florian55085f82012-11-21 00:36:55 +000011597static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011598s390_irgen_DR(UChar r1, UChar r2)
11599{
11600 IRTemp op2 = newTemp(Ity_I32);
11601
11602 assign(op2, get_gpr_w1(r2));
11603
11604 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11605
11606 return "dr";
11607}
11608
florian55085f82012-11-21 00:36:55 +000011609static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011610s390_irgen_D(UChar r1, IRTemp op2addr)
11611{
11612 IRTemp op2 = newTemp(Ity_I32);
11613
11614 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11615
11616 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11617
11618 return "d";
11619}
11620
florian55085f82012-11-21 00:36:55 +000011621static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011622s390_irgen_DLR(UChar r1, UChar r2)
11623{
11624 IRTemp op2 = newTemp(Ity_I32);
11625
11626 assign(op2, get_gpr_w1(r2));
11627
11628 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11629
florian7cd1cde2012-08-16 23:57:43 +000011630 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011631}
11632
florian55085f82012-11-21 00:36:55 +000011633static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011634s390_irgen_DL(UChar r1, IRTemp op2addr)
11635{
11636 IRTemp op2 = newTemp(Ity_I32);
11637
11638 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11639
11640 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11641
11642 return "dl";
11643}
11644
florian55085f82012-11-21 00:36:55 +000011645static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011646s390_irgen_DLG(UChar r1, IRTemp op2addr)
11647{
11648 IRTemp op2 = newTemp(Ity_I64);
11649
11650 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11651
11652 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11653
11654 return "dlg";
11655}
11656
florian55085f82012-11-21 00:36:55 +000011657static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011658s390_irgen_DLGR(UChar r1, UChar r2)
11659{
11660 IRTemp op2 = newTemp(Ity_I64);
11661
11662 assign(op2, get_gpr_dw0(r2));
11663
11664 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11665
11666 return "dlgr";
11667}
11668
florian55085f82012-11-21 00:36:55 +000011669static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011670s390_irgen_DSGR(UChar r1, UChar r2)
11671{
11672 IRTemp op2 = newTemp(Ity_I64);
11673
11674 assign(op2, get_gpr_dw0(r2));
11675
11676 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11677
11678 return "dsgr";
11679}
11680
florian55085f82012-11-21 00:36:55 +000011681static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011682s390_irgen_DSG(UChar r1, IRTemp op2addr)
11683{
11684 IRTemp op2 = newTemp(Ity_I64);
11685
11686 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11687
11688 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11689
11690 return "dsg";
11691}
11692
florian55085f82012-11-21 00:36:55 +000011693static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011694s390_irgen_DSGFR(UChar r1, UChar r2)
11695{
11696 IRTemp op2 = newTemp(Ity_I64);
11697
11698 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11699
11700 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11701
11702 return "dsgfr";
11703}
11704
florian55085f82012-11-21 00:36:55 +000011705static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011706s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11707{
11708 IRTemp op2 = newTemp(Ity_I64);
11709
11710 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11711
11712 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11713
11714 return "dsgf";
11715}
11716
11717static void
11718s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11719{
11720 UChar reg;
11721 IRTemp addr = newTemp(Ity_I64);
11722
11723 assign(addr, mkexpr(op2addr));
11724 reg = r1;
11725 do {
11726 IRTemp old = addr;
11727
11728 reg %= 16;
11729 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11730 addr = newTemp(Ity_I64);
11731 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11732 reg++;
11733 } while (reg != (r3 + 1));
11734}
11735
florian55085f82012-11-21 00:36:55 +000011736static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011737s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11738{
11739 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11740
11741 return "lam";
11742}
11743
florian55085f82012-11-21 00:36:55 +000011744static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011745s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11746{
11747 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11748
11749 return "lamy";
11750}
11751
11752static void
11753s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11754{
11755 UChar reg;
11756 IRTemp addr = newTemp(Ity_I64);
11757
11758 assign(addr, mkexpr(op2addr));
11759 reg = r1;
11760 do {
11761 IRTemp old = addr;
11762
11763 reg %= 16;
11764 store(mkexpr(addr), get_ar_w0(reg));
11765 addr = newTemp(Ity_I64);
11766 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11767 reg++;
11768 } while (reg != (r3 + 1));
11769}
11770
florian55085f82012-11-21 00:36:55 +000011771static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011772s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11773{
11774 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11775
11776 return "stam";
11777}
11778
florian55085f82012-11-21 00:36:55 +000011779static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011780s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11781{
11782 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11783
11784 return "stamy";
11785}
11786
11787
11788/* Implementation for 32-bit compare-and-swap */
11789static void
11790s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11791{
11792 IRCAS *cas;
11793 IRTemp op1 = newTemp(Ity_I32);
11794 IRTemp old_mem = newTemp(Ity_I32);
11795 IRTemp op3 = newTemp(Ity_I32);
11796 IRTemp result = newTemp(Ity_I32);
11797 IRTemp nequal = newTemp(Ity_I1);
11798
11799 assign(op1, get_gpr_w1(r1));
11800 assign(op3, get_gpr_w1(r3));
11801
11802 /* The first and second operands are compared. If they are equal,
11803 the third operand is stored at the second- operand location. */
11804 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11805 Iend_BE, mkexpr(op2addr),
11806 NULL, mkexpr(op1), /* expected value */
11807 NULL, mkexpr(op3) /* new value */);
11808 stmt(IRStmt_CAS(cas));
11809
11810 /* Set CC. Operands compared equal -> 0, else 1. */
11811 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11812 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11813
11814 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11815 Otherwise, store the old_value from memory in r1 and yield. */
11816 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11817 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011818 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011819}
11820
florian55085f82012-11-21 00:36:55 +000011821static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011822s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11823{
11824 s390_irgen_cas_32(r1, r3, op2addr);
11825
11826 return "cs";
11827}
11828
florian55085f82012-11-21 00:36:55 +000011829static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011830s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11831{
11832 s390_irgen_cas_32(r1, r3, op2addr);
11833
11834 return "csy";
11835}
11836
florian55085f82012-11-21 00:36:55 +000011837static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011838s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11839{
11840 IRCAS *cas;
11841 IRTemp op1 = newTemp(Ity_I64);
11842 IRTemp old_mem = newTemp(Ity_I64);
11843 IRTemp op3 = newTemp(Ity_I64);
11844 IRTemp result = newTemp(Ity_I64);
11845 IRTemp nequal = newTemp(Ity_I1);
11846
11847 assign(op1, get_gpr_dw0(r1));
11848 assign(op3, get_gpr_dw0(r3));
11849
11850 /* The first and second operands are compared. If they are equal,
11851 the third operand is stored at the second- operand location. */
11852 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11853 Iend_BE, mkexpr(op2addr),
11854 NULL, mkexpr(op1), /* expected value */
11855 NULL, mkexpr(op3) /* new value */);
11856 stmt(IRStmt_CAS(cas));
11857
11858 /* Set CC. Operands compared equal -> 0, else 1. */
11859 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11860 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11861
11862 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11863 Otherwise, store the old_value from memory in r1 and yield. */
11864 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11865 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011866 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011867
11868 return "csg";
11869}
11870
florian448cbba2012-06-06 02:26:01 +000011871/* Implementation for 32-bit compare-double-and-swap */
11872static void
11873s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11874{
11875 IRCAS *cas;
11876 IRTemp op1_high = newTemp(Ity_I32);
11877 IRTemp op1_low = newTemp(Ity_I32);
11878 IRTemp old_mem_high = newTemp(Ity_I32);
11879 IRTemp old_mem_low = newTemp(Ity_I32);
11880 IRTemp op3_high = newTemp(Ity_I32);
11881 IRTemp op3_low = newTemp(Ity_I32);
11882 IRTemp result = newTemp(Ity_I32);
11883 IRTemp nequal = newTemp(Ity_I1);
11884
11885 assign(op1_high, get_gpr_w1(r1));
11886 assign(op1_low, get_gpr_w1(r1+1));
11887 assign(op3_high, get_gpr_w1(r3));
11888 assign(op3_low, get_gpr_w1(r3+1));
11889
11890 /* The first and second operands are compared. If they are equal,
11891 the third operand is stored at the second-operand location. */
11892 cas = mkIRCAS(old_mem_high, old_mem_low,
11893 Iend_BE, mkexpr(op2addr),
11894 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11895 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11896 stmt(IRStmt_CAS(cas));
11897
11898 /* Set CC. Operands compared equal -> 0, else 1. */
11899 assign(result, unop(Iop_1Uto32,
11900 binop(Iop_CmpNE32,
11901 binop(Iop_Or32,
11902 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11903 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11904 mkU32(0))));
11905
11906 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11907
11908 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11909 Otherwise, store the old_value from memory in r1 and yield. */
11910 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11911 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11912 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011913 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011914}
11915
florian55085f82012-11-21 00:36:55 +000011916static const HChar *
florian448cbba2012-06-06 02:26:01 +000011917s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11918{
11919 s390_irgen_cdas_32(r1, r3, op2addr);
11920
11921 return "cds";
11922}
11923
florian55085f82012-11-21 00:36:55 +000011924static const HChar *
florian448cbba2012-06-06 02:26:01 +000011925s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11926{
11927 s390_irgen_cdas_32(r1, r3, op2addr);
11928
11929 return "cdsy";
11930}
11931
florian55085f82012-11-21 00:36:55 +000011932static const HChar *
florian448cbba2012-06-06 02:26:01 +000011933s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11934{
11935 IRCAS *cas;
11936 IRTemp op1_high = newTemp(Ity_I64);
11937 IRTemp op1_low = newTemp(Ity_I64);
11938 IRTemp old_mem_high = newTemp(Ity_I64);
11939 IRTemp old_mem_low = newTemp(Ity_I64);
11940 IRTemp op3_high = newTemp(Ity_I64);
11941 IRTemp op3_low = newTemp(Ity_I64);
11942 IRTemp result = newTemp(Ity_I64);
11943 IRTemp nequal = newTemp(Ity_I1);
11944
11945 assign(op1_high, get_gpr_dw0(r1));
11946 assign(op1_low, get_gpr_dw0(r1+1));
11947 assign(op3_high, get_gpr_dw0(r3));
11948 assign(op3_low, get_gpr_dw0(r3+1));
11949
11950 /* The first and second operands are compared. If they are equal,
11951 the third operand is stored at the second-operand location. */
11952 cas = mkIRCAS(old_mem_high, old_mem_low,
11953 Iend_BE, mkexpr(op2addr),
11954 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11955 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11956 stmt(IRStmt_CAS(cas));
11957
11958 /* Set CC. Operands compared equal -> 0, else 1. */
11959 assign(result, unop(Iop_1Uto64,
11960 binop(Iop_CmpNE64,
11961 binop(Iop_Or64,
11962 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11963 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11964 mkU64(0))));
11965
11966 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11967
11968 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11969 Otherwise, store the old_value from memory in r1 and yield. */
11970 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11971 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11972 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011973 yield_if(mkexpr(nequal));
11974
florian448cbba2012-06-06 02:26:01 +000011975 return "cdsg";
11976}
11977
sewardj2019a972011-03-07 16:04:07 +000011978
11979/* Binary floating point */
11980
florian55085f82012-11-21 00:36:55 +000011981static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011982s390_irgen_AXBR(UChar r1, UChar r2)
11983{
11984 IRTemp op1 = newTemp(Ity_F128);
11985 IRTemp op2 = newTemp(Ity_F128);
11986 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011987 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011988
11989 assign(op1, get_fpr_pair(r1));
11990 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011991 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011992 mkexpr(op2)));
11993 put_fpr_pair(r1, mkexpr(result));
11994
11995 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11996
11997 return "axbr";
11998}
11999
florian55085f82012-11-21 00:36:55 +000012000static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012001s390_irgen_CEBR(UChar r1, UChar r2)
12002{
12003 IRTemp op1 = newTemp(Ity_F32);
12004 IRTemp op2 = newTemp(Ity_F32);
12005 IRTemp cc_vex = newTemp(Ity_I32);
12006 IRTemp cc_s390 = newTemp(Ity_I32);
12007
12008 assign(op1, get_fpr_w0(r1));
12009 assign(op2, get_fpr_w0(r2));
12010 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12011
florian2d3d87f2012-12-21 21:05:17 +000012012 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012013 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12014
12015 return "cebr";
12016}
12017
florian55085f82012-11-21 00:36:55 +000012018static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012019s390_irgen_CDBR(UChar r1, UChar r2)
12020{
12021 IRTemp op1 = newTemp(Ity_F64);
12022 IRTemp op2 = newTemp(Ity_F64);
12023 IRTemp cc_vex = newTemp(Ity_I32);
12024 IRTemp cc_s390 = newTemp(Ity_I32);
12025
12026 assign(op1, get_fpr_dw0(r1));
12027 assign(op2, get_fpr_dw0(r2));
12028 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12029
florian2d3d87f2012-12-21 21:05:17 +000012030 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012031 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12032
12033 return "cdbr";
12034}
12035
florian55085f82012-11-21 00:36:55 +000012036static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012037s390_irgen_CXBR(UChar r1, UChar r2)
12038{
12039 IRTemp op1 = newTemp(Ity_F128);
12040 IRTemp op2 = newTemp(Ity_F128);
12041 IRTemp cc_vex = newTemp(Ity_I32);
12042 IRTemp cc_s390 = newTemp(Ity_I32);
12043
12044 assign(op1, get_fpr_pair(r1));
12045 assign(op2, get_fpr_pair(r2));
12046 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12047
florian2d3d87f2012-12-21 21:05:17 +000012048 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012049 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12050
12051 return "cxbr";
12052}
12053
florian55085f82012-11-21 00:36:55 +000012054static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012055s390_irgen_CEB(UChar r1, IRTemp op2addr)
12056{
12057 IRTemp op1 = newTemp(Ity_F32);
12058 IRTemp op2 = newTemp(Ity_F32);
12059 IRTemp cc_vex = newTemp(Ity_I32);
12060 IRTemp cc_s390 = newTemp(Ity_I32);
12061
12062 assign(op1, get_fpr_w0(r1));
12063 assign(op2, load(Ity_F32, mkexpr(op2addr)));
12064 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12065
florian2d3d87f2012-12-21 21:05:17 +000012066 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012067 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12068
12069 return "ceb";
12070}
12071
florian55085f82012-11-21 00:36:55 +000012072static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012073s390_irgen_CDB(UChar r1, IRTemp op2addr)
12074{
12075 IRTemp op1 = newTemp(Ity_F64);
12076 IRTemp op2 = newTemp(Ity_F64);
12077 IRTemp cc_vex = newTemp(Ity_I32);
12078 IRTemp cc_s390 = newTemp(Ity_I32);
12079
12080 assign(op1, get_fpr_dw0(r1));
12081 assign(op2, load(Ity_F64, mkexpr(op2addr)));
12082 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12083
florian2d3d87f2012-12-21 21:05:17 +000012084 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012085 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12086
12087 return "cdb";
12088}
12089
florian55085f82012-11-21 00:36:55 +000012090static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012091s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12092 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012093{
12094 IRTemp op2 = newTemp(Ity_I32);
12095
12096 assign(op2, get_gpr_w1(r2));
12097 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12098
12099 return "cxfbr";
12100}
12101
florian55085f82012-11-21 00:36:55 +000012102static const HChar *
floriand2129202012-09-01 20:01:39 +000012103s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12104 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012105{
floriane75dafa2012-09-01 17:54:09 +000012106 if (! s390_host_has_fpext) {
12107 emulation_failure(EmFail_S390X_fpext);
12108 } else {
12109 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000012110
floriane75dafa2012-09-01 17:54:09 +000012111 assign(op2, get_gpr_w1(r2));
12112 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12113 }
florian1c8f7ff2012-09-01 00:12:11 +000012114 return "cxlfbr";
12115}
12116
12117
florian55085f82012-11-21 00:36:55 +000012118static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012119s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12120 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012121{
12122 IRTemp op2 = newTemp(Ity_I64);
12123
12124 assign(op2, get_gpr_dw0(r2));
12125 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12126
12127 return "cxgbr";
12128}
12129
florian55085f82012-11-21 00:36:55 +000012130static const HChar *
floriand2129202012-09-01 20:01:39 +000012131s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12132 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012133{
floriane75dafa2012-09-01 17:54:09 +000012134 if (! s390_host_has_fpext) {
12135 emulation_failure(EmFail_S390X_fpext);
12136 } else {
12137 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000012138
floriane75dafa2012-09-01 17:54:09 +000012139 assign(op2, get_gpr_dw0(r2));
12140 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12141 }
florian1c8f7ff2012-09-01 00:12:11 +000012142 return "cxlgbr";
12143}
12144
florian55085f82012-11-21 00:36:55 +000012145static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012146s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12147 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012148{
12149 IRTemp op = newTemp(Ity_F128);
12150 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012151 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012152
12153 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012154 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012155 mkexpr(op)));
12156 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012157 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012158
12159 return "cfxbr";
12160}
12161
florian55085f82012-11-21 00:36:55 +000012162static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012163s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12164 UChar r1, UChar r2)
12165{
floriane75dafa2012-09-01 17:54:09 +000012166 if (! s390_host_has_fpext) {
12167 emulation_failure(EmFail_S390X_fpext);
12168 } else {
12169 IRTemp op = newTemp(Ity_F128);
12170 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012171 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012172
floriane75dafa2012-09-01 17:54:09 +000012173 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012174 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012175 mkexpr(op)));
12176 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012177 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012178 }
florian1c8f7ff2012-09-01 00:12:11 +000012179 return "clfxbr";
12180}
12181
12182
florian55085f82012-11-21 00:36:55 +000012183static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012184s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12185 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012186{
12187 IRTemp op = newTemp(Ity_F128);
12188 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012189 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012190
12191 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012192 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012193 mkexpr(op)));
12194 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012195 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012196
12197 return "cgxbr";
12198}
12199
florian55085f82012-11-21 00:36:55 +000012200static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012201s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12202 UChar r1, UChar r2)
12203{
floriane75dafa2012-09-01 17:54:09 +000012204 if (! s390_host_has_fpext) {
12205 emulation_failure(EmFail_S390X_fpext);
12206 } else {
12207 IRTemp op = newTemp(Ity_F128);
12208 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012209 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012210
floriane75dafa2012-09-01 17:54:09 +000012211 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012212 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012213 mkexpr(op)));
12214 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012215 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12216 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012217 }
florian1c8f7ff2012-09-01 00:12:11 +000012218 return "clgxbr";
12219}
12220
florian55085f82012-11-21 00:36:55 +000012221static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012222s390_irgen_DXBR(UChar r1, UChar r2)
12223{
12224 IRTemp op1 = newTemp(Ity_F128);
12225 IRTemp op2 = newTemp(Ity_F128);
12226 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012227 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012228
12229 assign(op1, get_fpr_pair(r1));
12230 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012231 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012232 mkexpr(op2)));
12233 put_fpr_pair(r1, mkexpr(result));
12234
12235 return "dxbr";
12236}
12237
florian55085f82012-11-21 00:36:55 +000012238static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012239s390_irgen_LTXBR(UChar r1, UChar r2)
12240{
12241 IRTemp result = newTemp(Ity_F128);
12242
12243 assign(result, get_fpr_pair(r2));
12244 put_fpr_pair(r1, mkexpr(result));
12245 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12246
12247 return "ltxbr";
12248}
12249
florian55085f82012-11-21 00:36:55 +000012250static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012251s390_irgen_LCXBR(UChar r1, UChar r2)
12252{
12253 IRTemp result = newTemp(Ity_F128);
12254
12255 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12256 put_fpr_pair(r1, mkexpr(result));
12257 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12258
12259 return "lcxbr";
12260}
12261
florian55085f82012-11-21 00:36:55 +000012262static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012263s390_irgen_LXDBR(UChar r1, UChar r2)
12264{
12265 IRTemp op = newTemp(Ity_F64);
12266
12267 assign(op, get_fpr_dw0(r2));
12268 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12269
12270 return "lxdbr";
12271}
12272
florian55085f82012-11-21 00:36:55 +000012273static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012274s390_irgen_LXEBR(UChar r1, UChar r2)
12275{
12276 IRTemp op = newTemp(Ity_F32);
12277
12278 assign(op, get_fpr_w0(r2));
12279 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12280
12281 return "lxebr";
12282}
12283
florian55085f82012-11-21 00:36:55 +000012284static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012285s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12286{
12287 IRTemp op = newTemp(Ity_F64);
12288
12289 assign(op, load(Ity_F64, mkexpr(op2addr)));
12290 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12291
12292 return "lxdb";
12293}
12294
florian55085f82012-11-21 00:36:55 +000012295static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012296s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12297{
12298 IRTemp op = newTemp(Ity_F32);
12299
12300 assign(op, load(Ity_F32, mkexpr(op2addr)));
12301 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12302
12303 return "lxeb";
12304}
12305
florian55085f82012-11-21 00:36:55 +000012306static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012307s390_irgen_LNEBR(UChar r1, UChar r2)
12308{
12309 IRTemp result = newTemp(Ity_F32);
12310
12311 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12312 put_fpr_w0(r1, mkexpr(result));
12313 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12314
12315 return "lnebr";
12316}
12317
florian55085f82012-11-21 00:36:55 +000012318static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012319s390_irgen_LNDBR(UChar r1, UChar r2)
12320{
12321 IRTemp result = newTemp(Ity_F64);
12322
12323 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12324 put_fpr_dw0(r1, mkexpr(result));
12325 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12326
12327 return "lndbr";
12328}
12329
florian55085f82012-11-21 00:36:55 +000012330static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012331s390_irgen_LNXBR(UChar r1, UChar r2)
12332{
12333 IRTemp result = newTemp(Ity_F128);
12334
12335 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, 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 "lnxbr";
12340}
12341
florian55085f82012-11-21 00:36:55 +000012342static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012343s390_irgen_LPEBR(UChar r1, UChar r2)
12344{
12345 IRTemp result = newTemp(Ity_F32);
12346
12347 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12348 put_fpr_w0(r1, mkexpr(result));
12349 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12350
12351 return "lpebr";
12352}
12353
florian55085f82012-11-21 00:36:55 +000012354static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012355s390_irgen_LPDBR(UChar r1, UChar r2)
12356{
12357 IRTemp result = newTemp(Ity_F64);
12358
12359 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12360 put_fpr_dw0(r1, mkexpr(result));
12361 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12362
12363 return "lpdbr";
12364}
12365
florian55085f82012-11-21 00:36:55 +000012366static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012367s390_irgen_LPXBR(UChar r1, UChar r2)
12368{
12369 IRTemp result = newTemp(Ity_F128);
12370
12371 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12372 put_fpr_pair(r1, mkexpr(result));
12373 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12374
12375 return "lpxbr";
12376}
12377
florian55085f82012-11-21 00:36:55 +000012378static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012379s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12380 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012381{
florian125e20d2012-10-07 15:42:37 +000012382 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012383 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012384 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012385 }
sewardj2019a972011-03-07 16:04:07 +000012386 IRTemp result = newTemp(Ity_F64);
12387
floriandb4fcaa2012-09-05 19:54:08 +000012388 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012389 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012390 put_fpr_dw0(r1, mkexpr(result));
12391
12392 return "ldxbr";
12393}
12394
florian55085f82012-11-21 00:36:55 +000012395static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012396s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12397 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012398{
florian125e20d2012-10-07 15:42:37 +000012399 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012400 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012401 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012402 }
sewardj2019a972011-03-07 16:04:07 +000012403 IRTemp result = newTemp(Ity_F32);
12404
floriandb4fcaa2012-09-05 19:54:08 +000012405 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012406 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012407 put_fpr_w0(r1, mkexpr(result));
12408
12409 return "lexbr";
12410}
12411
florian55085f82012-11-21 00:36:55 +000012412static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012413s390_irgen_MXBR(UChar r1, UChar r2)
12414{
12415 IRTemp op1 = newTemp(Ity_F128);
12416 IRTemp op2 = newTemp(Ity_F128);
12417 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012418 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012419
12420 assign(op1, get_fpr_pair(r1));
12421 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012422 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012423 mkexpr(op2)));
12424 put_fpr_pair(r1, mkexpr(result));
12425
12426 return "mxbr";
12427}
12428
florian55085f82012-11-21 00:36:55 +000012429static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012430s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12431{
florian125e20d2012-10-07 15:42:37 +000012432 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012433
floriandb4fcaa2012-09-05 19:54:08 +000012434 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012435 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012436
12437 return "maebr";
12438}
12439
florian55085f82012-11-21 00:36:55 +000012440static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012441s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12442{
florian125e20d2012-10-07 15:42:37 +000012443 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012444
floriandb4fcaa2012-09-05 19:54:08 +000012445 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012446 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012447
12448 return "madbr";
12449}
12450
florian55085f82012-11-21 00:36:55 +000012451static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012452s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12453{
12454 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012455 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012456
floriandb4fcaa2012-09-05 19:54:08 +000012457 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012458 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012459
12460 return "maeb";
12461}
12462
florian55085f82012-11-21 00:36:55 +000012463static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012464s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12465{
12466 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012467 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012468
floriandb4fcaa2012-09-05 19:54:08 +000012469 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012470 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012471
12472 return "madb";
12473}
12474
florian55085f82012-11-21 00:36:55 +000012475static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012476s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12477{
florian125e20d2012-10-07 15:42:37 +000012478 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012479
floriandb4fcaa2012-09-05 19:54:08 +000012480 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012481 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012482
12483 return "msebr";
12484}
12485
florian55085f82012-11-21 00:36:55 +000012486static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012487s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12488{
florian125e20d2012-10-07 15:42:37 +000012489 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012490
floriandb4fcaa2012-09-05 19:54:08 +000012491 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012492 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012493
12494 return "msdbr";
12495}
12496
florian55085f82012-11-21 00:36:55 +000012497static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012498s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12499{
12500 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012501 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012502
floriandb4fcaa2012-09-05 19:54:08 +000012503 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012504 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012505
12506 return "mseb";
12507}
12508
florian55085f82012-11-21 00:36:55 +000012509static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012510s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12511{
12512 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012513 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012514
floriandb4fcaa2012-09-05 19:54:08 +000012515 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012516 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012517
12518 return "msdb";
12519}
12520
florian55085f82012-11-21 00:36:55 +000012521static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012522s390_irgen_SQEBR(UChar r1, UChar r2)
12523{
12524 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012525 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012526
floriandb4fcaa2012-09-05 19:54:08 +000012527 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012528 put_fpr_w0(r1, mkexpr(result));
12529
12530 return "sqebr";
12531}
12532
florian55085f82012-11-21 00:36:55 +000012533static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012534s390_irgen_SQDBR(UChar r1, UChar r2)
12535{
12536 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012537 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012538
floriandb4fcaa2012-09-05 19:54:08 +000012539 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012540 put_fpr_dw0(r1, mkexpr(result));
12541
12542 return "sqdbr";
12543}
12544
florian55085f82012-11-21 00:36:55 +000012545static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012546s390_irgen_SQXBR(UChar r1, UChar r2)
12547{
12548 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012549 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012550
floriandb4fcaa2012-09-05 19:54:08 +000012551 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12552 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012553 put_fpr_pair(r1, mkexpr(result));
12554
12555 return "sqxbr";
12556}
12557
florian55085f82012-11-21 00:36:55 +000012558static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012559s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12560{
12561 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012562 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012563
12564 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012565 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012566
12567 return "sqeb";
12568}
12569
florian55085f82012-11-21 00:36:55 +000012570static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012571s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12572{
12573 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012574 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012575
12576 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012577 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012578
12579 return "sqdb";
12580}
12581
florian55085f82012-11-21 00:36:55 +000012582static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012583s390_irgen_SXBR(UChar r1, UChar r2)
12584{
12585 IRTemp op1 = newTemp(Ity_F128);
12586 IRTemp op2 = newTemp(Ity_F128);
12587 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012588 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012589
12590 assign(op1, get_fpr_pair(r1));
12591 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012592 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012593 mkexpr(op2)));
12594 put_fpr_pair(r1, mkexpr(result));
12595 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12596
12597 return "sxbr";
12598}
12599
florian55085f82012-11-21 00:36:55 +000012600static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012601s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12602{
12603 IRTemp value = newTemp(Ity_F32);
12604
12605 assign(value, get_fpr_w0(r1));
12606
12607 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12608
12609 return "tceb";
12610}
12611
florian55085f82012-11-21 00:36:55 +000012612static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012613s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12614{
12615 IRTemp value = newTemp(Ity_F64);
12616
12617 assign(value, get_fpr_dw0(r1));
12618
12619 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12620
12621 return "tcdb";
12622}
12623
florian55085f82012-11-21 00:36:55 +000012624static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012625s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12626{
12627 IRTemp value = newTemp(Ity_F128);
12628
12629 assign(value, get_fpr_pair(r1));
12630
12631 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12632
12633 return "tcxb";
12634}
12635
florian55085f82012-11-21 00:36:55 +000012636static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012637s390_irgen_LCDFR(UChar r1, UChar r2)
12638{
12639 IRTemp result = newTemp(Ity_F64);
12640
12641 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12642 put_fpr_dw0(r1, mkexpr(result));
12643
12644 return "lcdfr";
12645}
12646
florian55085f82012-11-21 00:36:55 +000012647static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012648s390_irgen_LNDFR(UChar r1, UChar r2)
12649{
12650 IRTemp result = newTemp(Ity_F64);
12651
12652 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12653 put_fpr_dw0(r1, mkexpr(result));
12654
12655 return "lndfr";
12656}
12657
florian55085f82012-11-21 00:36:55 +000012658static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012659s390_irgen_LPDFR(UChar r1, UChar r2)
12660{
12661 IRTemp result = newTemp(Ity_F64);
12662
12663 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12664 put_fpr_dw0(r1, mkexpr(result));
12665
12666 return "lpdfr";
12667}
12668
florian55085f82012-11-21 00:36:55 +000012669static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012670s390_irgen_LDGR(UChar r1, UChar r2)
12671{
12672 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12673
12674 return "ldgr";
12675}
12676
florian55085f82012-11-21 00:36:55 +000012677static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012678s390_irgen_LGDR(UChar r1, UChar r2)
12679{
12680 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12681
12682 return "lgdr";
12683}
12684
12685
florian55085f82012-11-21 00:36:55 +000012686static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012687s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12688{
12689 IRTemp sign = newTemp(Ity_I64);
12690 IRTemp value = newTemp(Ity_I64);
12691
12692 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12693 mkU64(1ULL << 63)));
12694 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12695 mkU64((1ULL << 63) - 1)));
12696 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12697 mkexpr(sign))));
12698
12699 return "cpsdr";
12700}
12701
12702
sewardj2019a972011-03-07 16:04:07 +000012703static IRExpr *
12704s390_call_cvb(IRExpr *in)
12705{
12706 IRExpr **args, *call;
12707
12708 args = mkIRExprVec_1(in);
12709 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12710 "s390_do_cvb", &s390_do_cvb, args);
12711
12712 /* Nothing is excluded from definedness checking. */
12713 call->Iex.CCall.cee->mcx_mask = 0;
12714
12715 return call;
12716}
12717
florian55085f82012-11-21 00:36:55 +000012718static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012719s390_irgen_CVB(UChar r1, IRTemp op2addr)
12720{
12721 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12722
12723 return "cvb";
12724}
12725
florian55085f82012-11-21 00:36:55 +000012726static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012727s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12728{
12729 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12730
12731 return "cvby";
12732}
12733
12734
sewardj2019a972011-03-07 16:04:07 +000012735static IRExpr *
12736s390_call_cvd(IRExpr *in)
12737{
12738 IRExpr **args, *call;
12739
12740 args = mkIRExprVec_1(in);
12741 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12742 "s390_do_cvd", &s390_do_cvd, args);
12743
12744 /* Nothing is excluded from definedness checking. */
12745 call->Iex.CCall.cee->mcx_mask = 0;
12746
12747 return call;
12748}
12749
florian55085f82012-11-21 00:36:55 +000012750static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012751s390_irgen_CVD(UChar r1, IRTemp op2addr)
12752{
florian11b8ee82012-08-06 13:35:33 +000012753 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012754
12755 return "cvd";
12756}
12757
florian55085f82012-11-21 00:36:55 +000012758static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012759s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12760{
12761 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12762
12763 return "cvdy";
12764}
12765
florian55085f82012-11-21 00:36:55 +000012766static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012767s390_irgen_FLOGR(UChar r1, UChar r2)
12768{
12769 IRTemp input = newTemp(Ity_I64);
12770 IRTemp not_zero = newTemp(Ity_I64);
12771 IRTemp tmpnum = newTemp(Ity_I64);
12772 IRTemp num = newTemp(Ity_I64);
12773 IRTemp shift_amount = newTemp(Ity_I8);
12774
12775 /* We use the "count leading zeroes" operator because the number of
12776 leading zeroes is identical with the bit position of the first '1' bit.
12777 However, that operator does not work when the input value is zero.
12778 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12779 the modified value. If input == 0, then the result is 64. Otherwise,
12780 the result of Clz64 is what we want. */
12781
12782 assign(input, get_gpr_dw0(r2));
12783 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12784 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12785
12786 /* num = (input == 0) ? 64 : tmpnum */
12787 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12788 /* == 0 */ mkU64(64),
12789 /* != 0 */ mkexpr(tmpnum)));
12790
12791 put_gpr_dw0(r1, mkexpr(num));
12792
12793 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12794 is to first shift the input value by NUM + 1 bits to the left which
12795 causes the leftmost '1' bit to disappear. Then we shift logically to
12796 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12797 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12798 the width of the value-to-be-shifted, we need to special case
12799 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12800 For both such INPUT values the result will be 0. */
12801
12802 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12803 mkU64(1))));
12804
12805 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012806 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12807 /* == 0 || == 1*/ mkU64(0),
12808 /* otherwise */
12809 binop(Iop_Shr64,
12810 binop(Iop_Shl64, mkexpr(input),
12811 mkexpr(shift_amount)),
12812 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012813
12814 /* Compare the original value as an unsigned integer with 0. */
12815 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12816 mktemp(Ity_I64, mkU64(0)), False);
12817
12818 return "flogr";
12819}
12820
florian55085f82012-11-21 00:36:55 +000012821static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012822s390_irgen_STCK(IRTemp op2addr)
12823{
12824 IRDirty *d;
12825 IRTemp cc = newTemp(Ity_I64);
12826
12827 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12828 &s390x_dirtyhelper_STCK,
12829 mkIRExprVec_1(mkexpr(op2addr)));
12830 d->mFx = Ifx_Write;
12831 d->mAddr = mkexpr(op2addr);
12832 d->mSize = 8;
12833 stmt(IRStmt_Dirty(d));
12834 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12835 mkexpr(cc), mkU64(0), mkU64(0));
12836 return "stck";
12837}
12838
florian55085f82012-11-21 00:36:55 +000012839static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012840s390_irgen_STCKF(IRTemp op2addr)
12841{
florianc5c669b2012-08-26 14:32:28 +000012842 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012843 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012844 } else {
12845 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012846
florianc5c669b2012-08-26 14:32:28 +000012847 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12848 &s390x_dirtyhelper_STCKF,
12849 mkIRExprVec_1(mkexpr(op2addr)));
12850 d->mFx = Ifx_Write;
12851 d->mAddr = mkexpr(op2addr);
12852 d->mSize = 8;
12853 stmt(IRStmt_Dirty(d));
12854 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12855 mkexpr(cc), mkU64(0), mkU64(0));
12856 }
sewardj1e5fea62011-05-17 16:18:36 +000012857 return "stckf";
12858}
12859
florian55085f82012-11-21 00:36:55 +000012860static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012861s390_irgen_STCKE(IRTemp op2addr)
12862{
12863 IRDirty *d;
12864 IRTemp cc = newTemp(Ity_I64);
12865
12866 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12867 &s390x_dirtyhelper_STCKE,
12868 mkIRExprVec_1(mkexpr(op2addr)));
12869 d->mFx = Ifx_Write;
12870 d->mAddr = mkexpr(op2addr);
12871 d->mSize = 16;
12872 stmt(IRStmt_Dirty(d));
12873 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12874 mkexpr(cc), mkU64(0), mkU64(0));
12875 return "stcke";
12876}
12877
florian55085f82012-11-21 00:36:55 +000012878static const HChar *
florian933065d2011-07-11 01:48:02 +000012879s390_irgen_STFLE(IRTemp op2addr)
12880{
florian4e0083e2012-08-26 03:41:56 +000012881 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012882 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012883 return "stfle";
12884 }
12885
florian933065d2011-07-11 01:48:02 +000012886 IRDirty *d;
12887 IRTemp cc = newTemp(Ity_I64);
12888
florian90419562013-08-15 20:54:52 +000012889 /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper */
florian933065d2011-07-11 01:48:02 +000012890 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12891 &s390x_dirtyhelper_STFLE,
florian90419562013-08-15 20:54:52 +000012892 mkIRExprVec_2(IRExpr_BBPTR(), mkexpr(op2addr)));
florian933065d2011-07-11 01:48:02 +000012893
sewardjc9069f22012-06-01 16:09:50 +000012894 d->nFxState = 1;
12895 vex_bzero(&d->fxState, sizeof(d->fxState));
12896
florian933065d2011-07-11 01:48:02 +000012897 d->fxState[0].fx = Ifx_Modify; /* read then write */
12898 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12899 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012900
12901 d->mAddr = mkexpr(op2addr);
12902 /* Pretend all double words are written */
12903 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12904 d->mFx = Ifx_Write;
12905
12906 stmt(IRStmt_Dirty(d));
12907
12908 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12909
12910 return "stfle";
12911}
12912
florian55085f82012-11-21 00:36:55 +000012913static const HChar *
floriana4384a32011-08-11 16:58:45 +000012914s390_irgen_CKSM(UChar r1,UChar r2)
12915{
12916 IRTemp addr = newTemp(Ity_I64);
12917 IRTemp op = newTemp(Ity_I32);
12918 IRTemp len = newTemp(Ity_I64);
12919 IRTemp oldval = newTemp(Ity_I32);
12920 IRTemp mask = newTemp(Ity_I32);
12921 IRTemp newop = newTemp(Ity_I32);
12922 IRTemp result = newTemp(Ity_I32);
12923 IRTemp result1 = newTemp(Ity_I32);
12924 IRTemp inc = newTemp(Ity_I64);
12925
12926 assign(oldval, get_gpr_w1(r1));
12927 assign(addr, get_gpr_dw0(r2));
12928 assign(len, get_gpr_dw0(r2+1));
12929
12930 /* Condition code is always zero. */
12931 s390_cc_set(0);
12932
12933 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012934 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012935
12936 /* Assiging the increment variable to adjust address and length
12937 later on. */
12938 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12939 mkexpr(len), mkU64(4)));
12940
12941 /* If length < 4 the final 4-byte 2nd operand value is computed by
12942 appending the remaining bytes to the right with 0. This is done
12943 by AND'ing the 4 bytes loaded from memory with an appropriate
12944 mask. If length >= 4, that mask is simply 0xffffffff. */
12945
12946 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12947 /* Mask computation when len < 4:
12948 0xffffffff << (32 - (len % 4)*8) */
12949 binop(Iop_Shl32, mkU32(0xffffffff),
12950 unop(Iop_32to8,
12951 binop(Iop_Sub32, mkU32(32),
12952 binop(Iop_Shl32,
12953 unop(Iop_64to32,
12954 binop(Iop_And64,
12955 mkexpr(len), mkU64(3))),
12956 mkU8(3))))),
12957 mkU32(0xffffffff)));
12958
12959 assign(op, load(Ity_I32, mkexpr(addr)));
12960 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12961 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12962
12963 /* Checking for carry */
12964 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12965 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12966 mkexpr(result)));
12967
12968 put_gpr_w1(r1, mkexpr(result1));
12969 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12970 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12971
florian6820ba52012-07-26 02:01:50 +000012972 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012973
12974 return "cksm";
12975}
12976
florian55085f82012-11-21 00:36:55 +000012977static const HChar *
florian9af37692012-01-15 21:01:16 +000012978s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12979{
12980 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12981 src_addr = newTemp(Ity_I64);
12982 des_addr = newTemp(Ity_I64);
12983 tab_addr = newTemp(Ity_I64);
12984 test_byte = newTemp(Ity_I8);
12985 src_len = newTemp(Ity_I64);
12986
12987 assign(src_addr, get_gpr_dw0(r2));
12988 assign(des_addr, get_gpr_dw0(r1));
12989 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012990 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012991 assign(test_byte, get_gpr_b7(0));
12992
12993 IRTemp op = newTemp(Ity_I8);
12994 IRTemp op1 = newTemp(Ity_I8);
12995 IRTemp result = newTemp(Ity_I64);
12996
12997 /* End of source string? We're done; proceed to next insn */
12998 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012999 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000013000
13001 /* Load character from source string, index translation table and
13002 store translated character in op1. */
13003 assign(op, load(Ity_I8, mkexpr(src_addr)));
13004
13005 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13006 mkexpr(tab_addr)));
13007 assign(op1, load(Ity_I8, mkexpr(result)));
13008
13009 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13010 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013011 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000013012 }
13013 store(get_gpr_dw0(r1), mkexpr(op1));
13014
13015 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13016 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13017 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13018
florian6820ba52012-07-26 02:01:50 +000013019 iterate();
florian9af37692012-01-15 21:01:16 +000013020
13021 return "troo";
13022}
13023
florian55085f82012-11-21 00:36:55 +000013024static const HChar *
florian730448f2012-02-04 17:07:07 +000013025s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13026{
13027 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13028 src_addr = newTemp(Ity_I64);
13029 des_addr = newTemp(Ity_I64);
13030 tab_addr = newTemp(Ity_I64);
13031 test_byte = newTemp(Ity_I8);
13032 src_len = newTemp(Ity_I64);
13033
13034 assign(src_addr, get_gpr_dw0(r2));
13035 assign(des_addr, get_gpr_dw0(r1));
13036 assign(tab_addr, get_gpr_dw0(1));
13037 assign(src_len, get_gpr_dw0(r1+1));
13038 assign(test_byte, get_gpr_b7(0));
13039
13040 IRTemp op = newTemp(Ity_I16);
13041 IRTemp op1 = newTemp(Ity_I8);
13042 IRTemp result = newTemp(Ity_I64);
13043
13044 /* End of source string? We're done; proceed to next insn */
13045 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013046 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013047
13048 /* Load character from source string, index translation table and
13049 store translated character in op1. */
13050 assign(op, load(Ity_I16, mkexpr(src_addr)));
13051
13052 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13053 mkexpr(tab_addr)));
13054
13055 assign(op1, load(Ity_I8, mkexpr(result)));
13056
13057 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13058 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013059 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013060 }
13061 store(get_gpr_dw0(r1), mkexpr(op1));
13062
13063 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13064 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13065 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13066
florian6820ba52012-07-26 02:01:50 +000013067 iterate();
florian730448f2012-02-04 17:07:07 +000013068
13069 return "trto";
13070}
13071
florian55085f82012-11-21 00:36:55 +000013072static const HChar *
florian730448f2012-02-04 17:07:07 +000013073s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13074{
13075 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13076 src_addr = newTemp(Ity_I64);
13077 des_addr = newTemp(Ity_I64);
13078 tab_addr = newTemp(Ity_I64);
13079 test_byte = newTemp(Ity_I16);
13080 src_len = newTemp(Ity_I64);
13081
13082 assign(src_addr, get_gpr_dw0(r2));
13083 assign(des_addr, get_gpr_dw0(r1));
13084 assign(tab_addr, get_gpr_dw0(1));
13085 assign(src_len, get_gpr_dw0(r1+1));
13086 assign(test_byte, get_gpr_hw3(0));
13087
13088 IRTemp op = newTemp(Ity_I8);
13089 IRTemp op1 = newTemp(Ity_I16);
13090 IRTemp result = newTemp(Ity_I64);
13091
13092 /* End of source string? We're done; proceed to next insn */
13093 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013094 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013095
13096 /* Load character from source string, index translation table and
13097 store translated character in op1. */
13098 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13099
13100 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13101 mkexpr(tab_addr)));
13102 assign(op1, load(Ity_I16, mkexpr(result)));
13103
13104 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13105 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013106 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013107 }
13108 store(get_gpr_dw0(r1), mkexpr(op1));
13109
13110 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13111 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13112 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13113
florian6820ba52012-07-26 02:01:50 +000013114 iterate();
florian730448f2012-02-04 17:07:07 +000013115
13116 return "trot";
13117}
13118
florian55085f82012-11-21 00:36:55 +000013119static const HChar *
florian730448f2012-02-04 17:07:07 +000013120s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13121{
13122 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13123 src_addr = newTemp(Ity_I64);
13124 des_addr = newTemp(Ity_I64);
13125 tab_addr = newTemp(Ity_I64);
13126 test_byte = newTemp(Ity_I16);
13127 src_len = newTemp(Ity_I64);
13128
13129 assign(src_addr, get_gpr_dw0(r2));
13130 assign(des_addr, get_gpr_dw0(r1));
13131 assign(tab_addr, get_gpr_dw0(1));
13132 assign(src_len, get_gpr_dw0(r1+1));
13133 assign(test_byte, get_gpr_hw3(0));
13134
13135 IRTemp op = newTemp(Ity_I16);
13136 IRTemp op1 = newTemp(Ity_I16);
13137 IRTemp result = newTemp(Ity_I64);
13138
13139 /* End of source string? We're done; proceed to next insn */
13140 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013141 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013142
13143 /* Load character from source string, index translation table and
13144 store translated character in op1. */
13145 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13146
13147 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13148 mkexpr(tab_addr)));
13149 assign(op1, load(Ity_I16, mkexpr(result)));
13150
13151 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13152 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013153 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013154 }
13155
13156 store(get_gpr_dw0(r1), mkexpr(op1));
13157
13158 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13159 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13160 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13161
florian6820ba52012-07-26 02:01:50 +000013162 iterate();
florian730448f2012-02-04 17:07:07 +000013163
13164 return "trtt";
13165}
13166
florian55085f82012-11-21 00:36:55 +000013167static const HChar *
florian730448f2012-02-04 17:07:07 +000013168s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13169{
florianf87d4fb2012-05-05 02:55:24 +000013170 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000013171
florianf87d4fb2012-05-05 02:55:24 +000013172 assign(len, mkU64(length));
13173 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000013174
13175 return "tr";
13176}
13177
florian55085f82012-11-21 00:36:55 +000013178static const HChar *
florian730448f2012-02-04 17:07:07 +000013179s390_irgen_TRE(UChar r1,UChar r2)
13180{
13181 IRTemp src_addr, tab_addr, src_len, test_byte;
13182 src_addr = newTemp(Ity_I64);
13183 tab_addr = newTemp(Ity_I64);
13184 src_len = newTemp(Ity_I64);
13185 test_byte = newTemp(Ity_I8);
13186
13187 assign(src_addr, get_gpr_dw0(r1));
13188 assign(src_len, get_gpr_dw0(r1+1));
13189 assign(tab_addr, get_gpr_dw0(r2));
13190 assign(test_byte, get_gpr_b7(0));
13191
13192 IRTemp op = newTemp(Ity_I8);
13193 IRTemp op1 = newTemp(Ity_I8);
13194 IRTemp result = newTemp(Ity_I64);
13195
13196 /* End of source string? We're done; proceed to next insn */
13197 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013198 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013199
13200 /* Load character from source string and compare with test byte */
13201 assign(op, load(Ity_I8, mkexpr(src_addr)));
13202
13203 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013204 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013205
13206 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13207 mkexpr(tab_addr)));
13208
13209 assign(op1, load(Ity_I8, mkexpr(result)));
13210
13211 store(get_gpr_dw0(r1), mkexpr(op1));
13212 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13213 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13214
florian6820ba52012-07-26 02:01:50 +000013215 iterate();
florian730448f2012-02-04 17:07:07 +000013216
13217 return "tre";
13218}
13219
floriana0100c92012-07-20 00:06:35 +000013220static IRExpr *
13221s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13222{
13223 IRExpr **args, *call;
13224 args = mkIRExprVec_2(srcval, low_surrogate);
13225 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13226 "s390_do_cu21", &s390_do_cu21, args);
13227
13228 /* Nothing is excluded from definedness checking. */
13229 call->Iex.CCall.cee->mcx_mask = 0;
13230
13231 return call;
13232}
13233
florian55085f82012-11-21 00:36:55 +000013234static const HChar *
floriana0100c92012-07-20 00:06:35 +000013235s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13236{
13237 IRTemp addr1 = newTemp(Ity_I64);
13238 IRTemp addr2 = newTemp(Ity_I64);
13239 IRTemp len1 = newTemp(Ity_I64);
13240 IRTemp len2 = newTemp(Ity_I64);
13241
13242 assign(addr1, get_gpr_dw0(r1));
13243 assign(addr2, get_gpr_dw0(r2));
13244 assign(len1, get_gpr_dw0(r1 + 1));
13245 assign(len2, get_gpr_dw0(r2 + 1));
13246
13247 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13248 there are less than 2 bytes left, then the 2nd operand is exhausted
13249 and we're done here. cc = 0 */
13250 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013251 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000013252
13253 /* There are at least two bytes there. Read them. */
13254 IRTemp srcval = newTemp(Ity_I32);
13255 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13256
13257 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13258 inside the interval [0xd800 - 0xdbff] */
13259 IRTemp is_high_surrogate = newTemp(Ity_I32);
13260 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13261 mkU32(1), mkU32(0));
13262 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13263 mkU32(1), mkU32(0));
13264 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13265
13266 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13267 then the 2nd operand is exhausted and we're done here. cc = 0 */
13268 IRExpr *not_enough_bytes =
13269 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13270
florian6820ba52012-07-26 02:01:50 +000013271 next_insn_if(binop(Iop_CmpEQ32,
13272 binop(Iop_And32, mkexpr(is_high_surrogate),
13273 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000013274
13275 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13276 surrogate, read the next two bytes (low surrogate). */
13277 IRTemp low_surrogate = newTemp(Ity_I32);
13278 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13279
13280 assign(low_surrogate,
13281 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13282 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13283 mkU32(0))); // any value is fine; it will not be used
13284
13285 /* Call the helper */
13286 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013287 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13288 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000013289
13290 /* Before we can test whether the 1st operand is exhausted we need to
13291 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13292 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13293 IRExpr *invalid_low_surrogate =
13294 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13295
13296 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013297 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000013298 }
13299
13300 /* Now test whether the 1st operand is exhausted */
13301 IRTemp num_bytes = newTemp(Ity_I64);
13302 assign(num_bytes, binop(Iop_And64,
13303 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13304 mkU64(0xff)));
13305 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013306 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000013307
13308 /* Extract the bytes to be stored at addr1 */
13309 IRTemp data = newTemp(Ity_I64);
13310 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13311
13312 /* To store the bytes construct 4 dirty helper calls. The helper calls
13313 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13314 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013315 UInt i;
floriana0100c92012-07-20 00:06:35 +000013316 for (i = 1; i <= 4; ++i) {
13317 IRDirty *d;
13318
13319 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13320 &s390x_dirtyhelper_CUxy,
13321 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13322 mkexpr(num_bytes)));
13323 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13324 d->mFx = Ifx_Write;
13325 d->mAddr = mkexpr(addr1);
13326 d->mSize = i;
13327 stmt(IRStmt_Dirty(d));
13328 }
13329
13330 /* Update source address and length */
13331 IRTemp num_src_bytes = newTemp(Ity_I64);
13332 assign(num_src_bytes,
13333 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13334 mkU64(4), mkU64(2)));
13335 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13336 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13337
13338 /* Update destination address and length */
13339 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13340 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13341
florian6820ba52012-07-26 02:01:50 +000013342 iterate();
floriana0100c92012-07-20 00:06:35 +000013343
13344 return "cu21";
13345}
13346
florian2a415a12012-07-21 17:41:36 +000013347static IRExpr *
13348s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13349{
13350 IRExpr **args, *call;
13351 args = mkIRExprVec_2(srcval, low_surrogate);
13352 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13353 "s390_do_cu24", &s390_do_cu24, args);
13354
13355 /* Nothing is excluded from definedness checking. */
13356 call->Iex.CCall.cee->mcx_mask = 0;
13357
13358 return call;
13359}
13360
florian55085f82012-11-21 00:36:55 +000013361static const HChar *
florian2a415a12012-07-21 17:41:36 +000013362s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13363{
13364 IRTemp addr1 = newTemp(Ity_I64);
13365 IRTemp addr2 = newTemp(Ity_I64);
13366 IRTemp len1 = newTemp(Ity_I64);
13367 IRTemp len2 = newTemp(Ity_I64);
13368
13369 assign(addr1, get_gpr_dw0(r1));
13370 assign(addr2, get_gpr_dw0(r2));
13371 assign(len1, get_gpr_dw0(r1 + 1));
13372 assign(len2, get_gpr_dw0(r2 + 1));
13373
13374 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13375 there are less than 2 bytes left, then the 2nd operand is exhausted
13376 and we're done here. cc = 0 */
13377 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013378 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013379
13380 /* There are at least two bytes there. Read them. */
13381 IRTemp srcval = newTemp(Ity_I32);
13382 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13383
13384 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13385 inside the interval [0xd800 - 0xdbff] */
13386 IRTemp is_high_surrogate = newTemp(Ity_I32);
13387 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13388 mkU32(1), mkU32(0));
13389 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13390 mkU32(1), mkU32(0));
13391 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13392
13393 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13394 then the 2nd operand is exhausted and we're done here. cc = 0 */
13395 IRExpr *not_enough_bytes =
13396 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13397
florian6820ba52012-07-26 02:01:50 +000013398 next_insn_if(binop(Iop_CmpEQ32,
13399 binop(Iop_And32, mkexpr(is_high_surrogate),
13400 not_enough_bytes),
13401 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013402
13403 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13404 surrogate, read the next two bytes (low surrogate). */
13405 IRTemp low_surrogate = newTemp(Ity_I32);
13406 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13407
13408 assign(low_surrogate,
13409 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13410 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13411 mkU32(0))); // any value is fine; it will not be used
13412
13413 /* Call the helper */
13414 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013415 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13416 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013417
13418 /* Before we can test whether the 1st operand is exhausted we need to
13419 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13420 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13421 IRExpr *invalid_low_surrogate =
13422 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13423
13424 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013425 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013426 }
13427
13428 /* Now test whether the 1st operand is exhausted */
13429 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013430 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013431
13432 /* Extract the bytes to be stored at addr1 */
13433 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13434
13435 store(mkexpr(addr1), data);
13436
13437 /* Update source address and length */
13438 IRTemp num_src_bytes = newTemp(Ity_I64);
13439 assign(num_src_bytes,
13440 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13441 mkU64(4), mkU64(2)));
13442 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13443 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13444
13445 /* Update destination address and length */
13446 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13447 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13448
florian6820ba52012-07-26 02:01:50 +000013449 iterate();
florian2a415a12012-07-21 17:41:36 +000013450
13451 return "cu24";
13452}
floriana4384a32011-08-11 16:58:45 +000013453
florian956194b2012-07-28 22:18:32 +000013454static IRExpr *
13455s390_call_cu42(IRExpr *srcval)
13456{
13457 IRExpr **args, *call;
13458 args = mkIRExprVec_1(srcval);
13459 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13460 "s390_do_cu42", &s390_do_cu42, args);
13461
13462 /* Nothing is excluded from definedness checking. */
13463 call->Iex.CCall.cee->mcx_mask = 0;
13464
13465 return call;
13466}
13467
florian55085f82012-11-21 00:36:55 +000013468static const HChar *
florian956194b2012-07-28 22:18:32 +000013469s390_irgen_CU42(UChar r1, UChar r2)
13470{
13471 IRTemp addr1 = newTemp(Ity_I64);
13472 IRTemp addr2 = newTemp(Ity_I64);
13473 IRTemp len1 = newTemp(Ity_I64);
13474 IRTemp len2 = newTemp(Ity_I64);
13475
13476 assign(addr1, get_gpr_dw0(r1));
13477 assign(addr2, get_gpr_dw0(r2));
13478 assign(len1, get_gpr_dw0(r1 + 1));
13479 assign(len2, get_gpr_dw0(r2 + 1));
13480
13481 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13482 there are less than 4 bytes left, then the 2nd operand is exhausted
13483 and we're done here. cc = 0 */
13484 s390_cc_set(0);
13485 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13486
13487 /* Read the 2nd operand. */
13488 IRTemp srcval = newTemp(Ity_I32);
13489 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13490
13491 /* Call the helper */
13492 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013493 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013494
13495 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13496 cc=2 outranks cc=1 (1st operand exhausted) */
13497 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13498
13499 s390_cc_set(2);
13500 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13501
13502 /* Now test whether the 1st operand is exhausted */
13503 IRTemp num_bytes = newTemp(Ity_I64);
13504 assign(num_bytes, binop(Iop_And64,
13505 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13506 mkU64(0xff)));
13507 s390_cc_set(1);
13508 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13509
13510 /* Extract the bytes to be stored at addr1 */
13511 IRTemp data = newTemp(Ity_I64);
13512 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13513
13514 /* To store the bytes construct 2 dirty helper calls. The helper calls
13515 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13516 that only one of them will be called at runtime. */
13517
13518 Int i;
13519 for (i = 2; i <= 4; ++i) {
13520 IRDirty *d;
13521
13522 if (i == 3) continue; // skip this one
13523
13524 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13525 &s390x_dirtyhelper_CUxy,
13526 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13527 mkexpr(num_bytes)));
13528 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13529 d->mFx = Ifx_Write;
13530 d->mAddr = mkexpr(addr1);
13531 d->mSize = i;
13532 stmt(IRStmt_Dirty(d));
13533 }
13534
13535 /* Update source address and length */
13536 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13537 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13538
13539 /* Update destination address and length */
13540 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13541 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13542
13543 iterate();
13544
13545 return "cu42";
13546}
13547
florian6d9b9b22012-08-03 18:35:39 +000013548static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013549s390_call_cu41(IRExpr *srcval)
13550{
13551 IRExpr **args, *call;
13552 args = mkIRExprVec_1(srcval);
13553 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13554 "s390_do_cu41", &s390_do_cu41, args);
13555
13556 /* Nothing is excluded from definedness checking. */
13557 call->Iex.CCall.cee->mcx_mask = 0;
13558
13559 return call;
13560}
13561
florian55085f82012-11-21 00:36:55 +000013562static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013563s390_irgen_CU41(UChar r1, UChar r2)
13564{
13565 IRTemp addr1 = newTemp(Ity_I64);
13566 IRTemp addr2 = newTemp(Ity_I64);
13567 IRTemp len1 = newTemp(Ity_I64);
13568 IRTemp len2 = newTemp(Ity_I64);
13569
13570 assign(addr1, get_gpr_dw0(r1));
13571 assign(addr2, get_gpr_dw0(r2));
13572 assign(len1, get_gpr_dw0(r1 + 1));
13573 assign(len2, get_gpr_dw0(r2 + 1));
13574
13575 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13576 there are less than 4 bytes left, then the 2nd operand is exhausted
13577 and we're done here. cc = 0 */
13578 s390_cc_set(0);
13579 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13580
13581 /* Read the 2nd operand. */
13582 IRTemp srcval = newTemp(Ity_I32);
13583 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13584
13585 /* Call the helper */
13586 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013587 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013588
13589 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13590 cc=2 outranks cc=1 (1st operand exhausted) */
13591 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13592
13593 s390_cc_set(2);
13594 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13595
13596 /* Now test whether the 1st operand is exhausted */
13597 IRTemp num_bytes = newTemp(Ity_I64);
13598 assign(num_bytes, binop(Iop_And64,
13599 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13600 mkU64(0xff)));
13601 s390_cc_set(1);
13602 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13603
13604 /* Extract the bytes to be stored at addr1 */
13605 IRTemp data = newTemp(Ity_I64);
13606 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13607
13608 /* To store the bytes construct 4 dirty helper calls. The helper calls
13609 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13610 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013611 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013612 for (i = 1; i <= 4; ++i) {
13613 IRDirty *d;
13614
13615 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13616 &s390x_dirtyhelper_CUxy,
13617 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13618 mkexpr(num_bytes)));
13619 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13620 d->mFx = Ifx_Write;
13621 d->mAddr = mkexpr(addr1);
13622 d->mSize = i;
13623 stmt(IRStmt_Dirty(d));
13624 }
13625
13626 /* Update source address and length */
13627 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13628 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13629
13630 /* Update destination address and length */
13631 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13632 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13633
13634 iterate();
13635
13636 return "cu41";
13637}
13638
13639static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013640s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013641{
13642 IRExpr **args, *call;
13643 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013644 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13645 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013646
13647 /* Nothing is excluded from definedness checking. */
13648 call->Iex.CCall.cee->mcx_mask = 0;
13649
13650 return call;
13651}
13652
13653static IRExpr *
13654s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13655 IRExpr *byte4, IRExpr *stuff)
13656{
13657 IRExpr **args, *call;
13658 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13659 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13660 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13661
13662 /* Nothing is excluded from definedness checking. */
13663 call->Iex.CCall.cee->mcx_mask = 0;
13664
13665 return call;
13666}
13667
florian3f8a96a2012-08-05 02:59:55 +000013668static IRExpr *
13669s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13670 IRExpr *byte4, IRExpr *stuff)
13671{
13672 IRExpr **args, *call;
13673 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13674 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13675 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13676
13677 /* Nothing is excluded from definedness checking. */
13678 call->Iex.CCall.cee->mcx_mask = 0;
13679
13680 return call;
13681}
13682
13683static void
13684s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013685{
13686 IRTemp addr1 = newTemp(Ity_I64);
13687 IRTemp addr2 = newTemp(Ity_I64);
13688 IRTemp len1 = newTemp(Ity_I64);
13689 IRTemp len2 = newTemp(Ity_I64);
13690
13691 assign(addr1, get_gpr_dw0(r1));
13692 assign(addr2, get_gpr_dw0(r2));
13693 assign(len1, get_gpr_dw0(r1 + 1));
13694 assign(len2, get_gpr_dw0(r2 + 1));
13695
13696 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13697
13698 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13699 there is less than 1 byte left, then the 2nd operand is exhausted
13700 and we're done here. cc = 0 */
13701 s390_cc_set(0);
13702 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13703
13704 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013705 IRTemp byte1 = newTemp(Ity_I64);
13706 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013707
13708 /* Call the helper to get number of bytes and invalid byte indicator */
13709 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013710 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013711 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013712
13713 /* Check for invalid 1st byte */
13714 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13715 s390_cc_set(2);
13716 next_insn_if(is_invalid);
13717
13718 /* How many bytes do we have to read? */
13719 IRTemp num_src_bytes = newTemp(Ity_I64);
13720 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13721
13722 /* Now test whether the 2nd operand is exhausted */
13723 s390_cc_set(0);
13724 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13725
13726 /* Read the remaining bytes */
13727 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13728
13729 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13730 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013731 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013732 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13733 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013734 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013735 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13736 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013737 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013738
13739 /* Call the helper to get the converted value and invalid byte indicator.
13740 We can pass at most 5 arguments; therefore some encoding is needed
13741 here */
13742 IRExpr *stuff = binop(Iop_Or64,
13743 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13744 mkU64(extended_checking));
13745 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013746
13747 if (is_cu12) {
13748 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13749 byte4, stuff));
13750 } else {
13751 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13752 byte4, stuff));
13753 }
florian6d9b9b22012-08-03 18:35:39 +000013754
13755 /* Check for invalid character */
13756 s390_cc_set(2);
13757 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13758 next_insn_if(is_invalid);
13759
13760 /* Now test whether the 1st operand is exhausted */
13761 IRTemp num_bytes = newTemp(Ity_I64);
13762 assign(num_bytes, binop(Iop_And64,
13763 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13764 mkU64(0xff)));
13765 s390_cc_set(1);
13766 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13767
13768 /* Extract the bytes to be stored at addr1 */
13769 IRTemp data = newTemp(Ity_I64);
13770 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13771
florian3f8a96a2012-08-05 02:59:55 +000013772 if (is_cu12) {
13773 /* To store the bytes construct 2 dirty helper calls. The helper calls
13774 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13775 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013776
florian3f8a96a2012-08-05 02:59:55 +000013777 Int i;
13778 for (i = 2; i <= 4; ++i) {
13779 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013780
florian3f8a96a2012-08-05 02:59:55 +000013781 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013782
florian3f8a96a2012-08-05 02:59:55 +000013783 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13784 &s390x_dirtyhelper_CUxy,
13785 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13786 mkexpr(num_bytes)));
13787 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13788 d->mFx = Ifx_Write;
13789 d->mAddr = mkexpr(addr1);
13790 d->mSize = i;
13791 stmt(IRStmt_Dirty(d));
13792 }
13793 } else {
13794 // cu14
13795 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013796 }
13797
13798 /* Update source address and length */
13799 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13800 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13801
13802 /* Update destination address and length */
13803 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13804 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13805
13806 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013807}
13808
florian55085f82012-11-21 00:36:55 +000013809static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013810s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13811{
13812 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013813
13814 return "cu12";
13815}
13816
florian55085f82012-11-21 00:36:55 +000013817static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013818s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13819{
13820 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13821
13822 return "cu14";
13823}
13824
florian8c88cb62012-08-26 18:58:13 +000013825static IRExpr *
13826s390_call_ecag(IRExpr *op2addr)
13827{
13828 IRExpr **args, *call;
13829
13830 args = mkIRExprVec_1(op2addr);
13831 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13832 "s390_do_ecag", &s390_do_ecag, args);
13833
13834 /* Nothing is excluded from definedness checking. */
13835 call->Iex.CCall.cee->mcx_mask = 0;
13836
13837 return call;
13838}
13839
florian55085f82012-11-21 00:36:55 +000013840static const HChar *
floriand2129202012-09-01 20:01:39 +000013841s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013842{
13843 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013844 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013845 } else {
13846 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13847 }
13848
13849 return "ecag";
13850}
13851
13852
florianb7def222012-12-04 04:45:32 +000013853/* New insns are added here.
13854 If an insn is contingent on a facility being installed also
13855 check whether the list of supported facilities in function
13856 s390x_dirtyhelper_STFLE needs updating */
13857
sewardj2019a972011-03-07 16:04:07 +000013858/*------------------------------------------------------------*/
13859/*--- Build IR for special instructions ---*/
13860/*------------------------------------------------------------*/
13861
florianb4df7682011-07-05 02:09:01 +000013862static void
sewardj2019a972011-03-07 16:04:07 +000013863s390_irgen_client_request(void)
13864{
13865 if (0)
13866 vex_printf("%%R3 = client_request ( %%R2 )\n");
13867
florianf9e1ed72012-04-17 02:41:56 +000013868 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13869 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013870
florianf9e1ed72012-04-17 02:41:56 +000013871 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013872 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013873
13874 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013875}
13876
florianb4df7682011-07-05 02:09:01 +000013877static void
sewardj2019a972011-03-07 16:04:07 +000013878s390_irgen_guest_NRADDR(void)
13879{
13880 if (0)
13881 vex_printf("%%R3 = guest_NRADDR\n");
13882
floriane88b3c92011-07-05 02:48:39 +000013883 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013884}
13885
florianb4df7682011-07-05 02:09:01 +000013886static void
sewardj2019a972011-03-07 16:04:07 +000013887s390_irgen_call_noredir(void)
13888{
florianf9e1ed72012-04-17 02:41:56 +000013889 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13890 + S390_SPECIAL_OP_SIZE;
13891
sewardj2019a972011-03-07 16:04:07 +000013892 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013893 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013894
13895 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013896 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013897
13898 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013899 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013900}
13901
13902/* Force proper alignment for the structures below. */
13903#pragma pack(1)
13904
13905
13906static s390_decode_t
13907s390_decode_2byte_and_irgen(UChar *bytes)
13908{
13909 typedef union {
13910 struct {
13911 unsigned int op : 16;
13912 } E;
13913 struct {
13914 unsigned int op : 8;
13915 unsigned int i : 8;
13916 } I;
13917 struct {
13918 unsigned int op : 8;
13919 unsigned int r1 : 4;
13920 unsigned int r2 : 4;
13921 } RR;
13922 } formats;
13923 union {
13924 formats fmt;
13925 UShort value;
13926 } ovl;
13927
13928 vassert(sizeof(formats) == 2);
13929
florianffbd84d2012-12-09 02:06:29 +000013930 ((UChar *)(&ovl.value))[0] = bytes[0];
13931 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013932
13933 switch (ovl.value & 0xffff) {
13934 case 0x0101: /* PR */ goto unimplemented;
13935 case 0x0102: /* UPT */ goto unimplemented;
13936 case 0x0104: /* PTFF */ goto unimplemented;
13937 case 0x0107: /* SCKPF */ goto unimplemented;
florian78d5ef72013-05-11 15:02:58 +000013938 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013939 case 0x010b: /* TAM */ goto unimplemented;
13940 case 0x010c: /* SAM24 */ goto unimplemented;
13941 case 0x010d: /* SAM31 */ goto unimplemented;
13942 case 0x010e: /* SAM64 */ goto unimplemented;
13943 case 0x01ff: /* TRAP2 */ goto unimplemented;
13944 }
13945
13946 switch ((ovl.value & 0xff00) >> 8) {
13947 case 0x04: /* SPM */ goto unimplemented;
13948 case 0x05: /* BALR */ goto unimplemented;
13949 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13950 goto ok;
13951 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13952 goto ok;
13953 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13954 case 0x0b: /* BSM */ goto unimplemented;
13955 case 0x0c: /* BASSM */ goto unimplemented;
13956 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13957 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013958 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13959 goto ok;
13960 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13961 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013962 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13963 goto ok;
13964 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13965 goto ok;
13966 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13967 goto ok;
13968 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13969 goto ok;
13970 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13971 goto ok;
13972 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13973 goto ok;
13974 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13975 goto ok;
13976 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13977 goto ok;
13978 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13979 goto ok;
13980 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13981 goto ok;
13982 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13983 goto ok;
13984 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13985 goto ok;
13986 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13987 goto ok;
13988 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13989 goto ok;
13990 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13991 goto ok;
13992 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13993 goto ok;
13994 case 0x20: /* LPDR */ goto unimplemented;
13995 case 0x21: /* LNDR */ goto unimplemented;
13996 case 0x22: /* LTDR */ goto unimplemented;
13997 case 0x23: /* LCDR */ goto unimplemented;
13998 case 0x24: /* HDR */ goto unimplemented;
13999 case 0x25: /* LDXR */ goto unimplemented;
14000 case 0x26: /* MXR */ goto unimplemented;
14001 case 0x27: /* MXDR */ goto unimplemented;
14002 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14003 goto ok;
14004 case 0x29: /* CDR */ goto unimplemented;
14005 case 0x2a: /* ADR */ goto unimplemented;
14006 case 0x2b: /* SDR */ goto unimplemented;
14007 case 0x2c: /* MDR */ goto unimplemented;
14008 case 0x2d: /* DDR */ goto unimplemented;
14009 case 0x2e: /* AWR */ goto unimplemented;
14010 case 0x2f: /* SWR */ goto unimplemented;
14011 case 0x30: /* LPER */ goto unimplemented;
14012 case 0x31: /* LNER */ goto unimplemented;
14013 case 0x32: /* LTER */ goto unimplemented;
14014 case 0x33: /* LCER */ goto unimplemented;
14015 case 0x34: /* HER */ goto unimplemented;
14016 case 0x35: /* LEDR */ goto unimplemented;
14017 case 0x36: /* AXR */ goto unimplemented;
14018 case 0x37: /* SXR */ goto unimplemented;
14019 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14020 goto ok;
14021 case 0x39: /* CER */ goto unimplemented;
14022 case 0x3a: /* AER */ goto unimplemented;
14023 case 0x3b: /* SER */ goto unimplemented;
14024 case 0x3c: /* MDER */ goto unimplemented;
14025 case 0x3d: /* DER */ goto unimplemented;
14026 case 0x3e: /* AUR */ goto unimplemented;
14027 case 0x3f: /* SUR */ goto unimplemented;
14028 }
14029
14030 return S390_DECODE_UNKNOWN_INSN;
14031
14032ok:
14033 return S390_DECODE_OK;
14034
14035unimplemented:
14036 return S390_DECODE_UNIMPLEMENTED_INSN;
14037}
14038
14039static s390_decode_t
14040s390_decode_4byte_and_irgen(UChar *bytes)
14041{
14042 typedef union {
14043 struct {
14044 unsigned int op1 : 8;
14045 unsigned int r1 : 4;
14046 unsigned int op2 : 4;
14047 unsigned int i2 : 16;
14048 } RI;
14049 struct {
14050 unsigned int op : 16;
14051 unsigned int : 8;
14052 unsigned int r1 : 4;
14053 unsigned int r2 : 4;
14054 } RRE;
14055 struct {
14056 unsigned int op : 16;
14057 unsigned int r1 : 4;
14058 unsigned int : 4;
14059 unsigned int r3 : 4;
14060 unsigned int r2 : 4;
14061 } RRF;
14062 struct {
14063 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000014064 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000014065 unsigned int m4 : 4;
14066 unsigned int r1 : 4;
14067 unsigned int r2 : 4;
14068 } RRF2;
14069 struct {
14070 unsigned int op : 16;
14071 unsigned int r3 : 4;
14072 unsigned int : 4;
14073 unsigned int r1 : 4;
14074 unsigned int r2 : 4;
14075 } RRF3;
14076 struct {
14077 unsigned int op : 16;
14078 unsigned int r3 : 4;
14079 unsigned int : 4;
14080 unsigned int r1 : 4;
14081 unsigned int r2 : 4;
14082 } RRR;
14083 struct {
14084 unsigned int op : 16;
14085 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000014086 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000014087 unsigned int r1 : 4;
14088 unsigned int r2 : 4;
14089 } RRF4;
14090 struct {
floriane38f6412012-12-21 17:32:12 +000014091 unsigned int op : 16;
14092 unsigned int : 4;
14093 unsigned int m4 : 4;
14094 unsigned int r1 : 4;
14095 unsigned int r2 : 4;
14096 } RRF5;
14097 struct {
sewardj2019a972011-03-07 16:04:07 +000014098 unsigned int op : 8;
14099 unsigned int r1 : 4;
14100 unsigned int r3 : 4;
14101 unsigned int b2 : 4;
14102 unsigned int d2 : 12;
14103 } RS;
14104 struct {
14105 unsigned int op : 8;
14106 unsigned int r1 : 4;
14107 unsigned int r3 : 4;
14108 unsigned int i2 : 16;
14109 } RSI;
14110 struct {
14111 unsigned int op : 8;
14112 unsigned int r1 : 4;
14113 unsigned int x2 : 4;
14114 unsigned int b2 : 4;
14115 unsigned int d2 : 12;
14116 } RX;
14117 struct {
14118 unsigned int op : 16;
14119 unsigned int b2 : 4;
14120 unsigned int d2 : 12;
14121 } S;
14122 struct {
14123 unsigned int op : 8;
14124 unsigned int i2 : 8;
14125 unsigned int b1 : 4;
14126 unsigned int d1 : 12;
14127 } SI;
14128 } formats;
14129 union {
14130 formats fmt;
14131 UInt value;
14132 } ovl;
14133
14134 vassert(sizeof(formats) == 4);
14135
florianffbd84d2012-12-09 02:06:29 +000014136 ((UChar *)(&ovl.value))[0] = bytes[0];
14137 ((UChar *)(&ovl.value))[1] = bytes[1];
14138 ((UChar *)(&ovl.value))[2] = bytes[2];
14139 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000014140
14141 switch ((ovl.value & 0xff0f0000) >> 16) {
14142 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14143 ovl.fmt.RI.i2); goto ok;
14144 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14145 ovl.fmt.RI.i2); goto ok;
14146 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14147 ovl.fmt.RI.i2); goto ok;
14148 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14149 ovl.fmt.RI.i2); goto ok;
14150 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14151 ovl.fmt.RI.i2); goto ok;
14152 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14153 ovl.fmt.RI.i2); goto ok;
14154 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14155 ovl.fmt.RI.i2); goto ok;
14156 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14157 ovl.fmt.RI.i2); goto ok;
14158 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14159 ovl.fmt.RI.i2); goto ok;
14160 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14161 ovl.fmt.RI.i2); goto ok;
14162 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14163 ovl.fmt.RI.i2); goto ok;
14164 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14165 ovl.fmt.RI.i2); goto ok;
14166 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14167 ovl.fmt.RI.i2); goto ok;
14168 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14169 ovl.fmt.RI.i2); goto ok;
14170 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14171 ovl.fmt.RI.i2); goto ok;
14172 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14173 ovl.fmt.RI.i2); goto ok;
14174 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14175 ovl.fmt.RI.i2); goto ok;
14176 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14177 ovl.fmt.RI.i2); goto ok;
14178 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14179 ovl.fmt.RI.i2); goto ok;
14180 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14181 ovl.fmt.RI.i2); goto ok;
14182 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14183 goto ok;
14184 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14185 ovl.fmt.RI.i2); goto ok;
14186 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14187 ovl.fmt.RI.i2); goto ok;
14188 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14189 ovl.fmt.RI.i2); goto ok;
14190 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14191 goto ok;
14192 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14193 ovl.fmt.RI.i2); goto ok;
14194 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14195 goto ok;
14196 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14197 ovl.fmt.RI.i2); goto ok;
14198 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14199 goto ok;
14200 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14201 ovl.fmt.RI.i2); goto ok;
14202 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14203 goto ok;
14204 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14205 ovl.fmt.RI.i2); goto ok;
14206 }
14207
14208 switch ((ovl.value & 0xffff0000) >> 16) {
14209 case 0x8000: /* SSM */ goto unimplemented;
14210 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014211 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014212 case 0xb202: /* STIDP */ goto unimplemented;
14213 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014214 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14215 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014216 case 0xb206: /* SCKC */ goto unimplemented;
14217 case 0xb207: /* STCKC */ goto unimplemented;
14218 case 0xb208: /* SPT */ goto unimplemented;
14219 case 0xb209: /* STPT */ goto unimplemented;
14220 case 0xb20a: /* SPKA */ goto unimplemented;
14221 case 0xb20b: /* IPK */ goto unimplemented;
14222 case 0xb20d: /* PTLB */ goto unimplemented;
14223 case 0xb210: /* SPX */ goto unimplemented;
14224 case 0xb211: /* STPX */ goto unimplemented;
14225 case 0xb212: /* STAP */ goto unimplemented;
14226 case 0xb214: /* SIE */ goto unimplemented;
14227 case 0xb218: /* PC */ goto unimplemented;
14228 case 0xb219: /* SAC */ goto unimplemented;
14229 case 0xb21a: /* CFC */ goto unimplemented;
14230 case 0xb221: /* IPTE */ goto unimplemented;
14231 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
14232 case 0xb223: /* IVSK */ goto unimplemented;
14233 case 0xb224: /* IAC */ goto unimplemented;
14234 case 0xb225: /* SSAR */ goto unimplemented;
14235 case 0xb226: /* EPAR */ goto unimplemented;
14236 case 0xb227: /* ESAR */ goto unimplemented;
14237 case 0xb228: /* PT */ goto unimplemented;
14238 case 0xb229: /* ISKE */ goto unimplemented;
14239 case 0xb22a: /* RRBE */ goto unimplemented;
14240 case 0xb22b: /* SSKE */ goto unimplemented;
14241 case 0xb22c: /* TB */ goto unimplemented;
14242 case 0xb22d: /* DXR */ goto unimplemented;
14243 case 0xb22e: /* PGIN */ goto unimplemented;
14244 case 0xb22f: /* PGOUT */ goto unimplemented;
14245 case 0xb230: /* CSCH */ goto unimplemented;
14246 case 0xb231: /* HSCH */ goto unimplemented;
14247 case 0xb232: /* MSCH */ goto unimplemented;
14248 case 0xb233: /* SSCH */ goto unimplemented;
14249 case 0xb234: /* STSCH */ goto unimplemented;
14250 case 0xb235: /* TSCH */ goto unimplemented;
14251 case 0xb236: /* TPI */ goto unimplemented;
14252 case 0xb237: /* SAL */ goto unimplemented;
14253 case 0xb238: /* RSCH */ goto unimplemented;
14254 case 0xb239: /* STCRW */ goto unimplemented;
14255 case 0xb23a: /* STCPS */ goto unimplemented;
14256 case 0xb23b: /* RCHP */ goto unimplemented;
14257 case 0xb23c: /* SCHM */ goto unimplemented;
14258 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000014259 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14260 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014261 case 0xb244: /* SQDR */ goto unimplemented;
14262 case 0xb245: /* SQER */ goto unimplemented;
14263 case 0xb246: /* STURA */ goto unimplemented;
14264 case 0xb247: /* MSTA */ goto unimplemented;
14265 case 0xb248: /* PALB */ goto unimplemented;
14266 case 0xb249: /* EREG */ goto unimplemented;
14267 case 0xb24a: /* ESTA */ goto unimplemented;
14268 case 0xb24b: /* LURA */ goto unimplemented;
14269 case 0xb24c: /* TAR */ goto unimplemented;
14270 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14271 ovl.fmt.RRE.r2); goto ok;
14272 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14273 goto ok;
14274 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14275 goto ok;
14276 case 0xb250: /* CSP */ goto unimplemented;
14277 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14278 ovl.fmt.RRE.r2); goto ok;
14279 case 0xb254: /* MVPG */ goto unimplemented;
14280 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14281 ovl.fmt.RRE.r2); goto ok;
14282 case 0xb257: /* CUSE */ goto unimplemented;
14283 case 0xb258: /* BSG */ goto unimplemented;
14284 case 0xb25a: /* BSA */ goto unimplemented;
14285 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14286 ovl.fmt.RRE.r2); goto ok;
14287 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14288 ovl.fmt.RRE.r2); goto ok;
14289 case 0xb263: /* CMPSC */ goto unimplemented;
14290 case 0xb274: /* SIGA */ goto unimplemented;
14291 case 0xb276: /* XSCH */ goto unimplemented;
14292 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014293 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 +000014294 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014295 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 +000014296 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014297 case 0xb280: /* LPP */ goto unimplemented;
14298 case 0xb284: /* LCCTL */ goto unimplemented;
14299 case 0xb285: /* LPCTL */ goto unimplemented;
14300 case 0xb286: /* QSI */ goto unimplemented;
14301 case 0xb287: /* LSCTL */ goto unimplemented;
14302 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014303 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14304 goto ok;
14305 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14306 goto ok;
14307 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14308 goto ok;
florian730448f2012-02-04 17:07:07 +000014309 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 +000014310 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14311 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14312 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000014313 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14314 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14315 goto ok;
florian933065d2011-07-11 01:48:02 +000014316 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14317 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014318 case 0xb2b1: /* STFL */ goto unimplemented;
14319 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000014320 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14321 goto ok;
florian82cdba62013-03-12 01:31:24 +000014322 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14323 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014324 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014325 case 0xb2e0: /* SCCTR */ goto unimplemented;
14326 case 0xb2e1: /* SPCTR */ goto unimplemented;
14327 case 0xb2e4: /* ECCTR */ goto unimplemented;
14328 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014329 case 0xb2e8: /* PPA */ goto unimplemented;
14330 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014331 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014332 case 0xb2f8: /* TEND */ goto unimplemented;
14333 case 0xb2fa: /* NIAI */ goto unimplemented;
14334 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014335 case 0xb2ff: /* TRAP4 */ goto unimplemented;
14336 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14337 ovl.fmt.RRE.r2); goto ok;
14338 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14339 ovl.fmt.RRE.r2); goto ok;
14340 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14341 ovl.fmt.RRE.r2); goto ok;
14342 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14343 ovl.fmt.RRE.r2); goto ok;
14344 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14345 ovl.fmt.RRE.r2); goto ok;
14346 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14347 ovl.fmt.RRE.r2); goto ok;
14348 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14349 ovl.fmt.RRE.r2); goto ok;
14350 case 0xb307: /* MXDBR */ goto unimplemented;
14351 case 0xb308: /* KEBR */ goto unimplemented;
14352 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14353 ovl.fmt.RRE.r2); goto ok;
14354 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14355 ovl.fmt.RRE.r2); goto ok;
14356 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14357 ovl.fmt.RRE.r2); goto ok;
14358 case 0xb30c: /* MDEBR */ goto unimplemented;
14359 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14360 ovl.fmt.RRE.r2); goto ok;
14361 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14362 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14363 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14364 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14365 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14366 ovl.fmt.RRE.r2); goto ok;
14367 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14368 ovl.fmt.RRE.r2); goto ok;
14369 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14370 ovl.fmt.RRE.r2); goto ok;
14371 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14372 ovl.fmt.RRE.r2); goto ok;
14373 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14374 ovl.fmt.RRE.r2); goto ok;
14375 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14376 ovl.fmt.RRE.r2); goto ok;
14377 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14378 ovl.fmt.RRE.r2); goto ok;
14379 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14380 ovl.fmt.RRE.r2); goto ok;
14381 case 0xb318: /* KDBR */ goto unimplemented;
14382 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14383 ovl.fmt.RRE.r2); goto ok;
14384 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14385 ovl.fmt.RRE.r2); goto ok;
14386 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14387 ovl.fmt.RRE.r2); goto ok;
14388 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14389 ovl.fmt.RRE.r2); goto ok;
14390 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14391 ovl.fmt.RRE.r2); goto ok;
14392 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14393 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14394 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14395 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14396 case 0xb324: /* LDER */ goto unimplemented;
14397 case 0xb325: /* LXDR */ goto unimplemented;
14398 case 0xb326: /* LXER */ goto unimplemented;
14399 case 0xb32e: /* MAER */ goto unimplemented;
14400 case 0xb32f: /* MSER */ goto unimplemented;
14401 case 0xb336: /* SQXR */ goto unimplemented;
14402 case 0xb337: /* MEER */ goto unimplemented;
14403 case 0xb338: /* MAYLR */ goto unimplemented;
14404 case 0xb339: /* MYLR */ goto unimplemented;
14405 case 0xb33a: /* MAYR */ goto unimplemented;
14406 case 0xb33b: /* MYR */ goto unimplemented;
14407 case 0xb33c: /* MAYHR */ goto unimplemented;
14408 case 0xb33d: /* MYHR */ goto unimplemented;
14409 case 0xb33e: /* MADR */ goto unimplemented;
14410 case 0xb33f: /* MSDR */ goto unimplemented;
14411 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14412 ovl.fmt.RRE.r2); goto ok;
14413 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14414 ovl.fmt.RRE.r2); goto ok;
14415 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14416 ovl.fmt.RRE.r2); goto ok;
14417 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14418 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014419 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14420 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14421 ovl.fmt.RRF2.r2); goto ok;
14422 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14423 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14424 ovl.fmt.RRF2.r2); goto ok;
14425 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14426 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14427 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014428 case 0xb347: /* FIXBR */ goto unimplemented;
14429 case 0xb348: /* KXBR */ goto unimplemented;
14430 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14431 ovl.fmt.RRE.r2); goto ok;
14432 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14433 ovl.fmt.RRE.r2); goto ok;
14434 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14435 ovl.fmt.RRE.r2); goto ok;
14436 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14437 ovl.fmt.RRE.r2); goto ok;
14438 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14439 ovl.fmt.RRE.r2); goto ok;
14440 case 0xb350: /* TBEDR */ goto unimplemented;
14441 case 0xb351: /* TBDR */ goto unimplemented;
14442 case 0xb353: /* DIEBR */ goto unimplemented;
14443 case 0xb357: /* FIEBR */ goto unimplemented;
14444 case 0xb358: /* THDER */ goto unimplemented;
14445 case 0xb359: /* THDR */ goto unimplemented;
14446 case 0xb35b: /* DIDBR */ goto unimplemented;
14447 case 0xb35f: /* FIDBR */ goto unimplemented;
14448 case 0xb360: /* LPXR */ goto unimplemented;
14449 case 0xb361: /* LNXR */ goto unimplemented;
14450 case 0xb362: /* LTXR */ goto unimplemented;
14451 case 0xb363: /* LCXR */ goto unimplemented;
14452 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14453 ovl.fmt.RRE.r2); goto ok;
14454 case 0xb366: /* LEXR */ goto unimplemented;
14455 case 0xb367: /* FIXR */ goto unimplemented;
14456 case 0xb369: /* CXR */ goto unimplemented;
14457 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14458 ovl.fmt.RRE.r2); goto ok;
14459 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14460 ovl.fmt.RRE.r2); goto ok;
14461 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14462 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14463 goto ok;
14464 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14465 ovl.fmt.RRE.r2); goto ok;
14466 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14467 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14468 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14469 case 0xb377: /* FIER */ goto unimplemented;
14470 case 0xb37f: /* FIDR */ goto unimplemented;
14471 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14472 case 0xb385: /* SFASR */ goto unimplemented;
14473 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014474 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14475 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14476 ovl.fmt.RRF2.r2); goto ok;
14477 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14478 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14479 ovl.fmt.RRF2.r2); goto ok;
14480 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14481 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14482 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014483 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14484 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14485 ovl.fmt.RRF2.r2); goto ok;
14486 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14487 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14488 ovl.fmt.RRF2.r2); goto ok;
14489 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14490 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14491 ovl.fmt.RRF2.r2); goto ok;
14492 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14493 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14494 ovl.fmt.RRF2.r2); goto ok;
14495 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14496 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14497 ovl.fmt.RRF2.r2); goto ok;
14498 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14499 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14500 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014501 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14502 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14503 ovl.fmt.RRF2.r2); goto ok;
14504 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14505 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14506 ovl.fmt.RRF2.r2); goto ok;
14507 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14508 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14509 ovl.fmt.RRF2.r2); goto ok;
14510 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14511 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14512 ovl.fmt.RRF2.r2); goto ok;
14513 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14514 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14515 ovl.fmt.RRF2.r2); goto ok;
14516 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14517 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14518 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014519 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14520 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14521 ovl.fmt.RRF2.r2); goto ok;
14522 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14523 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14524 ovl.fmt.RRF2.r2); goto ok;
14525 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14526 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14527 ovl.fmt.RRF2.r2); goto ok;
14528 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14529 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14530 ovl.fmt.RRF2.r2); goto ok;
14531 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14532 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14533 ovl.fmt.RRF2.r2); goto ok;
14534 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14535 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14536 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014537 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14538 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14539 ovl.fmt.RRF2.r2); goto ok;
14540 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14541 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14542 ovl.fmt.RRF2.r2); goto ok;
14543 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14544 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14545 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014546 case 0xb3b4: /* CEFR */ goto unimplemented;
14547 case 0xb3b5: /* CDFR */ goto unimplemented;
14548 case 0xb3b6: /* CXFR */ goto unimplemented;
14549 case 0xb3b8: /* CFER */ goto unimplemented;
14550 case 0xb3b9: /* CFDR */ goto unimplemented;
14551 case 0xb3ba: /* CFXR */ goto unimplemented;
14552 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14553 ovl.fmt.RRE.r2); goto ok;
14554 case 0xb3c4: /* CEGR */ goto unimplemented;
14555 case 0xb3c5: /* CDGR */ goto unimplemented;
14556 case 0xb3c6: /* CXGR */ goto unimplemented;
14557 case 0xb3c8: /* CGER */ goto unimplemented;
14558 case 0xb3c9: /* CGDR */ goto unimplemented;
14559 case 0xb3ca: /* CGXR */ goto unimplemented;
14560 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14561 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014562 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14563 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14564 ovl.fmt.RRF4.r2); goto ok;
14565 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14566 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14567 ovl.fmt.RRF4.r2); goto ok;
14568 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14569 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14570 ovl.fmt.RRF4.r2); goto ok;
14571 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14572 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14573 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014574 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14575 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14576 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14577 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14578 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014579 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14580 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014581 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014582 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14583 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14584 ovl.fmt.RRF4.r2); goto ok;
14585 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14586 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14587 ovl.fmt.RRF4.r2); goto ok;
14588 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14589 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14590 ovl.fmt.RRF4.r2); goto ok;
14591 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14592 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14593 ovl.fmt.RRF4.r2); goto ok;
14594 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14595 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14596 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14597 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14598 ovl.fmt.RRF2.r2); goto ok;
14599 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14600 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014601 case 0xb3df: /* FIXTR */ goto unimplemented;
14602 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014603 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14604 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14605 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014606 case 0xb3e2: /* CUDTR */ goto unimplemented;
14607 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014608 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14609 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014610 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14611 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014612 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14613 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014614 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014615 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14616 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14617 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014618 case 0xb3ea: /* CUXTR */ goto unimplemented;
14619 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014620 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14621 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014622 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14623 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014624 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14625 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014626 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14627 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14628 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014629 case 0xb3f2: /* CDUTR */ goto unimplemented;
14630 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014631 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14632 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014633 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14634 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14635 ovl.fmt.RRF4.r2); goto ok;
14636 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14637 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14638 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14639 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14640 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014641 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14642 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14643 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014644 case 0xb3fa: /* CXUTR */ goto unimplemented;
14645 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014646 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14647 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014648 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14649 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14650 ovl.fmt.RRF4.r2); goto ok;
14651 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14652 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14653 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14654 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14655 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014656 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14657 ovl.fmt.RRE.r2); goto ok;
14658 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14659 ovl.fmt.RRE.r2); goto ok;
14660 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14661 ovl.fmt.RRE.r2); goto ok;
14662 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14663 ovl.fmt.RRE.r2); goto ok;
14664 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14665 ovl.fmt.RRE.r2); goto ok;
14666 case 0xb905: /* LURAG */ goto unimplemented;
14667 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14668 ovl.fmt.RRE.r2); goto ok;
14669 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14670 ovl.fmt.RRE.r2); goto ok;
14671 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14672 ovl.fmt.RRE.r2); goto ok;
14673 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14674 ovl.fmt.RRE.r2); goto ok;
14675 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14676 ovl.fmt.RRE.r2); goto ok;
14677 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14678 ovl.fmt.RRE.r2); goto ok;
14679 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14680 ovl.fmt.RRE.r2); goto ok;
14681 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14682 ovl.fmt.RRE.r2); goto ok;
14683 case 0xb90e: /* EREGG */ goto unimplemented;
14684 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14685 ovl.fmt.RRE.r2); goto ok;
14686 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14687 ovl.fmt.RRE.r2); goto ok;
14688 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14689 ovl.fmt.RRE.r2); goto ok;
14690 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14691 ovl.fmt.RRE.r2); goto ok;
14692 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14693 ovl.fmt.RRE.r2); goto ok;
14694 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14695 ovl.fmt.RRE.r2); goto ok;
14696 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14697 ovl.fmt.RRE.r2); goto ok;
14698 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14699 ovl.fmt.RRE.r2); goto ok;
14700 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14701 ovl.fmt.RRE.r2); goto ok;
14702 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14703 ovl.fmt.RRE.r2); goto ok;
14704 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14705 ovl.fmt.RRE.r2); goto ok;
14706 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14707 ovl.fmt.RRE.r2); goto ok;
14708 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14709 ovl.fmt.RRE.r2); goto ok;
14710 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14711 ovl.fmt.RRE.r2); goto ok;
14712 case 0xb91e: /* KMAC */ goto unimplemented;
14713 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14714 ovl.fmt.RRE.r2); goto ok;
14715 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14716 ovl.fmt.RRE.r2); goto ok;
14717 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14718 ovl.fmt.RRE.r2); goto ok;
14719 case 0xb925: /* STURG */ goto unimplemented;
14720 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14721 ovl.fmt.RRE.r2); goto ok;
14722 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14723 ovl.fmt.RRE.r2); goto ok;
14724 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014725 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014726 case 0xb92b: /* KMO */ goto unimplemented;
14727 case 0xb92c: /* PCC */ goto unimplemented;
14728 case 0xb92d: /* KMCTR */ goto unimplemented;
14729 case 0xb92e: /* KM */ goto unimplemented;
14730 case 0xb92f: /* KMC */ goto unimplemented;
14731 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14732 ovl.fmt.RRE.r2); goto ok;
14733 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14734 ovl.fmt.RRE.r2); goto ok;
14735 case 0xb93e: /* KIMD */ goto unimplemented;
14736 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014737 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14738 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14739 ovl.fmt.RRF2.r2); goto ok;
14740 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14741 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14742 ovl.fmt.RRF2.r2); goto ok;
14743 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14744 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14745 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014746 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14747 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014748 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14749 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14750 ovl.fmt.RRF2.r2); goto ok;
14751 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14752 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14753 ovl.fmt.RRF2.r2); goto ok;
14754 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14755 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14756 ovl.fmt.RRF2.r2); goto ok;
14757 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14758 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14759 ovl.fmt.RRF2.r2); goto ok;
14760 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14761 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14762 ovl.fmt.RRF2.r2); goto ok;
14763 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14764 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14765 ovl.fmt.RRF2.r2); goto ok;
14766 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14767 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14768 ovl.fmt.RRF2.r2); goto ok;
14769 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14770 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14771 ovl.fmt.RRF2.r2); goto ok;
14772 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14773 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14774 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014775 case 0xb960: /* CGRT */ goto unimplemented;
14776 case 0xb961: /* CLGRT */ goto unimplemented;
14777 case 0xb972: /* CRT */ goto unimplemented;
14778 case 0xb973: /* CLRT */ goto unimplemented;
14779 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14780 ovl.fmt.RRE.r2); goto ok;
14781 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14782 ovl.fmt.RRE.r2); goto ok;
14783 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14784 ovl.fmt.RRE.r2); goto ok;
14785 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14786 ovl.fmt.RRE.r2); goto ok;
14787 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14788 ovl.fmt.RRE.r2); goto ok;
14789 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14790 ovl.fmt.RRE.r2); goto ok;
14791 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14792 ovl.fmt.RRE.r2); goto ok;
14793 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14794 ovl.fmt.RRE.r2); goto ok;
14795 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14796 ovl.fmt.RRE.r2); goto ok;
14797 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14798 ovl.fmt.RRE.r2); goto ok;
14799 case 0xb98a: /* CSPG */ goto unimplemented;
14800 case 0xb98d: /* EPSW */ goto unimplemented;
14801 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014802 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014803 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14804 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14805 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14806 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14807 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14808 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014809 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14810 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014811 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14812 ovl.fmt.RRE.r2); goto ok;
14813 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14814 ovl.fmt.RRE.r2); goto ok;
14815 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14816 ovl.fmt.RRE.r2); goto ok;
14817 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14818 ovl.fmt.RRE.r2); goto ok;
14819 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14820 ovl.fmt.RRE.r2); goto ok;
14821 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14822 ovl.fmt.RRE.r2); goto ok;
14823 case 0xb99a: /* EPAIR */ goto unimplemented;
14824 case 0xb99b: /* ESAIR */ goto unimplemented;
14825 case 0xb99d: /* ESEA */ goto unimplemented;
14826 case 0xb99e: /* PTI */ goto unimplemented;
14827 case 0xb99f: /* SSAIR */ goto unimplemented;
14828 case 0xb9a2: /* PTF */ goto unimplemented;
14829 case 0xb9aa: /* LPTEA */ goto unimplemented;
14830 case 0xb9ae: /* RRBM */ goto unimplemented;
14831 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014832 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14833 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14834 goto ok;
florian2a415a12012-07-21 17:41:36 +000014835 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14836 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14837 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014838 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14839 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014840 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14841 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014842 case 0xb9bd: /* TRTRE */ goto unimplemented;
14843 case 0xb9be: /* SRSTU */ goto unimplemented;
14844 case 0xb9bf: /* TRTE */ goto unimplemented;
14845 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14846 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14847 goto ok;
14848 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14849 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14850 goto ok;
14851 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14852 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14853 goto ok;
14854 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14855 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14856 goto ok;
14857 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14858 ovl.fmt.RRE.r2); goto ok;
14859 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14860 ovl.fmt.RRE.r2); goto ok;
14861 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14862 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14863 goto ok;
14864 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14865 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14866 goto ok;
14867 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14868 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14869 goto ok;
14870 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14871 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14872 goto ok;
14873 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14874 ovl.fmt.RRE.r2); goto ok;
14875 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14876 ovl.fmt.RRE.r2); goto ok;
14877 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014878 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14879 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14880 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014881 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14882 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14883 goto ok;
14884 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14885 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14886 goto ok;
14887 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14888 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14889 goto ok;
14890 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14891 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14892 goto ok;
14893 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14894 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14895 goto ok;
14896 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14897 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14898 goto ok;
14899 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14900 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14901 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014902 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14903 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14904 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014905 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14906 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14907 goto ok;
14908 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14909 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14910 goto ok;
14911 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14912 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14913 goto ok;
14914 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14915 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14916 goto ok;
14917 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14918 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14919 goto ok;
14920 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14921 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14922 goto ok;
14923 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14924 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14925 goto ok;
14926 }
14927
14928 switch ((ovl.value & 0xff000000) >> 24) {
14929 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14930 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14931 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14932 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14933 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14934 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14935 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14936 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14937 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14938 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14939 case 0x45: /* BAL */ goto unimplemented;
14940 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14941 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14942 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14943 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14944 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14945 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14946 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14947 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14948 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14949 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14950 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14951 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14952 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14953 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14954 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14955 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14956 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14957 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14958 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14959 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14960 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14961 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14962 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14963 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14964 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14965 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14966 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14967 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14968 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14969 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14970 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14971 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14972 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14973 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14974 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14975 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14976 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14977 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14978 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14979 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14980 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14981 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14982 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14983 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14984 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14985 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14986 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14987 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14988 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14989 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14990 case 0x67: /* MXD */ goto unimplemented;
14991 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14992 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14993 case 0x69: /* CD */ goto unimplemented;
14994 case 0x6a: /* AD */ goto unimplemented;
14995 case 0x6b: /* SD */ goto unimplemented;
14996 case 0x6c: /* MD */ goto unimplemented;
14997 case 0x6d: /* DD */ goto unimplemented;
14998 case 0x6e: /* AW */ goto unimplemented;
14999 case 0x6f: /* SW */ goto unimplemented;
15000 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15001 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15002 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15003 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15004 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
15005 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
15006 case 0x79: /* CE */ goto unimplemented;
15007 case 0x7a: /* AE */ goto unimplemented;
15008 case 0x7b: /* SE */ goto unimplemented;
15009 case 0x7c: /* MDE */ goto unimplemented;
15010 case 0x7d: /* DE */ goto unimplemented;
15011 case 0x7e: /* AU */ goto unimplemented;
15012 case 0x7f: /* SU */ goto unimplemented;
15013 case 0x83: /* DIAG */ goto unimplemented;
15014 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15015 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15016 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15017 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15018 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15019 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15020 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15021 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15022 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15023 ovl.fmt.RS.d2); goto ok;
15024 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15025 ovl.fmt.RS.d2); goto ok;
15026 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15027 ovl.fmt.RS.d2); goto ok;
15028 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15029 ovl.fmt.RS.d2); goto ok;
15030 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15031 ovl.fmt.RS.d2); goto ok;
15032 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15033 ovl.fmt.RS.d2); goto ok;
15034 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15035 ovl.fmt.RS.d2); goto ok;
15036 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15037 ovl.fmt.RS.d2); goto ok;
15038 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15039 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15040 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15041 ovl.fmt.SI.d1); goto ok;
15042 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15043 ovl.fmt.SI.d1); goto ok;
15044 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15045 ovl.fmt.SI.d1); goto ok;
15046 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15047 ovl.fmt.SI.d1); goto ok;
15048 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15049 ovl.fmt.SI.d1); goto ok;
15050 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15051 ovl.fmt.SI.d1); goto ok;
15052 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15053 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15054 case 0x99: /* TRACE */ goto unimplemented;
15055 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15056 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15057 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15058 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15059 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15060 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15061 goto ok;
15062 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15063 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15064 goto ok;
15065 case 0xac: /* STNSM */ goto unimplemented;
15066 case 0xad: /* STOSM */ goto unimplemented;
15067 case 0xae: /* SIGP */ goto unimplemented;
15068 case 0xaf: /* MC */ goto unimplemented;
15069 case 0xb1: /* LRA */ goto unimplemented;
15070 case 0xb6: /* STCTL */ goto unimplemented;
15071 case 0xb7: /* LCTL */ goto unimplemented;
15072 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15073 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015074 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15075 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015076 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15077 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15078 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15079 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15080 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15081 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15082 }
15083
15084 return S390_DECODE_UNKNOWN_INSN;
15085
15086ok:
15087 return S390_DECODE_OK;
15088
15089unimplemented:
15090 return S390_DECODE_UNIMPLEMENTED_INSN;
15091}
15092
15093static s390_decode_t
15094s390_decode_6byte_and_irgen(UChar *bytes)
15095{
15096 typedef union {
15097 struct {
15098 unsigned int op1 : 8;
15099 unsigned int r1 : 4;
15100 unsigned int r3 : 4;
15101 unsigned int i2 : 16;
15102 unsigned int : 8;
15103 unsigned int op2 : 8;
15104 } RIE;
15105 struct {
15106 unsigned int op1 : 8;
15107 unsigned int r1 : 4;
15108 unsigned int r2 : 4;
15109 unsigned int i3 : 8;
15110 unsigned int i4 : 8;
15111 unsigned int i5 : 8;
15112 unsigned int op2 : 8;
15113 } RIE_RRUUU;
15114 struct {
15115 unsigned int op1 : 8;
15116 unsigned int r1 : 4;
15117 unsigned int : 4;
15118 unsigned int i2 : 16;
15119 unsigned int m3 : 4;
15120 unsigned int : 4;
15121 unsigned int op2 : 8;
15122 } RIEv1;
15123 struct {
15124 unsigned int op1 : 8;
15125 unsigned int r1 : 4;
15126 unsigned int r2 : 4;
15127 unsigned int i4 : 16;
15128 unsigned int m3 : 4;
15129 unsigned int : 4;
15130 unsigned int op2 : 8;
15131 } RIE_RRPU;
15132 struct {
15133 unsigned int op1 : 8;
15134 unsigned int r1 : 4;
15135 unsigned int m3 : 4;
15136 unsigned int i4 : 16;
15137 unsigned int i2 : 8;
15138 unsigned int op2 : 8;
15139 } RIEv3;
15140 struct {
15141 unsigned int op1 : 8;
15142 unsigned int r1 : 4;
15143 unsigned int op2 : 4;
15144 unsigned int i2 : 32;
15145 } RIL;
15146 struct {
15147 unsigned int op1 : 8;
15148 unsigned int r1 : 4;
15149 unsigned int m3 : 4;
15150 unsigned int b4 : 4;
15151 unsigned int d4 : 12;
15152 unsigned int i2 : 8;
15153 unsigned int op2 : 8;
15154 } RIS;
15155 struct {
15156 unsigned int op1 : 8;
15157 unsigned int r1 : 4;
15158 unsigned int r2 : 4;
15159 unsigned int b4 : 4;
15160 unsigned int d4 : 12;
15161 unsigned int m3 : 4;
15162 unsigned int : 4;
15163 unsigned int op2 : 8;
15164 } RRS;
15165 struct {
15166 unsigned int op1 : 8;
15167 unsigned int l1 : 4;
15168 unsigned int : 4;
15169 unsigned int b1 : 4;
15170 unsigned int d1 : 12;
15171 unsigned int : 8;
15172 unsigned int op2 : 8;
15173 } RSL;
15174 struct {
15175 unsigned int op1 : 8;
15176 unsigned int r1 : 4;
15177 unsigned int r3 : 4;
15178 unsigned int b2 : 4;
15179 unsigned int dl2 : 12;
15180 unsigned int dh2 : 8;
15181 unsigned int op2 : 8;
15182 } RSY;
15183 struct {
15184 unsigned int op1 : 8;
15185 unsigned int r1 : 4;
15186 unsigned int x2 : 4;
15187 unsigned int b2 : 4;
15188 unsigned int d2 : 12;
15189 unsigned int : 8;
15190 unsigned int op2 : 8;
15191 } RXE;
15192 struct {
15193 unsigned int op1 : 8;
15194 unsigned int r3 : 4;
15195 unsigned int x2 : 4;
15196 unsigned int b2 : 4;
15197 unsigned int d2 : 12;
15198 unsigned int r1 : 4;
15199 unsigned int : 4;
15200 unsigned int op2 : 8;
15201 } RXF;
15202 struct {
15203 unsigned int op1 : 8;
15204 unsigned int r1 : 4;
15205 unsigned int x2 : 4;
15206 unsigned int b2 : 4;
15207 unsigned int dl2 : 12;
15208 unsigned int dh2 : 8;
15209 unsigned int op2 : 8;
15210 } RXY;
15211 struct {
15212 unsigned int op1 : 8;
15213 unsigned int i2 : 8;
15214 unsigned int b1 : 4;
15215 unsigned int dl1 : 12;
15216 unsigned int dh1 : 8;
15217 unsigned int op2 : 8;
15218 } SIY;
15219 struct {
15220 unsigned int op : 8;
15221 unsigned int l : 8;
15222 unsigned int b1 : 4;
15223 unsigned int d1 : 12;
15224 unsigned int b2 : 4;
15225 unsigned int d2 : 12;
15226 } SS;
15227 struct {
15228 unsigned int op : 8;
15229 unsigned int l1 : 4;
15230 unsigned int l2 : 4;
15231 unsigned int b1 : 4;
15232 unsigned int d1 : 12;
15233 unsigned int b2 : 4;
15234 unsigned int d2 : 12;
15235 } SS_LLRDRD;
15236 struct {
15237 unsigned int op : 8;
15238 unsigned int r1 : 4;
15239 unsigned int r3 : 4;
15240 unsigned int b2 : 4;
15241 unsigned int d2 : 12;
15242 unsigned int b4 : 4;
15243 unsigned int d4 : 12;
15244 } SS_RRRDRD2;
15245 struct {
15246 unsigned int op : 16;
15247 unsigned int b1 : 4;
15248 unsigned int d1 : 12;
15249 unsigned int b2 : 4;
15250 unsigned int d2 : 12;
15251 } SSE;
15252 struct {
15253 unsigned int op1 : 8;
15254 unsigned int r3 : 4;
15255 unsigned int op2 : 4;
15256 unsigned int b1 : 4;
15257 unsigned int d1 : 12;
15258 unsigned int b2 : 4;
15259 unsigned int d2 : 12;
15260 } SSF;
15261 struct {
15262 unsigned int op : 16;
15263 unsigned int b1 : 4;
15264 unsigned int d1 : 12;
15265 unsigned int i2 : 16;
15266 } SIL;
15267 } formats;
15268 union {
15269 formats fmt;
15270 ULong value;
15271 } ovl;
15272
15273 vassert(sizeof(formats) == 6);
15274
florianffbd84d2012-12-09 02:06:29 +000015275 ((UChar *)(&ovl.value))[0] = bytes[0];
15276 ((UChar *)(&ovl.value))[1] = bytes[1];
15277 ((UChar *)(&ovl.value))[2] = bytes[2];
15278 ((UChar *)(&ovl.value))[3] = bytes[3];
15279 ((UChar *)(&ovl.value))[4] = bytes[4];
15280 ((UChar *)(&ovl.value))[5] = bytes[5];
15281 ((UChar *)(&ovl.value))[6] = 0x0;
15282 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000015283
15284 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15285 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15286 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15287 ovl.fmt.RXY.dl2,
15288 ovl.fmt.RXY.dh2); goto ok;
15289 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15290 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15291 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15292 ovl.fmt.RXY.dl2,
15293 ovl.fmt.RXY.dh2); goto ok;
15294 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15295 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15296 ovl.fmt.RXY.dl2,
15297 ovl.fmt.RXY.dh2); goto ok;
15298 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15299 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15300 ovl.fmt.RXY.dl2,
15301 ovl.fmt.RXY.dh2); goto ok;
15302 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15303 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15304 ovl.fmt.RXY.dl2,
15305 ovl.fmt.RXY.dh2); goto ok;
15306 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15307 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15308 ovl.fmt.RXY.dl2,
15309 ovl.fmt.RXY.dh2); goto ok;
15310 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15311 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15312 ovl.fmt.RXY.dl2,
15313 ovl.fmt.RXY.dh2); goto ok;
15314 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15315 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15316 ovl.fmt.RXY.dl2,
15317 ovl.fmt.RXY.dh2); goto ok;
15318 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15319 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15320 ovl.fmt.RXY.dl2,
15321 ovl.fmt.RXY.dh2); goto ok;
15322 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15323 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15324 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15325 ovl.fmt.RXY.dl2,
15326 ovl.fmt.RXY.dh2); goto ok;
15327 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15328 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15329 ovl.fmt.RXY.dl2,
15330 ovl.fmt.RXY.dh2); goto ok;
15331 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15332 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15333 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15334 ovl.fmt.RXY.dl2,
15335 ovl.fmt.RXY.dh2); goto ok;
15336 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15337 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15338 ovl.fmt.RXY.dl2,
15339 ovl.fmt.RXY.dh2); goto ok;
15340 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15341 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15342 ovl.fmt.RXY.dl2,
15343 ovl.fmt.RXY.dh2); goto ok;
15344 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15345 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15346 ovl.fmt.RXY.dl2,
15347 ovl.fmt.RXY.dh2); goto ok;
15348 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15349 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15350 ovl.fmt.RXY.dl2,
15351 ovl.fmt.RXY.dh2); goto ok;
15352 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15353 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15354 ovl.fmt.RXY.dl2,
15355 ovl.fmt.RXY.dh2); goto ok;
15356 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15357 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15358 ovl.fmt.RXY.dl2,
15359 ovl.fmt.RXY.dh2); goto ok;
15360 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15361 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15362 ovl.fmt.RXY.dl2,
15363 ovl.fmt.RXY.dh2); goto ok;
15364 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15365 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15366 ovl.fmt.RXY.dl2,
15367 ovl.fmt.RXY.dh2); goto ok;
15368 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15369 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15370 ovl.fmt.RXY.dl2,
15371 ovl.fmt.RXY.dh2); goto ok;
15372 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15373 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15374 ovl.fmt.RXY.dl2,
15375 ovl.fmt.RXY.dh2); goto ok;
15376 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15377 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15378 ovl.fmt.RXY.dl2,
15379 ovl.fmt.RXY.dh2); goto ok;
15380 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15381 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15382 ovl.fmt.RXY.dl2,
15383 ovl.fmt.RXY.dh2); goto ok;
15384 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15385 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15386 ovl.fmt.RXY.dl2,
15387 ovl.fmt.RXY.dh2); goto ok;
15388 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15389 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15390 ovl.fmt.RXY.dl2,
15391 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015392 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015393 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15394 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15395 ovl.fmt.RXY.dl2,
15396 ovl.fmt.RXY.dh2); goto ok;
15397 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15398 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15399 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15400 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15401 ovl.fmt.RXY.dh2); goto ok;
15402 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15403 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15404 ovl.fmt.RXY.dl2,
15405 ovl.fmt.RXY.dh2); goto ok;
15406 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15407 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15408 ovl.fmt.RXY.dl2,
15409 ovl.fmt.RXY.dh2); goto ok;
15410 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15411 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15412 ovl.fmt.RXY.dl2,
15413 ovl.fmt.RXY.dh2); goto ok;
15414 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15415 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15416 ovl.fmt.RXY.dl2,
15417 ovl.fmt.RXY.dh2); goto ok;
15418 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15419 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15420 ovl.fmt.RXY.dl2,
15421 ovl.fmt.RXY.dh2); goto ok;
15422 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15423 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15424 ovl.fmt.RXY.dl2,
15425 ovl.fmt.RXY.dh2); goto ok;
15426 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15427 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15428 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15429 ovl.fmt.RXY.dh2); goto ok;
15430 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15431 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15432 ovl.fmt.RXY.dl2,
15433 ovl.fmt.RXY.dh2); goto ok;
15434 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15435 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15436 ovl.fmt.RXY.dl2,
15437 ovl.fmt.RXY.dh2); goto ok;
15438 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15439 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15440 ovl.fmt.RXY.dl2,
15441 ovl.fmt.RXY.dh2); goto ok;
15442 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15443 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15444 ovl.fmt.RXY.dl2,
15445 ovl.fmt.RXY.dh2); goto ok;
15446 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15447 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15448 ovl.fmt.RXY.dl2,
15449 ovl.fmt.RXY.dh2); goto ok;
15450 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15451 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15452 ovl.fmt.RXY.dl2,
15453 ovl.fmt.RXY.dh2); goto ok;
15454 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15455 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15456 ovl.fmt.RXY.dl2,
15457 ovl.fmt.RXY.dh2); goto ok;
15458 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15459 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15460 ovl.fmt.RXY.dl2,
15461 ovl.fmt.RXY.dh2); goto ok;
15462 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15463 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15464 ovl.fmt.RXY.dl2,
15465 ovl.fmt.RXY.dh2); goto ok;
15466 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15467 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15468 ovl.fmt.RXY.dl2,
15469 ovl.fmt.RXY.dh2); goto ok;
15470 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15471 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15472 ovl.fmt.RXY.dl2,
15473 ovl.fmt.RXY.dh2); goto ok;
15474 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15475 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15476 ovl.fmt.RXY.dl2,
15477 ovl.fmt.RXY.dh2); goto ok;
15478 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15479 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15480 ovl.fmt.RXY.dl2,
15481 ovl.fmt.RXY.dh2); goto ok;
15482 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, 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 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, 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 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, 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 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, 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 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, 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 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, 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 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15507 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15508 ovl.fmt.RXY.dl2,
15509 ovl.fmt.RXY.dh2); goto ok;
15510 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, 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 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, 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 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, 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 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, 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 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, 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 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, 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 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, 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 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, 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 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, 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;
florian2289cd42012-12-05 04:23:42 +000015546 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015547 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15548 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15549 ovl.fmt.RXY.dl2,
15550 ovl.fmt.RXY.dh2); goto ok;
15551 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15552 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15553 ovl.fmt.RXY.dl2,
15554 ovl.fmt.RXY.dh2); goto ok;
15555 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15556 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15557 ovl.fmt.RXY.dl2,
15558 ovl.fmt.RXY.dh2); goto ok;
15559 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15560 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15561 ovl.fmt.RXY.dl2,
15562 ovl.fmt.RXY.dh2); goto ok;
15563 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15564 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15565 ovl.fmt.RXY.dl2,
15566 ovl.fmt.RXY.dh2); goto ok;
15567 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15568 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15569 ovl.fmt.RXY.dl2,
15570 ovl.fmt.RXY.dh2); goto ok;
15571 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15572 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15573 ovl.fmt.RXY.dl2,
15574 ovl.fmt.RXY.dh2); goto ok;
15575 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15576 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15577 ovl.fmt.RXY.dl2,
15578 ovl.fmt.RXY.dh2); goto ok;
15579 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15580 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15581 ovl.fmt.RXY.dl2,
15582 ovl.fmt.RXY.dh2); goto ok;
15583 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15584 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15585 ovl.fmt.RXY.dl2,
15586 ovl.fmt.RXY.dh2); goto ok;
15587 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15588 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15589 ovl.fmt.RXY.dl2,
15590 ovl.fmt.RXY.dh2); goto ok;
15591 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15592 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15593 ovl.fmt.RXY.dl2,
15594 ovl.fmt.RXY.dh2); goto ok;
15595 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15596 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15597 ovl.fmt.RXY.dl2,
15598 ovl.fmt.RXY.dh2); goto ok;
15599 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15600 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15601 ovl.fmt.RXY.dl2,
15602 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015603 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15604 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15605 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015606 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, 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 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, 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 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, 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 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, 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 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, 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;
15626 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15627 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15628 ovl.fmt.RXY.dl2,
15629 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015630 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015631 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, 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 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, 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 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, 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 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, 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 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15648 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15649 ovl.fmt.RSY.dl2,
15650 ovl.fmt.RSY.dh2); goto ok;
15651 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15652 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15653 ovl.fmt.RSY.dl2,
15654 ovl.fmt.RSY.dh2); goto ok;
15655 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15656 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15657 ovl.fmt.RSY.dl2,
15658 ovl.fmt.RSY.dh2); goto ok;
15659 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15660 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15661 ovl.fmt.RSY.dl2,
15662 ovl.fmt.RSY.dh2); goto ok;
15663 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15664 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15665 ovl.fmt.RSY.dl2,
15666 ovl.fmt.RSY.dh2); goto ok;
15667 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15668 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15669 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15670 ovl.fmt.RSY.dl2,
15671 ovl.fmt.RSY.dh2); goto ok;
15672 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15673 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15674 ovl.fmt.RSY.dl2,
15675 ovl.fmt.RSY.dh2); goto ok;
15676 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15677 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15678 ovl.fmt.RSY.dl2,
15679 ovl.fmt.RSY.dh2); goto ok;
15680 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15681 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15682 ovl.fmt.RSY.dl2,
15683 ovl.fmt.RSY.dh2); goto ok;
15684 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15685 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15686 ovl.fmt.RSY.dl2,
15687 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015688 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015689 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15690 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15691 ovl.fmt.RSY.dl2,
15692 ovl.fmt.RSY.dh2); goto ok;
15693 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15694 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15695 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15696 ovl.fmt.RSY.dl2,
15697 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015698 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015699 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15700 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15701 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15702 ovl.fmt.RSY.dh2); goto ok;
15703 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15704 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15705 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15706 ovl.fmt.RSY.dh2); goto ok;
15707 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15708 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15709 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15710 ovl.fmt.RSY.dl2,
15711 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015712 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15713 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15714 ovl.fmt.RSY.dl2,
15715 ovl.fmt.RSY.dh2); goto ok;
15716 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15717 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15718 ovl.fmt.RSY.dl2,
15719 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015720 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15721 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15722 ovl.fmt.RSY.dl2,
15723 ovl.fmt.RSY.dh2); goto ok;
15724 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15725 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15726 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15727 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015728 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15729 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15730 ovl.fmt.RSY.dl2,
15731 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015732 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15733 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15734 ovl.fmt.SIY.dh1); goto ok;
15735 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15736 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15737 ovl.fmt.SIY.dh1); goto ok;
15738 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15739 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15740 ovl.fmt.SIY.dh1); goto ok;
15741 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15742 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15743 ovl.fmt.SIY.dh1); goto ok;
15744 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15745 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15746 ovl.fmt.SIY.dh1); goto ok;
15747 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15748 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15749 ovl.fmt.SIY.dh1); goto ok;
15750 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15751 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15752 ovl.fmt.SIY.dh1); goto ok;
15753 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15754 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15755 ovl.fmt.SIY.dh1); goto ok;
15756 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15757 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15758 ovl.fmt.SIY.dh1); goto ok;
15759 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15760 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15761 ovl.fmt.SIY.dh1); goto ok;
15762 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15763 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15764 ovl.fmt.RSY.dl2,
15765 ovl.fmt.RSY.dh2); goto ok;
15766 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15767 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15768 ovl.fmt.RSY.dl2,
15769 ovl.fmt.RSY.dh2); goto ok;
15770 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15771 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15772 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15773 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15774 ovl.fmt.RSY.dl2,
15775 ovl.fmt.RSY.dh2); goto ok;
15776 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15777 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15778 ovl.fmt.RSY.dl2,
15779 ovl.fmt.RSY.dh2); goto ok;
15780 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15781 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15782 ovl.fmt.RSY.dl2,
15783 ovl.fmt.RSY.dh2); goto ok;
15784 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15785 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15786 ovl.fmt.RSY.dl2,
15787 ovl.fmt.RSY.dh2); goto ok;
15788 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15789 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15790 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15791 ovl.fmt.RSY.dh2); goto ok;
15792 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15793 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15794 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15795 ovl.fmt.RSY.dl2,
15796 ovl.fmt.RSY.dh2); goto ok;
15797 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15798 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15799 ovl.fmt.RSY.dl2,
15800 ovl.fmt.RSY.dh2); goto ok;
15801 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15802 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15803 ovl.fmt.RSY.dl2,
15804 ovl.fmt.RSY.dh2); goto ok;
15805 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15806 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15807 ovl.fmt.RSY.dl2,
15808 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015809 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15810 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15811 ovl.fmt.RSY.dl2,
15812 ovl.fmt.RSY.dh2,
15813 S390_XMNM_LOCG); goto ok;
15814 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15815 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15816 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15817 ovl.fmt.RSY.dh2,
15818 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015819 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15820 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15821 ovl.fmt.RSY.dl2,
15822 ovl.fmt.RSY.dh2); goto ok;
15823 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15824 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15825 ovl.fmt.RSY.dl2,
15826 ovl.fmt.RSY.dh2); goto ok;
15827 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15828 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15829 ovl.fmt.RSY.dl2,
15830 ovl.fmt.RSY.dh2); goto ok;
15831 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15832 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15833 ovl.fmt.RSY.dl2,
15834 ovl.fmt.RSY.dh2); goto ok;
15835 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15836 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15837 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15838 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015839 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15840 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15841 ovl.fmt.RSY.dl2,
15842 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15843 goto ok;
15844 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15845 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15846 ovl.fmt.RSY.dl2,
15847 ovl.fmt.RSY.dh2,
15848 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015849 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15850 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15851 ovl.fmt.RSY.dl2,
15852 ovl.fmt.RSY.dh2); goto ok;
15853 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15854 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15855 ovl.fmt.RSY.dl2,
15856 ovl.fmt.RSY.dh2); goto ok;
15857 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15858 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15859 ovl.fmt.RSY.dl2,
15860 ovl.fmt.RSY.dh2); goto ok;
15861 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15862 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15863 ovl.fmt.RSY.dl2,
15864 ovl.fmt.RSY.dh2); goto ok;
15865 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15866 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15867 ovl.fmt.RSY.dl2,
15868 ovl.fmt.RSY.dh2); goto ok;
15869 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15870 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15871 goto ok;
15872 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15873 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15874 goto ok;
15875 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15876 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15877 ovl.fmt.RIE_RRUUU.r1,
15878 ovl.fmt.RIE_RRUUU.r2,
15879 ovl.fmt.RIE_RRUUU.i3,
15880 ovl.fmt.RIE_RRUUU.i4,
15881 ovl.fmt.RIE_RRUUU.i5);
15882 goto ok;
15883 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15884 ovl.fmt.RIE_RRUUU.r1,
15885 ovl.fmt.RIE_RRUUU.r2,
15886 ovl.fmt.RIE_RRUUU.i3,
15887 ovl.fmt.RIE_RRUUU.i4,
15888 ovl.fmt.RIE_RRUUU.i5);
15889 goto ok;
15890 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15891 ovl.fmt.RIE_RRUUU.r1,
15892 ovl.fmt.RIE_RRUUU.r2,
15893 ovl.fmt.RIE_RRUUU.i3,
15894 ovl.fmt.RIE_RRUUU.i4,
15895 ovl.fmt.RIE_RRUUU.i5);
15896 goto ok;
15897 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15898 ovl.fmt.RIE_RRUUU.r1,
15899 ovl.fmt.RIE_RRUUU.r2,
15900 ovl.fmt.RIE_RRUUU.i3,
15901 ovl.fmt.RIE_RRUUU.i4,
15902 ovl.fmt.RIE_RRUUU.i5);
15903 goto ok;
florian2289cd42012-12-05 04:23:42 +000015904 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015905 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15906 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15907 ovl.fmt.RIE_RRPU.r1,
15908 ovl.fmt.RIE_RRPU.r2,
15909 ovl.fmt.RIE_RRPU.i4,
15910 ovl.fmt.RIE_RRPU.m3); goto ok;
15911 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15912 ovl.fmt.RIE_RRPU.r1,
15913 ovl.fmt.RIE_RRPU.r2,
15914 ovl.fmt.RIE_RRPU.i4,
15915 ovl.fmt.RIE_RRPU.m3); goto ok;
15916 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15917 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15918 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15919 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15920 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15921 ovl.fmt.RIE_RRPU.r1,
15922 ovl.fmt.RIE_RRPU.r2,
15923 ovl.fmt.RIE_RRPU.i4,
15924 ovl.fmt.RIE_RRPU.m3); goto ok;
15925 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15926 ovl.fmt.RIE_RRPU.r1,
15927 ovl.fmt.RIE_RRPU.r2,
15928 ovl.fmt.RIE_RRPU.i4,
15929 ovl.fmt.RIE_RRPU.m3); goto ok;
15930 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15931 ovl.fmt.RIEv3.r1,
15932 ovl.fmt.RIEv3.m3,
15933 ovl.fmt.RIEv3.i4,
15934 ovl.fmt.RIEv3.i2); goto ok;
15935 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15936 ovl.fmt.RIEv3.r1,
15937 ovl.fmt.RIEv3.m3,
15938 ovl.fmt.RIEv3.i4,
15939 ovl.fmt.RIEv3.i2); goto ok;
15940 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15941 ovl.fmt.RIEv3.r1,
15942 ovl.fmt.RIEv3.m3,
15943 ovl.fmt.RIEv3.i4,
15944 ovl.fmt.RIEv3.i2); goto ok;
15945 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15946 ovl.fmt.RIEv3.r1,
15947 ovl.fmt.RIEv3.m3,
15948 ovl.fmt.RIEv3.i4,
15949 ovl.fmt.RIEv3.i2); goto ok;
15950 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15951 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15952 goto ok;
15953 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15954 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15955 ovl.fmt.RIE.i2); goto ok;
15956 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15957 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15958 ovl.fmt.RIE.i2); goto ok;
15959 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15960 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15961 ovl.fmt.RIE.i2); goto ok;
15962 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15963 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15964 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15965 goto ok;
15966 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15967 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15968 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15969 goto ok;
15970 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15971 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15972 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15973 goto ok;
15974 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15975 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15976 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15977 goto ok;
15978 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15979 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15980 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15981 ovl.fmt.RIS.i2); goto ok;
15982 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15983 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15984 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15985 ovl.fmt.RIS.i2); goto ok;
15986 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15987 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15988 ovl.fmt.RIS.d4,
15989 ovl.fmt.RIS.i2); goto ok;
15990 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15991 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15992 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15993 ovl.fmt.RIS.i2); goto ok;
15994 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15995 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15996 ovl.fmt.RXE.d2); goto ok;
15997 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15998 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15999 ovl.fmt.RXE.d2); goto ok;
16000 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
16001 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16002 ovl.fmt.RXE.d2); goto ok;
16003 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
16004 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
16005 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
16006 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16007 ovl.fmt.RXE.d2); goto ok;
16008 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
16009 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16010 ovl.fmt.RXE.d2); goto ok;
16011 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16012 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16013 ovl.fmt.RXE.d2); goto ok;
16014 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16015 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16016 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16017 ovl.fmt.RXE.d2); goto ok;
16018 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16019 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16020 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16021 ovl.fmt.RXF.r1); goto ok;
16022 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16023 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16024 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16025 ovl.fmt.RXF.r1); goto ok;
16026 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16027 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16028 ovl.fmt.RXE.d2); goto ok;
16029 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16030 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16031 ovl.fmt.RXE.d2); goto ok;
16032 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16033 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16034 ovl.fmt.RXE.d2); goto ok;
16035 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16036 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16037 ovl.fmt.RXE.d2); goto ok;
16038 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16039 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16040 ovl.fmt.RXE.d2); goto ok;
16041 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16042 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16043 ovl.fmt.RXE.d2); goto ok;
16044 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16045 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16046 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16047 ovl.fmt.RXE.d2); goto ok;
16048 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16049 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16050 ovl.fmt.RXE.d2); goto ok;
16051 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16052 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16053 ovl.fmt.RXE.d2); goto ok;
16054 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16055 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16056 ovl.fmt.RXE.d2); goto ok;
16057 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16058 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16059 ovl.fmt.RXE.d2); goto ok;
16060 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16061 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16062 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16063 ovl.fmt.RXF.r1); goto ok;
16064 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16065 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16066 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16067 ovl.fmt.RXF.r1); goto ok;
16068 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
16069 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16070 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16071 case 0xed000000002eULL: /* MAE */ goto unimplemented;
16072 case 0xed000000002fULL: /* MSE */ goto unimplemented;
16073 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16074 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16075 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16076 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16077 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16078 case 0xed000000003aULL: /* MAY */ goto unimplemented;
16079 case 0xed000000003bULL: /* MY */ goto unimplemented;
16080 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16081 case 0xed000000003dULL: /* MYH */ goto unimplemented;
16082 case 0xed000000003eULL: /* MAD */ goto unimplemented;
16083 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000016084 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16085 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16086 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16087 ovl.fmt.RXF.r1); goto ok;
16088 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16089 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16090 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16091 ovl.fmt.RXF.r1); goto ok;
16092 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16093 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16094 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16095 ovl.fmt.RXF.r1); goto ok;
16096 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16097 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16098 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16099 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000016100 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16101 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16102 ovl.fmt.RXE.d2); goto ok;
16103 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16104 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16105 ovl.fmt.RXE.d2); goto ok;
16106 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16107 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16108 ovl.fmt.RXE.d2); goto ok;
16109 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16110 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16111 ovl.fmt.RXE.d2); goto ok;
16112 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16113 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16114 ovl.fmt.RXE.d2); goto ok;
16115 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16116 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16117 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016118 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16119 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16120 ovl.fmt.RXY.dl2,
16121 ovl.fmt.RXY.dh2); goto ok;
16122 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16123 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16124 ovl.fmt.RXY.dl2,
16125 ovl.fmt.RXY.dh2); goto ok;
16126 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16127 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16128 ovl.fmt.RXY.dl2,
16129 ovl.fmt.RXY.dh2); goto ok;
16130 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16131 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16132 ovl.fmt.RXY.dl2,
16133 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000016134 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16135 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16136 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16137 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016138 }
16139
16140 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16141 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16142 ovl.fmt.RIL.i2); goto ok;
16143 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16144 ovl.fmt.RIL.i2); goto ok;
16145 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16146 ovl.fmt.RIL.i2); goto ok;
16147 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16148 ovl.fmt.RIL.i2); goto ok;
16149 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16150 ovl.fmt.RIL.i2); goto ok;
16151 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16152 ovl.fmt.RIL.i2); goto ok;
16153 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16154 ovl.fmt.RIL.i2); goto ok;
16155 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16156 ovl.fmt.RIL.i2); goto ok;
16157 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16158 ovl.fmt.RIL.i2); goto ok;
16159 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16160 ovl.fmt.RIL.i2); goto ok;
16161 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16162 ovl.fmt.RIL.i2); goto ok;
16163 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16164 ovl.fmt.RIL.i2); goto ok;
16165 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16166 ovl.fmt.RIL.i2); goto ok;
16167 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16168 ovl.fmt.RIL.i2); goto ok;
16169 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16170 ovl.fmt.RIL.i2); goto ok;
16171 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16172 ovl.fmt.RIL.i2); goto ok;
16173 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16174 ovl.fmt.RIL.i2); goto ok;
16175 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16176 ovl.fmt.RIL.i2); goto ok;
16177 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16178 ovl.fmt.RIL.i2); goto ok;
16179 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16180 ovl.fmt.RIL.i2); goto ok;
16181 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16182 ovl.fmt.RIL.i2); goto ok;
16183 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16184 ovl.fmt.RIL.i2); goto ok;
16185 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16186 ovl.fmt.RIL.i2); goto ok;
16187 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16188 ovl.fmt.RIL.i2); goto ok;
16189 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16190 ovl.fmt.RIL.i2); goto ok;
16191 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16192 ovl.fmt.RIL.i2); goto ok;
16193 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16194 ovl.fmt.RIL.i2); goto ok;
16195 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16196 ovl.fmt.RIL.i2); goto ok;
16197 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16198 ovl.fmt.RIL.i2); goto ok;
16199 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16200 ovl.fmt.RIL.i2); goto ok;
16201 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16202 ovl.fmt.RIL.i2); goto ok;
16203 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16204 ovl.fmt.RIL.i2); goto ok;
16205 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16206 ovl.fmt.RIL.i2); goto ok;
16207 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16208 ovl.fmt.RIL.i2); goto ok;
16209 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16210 ovl.fmt.RIL.i2); goto ok;
16211 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16212 ovl.fmt.RIL.i2); goto ok;
16213 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16214 ovl.fmt.RIL.i2); goto ok;
16215 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16216 ovl.fmt.RIL.i2); goto ok;
16217 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16218 ovl.fmt.RIL.i2); goto ok;
16219 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16220 ovl.fmt.RIL.i2); goto ok;
16221 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16222 ovl.fmt.RIL.i2); goto ok;
16223 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16224 ovl.fmt.RIL.i2); goto ok;
16225 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16226 ovl.fmt.RIL.i2); goto ok;
16227 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16228 ovl.fmt.RIL.i2); goto ok;
16229 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16230 ovl.fmt.RIL.i2); goto ok;
16231 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16232 ovl.fmt.RIL.i2); goto ok;
16233 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16234 ovl.fmt.RIL.i2); goto ok;
16235 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16236 ovl.fmt.RIL.i2); goto ok;
16237 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16238 ovl.fmt.RIL.i2); goto ok;
16239 case 0xc800ULL: /* MVCOS */ goto unimplemented;
16240 case 0xc801ULL: /* ECTG */ goto unimplemented;
16241 case 0xc802ULL: /* CSST */ goto unimplemented;
16242 case 0xc804ULL: /* LPD */ goto unimplemented;
16243 case 0xc805ULL: /* LPDG */ goto unimplemented;
16244 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
16245 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16246 ovl.fmt.RIL.i2); goto ok;
16247 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16248 ovl.fmt.RIL.i2); goto ok;
16249 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16250 ovl.fmt.RIL.i2); goto ok;
16251 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16252 ovl.fmt.RIL.i2); goto ok;
16253 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16254 ovl.fmt.RIL.i2); goto ok;
16255 }
16256
16257 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000016258 case 0xc5ULL: /* BPRP */ goto unimplemented;
16259 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016260 case 0xd0ULL: /* TRTR */ goto unimplemented;
16261 case 0xd1ULL: /* MVN */ goto unimplemented;
16262 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16263 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16264 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16265 case 0xd3ULL: /* MVZ */ goto unimplemented;
16266 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16267 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16268 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16269 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16270 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16271 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16272 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16273 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16274 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000016275 case 0xd7ULL:
16276 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16277 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16278 else
16279 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16280 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16281 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16282 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016283 case 0xd9ULL: /* MVCK */ goto unimplemented;
16284 case 0xdaULL: /* MVCP */ goto unimplemented;
16285 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000016286 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16287 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16288 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016289 case 0xddULL: /* TRT */ goto unimplemented;
16290 case 0xdeULL: /* ED */ goto unimplemented;
16291 case 0xdfULL: /* EDMK */ goto unimplemented;
16292 case 0xe1ULL: /* PKU */ goto unimplemented;
16293 case 0xe2ULL: /* UNPKU */ goto unimplemented;
16294 case 0xe8ULL: /* MVCIN */ goto unimplemented;
16295 case 0xe9ULL: /* PKA */ goto unimplemented;
16296 case 0xeaULL: /* UNPKA */ goto unimplemented;
16297 case 0xeeULL: /* PLO */ goto unimplemented;
16298 case 0xefULL: /* LMD */ goto unimplemented;
16299 case 0xf0ULL: /* SRP */ goto unimplemented;
16300 case 0xf1ULL: /* MVO */ goto unimplemented;
16301 case 0xf2ULL: /* PACK */ goto unimplemented;
16302 case 0xf3ULL: /* UNPK */ goto unimplemented;
16303 case 0xf8ULL: /* ZAP */ goto unimplemented;
16304 case 0xf9ULL: /* CP */ goto unimplemented;
16305 case 0xfaULL: /* AP */ goto unimplemented;
16306 case 0xfbULL: /* SP */ goto unimplemented;
16307 case 0xfcULL: /* MP */ goto unimplemented;
16308 case 0xfdULL: /* DP */ goto unimplemented;
16309 }
16310
16311 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16312 case 0xe500ULL: /* LASP */ goto unimplemented;
16313 case 0xe501ULL: /* TPROT */ goto unimplemented;
16314 case 0xe502ULL: /* STRAG */ goto unimplemented;
16315 case 0xe50eULL: /* MVCSK */ goto unimplemented;
16316 case 0xe50fULL: /* MVCDK */ goto unimplemented;
16317 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16318 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16319 goto ok;
16320 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16321 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16322 goto ok;
16323 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16324 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16325 goto ok;
16326 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16327 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16328 goto ok;
16329 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16330 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16331 goto ok;
16332 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16333 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16334 goto ok;
16335 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16336 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16337 goto ok;
16338 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16339 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16340 goto ok;
16341 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16342 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16343 goto ok;
florian2289cd42012-12-05 04:23:42 +000016344 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16345 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016346 }
16347
16348 return S390_DECODE_UNKNOWN_INSN;
16349
16350ok:
16351 return S390_DECODE_OK;
16352
16353unimplemented:
16354 return S390_DECODE_UNIMPLEMENTED_INSN;
16355}
16356
16357/* Handle "special" instructions. */
16358static s390_decode_t
16359s390_decode_special_and_irgen(UChar *bytes)
16360{
16361 s390_decode_t status = S390_DECODE_OK;
16362
16363 /* Got a "Special" instruction preamble. Which one is it? */
16364 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16365 s390_irgen_client_request();
16366 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16367 s390_irgen_guest_NRADDR();
16368 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16369 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016370 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16371 vex_inject_ir(irsb, Iend_BE);
16372
16373 /* Invalidate the current insn. The reason is that the IRop we're
16374 injecting here can change. In which case the translation has to
16375 be redone. For ease of handling, we simply invalidate all the
16376 time. */
sewardj05f5e012014-05-04 10:52:11 +000016377 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian2245ce92012-08-28 16:49:30 +000016378 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000016379 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
florian2245ce92012-08-28 16:49:30 +000016380 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16381 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16382 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16383
16384 put_IA(mkaddr_expr(guest_IA_next_instr));
16385 dis_res->whatNext = Dis_StopHere;
sewardj05f5e012014-05-04 10:52:11 +000016386 dis_res->jk_StopHere = Ijk_InvalICache;
sewardj2019a972011-03-07 16:04:07 +000016387 } else {
16388 /* We don't know what it is. */
16389 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16390 }
16391
16392 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16393
16394 return status;
16395}
16396
16397
16398/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016399static UInt
sewardj2019a972011-03-07 16:04:07 +000016400s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
16401{
16402 s390_decode_t status;
16403
16404 dis_res = dres;
16405
16406 /* Spot the 8-byte preamble: 18ff lr r15,r15
16407 1811 lr r1,r1
16408 1822 lr r2,r2
16409 1833 lr r3,r3 */
16410 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16411 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16412 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16413
16414 /* Handle special instruction that follows that preamble. */
16415 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016416
16417 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16418 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16419
16420 status =
16421 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016422 } else {
16423 /* Handle normal instructions. */
16424 switch (insn_length) {
16425 case 2:
16426 status = s390_decode_2byte_and_irgen(bytes);
16427 break;
16428
16429 case 4:
16430 status = s390_decode_4byte_and_irgen(bytes);
16431 break;
16432
16433 case 6:
16434 status = s390_decode_6byte_and_irgen(bytes);
16435 break;
16436
16437 default:
16438 status = S390_DECODE_ERROR;
16439 break;
16440 }
16441 }
florian5fcbba22011-07-27 20:40:22 +000016442 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016443 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16444 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016445 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016446 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016447 }
16448
16449 if (status == S390_DECODE_OK) return insn_length; /* OK */
16450
16451 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016452 if (sigill_diag) {
16453 vex_printf("vex s390->IR: ");
16454 switch (status) {
16455 case S390_DECODE_UNKNOWN_INSN:
16456 vex_printf("unknown insn: ");
16457 break;
sewardj2019a972011-03-07 16:04:07 +000016458
sewardj442e51a2012-12-06 18:08:04 +000016459 case S390_DECODE_UNIMPLEMENTED_INSN:
16460 vex_printf("unimplemented insn: ");
16461 break;
sewardj2019a972011-03-07 16:04:07 +000016462
sewardj442e51a2012-12-06 18:08:04 +000016463 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16464 vex_printf("unimplemented special insn: ");
16465 break;
sewardj2019a972011-03-07 16:04:07 +000016466
sewardj442e51a2012-12-06 18:08:04 +000016467 case S390_DECODE_ERROR:
16468 vex_printf("decoding error: ");
16469 break;
florian2580da42014-09-16 21:49:45 +000016470
16471 default:
16472 vpanic("s390_decode_and_irgen");
sewardj442e51a2012-12-06 18:08:04 +000016473 }
16474
16475 vex_printf("%02x%02x", bytes[0], bytes[1]);
16476 if (insn_length > 2) {
16477 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16478 }
16479 if (insn_length > 4) {
16480 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16481 }
16482 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016483 }
16484
sewardj2019a972011-03-07 16:04:07 +000016485 return 0; /* Failed */
16486}
16487
16488
sewardj2019a972011-03-07 16:04:07 +000016489/* Disassemble a single instruction INSN into IR. */
16490static DisResult
florian420c5012011-07-22 02:12:28 +000016491disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016492{
16493 UChar byte;
16494 UInt insn_length;
16495 DisResult dres;
16496
16497 /* ---------------------------------------------------- */
16498 /* --- Compute instruction length -- */
16499 /* ---------------------------------------------------- */
16500
16501 /* Get the first byte of the insn. */
16502 byte = insn[0];
16503
16504 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16505 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16506 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16507
16508 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16509
16510 /* ---------------------------------------------------- */
16511 /* --- Initialise the DisResult data -- */
16512 /* ---------------------------------------------------- */
16513 dres.whatNext = Dis_Continue;
16514 dres.len = insn_length;
16515 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016516 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000016517
floriana99f20e2011-07-17 14:16:41 +000016518 /* fixs390: consider chasing of conditional jumps */
16519
sewardj2019a972011-03-07 16:04:07 +000016520 /* Normal and special instruction handling starts here. */
16521 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16522 /* All decode failures end up here. The decoder has already issued an
16523 error message.
16524 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016525 not been executed, and (is currently) the next to be executed.
16526 The insn address in the guest state needs to be set to
16527 guest_IA_curr_instr, otherwise the complaint will report an
16528 incorrect address. */
16529 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016530
philippe2faf5912014-08-11 22:45:47 +000016531 dres.len = 0;
florian8844a632012-04-13 04:04:06 +000016532 dres.whatNext = Dis_StopHere;
16533 dres.jk_StopHere = Ijk_NoDecode;
16534 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016535 } else {
16536 /* Decode success */
16537 switch (dres.whatNext) {
16538 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016539 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016540 break;
16541 case Dis_ResteerU:
16542 case Dis_ResteerC:
16543 put_IA(mkaddr_expr(dres.continueAt));
16544 break;
16545 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016546 if (dres.jk_StopHere == Ijk_EmWarn ||
16547 dres.jk_StopHere == Ijk_EmFail) {
16548 /* We assume here, that emulation warnings are not given for
16549 insns that transfer control. There is no good way to
16550 do that. */
16551 put_IA(mkaddr_expr(guest_IA_next_instr));
16552 }
florian8844a632012-04-13 04:04:06 +000016553 break;
16554 default:
florian2580da42014-09-16 21:49:45 +000016555 vpanic("disInstr_S390_WRK");
florian8844a632012-04-13 04:04:06 +000016556 }
sewardj2019a972011-03-07 16:04:07 +000016557 }
16558
16559 return dres;
16560}
16561
16562
16563/*------------------------------------------------------------*/
16564/*--- Top-level fn ---*/
16565/*------------------------------------------------------------*/
16566
16567/* Disassemble a single instruction into IR. The instruction
16568 is located in host memory at &guest_code[delta]. */
16569
16570DisResult
16571disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000016572 Bool (*resteerOkFn)(void *, Addr64),
16573 Bool resteerCisOk,
16574 void *callback_opaque,
16575 UChar *guest_code,
16576 Long delta,
16577 Addr64 guest_IP,
16578 VexArch guest_arch,
16579 VexArchInfo *archinfo,
16580 VexAbiInfo *abiinfo,
sewardj9b769162014-07-24 12:42:03 +000016581 VexEndness host_endness,
sewardj442e51a2012-12-06 18:08:04 +000016582 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016583{
16584 vassert(guest_arch == VexArchS390X);
16585
16586 /* The instruction decoder requires a big-endian machine. */
sewardj9b769162014-07-24 12:42:03 +000016587 vassert(host_endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +000016588
16589 /* Set globals (see top of this file) */
16590 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016591 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016592 resteer_fn = resteerOkFn;
16593 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016594 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016595
florian420c5012011-07-22 02:12:28 +000016596 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016597}
16598
16599/*---------------------------------------------------------------*/
16600/*--- end guest_s390_toIR.c ---*/
16601/*---------------------------------------------------------------*/