blob: 2f715978a8a8841e3646de9a22c900537203fdaf [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
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
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
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
florianbafb8262013-05-31 15:41:55 +0000635 /* Make the CC_DEP1 slot appear completely defined.
636 Otherwise, assigning a 32-bit value will cause memcheck
637 to trigger an undefinedness error.
638 */
639 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
640 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
641 stmt(IRStmt_Put(dep1_off, mkU64(0)));
642 }
sewardj2019a972011-03-07 16:04:07 +0000643 op = mkU64(opc);
644 dep1 = mkexpr(d1);
645 dep2 = mkU64(0);
646 ndep = mkU64(0);
647
648 s390_cc_thunk_fill(op, dep1, dep2, ndep);
649}
650
651
652/* Write a floating point value and an integer into the flags thunk. The
653 integer value is zero-extended first. */
654static void
655s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
656{
657 IRExpr *op, *dep1, *dep2, *ndep;
658
florianbafb8262013-05-31 15:41:55 +0000659 /* Make the CC_DEP1 slot appear completely defined.
660 Otherwise, assigning a 32-bit value will cause memcheck
661 to trigger an undefinedness error.
662 */
663 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
664 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
665 stmt(IRStmt_Put(dep1_off, mkU64(0)));
666 }
sewardj2019a972011-03-07 16:04:07 +0000667 op = mkU64(opc);
668 dep1 = mkexpr(d1);
669 dep2 = s390_cc_widen(d2, False);
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, dep1, dep2, ndep);
673}
674
675
676/* Write a 128-bit floating point value into the flags thunk. This is
677 done by splitting the value into two 64-bits values. */
678static void
679s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
680{
681 IRExpr *op, *hi, *lo, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
686 ndep = mkU64(0);
687
688 s390_cc_thunk_fill(op, hi, lo, ndep);
689}
690
691
692/* Write a 128-bit floating point value and an integer into the flags thunk.
693 The integer value is zero-extended first. */
694static void
695s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
696{
697 IRExpr *op, *hi, *lo, *lox, *ndep;
698
699 op = mkU64(opc);
700 hi = unop(Iop_F128HItoF64, mkexpr(d1));
701 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
702 ndep = s390_cc_widen(nd, False);
703
704 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
705
706 s390_cc_thunk_fill(op, hi, lox, ndep);
707}
708
709
floriane38f6412012-12-21 17:32:12 +0000710/* Write a 128-bit decimal floating point value into the flags thunk.
711 This is done by splitting the value into two 64-bits values. */
712static void
713s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
714{
715 IRExpr *op, *hi, *lo, *ndep;
716
717 op = mkU64(opc);
718 hi = unop(Iop_D128HItoD64, mkexpr(d1));
719 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
720 ndep = mkU64(0);
721
722 s390_cc_thunk_fill(op, hi, lo, ndep);
723}
724
725
floriance9e3db2012-12-27 20:14:03 +0000726/* Write a 128-bit decimal floating point value and an integer into the flags
727 thunk. The integer value is zero-extended first. */
728static void
729s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
730{
731 IRExpr *op, *hi, *lo, *lox, *ndep;
732
733 op = mkU64(opc);
734 hi = unop(Iop_D128HItoD64, mkexpr(d1));
735 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
736 ndep = s390_cc_widen(nd, False);
737
738 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
739
740 s390_cc_thunk_fill(op, hi, lox, ndep);
741}
742
743
sewardj2019a972011-03-07 16:04:07 +0000744static void
745s390_cc_set(UInt val)
746{
747 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
748 mkU64(val), mkU64(0), mkU64(0));
749}
750
751/* Build IR to calculate the condition code from flags thunk.
752 Returns an expression of type Ity_I32 */
753static IRExpr *
754s390_call_calculate_cc(void)
755{
756 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
757
florian428dfdd2012-03-27 03:09:49 +0000758 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
759 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
760 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
761 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000762
763 args = mkIRExprVec_4(op, dep1, dep2, ndep);
764 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
765 "s390_calculate_cc", &s390_calculate_cc, args);
766
767 /* Exclude OP and NDEP from definedness checking. We're only
768 interested in DEP1 and DEP2. */
769 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
770
771 return call;
772}
773
774/* Build IR to calculate the internal condition code for a "compare and branch"
775 insn. Returns an expression of type Ity_I32 */
776static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000777s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000778{
florianff9613f2012-05-12 15:26:44 +0000779 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000780
florianff9613f2012-05-12 15:26:44 +0000781 switch (opc) {
782 case S390_CC_OP_SIGNED_COMPARE:
783 dep1 = s390_cc_widen(op1, True);
784 dep2 = s390_cc_widen(op2, True);
785 break;
786
787 case S390_CC_OP_UNSIGNED_COMPARE:
788 dep1 = s390_cc_widen(op1, False);
789 dep2 = s390_cc_widen(op2, False);
790 break;
791
792 default:
793 vpanic("s390_call_calculate_icc");
794 }
795
796 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000797 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000798
florianff9613f2012-05-12 15:26:44 +0000799 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000800 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000801 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000802
florianff9613f2012-05-12 15:26:44 +0000803 /* Exclude the requested condition, OP and NDEP from definedness
804 checking. We're only interested in DEP1 and DEP2. */
805 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000806
807 return call;
808}
809
810/* Build IR to calculate the condition code from flags thunk.
811 Returns an expression of type Ity_I32 */
812static IRExpr *
813s390_call_calculate_cond(UInt m)
814{
815 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
816
817 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000818 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
819 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
820 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
821 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000822
823 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
824 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
825 "s390_calculate_cond", &s390_calculate_cond, args);
826
827 /* Exclude the requested condition, OP and NDEP from definedness
828 checking. We're only interested in DEP1 and DEP2. */
829 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
830
831 return call;
832}
833
834#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
835#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
836#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
837#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
838#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
839#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
840#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
841 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
842#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
843 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000844
845
sewardj2019a972011-03-07 16:04:07 +0000846
847
848/*------------------------------------------------------------*/
849/*--- Guest register access ---*/
850/*------------------------------------------------------------*/
851
852
853/*------------------------------------------------------------*/
854/*--- ar registers ---*/
855/*------------------------------------------------------------*/
856
857/* Return the guest state offset of a ar register. */
858static UInt
859ar_offset(UInt archreg)
860{
861 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000862 S390X_GUEST_OFFSET(guest_a0),
863 S390X_GUEST_OFFSET(guest_a1),
864 S390X_GUEST_OFFSET(guest_a2),
865 S390X_GUEST_OFFSET(guest_a3),
866 S390X_GUEST_OFFSET(guest_a4),
867 S390X_GUEST_OFFSET(guest_a5),
868 S390X_GUEST_OFFSET(guest_a6),
869 S390X_GUEST_OFFSET(guest_a7),
870 S390X_GUEST_OFFSET(guest_a8),
871 S390X_GUEST_OFFSET(guest_a9),
872 S390X_GUEST_OFFSET(guest_a10),
873 S390X_GUEST_OFFSET(guest_a11),
874 S390X_GUEST_OFFSET(guest_a12),
875 S390X_GUEST_OFFSET(guest_a13),
876 S390X_GUEST_OFFSET(guest_a14),
877 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000878 };
879
880 vassert(archreg < 16);
881
882 return offset[archreg];
883}
884
885
886/* Return the guest state offset of word #0 of a ar register. */
887static __inline__ UInt
888ar_w0_offset(UInt archreg)
889{
890 return ar_offset(archreg) + 0;
891}
892
893/* Write word #0 of a ar to the guest state. */
894static __inline__ void
895put_ar_w0(UInt archreg, IRExpr *expr)
896{
897 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
898
899 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
900}
901
902/* Read word #0 of a ar register. */
903static __inline__ IRExpr *
904get_ar_w0(UInt archreg)
905{
906 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
907}
908
909
910/*------------------------------------------------------------*/
911/*--- fpr registers ---*/
912/*------------------------------------------------------------*/
913
914/* Return the guest state offset of a fpr register. */
915static UInt
916fpr_offset(UInt archreg)
917{
918 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000919 S390X_GUEST_OFFSET(guest_f0),
920 S390X_GUEST_OFFSET(guest_f1),
921 S390X_GUEST_OFFSET(guest_f2),
922 S390X_GUEST_OFFSET(guest_f3),
923 S390X_GUEST_OFFSET(guest_f4),
924 S390X_GUEST_OFFSET(guest_f5),
925 S390X_GUEST_OFFSET(guest_f6),
926 S390X_GUEST_OFFSET(guest_f7),
927 S390X_GUEST_OFFSET(guest_f8),
928 S390X_GUEST_OFFSET(guest_f9),
929 S390X_GUEST_OFFSET(guest_f10),
930 S390X_GUEST_OFFSET(guest_f11),
931 S390X_GUEST_OFFSET(guest_f12),
932 S390X_GUEST_OFFSET(guest_f13),
933 S390X_GUEST_OFFSET(guest_f14),
934 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000935 };
936
937 vassert(archreg < 16);
938
939 return offset[archreg];
940}
941
942
943/* Return the guest state offset of word #0 of a fpr register. */
944static __inline__ UInt
945fpr_w0_offset(UInt archreg)
946{
947 return fpr_offset(archreg) + 0;
948}
949
950/* Write word #0 of a fpr to the guest state. */
951static __inline__ void
952put_fpr_w0(UInt archreg, IRExpr *expr)
953{
954 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
955
956 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
957}
958
959/* Read word #0 of a fpr register. */
960static __inline__ IRExpr *
961get_fpr_w0(UInt archreg)
962{
963 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
964}
965
966/* Return the guest state offset of double word #0 of a fpr register. */
967static __inline__ UInt
968fpr_dw0_offset(UInt archreg)
969{
970 return fpr_offset(archreg) + 0;
971}
972
973/* Write double word #0 of a fpr to the guest state. */
974static __inline__ void
975put_fpr_dw0(UInt archreg, IRExpr *expr)
976{
977 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
978
979 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
980}
981
982/* Read double word #0 of a fpr register. */
983static __inline__ IRExpr *
984get_fpr_dw0(UInt archreg)
985{
986 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
987}
988
floriane38f6412012-12-21 17:32:12 +0000989/* Write word #0 of a dpr to the guest state. */
990static __inline__ void
991put_dpr_w0(UInt archreg, IRExpr *expr)
992{
993 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
994
995 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
996}
997
998/* Read word #0 of a dpr register. */
999static __inline__ IRExpr *
1000get_dpr_w0(UInt archreg)
1001{
1002 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1003}
1004
florian12390202012-11-10 22:34:14 +00001005/* Write double word #0 of a fpr containg DFP value to the guest state. */
1006static __inline__ void
1007put_dpr_dw0(UInt archreg, IRExpr *expr)
1008{
1009 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1010
1011 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1012}
1013
1014/* Read double word #0 of a fpr register containing DFP value. */
1015static __inline__ IRExpr *
1016get_dpr_dw0(UInt archreg)
1017{
1018 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1019}
sewardj2019a972011-03-07 16:04:07 +00001020
1021/*------------------------------------------------------------*/
1022/*--- gpr registers ---*/
1023/*------------------------------------------------------------*/
1024
1025/* Return the guest state offset of a gpr register. */
1026static UInt
1027gpr_offset(UInt archreg)
1028{
1029 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001030 S390X_GUEST_OFFSET(guest_r0),
1031 S390X_GUEST_OFFSET(guest_r1),
1032 S390X_GUEST_OFFSET(guest_r2),
1033 S390X_GUEST_OFFSET(guest_r3),
1034 S390X_GUEST_OFFSET(guest_r4),
1035 S390X_GUEST_OFFSET(guest_r5),
1036 S390X_GUEST_OFFSET(guest_r6),
1037 S390X_GUEST_OFFSET(guest_r7),
1038 S390X_GUEST_OFFSET(guest_r8),
1039 S390X_GUEST_OFFSET(guest_r9),
1040 S390X_GUEST_OFFSET(guest_r10),
1041 S390X_GUEST_OFFSET(guest_r11),
1042 S390X_GUEST_OFFSET(guest_r12),
1043 S390X_GUEST_OFFSET(guest_r13),
1044 S390X_GUEST_OFFSET(guest_r14),
1045 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001046 };
1047
1048 vassert(archreg < 16);
1049
1050 return offset[archreg];
1051}
1052
1053
1054/* Return the guest state offset of word #0 of a gpr register. */
1055static __inline__ UInt
1056gpr_w0_offset(UInt archreg)
1057{
1058 return gpr_offset(archreg) + 0;
1059}
1060
1061/* Write word #0 of a gpr to the guest state. */
1062static __inline__ void
1063put_gpr_w0(UInt archreg, IRExpr *expr)
1064{
1065 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1066
1067 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1068}
1069
1070/* Read word #0 of a gpr register. */
1071static __inline__ IRExpr *
1072get_gpr_w0(UInt archreg)
1073{
1074 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1075}
1076
1077/* Return the guest state offset of double word #0 of a gpr register. */
1078static __inline__ UInt
1079gpr_dw0_offset(UInt archreg)
1080{
1081 return gpr_offset(archreg) + 0;
1082}
1083
1084/* Write double word #0 of a gpr to the guest state. */
1085static __inline__ void
1086put_gpr_dw0(UInt archreg, IRExpr *expr)
1087{
1088 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1089
1090 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1091}
1092
1093/* Read double word #0 of a gpr register. */
1094static __inline__ IRExpr *
1095get_gpr_dw0(UInt archreg)
1096{
1097 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1098}
1099
1100/* Return the guest state offset of half word #1 of a gpr register. */
1101static __inline__ UInt
1102gpr_hw1_offset(UInt archreg)
1103{
1104 return gpr_offset(archreg) + 2;
1105}
1106
1107/* Write half word #1 of a gpr to the guest state. */
1108static __inline__ void
1109put_gpr_hw1(UInt archreg, IRExpr *expr)
1110{
1111 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1112
1113 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1114}
1115
1116/* Read half word #1 of a gpr register. */
1117static __inline__ IRExpr *
1118get_gpr_hw1(UInt archreg)
1119{
1120 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1121}
1122
1123/* Return the guest state offset of byte #6 of a gpr register. */
1124static __inline__ UInt
1125gpr_b6_offset(UInt archreg)
1126{
1127 return gpr_offset(archreg) + 6;
1128}
1129
1130/* Write byte #6 of a gpr to the guest state. */
1131static __inline__ void
1132put_gpr_b6(UInt archreg, IRExpr *expr)
1133{
1134 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1135
1136 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1137}
1138
1139/* Read byte #6 of a gpr register. */
1140static __inline__ IRExpr *
1141get_gpr_b6(UInt archreg)
1142{
1143 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1144}
1145
1146/* Return the guest state offset of byte #3 of a gpr register. */
1147static __inline__ UInt
1148gpr_b3_offset(UInt archreg)
1149{
1150 return gpr_offset(archreg) + 3;
1151}
1152
1153/* Write byte #3 of a gpr to the guest state. */
1154static __inline__ void
1155put_gpr_b3(UInt archreg, IRExpr *expr)
1156{
1157 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1158
1159 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1160}
1161
1162/* Read byte #3 of a gpr register. */
1163static __inline__ IRExpr *
1164get_gpr_b3(UInt archreg)
1165{
1166 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1167}
1168
1169/* Return the guest state offset of byte #0 of a gpr register. */
1170static __inline__ UInt
1171gpr_b0_offset(UInt archreg)
1172{
1173 return gpr_offset(archreg) + 0;
1174}
1175
1176/* Write byte #0 of a gpr to the guest state. */
1177static __inline__ void
1178put_gpr_b0(UInt archreg, IRExpr *expr)
1179{
1180 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1181
1182 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1183}
1184
1185/* Read byte #0 of a gpr register. */
1186static __inline__ IRExpr *
1187get_gpr_b0(UInt archreg)
1188{
1189 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1190}
1191
1192/* Return the guest state offset of word #1 of a gpr register. */
1193static __inline__ UInt
1194gpr_w1_offset(UInt archreg)
1195{
1196 return gpr_offset(archreg) + 4;
1197}
1198
1199/* Write word #1 of a gpr to the guest state. */
1200static __inline__ void
1201put_gpr_w1(UInt archreg, IRExpr *expr)
1202{
1203 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1204
1205 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1206}
1207
1208/* Read word #1 of a gpr register. */
1209static __inline__ IRExpr *
1210get_gpr_w1(UInt archreg)
1211{
1212 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1213}
1214
1215/* Return the guest state offset of half word #3 of a gpr register. */
1216static __inline__ UInt
1217gpr_hw3_offset(UInt archreg)
1218{
1219 return gpr_offset(archreg) + 6;
1220}
1221
1222/* Write half word #3 of a gpr to the guest state. */
1223static __inline__ void
1224put_gpr_hw3(UInt archreg, IRExpr *expr)
1225{
1226 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1227
1228 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1229}
1230
1231/* Read half word #3 of a gpr register. */
1232static __inline__ IRExpr *
1233get_gpr_hw3(UInt archreg)
1234{
1235 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1236}
1237
1238/* Return the guest state offset of byte #7 of a gpr register. */
1239static __inline__ UInt
1240gpr_b7_offset(UInt archreg)
1241{
1242 return gpr_offset(archreg) + 7;
1243}
1244
1245/* Write byte #7 of a gpr to the guest state. */
1246static __inline__ void
1247put_gpr_b7(UInt archreg, IRExpr *expr)
1248{
1249 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1250
1251 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1252}
1253
1254/* Read byte #7 of a gpr register. */
1255static __inline__ IRExpr *
1256get_gpr_b7(UInt archreg)
1257{
1258 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1259}
1260
1261/* Return the guest state offset of half word #0 of a gpr register. */
1262static __inline__ UInt
1263gpr_hw0_offset(UInt archreg)
1264{
1265 return gpr_offset(archreg) + 0;
1266}
1267
1268/* Write half word #0 of a gpr to the guest state. */
1269static __inline__ void
1270put_gpr_hw0(UInt archreg, IRExpr *expr)
1271{
1272 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1273
1274 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1275}
1276
1277/* Read half word #0 of a gpr register. */
1278static __inline__ IRExpr *
1279get_gpr_hw0(UInt archreg)
1280{
1281 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1282}
1283
1284/* Return the guest state offset of byte #4 of a gpr register. */
1285static __inline__ UInt
1286gpr_b4_offset(UInt archreg)
1287{
1288 return gpr_offset(archreg) + 4;
1289}
1290
1291/* Write byte #4 of a gpr to the guest state. */
1292static __inline__ void
1293put_gpr_b4(UInt archreg, IRExpr *expr)
1294{
1295 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1296
1297 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1298}
1299
1300/* Read byte #4 of a gpr register. */
1301static __inline__ IRExpr *
1302get_gpr_b4(UInt archreg)
1303{
1304 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1305}
1306
1307/* Return the guest state offset of byte #1 of a gpr register. */
1308static __inline__ UInt
1309gpr_b1_offset(UInt archreg)
1310{
1311 return gpr_offset(archreg) + 1;
1312}
1313
1314/* Write byte #1 of a gpr to the guest state. */
1315static __inline__ void
1316put_gpr_b1(UInt archreg, IRExpr *expr)
1317{
1318 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1319
1320 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1321}
1322
1323/* Read byte #1 of a gpr register. */
1324static __inline__ IRExpr *
1325get_gpr_b1(UInt archreg)
1326{
1327 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1328}
1329
1330/* Return the guest state offset of half word #2 of a gpr register. */
1331static __inline__ UInt
1332gpr_hw2_offset(UInt archreg)
1333{
1334 return gpr_offset(archreg) + 4;
1335}
1336
1337/* Write half word #2 of a gpr to the guest state. */
1338static __inline__ void
1339put_gpr_hw2(UInt archreg, IRExpr *expr)
1340{
1341 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1342
1343 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1344}
1345
1346/* Read half word #2 of a gpr register. */
1347static __inline__ IRExpr *
1348get_gpr_hw2(UInt archreg)
1349{
1350 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1351}
1352
1353/* Return the guest state offset of byte #5 of a gpr register. */
1354static __inline__ UInt
1355gpr_b5_offset(UInt archreg)
1356{
1357 return gpr_offset(archreg) + 5;
1358}
1359
1360/* Write byte #5 of a gpr to the guest state. */
1361static __inline__ void
1362put_gpr_b5(UInt archreg, IRExpr *expr)
1363{
1364 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1365
1366 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1367}
1368
1369/* Read byte #5 of a gpr register. */
1370static __inline__ IRExpr *
1371get_gpr_b5(UInt archreg)
1372{
1373 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1374}
1375
1376/* Return the guest state offset of byte #2 of a gpr register. */
1377static __inline__ UInt
1378gpr_b2_offset(UInt archreg)
1379{
1380 return gpr_offset(archreg) + 2;
1381}
1382
1383/* Write byte #2 of a gpr to the guest state. */
1384static __inline__ void
1385put_gpr_b2(UInt archreg, IRExpr *expr)
1386{
1387 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1388
1389 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1390}
1391
1392/* Read byte #2 of a gpr register. */
1393static __inline__ IRExpr *
1394get_gpr_b2(UInt archreg)
1395{
1396 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1397}
1398
1399/* Return the guest state offset of the counter register. */
1400static UInt
1401counter_offset(void)
1402{
floriane88b3c92011-07-05 02:48:39 +00001403 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001404}
1405
1406/* Return the guest state offset of double word #0 of the counter register. */
1407static __inline__ UInt
1408counter_dw0_offset(void)
1409{
1410 return counter_offset() + 0;
1411}
1412
1413/* Write double word #0 of the counter to the guest state. */
1414static __inline__ void
1415put_counter_dw0(IRExpr *expr)
1416{
1417 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1418
1419 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1420}
1421
1422/* Read double word #0 of the counter register. */
1423static __inline__ IRExpr *
1424get_counter_dw0(void)
1425{
1426 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1427}
1428
1429/* Return the guest state offset of word #0 of the counter register. */
1430static __inline__ UInt
1431counter_w0_offset(void)
1432{
1433 return counter_offset() + 0;
1434}
1435
1436/* Return the guest state offset of word #1 of the counter register. */
1437static __inline__ UInt
1438counter_w1_offset(void)
1439{
1440 return counter_offset() + 4;
1441}
1442
1443/* Write word #0 of the counter to the guest state. */
1444static __inline__ void
1445put_counter_w0(IRExpr *expr)
1446{
1447 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1448
1449 stmt(IRStmt_Put(counter_w0_offset(), expr));
1450}
1451
1452/* Read word #0 of the counter register. */
1453static __inline__ IRExpr *
1454get_counter_w0(void)
1455{
1456 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1457}
1458
1459/* Write word #1 of the counter to the guest state. */
1460static __inline__ void
1461put_counter_w1(IRExpr *expr)
1462{
1463 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1464
1465 stmt(IRStmt_Put(counter_w1_offset(), expr));
1466}
1467
1468/* Read word #1 of the counter register. */
1469static __inline__ IRExpr *
1470get_counter_w1(void)
1471{
1472 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1473}
1474
1475/* Return the guest state offset of the fpc register. */
1476static UInt
1477fpc_offset(void)
1478{
floriane88b3c92011-07-05 02:48:39 +00001479 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001480}
1481
1482/* Return the guest state offset of word #0 of the fpc register. */
1483static __inline__ UInt
1484fpc_w0_offset(void)
1485{
1486 return fpc_offset() + 0;
1487}
1488
1489/* Write word #0 of the fpc to the guest state. */
1490static __inline__ void
1491put_fpc_w0(IRExpr *expr)
1492{
1493 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1494
1495 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1496}
1497
1498/* Read word #0 of the fpc register. */
1499static __inline__ IRExpr *
1500get_fpc_w0(void)
1501{
1502 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1503}
1504
1505
1506/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001507/*--- Rounding modes ---*/
1508/*------------------------------------------------------------*/
1509
florian125e20d2012-10-07 15:42:37 +00001510/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001511 IRRoundingMode:
1512
1513 rounding mode | s390 | IR
1514 -------------------------
1515 to nearest | 00 | 00
1516 to zero | 01 | 11
1517 to +infinity | 10 | 10
1518 to -infinity | 11 | 01
1519
1520 So: IR = (4 - s390) & 3
1521*/
1522static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001523get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001524{
1525 IRTemp fpc_bits = newTemp(Ity_I32);
1526
1527 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1528 Prior to that bits [30:31] contained the bfp rounding mode with
1529 bit 29 being unused and having a value of 0. So we can always
1530 extract the least significant 3 bits. */
1531 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1532
1533 /* fixs390:
1534
1535
1536 if (! s390_host_has_fpext && rounding_mode > 3) {
1537 emulation warning @ runtime and
1538 set fpc to round nearest
1539 }
1540 */
1541
1542 /* For now silently adjust an unsupported rounding mode to "nearest" */
1543 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1544 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001545 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001546
1547 // rm_IR = (4 - rm_s390) & 3;
1548 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1549}
1550
1551/* Encode the s390 rounding mode as it appears in the m3 field of certain
1552 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1553 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1554 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1555 considers the default rounding mode (4.3.3). */
1556static IRTemp
1557encode_bfp_rounding_mode(UChar mode)
1558{
1559 IRExpr *rm;
1560
1561 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001562 case S390_BFP_ROUND_PER_FPC:
1563 rm = get_bfp_rounding_mode_from_fpc();
1564 break;
1565 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1566 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1567 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1568 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1569 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1570 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001571 default:
1572 vpanic("encode_bfp_rounding_mode");
1573 }
1574
1575 return mktemp(Ity_I32, rm);
1576}
1577
florianc8e4f562012-10-27 16:19:31 +00001578/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1579 IRRoundingMode:
1580
1581 rounding mode | s390 | IR
1582 ------------------------------------------------
1583 to nearest, ties to even | 000 | 000
1584 to zero | 001 | 011
1585 to +infinity | 010 | 010
1586 to -infinity | 011 | 001
1587 to nearest, ties away from 0 | 100 | 100
1588 to nearest, ties toward 0 | 101 | 111
1589 to away from 0 | 110 | 110
1590 to prepare for shorter precision | 111 | 101
1591
1592 So: IR = (s390 ^ ((s390 << 1) & 2))
1593*/
florianc8e4f562012-10-27 16:19:31 +00001594static IRExpr *
1595get_dfp_rounding_mode_from_fpc(void)
1596{
1597 IRTemp fpc_bits = newTemp(Ity_I32);
1598
1599 /* The dfp rounding mode is stored in bits [25:27].
1600 extract the bits at 25:27 and right shift 4 times. */
1601 assign(fpc_bits, binop(Iop_Shr32,
1602 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1603 mkU8(4)));
1604
1605 IRExpr *rm_s390 = mkexpr(fpc_bits);
1606 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1607
1608 return binop(Iop_Xor32, rm_s390,
1609 binop( Iop_And32,
1610 binop(Iop_Shl32, rm_s390, mkU8(1)),
1611 mkU32(2)));
1612}
1613
1614/* Encode the s390 rounding mode as it appears in the m3 field of certain
1615 instructions to VEX's IRRoundingMode. */
1616static IRTemp
1617encode_dfp_rounding_mode(UChar mode)
1618{
1619 IRExpr *rm;
1620
1621 switch (mode) {
1622 case S390_DFP_ROUND_PER_FPC_0:
1623 case S390_DFP_ROUND_PER_FPC_2:
1624 rm = get_dfp_rounding_mode_from_fpc(); break;
1625 case S390_DFP_ROUND_NEAREST_EVEN_4:
1626 case S390_DFP_ROUND_NEAREST_EVEN_8:
florian79e5a482013-06-06 19:12:46 +00001627 rm = mkU32(Irrm_NEAREST); break;
florianc8e4f562012-10-27 16:19:31 +00001628 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1629 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
florian79e5a482013-06-06 19:12:46 +00001630 rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
florianc8e4f562012-10-27 16:19:31 +00001631 case S390_DFP_ROUND_PREPARE_SHORT_3:
1632 case S390_DFP_ROUND_PREPARE_SHORT_15:
florian79e5a482013-06-06 19:12:46 +00001633 rm = mkU32(Irrm_PREPARE_SHORTER); break;
florianc8e4f562012-10-27 16:19:31 +00001634 case S390_DFP_ROUND_ZERO_5:
1635 case S390_DFP_ROUND_ZERO_9:
florian79e5a482013-06-06 19:12:46 +00001636 rm = mkU32(Irrm_ZERO ); break;
florianc8e4f562012-10-27 16:19:31 +00001637 case S390_DFP_ROUND_POSINF_6:
1638 case S390_DFP_ROUND_POSINF_10:
florian79e5a482013-06-06 19:12:46 +00001639 rm = mkU32(Irrm_PosINF); break;
florianc8e4f562012-10-27 16:19:31 +00001640 case S390_DFP_ROUND_NEGINF_7:
1641 case S390_DFP_ROUND_NEGINF_11:
florian79e5a482013-06-06 19:12:46 +00001642 rm = mkU32(Irrm_NegINF); break;
florianc8e4f562012-10-27 16:19:31 +00001643 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
florian79e5a482013-06-06 19:12:46 +00001644 rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
florianc8e4f562012-10-27 16:19:31 +00001645 case S390_DFP_ROUND_AWAY_0:
florian79e5a482013-06-06 19:12:46 +00001646 rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
florianc8e4f562012-10-27 16:19:31 +00001647 default:
1648 vpanic("encode_dfp_rounding_mode");
1649 }
1650
1651 return mktemp(Ity_I32, rm);
1652}
florian12390202012-11-10 22:34:14 +00001653
florianc8e4f562012-10-27 16:19:31 +00001654
florian2c74d242012-09-12 19:38:42 +00001655/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001656/*--- Condition code helpers ---*/
1657/*------------------------------------------------------------*/
1658
1659/* The result of a Iop_CmpFxx operation is a condition code. It is
1660 encoded using the values defined in type IRCmpFxxResult.
1661 Before we can store the condition code into the guest state (or do
1662 anything else with it for that matter) we need to convert it to
1663 the encoding that s390 uses. This is what this function does.
1664
1665 s390 VEX b6 b2 b0 cc.1 cc.0
1666 0 0x40 EQ 1 0 0 0 0
1667 1 0x01 LT 0 0 1 0 1
1668 2 0x00 GT 0 0 0 1 0
1669 3 0x45 Unordered 1 1 1 1 1
1670
1671 The following bits from the VEX encoding are interesting:
1672 b0, b2, b6 with b0 being the LSB. We observe:
1673
1674 cc.0 = b0;
1675 cc.1 = b2 | (~b0 & ~b6)
1676
1677 with cc being the s390 condition code.
1678*/
1679static IRExpr *
1680convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1681{
1682 IRTemp cc0 = newTemp(Ity_I32);
1683 IRTemp cc1 = newTemp(Ity_I32);
1684 IRTemp b0 = newTemp(Ity_I32);
1685 IRTemp b2 = newTemp(Ity_I32);
1686 IRTemp b6 = newTemp(Ity_I32);
1687
1688 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1689 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1690 mkU32(1)));
1691 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1692 mkU32(1)));
1693
1694 assign(cc0, mkexpr(b0));
1695 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1696 binop(Iop_And32,
1697 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1698 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1699 )));
1700
1701 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1702}
1703
1704
1705/* The result of a Iop_CmpDxx operation is a condition code. It is
1706 encoded using the values defined in type IRCmpDxxResult.
1707 Before we can store the condition code into the guest state (or do
1708 anything else with it for that matter) we need to convert it to
1709 the encoding that s390 uses. This is what this function does. */
1710static IRExpr *
1711convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1712{
1713 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1714 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001715 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001716}
1717
1718
1719/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001720/*--- Build IR for formats ---*/
1721/*------------------------------------------------------------*/
1722static void
florian55085f82012-11-21 00:36:55 +00001723s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001724 UChar i)
1725{
florian55085f82012-11-21 00:36:55 +00001726 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001727
sewardj7ee97522011-05-09 21:45:04 +00001728 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001729 s390_disasm(ENC2(MNM, UINT), mnm, i);
1730}
1731
1732static void
florian78d5ef72013-05-11 15:02:58 +00001733s390_format_E(const HChar *(*irgen)(void))
1734{
1735 const HChar *mnm = irgen();
1736
1737 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1738 s390_disasm(ENC1(MNM), mnm);
1739}
1740
1741static void
florian55085f82012-11-21 00:36:55 +00001742s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001743 UChar r1, UShort i2)
1744{
1745 irgen(r1, i2);
1746}
1747
1748static void
florian55085f82012-11-21 00:36:55 +00001749s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001750 UChar r1, UShort i2)
1751{
florian55085f82012-11-21 00:36:55 +00001752 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001753
sewardj7ee97522011-05-09 21:45:04 +00001754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001755 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1756}
1757
1758static void
florian55085f82012-11-21 00:36:55 +00001759s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001760 UChar r1, UShort i2)
1761{
florian55085f82012-11-21 00:36:55 +00001762 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001763
sewardj7ee97522011-05-09 21:45:04 +00001764 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001765 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1766}
1767
1768static void
florian55085f82012-11-21 00:36:55 +00001769s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001770 UChar r1, UShort i2)
1771{
florian55085f82012-11-21 00:36:55 +00001772 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001773
sewardj7ee97522011-05-09 21:45:04 +00001774 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001775 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1776}
1777
1778static void
florian55085f82012-11-21 00:36:55 +00001779s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001780 UChar r1, UChar r3, UShort i2)
1781{
florian55085f82012-11-21 00:36:55 +00001782 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001783
sewardj7ee97522011-05-09 21:45:04 +00001784 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001785 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1786}
1787
1788static void
florian55085f82012-11-21 00:36:55 +00001789s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001790 UChar r1, UChar r3, UShort i2)
1791{
florian55085f82012-11-21 00:36:55 +00001792 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001793
sewardj7ee97522011-05-09 21:45:04 +00001794 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001795 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1796}
1797
1798static void
florian55085f82012-11-21 00:36:55 +00001799s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1800 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001801 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1802{
florian55085f82012-11-21 00:36:55 +00001803 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001804
sewardj7ee97522011-05-09 21:45:04 +00001805 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001806 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1807 i5);
1808}
1809
1810static void
florian55085f82012-11-21 00:36:55 +00001811s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1812 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001813 UChar r1, UChar r2, UShort i4, UChar m3)
1814{
florian55085f82012-11-21 00:36:55 +00001815 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001816
sewardj7ee97522011-05-09 21:45:04 +00001817 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001818 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1819 r2, m3, (Int)(Short)i4);
1820}
1821
1822static void
florian55085f82012-11-21 00:36:55 +00001823s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1824 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001825 UChar r1, UChar m3, UShort i4, UChar i2)
1826{
florian55085f82012-11-21 00:36:55 +00001827 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001828
sewardj7ee97522011-05-09 21:45:04 +00001829 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001830 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1831 r1, i2, m3, (Int)(Short)i4);
1832}
1833
1834static void
florian55085f82012-11-21 00:36:55 +00001835s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1836 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001837 UChar r1, UChar m3, UShort i4, UChar i2)
1838{
florian55085f82012-11-21 00:36:55 +00001839 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001840
sewardj7ee97522011-05-09 21:45:04 +00001841 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001842 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1843 (Int)(Char)i2, m3, (Int)(Short)i4);
1844}
1845
1846static void
florian55085f82012-11-21 00:36:55 +00001847s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001848 UChar r1, UInt i2)
1849{
1850 irgen(r1, i2);
1851}
1852
1853static void
florian55085f82012-11-21 00:36:55 +00001854s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001855 UChar r1, UInt i2)
1856{
florian55085f82012-11-21 00:36:55 +00001857 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001858
sewardj7ee97522011-05-09 21:45:04 +00001859 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001860 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1861}
1862
1863static void
florian55085f82012-11-21 00:36:55 +00001864s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001865 UChar r1, UInt i2)
1866{
florian55085f82012-11-21 00:36:55 +00001867 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001868
sewardj7ee97522011-05-09 21:45:04 +00001869 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001870 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1871}
1872
1873static void
florian55085f82012-11-21 00:36:55 +00001874s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001875 UChar r1, UInt i2)
1876{
florian55085f82012-11-21 00:36:55 +00001877 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001878
sewardj7ee97522011-05-09 21:45:04 +00001879 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001880 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1881}
1882
1883static void
florian55085f82012-11-21 00:36:55 +00001884s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001885 UChar r1, UInt i2)
1886{
florian55085f82012-11-21 00:36:55 +00001887 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001888
sewardj7ee97522011-05-09 21:45:04 +00001889 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001890 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1891}
1892
1893static void
florian55085f82012-11-21 00:36:55 +00001894s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001895 IRTemp op4addr),
1896 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1897{
florian55085f82012-11-21 00:36:55 +00001898 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001899 IRTemp op4addr = newTemp(Ity_I64);
1900
1901 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1902 mkU64(0)));
1903
1904 mnm = irgen(r1, m3, i2, op4addr);
1905
sewardj7ee97522011-05-09 21:45:04 +00001906 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001907 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1908 (Int)(Char)i2, m3, d4, 0, b4);
1909}
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001913 IRTemp op4addr),
1914 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1915{
florian55085f82012-11-21 00:36:55 +00001916 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001917 IRTemp op4addr = newTemp(Ity_I64);
1918
1919 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1920 mkU64(0)));
1921
1922 mnm = irgen(r1, m3, i2, op4addr);
1923
sewardj7ee97522011-05-09 21:45:04 +00001924 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001925 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1926 i2, m3, d4, 0, b4);
1927}
1928
1929static void
florian55085f82012-11-21 00:36:55 +00001930s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001931 UChar r1, UChar r2)
1932{
1933 irgen(r1, r2);
1934}
1935
1936static void
florian55085f82012-11-21 00:36:55 +00001937s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001938 UChar r1, UChar r2)
1939{
florian55085f82012-11-21 00:36:55 +00001940 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001941
sewardj7ee97522011-05-09 21:45:04 +00001942 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001943 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1944}
1945
1946static void
florian55085f82012-11-21 00:36:55 +00001947s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001948 UChar r1, UChar r2)
1949{
florian55085f82012-11-21 00:36:55 +00001950 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001951
sewardj7ee97522011-05-09 21:45:04 +00001952 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001953 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1954}
1955
1956static void
florian55085f82012-11-21 00:36:55 +00001957s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001958 UChar r1, UChar r2)
1959{
1960 irgen(r1, r2);
1961}
1962
1963static void
florian55085f82012-11-21 00:36:55 +00001964s390_format_RRE_RR(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, GPR, GPR), mnm, r1, r2);
1971}
1972
1973static void
florian55085f82012-11-21 00:36:55 +00001974s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001975 UChar r1, UChar r2)
1976{
florian55085f82012-11-21 00:36:55 +00001977 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001978
sewardj7ee97522011-05-09 21:45:04 +00001979 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001980 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1981}
1982
1983static void
florian55085f82012-11-21 00:36:55 +00001984s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001985 UChar r1, UChar r2)
1986{
florian55085f82012-11-21 00:36:55 +00001987 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001988
sewardj7ee97522011-05-09 21:45:04 +00001989 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001990 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1991}
1992
1993static void
florian55085f82012-11-21 00:36:55 +00001994s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001995 UChar r1, UChar r2)
1996{
florian55085f82012-11-21 00:36:55 +00001997 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001998
sewardj7ee97522011-05-09 21:45:04 +00001999 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002000 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2001}
2002
2003static void
florian55085f82012-11-21 00:36:55 +00002004s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002005 UChar r1)
2006{
florian55085f82012-11-21 00:36:55 +00002007 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002008
sewardj7ee97522011-05-09 21:45:04 +00002009 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002010 s390_disasm(ENC2(MNM, GPR), mnm, r1);
2011}
2012
2013static void
florian55085f82012-11-21 00:36:55 +00002014s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002015 UChar r1)
2016{
florian55085f82012-11-21 00:36:55 +00002017 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002018
sewardj7ee97522011-05-09 21:45:04 +00002019 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002020 s390_disasm(ENC2(MNM, FPR), mnm, r1);
2021}
2022
2023static void
florian55085f82012-11-21 00:36:55 +00002024s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002025 UChar m3, UChar r1, UChar r2)
2026{
florian55085f82012-11-21 00:36:55 +00002027 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002028
2029 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002030 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002031}
2032
2033static void
florian55085f82012-11-21 00:36:55 +00002034s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002035 UChar r1, UChar r3, UChar r2)
2036{
florian55085f82012-11-21 00:36:55 +00002037 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002038
sewardj7ee97522011-05-09 21:45:04 +00002039 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002040 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2041}
2042
2043static void
florian5c539732013-02-14 14:27:12 +00002044s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2045 UChar r3, UChar r1, UChar r2)
2046{
2047 const HChar *mnm = irgen(r3, r1, r2);
2048
2049 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2050 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2051}
2052
2053static void
florian55085f82012-11-21 00:36:55 +00002054s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2055 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002056 UChar m3, UChar m4, UChar r1, UChar r2)
2057{
florian55085f82012-11-21 00:36:55 +00002058 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002059
2060 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2061 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2062}
2063
2064static void
floriane38f6412012-12-21 17:32:12 +00002065s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2066 UChar m4, UChar r1, UChar r2)
2067{
2068 const HChar *mnm = irgen(m4, r1, r2);
2069
2070 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2071 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2072}
2073
2074static void
florian55085f82012-11-21 00:36:55 +00002075s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2076 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002077 UChar m3, UChar m4, UChar r1, UChar r2)
2078{
florian55085f82012-11-21 00:36:55 +00002079 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002080
2081 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2082 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2083}
2084
2085static void
florian55085f82012-11-21 00:36:55 +00002086s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2087 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002088 UChar m3, UChar m4, UChar r1, UChar r2)
2089{
florian55085f82012-11-21 00:36:55 +00002090 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002091
2092 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2093 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2094}
2095
2096
2097static void
florian55085f82012-11-21 00:36:55 +00002098s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002099 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2100{
2101 irgen(m3, r1, r2);
2102
sewardj7ee97522011-05-09 21:45:04 +00002103 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002104 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2105}
2106
2107static void
florian55085f82012-11-21 00:36:55 +00002108s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002109 UChar r3, UChar r1, UChar r2)
2110{
florian55085f82012-11-21 00:36:55 +00002111 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002112
sewardj7ee97522011-05-09 21:45:04 +00002113 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002114 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2115}
2116
2117static void
florian5c539732013-02-14 14:27:12 +00002118s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2119 UChar r3, UChar m4, UChar r1, UChar r2)
2120{
2121 const HChar *mnm = irgen(r3, m4, r1, r2);
2122
2123 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2124 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2125}
2126
2127static void
2128s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2129 UChar r3, UChar m4, UChar r1, UChar r2)
2130{
2131 const HChar *mnm = irgen(r3, m4, r1, r2);
2132
2133 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2134 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2135}
2136
2137static void
florian55085f82012-11-21 00:36:55 +00002138s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002139 UChar r3, UChar m4, UChar r1, UChar r2)
2140{
florian55085f82012-11-21 00:36:55 +00002141 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002142
2143 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2144 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2145}
2146
2147static void
florian55085f82012-11-21 00:36:55 +00002148s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002149 UChar r3, UChar r1, UChar r2)
2150{
florian55085f82012-11-21 00:36:55 +00002151 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002152
sewardj7ee97522011-05-09 21:45:04 +00002153 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002154 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2155}
2156
2157static void
florian55085f82012-11-21 00:36:55 +00002158s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2159 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002160 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2161{
florian55085f82012-11-21 00:36:55 +00002162 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002163 IRTemp op4addr = newTemp(Ity_I64);
2164
2165 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2166 mkU64(0)));
2167
2168 mnm = irgen(r1, r2, m3, op4addr);
2169
sewardj7ee97522011-05-09 21:45:04 +00002170 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002171 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2172 r2, m3, d4, 0, b4);
2173}
2174
2175static void
florian55085f82012-11-21 00:36:55 +00002176s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002177 UChar r1, UChar b2, UShort d2)
2178{
florian55085f82012-11-21 00:36:55 +00002179 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002180 IRTemp op2addr = newTemp(Ity_I64);
2181
2182 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2183 mkU64(0)));
2184
2185 mnm = irgen(r1, op2addr);
2186
sewardj7ee97522011-05-09 21:45:04 +00002187 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002188 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2189}
2190
2191static void
florian55085f82012-11-21 00:36:55 +00002192s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002193 UChar r1, UChar r3, UChar b2, UShort d2)
2194{
florian55085f82012-11-21 00:36:55 +00002195 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002196 IRTemp op2addr = newTemp(Ity_I64);
2197
2198 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2199 mkU64(0)));
2200
2201 mnm = irgen(r1, r3, op2addr);
2202
sewardj7ee97522011-05-09 21:45:04 +00002203 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002204 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2205}
2206
2207static void
florian55085f82012-11-21 00:36:55 +00002208s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002209 UChar r1, UChar r3, UChar b2, UShort d2)
2210{
florian55085f82012-11-21 00:36:55 +00002211 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002212 IRTemp op2addr = newTemp(Ity_I64);
2213
2214 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2215 mkU64(0)));
2216
2217 mnm = irgen(r1, r3, op2addr);
2218
sewardj7ee97522011-05-09 21:45:04 +00002219 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002220 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2221}
2222
2223static void
florian55085f82012-11-21 00:36:55 +00002224s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002225 UChar r1, UChar r3, UChar b2, UShort d2)
2226{
florian55085f82012-11-21 00:36:55 +00002227 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002228 IRTemp op2addr = newTemp(Ity_I64);
2229
2230 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2231 mkU64(0)));
2232
2233 mnm = irgen(r1, r3, op2addr);
2234
sewardj7ee97522011-05-09 21:45:04 +00002235 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002236 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2237}
2238
2239static void
florian55085f82012-11-21 00:36:55 +00002240s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002241 UChar r1, UChar r3, UShort i2)
2242{
florian55085f82012-11-21 00:36:55 +00002243 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002244
sewardj7ee97522011-05-09 21:45:04 +00002245 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002246 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2247}
2248
2249static void
florian55085f82012-11-21 00:36:55 +00002250s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002251 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2252{
florian55085f82012-11-21 00:36:55 +00002253 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002254 IRTemp op2addr = newTemp(Ity_I64);
2255 IRTemp d2 = newTemp(Ity_I64);
2256
2257 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2258 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2259 mkU64(0)));
2260
2261 mnm = irgen(r1, r3, op2addr);
2262
sewardj7ee97522011-05-09 21:45:04 +00002263 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002264 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2265}
2266
2267static void
florian55085f82012-11-21 00:36:55 +00002268s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002269 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2270{
florian55085f82012-11-21 00:36:55 +00002271 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002272 IRTemp op2addr = newTemp(Ity_I64);
2273 IRTemp d2 = newTemp(Ity_I64);
2274
2275 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2276 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2277 mkU64(0)));
2278
2279 mnm = irgen(r1, r3, op2addr);
2280
sewardj7ee97522011-05-09 21:45:04 +00002281 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002282 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2283}
2284
2285static void
florian55085f82012-11-21 00:36:55 +00002286s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002287 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2288{
florian55085f82012-11-21 00:36:55 +00002289 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002290 IRTemp op2addr = newTemp(Ity_I64);
2291 IRTemp d2 = newTemp(Ity_I64);
2292
2293 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2294 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2295 mkU64(0)));
2296
2297 mnm = irgen(r1, r3, op2addr);
2298
sewardj7ee97522011-05-09 21:45:04 +00002299 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002300 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2301}
2302
2303static void
florian55085f82012-11-21 00:36:55 +00002304s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002305 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2306 Int xmnm_kind)
2307{
2308 IRTemp op2addr = newTemp(Ity_I64);
2309 IRTemp d2 = newTemp(Ity_I64);
2310
florian6820ba52012-07-26 02:01:50 +00002311 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2312
sewardjd7bde722011-04-05 13:19:33 +00002313 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2314 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2315 mkU64(0)));
2316
2317 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002318
2319 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002320
sewardj7ee97522011-05-09 21:45:04 +00002321 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002322 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2323}
2324
2325static void
florian55085f82012-11-21 00:36:55 +00002326s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002327 IRTemp op2addr),
2328 UChar r1, UChar x2, UChar b2, UShort d2)
2329{
2330 IRTemp op2addr = newTemp(Ity_I64);
2331
2332 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2333 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2334 mkU64(0)));
2335
2336 irgen(r1, x2, b2, d2, op2addr);
2337}
2338
2339static void
florian55085f82012-11-21 00:36:55 +00002340s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002341 UChar r1, UChar x2, UChar b2, UShort d2)
2342{
florian55085f82012-11-21 00:36:55 +00002343 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002344 IRTemp op2addr = newTemp(Ity_I64);
2345
2346 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2347 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2348 mkU64(0)));
2349
2350 mnm = irgen(r1, op2addr);
2351
sewardj7ee97522011-05-09 21:45:04 +00002352 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002353 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2354}
2355
2356static void
florian55085f82012-11-21 00:36:55 +00002357s390_format_RX_FRRD(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, FPR, UDXB), mnm, r1, d2, x2, b2);
2371}
2372
2373static void
florian55085f82012-11-21 00:36:55 +00002374s390_format_RXE_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_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002392 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
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(r3, op2addr, r1);
2402
sewardj7ee97522011-05-09 21:45:04 +00002403 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002404 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2405}
2406
2407static void
florian55085f82012-11-21 00:36:55 +00002408s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002409 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2410{
florian55085f82012-11-21 00:36:55 +00002411 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002412 IRTemp op2addr = newTemp(Ity_I64);
2413 IRTemp d2 = newTemp(Ity_I64);
2414
2415 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2416 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2417 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2418 mkU64(0)));
2419
2420 mnm = irgen(r1, op2addr);
2421
sewardj7ee97522011-05-09 21:45:04 +00002422 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002423 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2424}
2425
2426static void
florian55085f82012-11-21 00:36:55 +00002427s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002428 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2429{
florian55085f82012-11-21 00:36:55 +00002430 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002431 IRTemp op2addr = newTemp(Ity_I64);
2432 IRTemp d2 = newTemp(Ity_I64);
2433
2434 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2435 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2436 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2437 mkU64(0)));
2438
2439 mnm = irgen(r1, op2addr);
2440
sewardj7ee97522011-05-09 21:45:04 +00002441 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002442 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2443}
2444
2445static void
florian55085f82012-11-21 00:36:55 +00002446s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002447 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2448{
florian55085f82012-11-21 00:36:55 +00002449 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002450 IRTemp op2addr = newTemp(Ity_I64);
2451 IRTemp d2 = newTemp(Ity_I64);
2452
2453 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2454 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2455 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2456 mkU64(0)));
2457
2458 mnm = irgen();
2459
sewardj7ee97522011-05-09 21:45:04 +00002460 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002461 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2462}
2463
2464static void
florian55085f82012-11-21 00:36:55 +00002465s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002466 UChar b2, UShort d2)
2467{
florian55085f82012-11-21 00:36:55 +00002468 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002469 IRTemp op2addr = newTemp(Ity_I64);
2470
2471 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2472 mkU64(0)));
2473
2474 mnm = irgen(op2addr);
2475
sewardj7ee97522011-05-09 21:45:04 +00002476 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002477 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2478}
2479
2480static void
florian55085f82012-11-21 00:36:55 +00002481s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002482 UChar i2, UChar b1, UShort d1)
2483{
florian55085f82012-11-21 00:36:55 +00002484 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002485 IRTemp op1addr = newTemp(Ity_I64);
2486
2487 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2488 mkU64(0)));
2489
2490 mnm = irgen(i2, op1addr);
2491
sewardj7ee97522011-05-09 21:45:04 +00002492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002493 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2494}
2495
2496static void
florian55085f82012-11-21 00:36:55 +00002497s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002498 UChar i2, UChar b1, UShort dl1, UChar dh1)
2499{
florian55085f82012-11-21 00:36:55 +00002500 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002501 IRTemp op1addr = newTemp(Ity_I64);
2502 IRTemp d1 = newTemp(Ity_I64);
2503
2504 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2505 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2506 mkU64(0)));
2507
2508 mnm = irgen(i2, op1addr);
2509
sewardj7ee97522011-05-09 21:45:04 +00002510 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002511 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2512}
2513
2514static void
florian55085f82012-11-21 00:36:55 +00002515s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002516 UChar i2, UChar b1, UShort dl1, UChar dh1)
2517{
florian55085f82012-11-21 00:36:55 +00002518 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002519 IRTemp op1addr = newTemp(Ity_I64);
2520 IRTemp d1 = newTemp(Ity_I64);
2521
2522 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2523 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2524 mkU64(0)));
2525
2526 mnm = irgen(i2, op1addr);
2527
sewardj7ee97522011-05-09 21:45:04 +00002528 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002529 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2530}
2531
2532static void
florian55085f82012-11-21 00:36:55 +00002533s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002534 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2535{
florian55085f82012-11-21 00:36:55 +00002536 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002537 IRTemp op1addr = newTemp(Ity_I64);
2538 IRTemp op2addr = newTemp(Ity_I64);
2539
2540 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2541 mkU64(0)));
2542 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2543 mkU64(0)));
2544
2545 mnm = irgen(l, op1addr, op2addr);
2546
sewardj7ee97522011-05-09 21:45:04 +00002547 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002548 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2549}
2550
2551static void
florian55085f82012-11-21 00:36:55 +00002552s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002553 UChar b1, UShort d1, UShort i2)
2554{
florian55085f82012-11-21 00:36:55 +00002555 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002556 IRTemp op1addr = newTemp(Ity_I64);
2557
2558 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2559 mkU64(0)));
2560
2561 mnm = irgen(i2, op1addr);
2562
sewardj7ee97522011-05-09 21:45:04 +00002563 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002564 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2565}
2566
2567static void
florian55085f82012-11-21 00:36:55 +00002568s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002569 UChar b1, UShort d1, UShort i2)
2570{
florian55085f82012-11-21 00:36:55 +00002571 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002572 IRTemp op1addr = newTemp(Ity_I64);
2573
2574 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2575 mkU64(0)));
2576
2577 mnm = irgen(i2, op1addr);
2578
sewardj7ee97522011-05-09 21:45:04 +00002579 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002580 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2581}
2582
2583
2584
2585/*------------------------------------------------------------*/
2586/*--- Build IR for opcodes ---*/
2587/*------------------------------------------------------------*/
2588
florian55085f82012-11-21 00:36:55 +00002589static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002590s390_irgen_AR(UChar r1, UChar r2)
2591{
2592 IRTemp op1 = newTemp(Ity_I32);
2593 IRTemp op2 = newTemp(Ity_I32);
2594 IRTemp result = newTemp(Ity_I32);
2595
2596 assign(op1, get_gpr_w1(r1));
2597 assign(op2, get_gpr_w1(r2));
2598 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2599 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2600 put_gpr_w1(r1, mkexpr(result));
2601
2602 return "ar";
2603}
2604
florian55085f82012-11-21 00:36:55 +00002605static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002606s390_irgen_AGR(UChar r1, UChar r2)
2607{
2608 IRTemp op1 = newTemp(Ity_I64);
2609 IRTemp op2 = newTemp(Ity_I64);
2610 IRTemp result = newTemp(Ity_I64);
2611
2612 assign(op1, get_gpr_dw0(r1));
2613 assign(op2, get_gpr_dw0(r2));
2614 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2615 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2616 put_gpr_dw0(r1, mkexpr(result));
2617
2618 return "agr";
2619}
2620
florian55085f82012-11-21 00:36:55 +00002621static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002622s390_irgen_AGFR(UChar r1, UChar r2)
2623{
2624 IRTemp op1 = newTemp(Ity_I64);
2625 IRTemp op2 = newTemp(Ity_I64);
2626 IRTemp result = newTemp(Ity_I64);
2627
2628 assign(op1, get_gpr_dw0(r1));
2629 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2630 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2631 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2632 put_gpr_dw0(r1, mkexpr(result));
2633
2634 return "agfr";
2635}
2636
florian55085f82012-11-21 00:36:55 +00002637static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002638s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2639{
2640 IRTemp op2 = newTemp(Ity_I32);
2641 IRTemp op3 = newTemp(Ity_I32);
2642 IRTemp result = newTemp(Ity_I32);
2643
2644 assign(op2, get_gpr_w1(r2));
2645 assign(op3, get_gpr_w1(r3));
2646 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2647 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2648 put_gpr_w1(r1, mkexpr(result));
2649
2650 return "ark";
2651}
2652
florian55085f82012-11-21 00:36:55 +00002653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002654s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2655{
2656 IRTemp op2 = newTemp(Ity_I64);
2657 IRTemp op3 = newTemp(Ity_I64);
2658 IRTemp result = newTemp(Ity_I64);
2659
2660 assign(op2, get_gpr_dw0(r2));
2661 assign(op3, get_gpr_dw0(r3));
2662 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2663 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2664 put_gpr_dw0(r1, mkexpr(result));
2665
2666 return "agrk";
2667}
2668
florian55085f82012-11-21 00:36:55 +00002669static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002670s390_irgen_A(UChar r1, IRTemp op2addr)
2671{
2672 IRTemp op1 = newTemp(Ity_I32);
2673 IRTemp op2 = newTemp(Ity_I32);
2674 IRTemp result = newTemp(Ity_I32);
2675
2676 assign(op1, get_gpr_w1(r1));
2677 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2678 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2679 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2680 put_gpr_w1(r1, mkexpr(result));
2681
2682 return "a";
2683}
2684
florian55085f82012-11-21 00:36:55 +00002685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002686s390_irgen_AY(UChar r1, IRTemp op2addr)
2687{
2688 IRTemp op1 = newTemp(Ity_I32);
2689 IRTemp op2 = newTemp(Ity_I32);
2690 IRTemp result = newTemp(Ity_I32);
2691
2692 assign(op1, get_gpr_w1(r1));
2693 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2694 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2695 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2696 put_gpr_w1(r1, mkexpr(result));
2697
2698 return "ay";
2699}
2700
florian55085f82012-11-21 00:36:55 +00002701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002702s390_irgen_AG(UChar r1, IRTemp op2addr)
2703{
2704 IRTemp op1 = newTemp(Ity_I64);
2705 IRTemp op2 = newTemp(Ity_I64);
2706 IRTemp result = newTemp(Ity_I64);
2707
2708 assign(op1, get_gpr_dw0(r1));
2709 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2710 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2711 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2712 put_gpr_dw0(r1, mkexpr(result));
2713
2714 return "ag";
2715}
2716
florian55085f82012-11-21 00:36:55 +00002717static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002718s390_irgen_AGF(UChar r1, IRTemp op2addr)
2719{
2720 IRTemp op1 = newTemp(Ity_I64);
2721 IRTemp op2 = newTemp(Ity_I64);
2722 IRTemp result = newTemp(Ity_I64);
2723
2724 assign(op1, get_gpr_dw0(r1));
2725 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2726 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2727 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2728 put_gpr_dw0(r1, mkexpr(result));
2729
2730 return "agf";
2731}
2732
florian55085f82012-11-21 00:36:55 +00002733static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002734s390_irgen_AFI(UChar r1, UInt i2)
2735{
2736 IRTemp op1 = newTemp(Ity_I32);
2737 Int op2;
2738 IRTemp result = newTemp(Ity_I32);
2739
2740 assign(op1, get_gpr_w1(r1));
2741 op2 = (Int)i2;
2742 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2743 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2744 mkU32((UInt)op2)));
2745 put_gpr_w1(r1, mkexpr(result));
2746
2747 return "afi";
2748}
2749
florian55085f82012-11-21 00:36:55 +00002750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002751s390_irgen_AGFI(UChar r1, UInt i2)
2752{
2753 IRTemp op1 = newTemp(Ity_I64);
2754 Long op2;
2755 IRTemp result = newTemp(Ity_I64);
2756
2757 assign(op1, get_gpr_dw0(r1));
2758 op2 = (Long)(Int)i2;
2759 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2760 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2761 mkU64((ULong)op2)));
2762 put_gpr_dw0(r1, mkexpr(result));
2763
2764 return "agfi";
2765}
2766
florian55085f82012-11-21 00:36:55 +00002767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002768s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2769{
2770 Int op2;
2771 IRTemp op3 = newTemp(Ity_I32);
2772 IRTemp result = newTemp(Ity_I32);
2773
2774 op2 = (Int)(Short)i2;
2775 assign(op3, get_gpr_w1(r3));
2776 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2777 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2778 op2)), op3);
2779 put_gpr_w1(r1, mkexpr(result));
2780
2781 return "ahik";
2782}
2783
florian55085f82012-11-21 00:36:55 +00002784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002785s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2786{
2787 Long op2;
2788 IRTemp op3 = newTemp(Ity_I64);
2789 IRTemp result = newTemp(Ity_I64);
2790
2791 op2 = (Long)(Short)i2;
2792 assign(op3, get_gpr_dw0(r3));
2793 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2794 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2795 op2)), op3);
2796 put_gpr_dw0(r1, mkexpr(result));
2797
2798 return "aghik";
2799}
2800
florian55085f82012-11-21 00:36:55 +00002801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002802s390_irgen_ASI(UChar i2, IRTemp op1addr)
2803{
2804 IRTemp op1 = newTemp(Ity_I32);
2805 Int op2;
2806 IRTemp result = newTemp(Ity_I32);
2807
2808 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2809 op2 = (Int)(Char)i2;
2810 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2811 store(mkexpr(op1addr), mkexpr(result));
2812 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2813 mkU32((UInt)op2)));
2814
2815 return "asi";
2816}
2817
florian55085f82012-11-21 00:36:55 +00002818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002819s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2820{
2821 IRTemp op1 = newTemp(Ity_I64);
2822 Long op2;
2823 IRTemp result = newTemp(Ity_I64);
2824
2825 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2826 op2 = (Long)(Char)i2;
2827 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2828 store(mkexpr(op1addr), mkexpr(result));
2829 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2830 mkU64((ULong)op2)));
2831
2832 return "agsi";
2833}
2834
florian55085f82012-11-21 00:36:55 +00002835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002836s390_irgen_AH(UChar r1, IRTemp op2addr)
2837{
2838 IRTemp op1 = newTemp(Ity_I32);
2839 IRTemp op2 = newTemp(Ity_I32);
2840 IRTemp result = newTemp(Ity_I32);
2841
2842 assign(op1, get_gpr_w1(r1));
2843 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2844 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2845 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2846 put_gpr_w1(r1, mkexpr(result));
2847
2848 return "ah";
2849}
2850
florian55085f82012-11-21 00:36:55 +00002851static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002852s390_irgen_AHY(UChar r1, IRTemp op2addr)
2853{
2854 IRTemp op1 = newTemp(Ity_I32);
2855 IRTemp op2 = newTemp(Ity_I32);
2856 IRTemp result = newTemp(Ity_I32);
2857
2858 assign(op1, get_gpr_w1(r1));
2859 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2860 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2861 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2862 put_gpr_w1(r1, mkexpr(result));
2863
2864 return "ahy";
2865}
2866
florian55085f82012-11-21 00:36:55 +00002867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002868s390_irgen_AHI(UChar r1, UShort i2)
2869{
2870 IRTemp op1 = newTemp(Ity_I32);
2871 Int op2;
2872 IRTemp result = newTemp(Ity_I32);
2873
2874 assign(op1, get_gpr_w1(r1));
2875 op2 = (Int)(Short)i2;
2876 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2877 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2878 mkU32((UInt)op2)));
2879 put_gpr_w1(r1, mkexpr(result));
2880
2881 return "ahi";
2882}
2883
florian55085f82012-11-21 00:36:55 +00002884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002885s390_irgen_AGHI(UChar r1, UShort i2)
2886{
2887 IRTemp op1 = newTemp(Ity_I64);
2888 Long op2;
2889 IRTemp result = newTemp(Ity_I64);
2890
2891 assign(op1, get_gpr_dw0(r1));
2892 op2 = (Long)(Short)i2;
2893 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2894 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2895 mkU64((ULong)op2)));
2896 put_gpr_dw0(r1, mkexpr(result));
2897
2898 return "aghi";
2899}
2900
florian55085f82012-11-21 00:36:55 +00002901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002902s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2903{
2904 IRTemp op2 = newTemp(Ity_I32);
2905 IRTemp op3 = newTemp(Ity_I32);
2906 IRTemp result = newTemp(Ity_I32);
2907
2908 assign(op2, get_gpr_w0(r2));
2909 assign(op3, get_gpr_w0(r3));
2910 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2911 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2912 put_gpr_w0(r1, mkexpr(result));
2913
2914 return "ahhhr";
2915}
2916
florian55085f82012-11-21 00:36:55 +00002917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002918s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2919{
2920 IRTemp op2 = newTemp(Ity_I32);
2921 IRTemp op3 = newTemp(Ity_I32);
2922 IRTemp result = newTemp(Ity_I32);
2923
2924 assign(op2, get_gpr_w0(r2));
2925 assign(op3, get_gpr_w1(r3));
2926 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2927 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2928 put_gpr_w0(r1, mkexpr(result));
2929
2930 return "ahhlr";
2931}
2932
florian55085f82012-11-21 00:36:55 +00002933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002934s390_irgen_AIH(UChar r1, UInt i2)
2935{
2936 IRTemp op1 = newTemp(Ity_I32);
2937 Int op2;
2938 IRTemp result = newTemp(Ity_I32);
2939
2940 assign(op1, get_gpr_w0(r1));
2941 op2 = (Int)i2;
2942 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2943 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2944 mkU32((UInt)op2)));
2945 put_gpr_w0(r1, mkexpr(result));
2946
2947 return "aih";
2948}
2949
florian55085f82012-11-21 00:36:55 +00002950static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002951s390_irgen_ALR(UChar r1, UChar r2)
2952{
2953 IRTemp op1 = newTemp(Ity_I32);
2954 IRTemp op2 = newTemp(Ity_I32);
2955 IRTemp result = newTemp(Ity_I32);
2956
2957 assign(op1, get_gpr_w1(r1));
2958 assign(op2, get_gpr_w1(r2));
2959 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2960 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2961 put_gpr_w1(r1, mkexpr(result));
2962
2963 return "alr";
2964}
2965
florian55085f82012-11-21 00:36:55 +00002966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002967s390_irgen_ALGR(UChar r1, UChar r2)
2968{
2969 IRTemp op1 = newTemp(Ity_I64);
2970 IRTemp op2 = newTemp(Ity_I64);
2971 IRTemp result = newTemp(Ity_I64);
2972
2973 assign(op1, get_gpr_dw0(r1));
2974 assign(op2, get_gpr_dw0(r2));
2975 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2976 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2977 put_gpr_dw0(r1, mkexpr(result));
2978
2979 return "algr";
2980}
2981
florian55085f82012-11-21 00:36:55 +00002982static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002983s390_irgen_ALGFR(UChar r1, UChar r2)
2984{
2985 IRTemp op1 = newTemp(Ity_I64);
2986 IRTemp op2 = newTemp(Ity_I64);
2987 IRTemp result = newTemp(Ity_I64);
2988
2989 assign(op1, get_gpr_dw0(r1));
2990 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2991 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2992 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2993 put_gpr_dw0(r1, mkexpr(result));
2994
2995 return "algfr";
2996}
2997
florian55085f82012-11-21 00:36:55 +00002998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002999s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
3000{
3001 IRTemp op2 = newTemp(Ity_I32);
3002 IRTemp op3 = newTemp(Ity_I32);
3003 IRTemp result = newTemp(Ity_I32);
3004
3005 assign(op2, get_gpr_w1(r2));
3006 assign(op3, get_gpr_w1(r3));
3007 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3008 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3009 put_gpr_w1(r1, mkexpr(result));
3010
3011 return "alrk";
3012}
3013
florian55085f82012-11-21 00:36:55 +00003014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003015s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
3016{
3017 IRTemp op2 = newTemp(Ity_I64);
3018 IRTemp op3 = newTemp(Ity_I64);
3019 IRTemp result = newTemp(Ity_I64);
3020
3021 assign(op2, get_gpr_dw0(r2));
3022 assign(op3, get_gpr_dw0(r3));
3023 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
3024 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3025 put_gpr_dw0(r1, mkexpr(result));
3026
3027 return "algrk";
3028}
3029
florian55085f82012-11-21 00:36:55 +00003030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003031s390_irgen_AL(UChar r1, IRTemp op2addr)
3032{
3033 IRTemp op1 = newTemp(Ity_I32);
3034 IRTemp op2 = newTemp(Ity_I32);
3035 IRTemp result = newTemp(Ity_I32);
3036
3037 assign(op1, get_gpr_w1(r1));
3038 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3039 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3040 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3041 put_gpr_w1(r1, mkexpr(result));
3042
3043 return "al";
3044}
3045
florian55085f82012-11-21 00:36:55 +00003046static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003047s390_irgen_ALY(UChar r1, IRTemp op2addr)
3048{
3049 IRTemp op1 = newTemp(Ity_I32);
3050 IRTemp op2 = newTemp(Ity_I32);
3051 IRTemp result = newTemp(Ity_I32);
3052
3053 assign(op1, get_gpr_w1(r1));
3054 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3055 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3056 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3057 put_gpr_w1(r1, mkexpr(result));
3058
3059 return "aly";
3060}
3061
florian55085f82012-11-21 00:36:55 +00003062static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003063s390_irgen_ALG(UChar r1, IRTemp op2addr)
3064{
3065 IRTemp op1 = newTemp(Ity_I64);
3066 IRTemp op2 = newTemp(Ity_I64);
3067 IRTemp result = newTemp(Ity_I64);
3068
3069 assign(op1, get_gpr_dw0(r1));
3070 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3071 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3072 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3073 put_gpr_dw0(r1, mkexpr(result));
3074
3075 return "alg";
3076}
3077
florian55085f82012-11-21 00:36:55 +00003078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003079s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3080{
3081 IRTemp op1 = newTemp(Ity_I64);
3082 IRTemp op2 = newTemp(Ity_I64);
3083 IRTemp result = newTemp(Ity_I64);
3084
3085 assign(op1, get_gpr_dw0(r1));
3086 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3087 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3088 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3089 put_gpr_dw0(r1, mkexpr(result));
3090
3091 return "algf";
3092}
3093
florian55085f82012-11-21 00:36:55 +00003094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003095s390_irgen_ALFI(UChar r1, UInt i2)
3096{
3097 IRTemp op1 = newTemp(Ity_I32);
3098 UInt op2;
3099 IRTemp result = newTemp(Ity_I32);
3100
3101 assign(op1, get_gpr_w1(r1));
3102 op2 = i2;
3103 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3104 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3105 mkU32(op2)));
3106 put_gpr_w1(r1, mkexpr(result));
3107
3108 return "alfi";
3109}
3110
florian55085f82012-11-21 00:36:55 +00003111static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003112s390_irgen_ALGFI(UChar r1, UInt i2)
3113{
3114 IRTemp op1 = newTemp(Ity_I64);
3115 ULong op2;
3116 IRTemp result = newTemp(Ity_I64);
3117
3118 assign(op1, get_gpr_dw0(r1));
3119 op2 = (ULong)i2;
3120 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3121 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3122 mkU64(op2)));
3123 put_gpr_dw0(r1, mkexpr(result));
3124
3125 return "algfi";
3126}
3127
florian55085f82012-11-21 00:36:55 +00003128static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003129s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3130{
3131 IRTemp op2 = newTemp(Ity_I32);
3132 IRTemp op3 = newTemp(Ity_I32);
3133 IRTemp result = newTemp(Ity_I32);
3134
3135 assign(op2, get_gpr_w0(r2));
3136 assign(op3, get_gpr_w0(r3));
3137 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3138 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3139 put_gpr_w0(r1, mkexpr(result));
3140
3141 return "alhhhr";
3142}
3143
florian55085f82012-11-21 00:36:55 +00003144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003145s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3146{
3147 IRTemp op2 = newTemp(Ity_I32);
3148 IRTemp op3 = newTemp(Ity_I32);
3149 IRTemp result = newTemp(Ity_I32);
3150
3151 assign(op2, get_gpr_w0(r2));
3152 assign(op3, get_gpr_w1(r3));
3153 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3154 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3155 put_gpr_w0(r1, mkexpr(result));
3156
3157 return "alhhlr";
3158}
3159
florian55085f82012-11-21 00:36:55 +00003160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003161s390_irgen_ALCR(UChar r1, UChar r2)
3162{
3163 IRTemp op1 = newTemp(Ity_I32);
3164 IRTemp op2 = newTemp(Ity_I32);
3165 IRTemp result = newTemp(Ity_I32);
3166 IRTemp carry_in = newTemp(Ity_I32);
3167
3168 assign(op1, get_gpr_w1(r1));
3169 assign(op2, get_gpr_w1(r2));
3170 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3171 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3172 mkexpr(carry_in)));
3173 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3174 put_gpr_w1(r1, mkexpr(result));
3175
3176 return "alcr";
3177}
3178
florian55085f82012-11-21 00:36:55 +00003179static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003180s390_irgen_ALCGR(UChar r1, UChar r2)
3181{
3182 IRTemp op1 = newTemp(Ity_I64);
3183 IRTemp op2 = newTemp(Ity_I64);
3184 IRTemp result = newTemp(Ity_I64);
3185 IRTemp carry_in = newTemp(Ity_I64);
3186
3187 assign(op1, get_gpr_dw0(r1));
3188 assign(op2, get_gpr_dw0(r2));
3189 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3190 mkU8(1))));
3191 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3192 mkexpr(carry_in)));
3193 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3194 put_gpr_dw0(r1, mkexpr(result));
3195
3196 return "alcgr";
3197}
3198
florian55085f82012-11-21 00:36:55 +00003199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003200s390_irgen_ALC(UChar r1, IRTemp op2addr)
3201{
3202 IRTemp op1 = newTemp(Ity_I32);
3203 IRTemp op2 = newTemp(Ity_I32);
3204 IRTemp result = newTemp(Ity_I32);
3205 IRTemp carry_in = newTemp(Ity_I32);
3206
3207 assign(op1, get_gpr_w1(r1));
3208 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3209 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3210 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3211 mkexpr(carry_in)));
3212 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3213 put_gpr_w1(r1, mkexpr(result));
3214
3215 return "alc";
3216}
3217
florian55085f82012-11-21 00:36:55 +00003218static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003219s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3220{
3221 IRTemp op1 = newTemp(Ity_I64);
3222 IRTemp op2 = newTemp(Ity_I64);
3223 IRTemp result = newTemp(Ity_I64);
3224 IRTemp carry_in = newTemp(Ity_I64);
3225
3226 assign(op1, get_gpr_dw0(r1));
3227 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3228 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3229 mkU8(1))));
3230 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3231 mkexpr(carry_in)));
3232 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3233 put_gpr_dw0(r1, mkexpr(result));
3234
3235 return "alcg";
3236}
3237
florian55085f82012-11-21 00:36:55 +00003238static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003239s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3240{
3241 IRTemp op1 = newTemp(Ity_I32);
3242 UInt op2;
3243 IRTemp result = newTemp(Ity_I32);
3244
3245 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3246 op2 = (UInt)(Int)(Char)i2;
3247 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3248 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3249 mkU32(op2)));
3250 store(mkexpr(op1addr), mkexpr(result));
3251
3252 return "alsi";
3253}
3254
florian55085f82012-11-21 00:36:55 +00003255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003256s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3257{
3258 IRTemp op1 = newTemp(Ity_I64);
3259 ULong op2;
3260 IRTemp result = newTemp(Ity_I64);
3261
3262 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3263 op2 = (ULong)(Long)(Char)i2;
3264 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3265 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3266 mkU64(op2)));
3267 store(mkexpr(op1addr), mkexpr(result));
3268
3269 return "algsi";
3270}
3271
florian55085f82012-11-21 00:36:55 +00003272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003273s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3274{
3275 UInt op2;
3276 IRTemp op3 = newTemp(Ity_I32);
3277 IRTemp result = newTemp(Ity_I32);
3278
3279 op2 = (UInt)(Int)(Short)i2;
3280 assign(op3, get_gpr_w1(r3));
3281 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3282 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3283 op3);
3284 put_gpr_w1(r1, mkexpr(result));
3285
3286 return "alhsik";
3287}
3288
florian55085f82012-11-21 00:36:55 +00003289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003290s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3291{
3292 ULong op2;
3293 IRTemp op3 = newTemp(Ity_I64);
3294 IRTemp result = newTemp(Ity_I64);
3295
3296 op2 = (ULong)(Long)(Short)i2;
3297 assign(op3, get_gpr_dw0(r3));
3298 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3299 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3300 op3);
3301 put_gpr_dw0(r1, mkexpr(result));
3302
3303 return "alghsik";
3304}
3305
florian55085f82012-11-21 00:36:55 +00003306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003307s390_irgen_ALSIH(UChar r1, UInt i2)
3308{
3309 IRTemp op1 = newTemp(Ity_I32);
3310 UInt op2;
3311 IRTemp result = newTemp(Ity_I32);
3312
3313 assign(op1, get_gpr_w0(r1));
3314 op2 = i2;
3315 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3316 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3317 mkU32(op2)));
3318 put_gpr_w0(r1, mkexpr(result));
3319
3320 return "alsih";
3321}
3322
florian55085f82012-11-21 00:36:55 +00003323static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003324s390_irgen_ALSIHN(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 put_gpr_w0(r1, mkexpr(result));
3334
3335 return "alsihn";
3336}
3337
florian55085f82012-11-21 00:36:55 +00003338static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003339s390_irgen_NR(UChar r1, UChar r2)
3340{
3341 IRTemp op1 = newTemp(Ity_I32);
3342 IRTemp op2 = newTemp(Ity_I32);
3343 IRTemp result = newTemp(Ity_I32);
3344
3345 assign(op1, get_gpr_w1(r1));
3346 assign(op2, get_gpr_w1(r2));
3347 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3348 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3349 put_gpr_w1(r1, mkexpr(result));
3350
3351 return "nr";
3352}
3353
florian55085f82012-11-21 00:36:55 +00003354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003355s390_irgen_NGR(UChar r1, UChar r2)
3356{
3357 IRTemp op1 = newTemp(Ity_I64);
3358 IRTemp op2 = newTemp(Ity_I64);
3359 IRTemp result = newTemp(Ity_I64);
3360
3361 assign(op1, get_gpr_dw0(r1));
3362 assign(op2, get_gpr_dw0(r2));
3363 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3364 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3365 put_gpr_dw0(r1, mkexpr(result));
3366
3367 return "ngr";
3368}
3369
florian55085f82012-11-21 00:36:55 +00003370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003371s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3372{
3373 IRTemp op2 = newTemp(Ity_I32);
3374 IRTemp op3 = newTemp(Ity_I32);
3375 IRTemp result = newTemp(Ity_I32);
3376
3377 assign(op2, get_gpr_w1(r2));
3378 assign(op3, get_gpr_w1(r3));
3379 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3380 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3381 put_gpr_w1(r1, mkexpr(result));
3382
3383 return "nrk";
3384}
3385
florian55085f82012-11-21 00:36:55 +00003386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003387s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3388{
3389 IRTemp op2 = newTemp(Ity_I64);
3390 IRTemp op3 = newTemp(Ity_I64);
3391 IRTemp result = newTemp(Ity_I64);
3392
3393 assign(op2, get_gpr_dw0(r2));
3394 assign(op3, get_gpr_dw0(r3));
3395 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3396 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3397 put_gpr_dw0(r1, mkexpr(result));
3398
3399 return "ngrk";
3400}
3401
florian55085f82012-11-21 00:36:55 +00003402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003403s390_irgen_N(UChar r1, IRTemp op2addr)
3404{
3405 IRTemp op1 = newTemp(Ity_I32);
3406 IRTemp op2 = newTemp(Ity_I32);
3407 IRTemp result = newTemp(Ity_I32);
3408
3409 assign(op1, get_gpr_w1(r1));
3410 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3411 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3412 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3413 put_gpr_w1(r1, mkexpr(result));
3414
3415 return "n";
3416}
3417
florian55085f82012-11-21 00:36:55 +00003418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003419s390_irgen_NY(UChar r1, IRTemp op2addr)
3420{
3421 IRTemp op1 = newTemp(Ity_I32);
3422 IRTemp op2 = newTemp(Ity_I32);
3423 IRTemp result = newTemp(Ity_I32);
3424
3425 assign(op1, get_gpr_w1(r1));
3426 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3427 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3428 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3429 put_gpr_w1(r1, mkexpr(result));
3430
3431 return "ny";
3432}
3433
florian55085f82012-11-21 00:36:55 +00003434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003435s390_irgen_NG(UChar r1, IRTemp op2addr)
3436{
3437 IRTemp op1 = newTemp(Ity_I64);
3438 IRTemp op2 = newTemp(Ity_I64);
3439 IRTemp result = newTemp(Ity_I64);
3440
3441 assign(op1, get_gpr_dw0(r1));
3442 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3443 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3444 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3445 put_gpr_dw0(r1, mkexpr(result));
3446
3447 return "ng";
3448}
3449
florian55085f82012-11-21 00:36:55 +00003450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003451s390_irgen_NI(UChar i2, IRTemp op1addr)
3452{
3453 IRTemp op1 = newTemp(Ity_I8);
3454 UChar op2;
3455 IRTemp result = newTemp(Ity_I8);
3456
3457 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3458 op2 = i2;
3459 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3460 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3461 store(mkexpr(op1addr), mkexpr(result));
3462
3463 return "ni";
3464}
3465
florian55085f82012-11-21 00:36:55 +00003466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003467s390_irgen_NIY(UChar i2, IRTemp op1addr)
3468{
3469 IRTemp op1 = newTemp(Ity_I8);
3470 UChar op2;
3471 IRTemp result = newTemp(Ity_I8);
3472
3473 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3474 op2 = i2;
3475 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3476 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3477 store(mkexpr(op1addr), mkexpr(result));
3478
3479 return "niy";
3480}
3481
florian55085f82012-11-21 00:36:55 +00003482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003483s390_irgen_NIHF(UChar r1, UInt i2)
3484{
3485 IRTemp op1 = newTemp(Ity_I32);
3486 UInt op2;
3487 IRTemp result = newTemp(Ity_I32);
3488
3489 assign(op1, get_gpr_w0(r1));
3490 op2 = i2;
3491 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3492 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3493 put_gpr_w0(r1, mkexpr(result));
3494
3495 return "nihf";
3496}
3497
florian55085f82012-11-21 00:36:55 +00003498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003499s390_irgen_NIHH(UChar r1, UShort i2)
3500{
3501 IRTemp op1 = newTemp(Ity_I16);
3502 UShort op2;
3503 IRTemp result = newTemp(Ity_I16);
3504
3505 assign(op1, get_gpr_hw0(r1));
3506 op2 = i2;
3507 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3508 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3509 put_gpr_hw0(r1, mkexpr(result));
3510
3511 return "nihh";
3512}
3513
florian55085f82012-11-21 00:36:55 +00003514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003515s390_irgen_NIHL(UChar r1, UShort i2)
3516{
3517 IRTemp op1 = newTemp(Ity_I16);
3518 UShort op2;
3519 IRTemp result = newTemp(Ity_I16);
3520
3521 assign(op1, get_gpr_hw1(r1));
3522 op2 = i2;
3523 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3524 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3525 put_gpr_hw1(r1, mkexpr(result));
3526
3527 return "nihl";
3528}
3529
florian55085f82012-11-21 00:36:55 +00003530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003531s390_irgen_NILF(UChar r1, UInt i2)
3532{
3533 IRTemp op1 = newTemp(Ity_I32);
3534 UInt op2;
3535 IRTemp result = newTemp(Ity_I32);
3536
3537 assign(op1, get_gpr_w1(r1));
3538 op2 = i2;
3539 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3540 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3541 put_gpr_w1(r1, mkexpr(result));
3542
3543 return "nilf";
3544}
3545
florian55085f82012-11-21 00:36:55 +00003546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003547s390_irgen_NILH(UChar r1, UShort i2)
3548{
3549 IRTemp op1 = newTemp(Ity_I16);
3550 UShort op2;
3551 IRTemp result = newTemp(Ity_I16);
3552
3553 assign(op1, get_gpr_hw2(r1));
3554 op2 = i2;
3555 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3556 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3557 put_gpr_hw2(r1, mkexpr(result));
3558
3559 return "nilh";
3560}
3561
florian55085f82012-11-21 00:36:55 +00003562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003563s390_irgen_NILL(UChar r1, UShort i2)
3564{
3565 IRTemp op1 = newTemp(Ity_I16);
3566 UShort op2;
3567 IRTemp result = newTemp(Ity_I16);
3568
3569 assign(op1, get_gpr_hw3(r1));
3570 op2 = i2;
3571 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3572 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3573 put_gpr_hw3(r1, mkexpr(result));
3574
3575 return "nill";
3576}
3577
florian55085f82012-11-21 00:36:55 +00003578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003579s390_irgen_BASR(UChar r1, UChar r2)
3580{
3581 IRTemp target = newTemp(Ity_I64);
3582
3583 if (r2 == 0) {
3584 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3585 } else {
3586 if (r1 != r2) {
3587 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3588 call_function(get_gpr_dw0(r2));
3589 } else {
3590 assign(target, get_gpr_dw0(r2));
3591 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3592 call_function(mkexpr(target));
3593 }
3594 }
3595
3596 return "basr";
3597}
3598
florian55085f82012-11-21 00:36:55 +00003599static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003600s390_irgen_BAS(UChar r1, IRTemp op2addr)
3601{
3602 IRTemp target = newTemp(Ity_I64);
3603
3604 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3605 assign(target, mkexpr(op2addr));
3606 call_function(mkexpr(target));
3607
3608 return "bas";
3609}
3610
florian55085f82012-11-21 00:36:55 +00003611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003612s390_irgen_BCR(UChar r1, UChar r2)
3613{
3614 IRTemp cond = newTemp(Ity_I32);
3615
sewardja52e37e2011-04-28 18:48:06 +00003616 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3617 stmt(IRStmt_MBE(Imbe_Fence));
3618 }
3619
sewardj2019a972011-03-07 16:04:07 +00003620 if ((r2 == 0) || (r1 == 0)) {
3621 } else {
3622 if (r1 == 15) {
3623 return_from_function(get_gpr_dw0(r2));
3624 } else {
3625 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003626 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3627 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003628 }
3629 }
sewardj7ee97522011-05-09 21:45:04 +00003630 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003631 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3632
3633 return "bcr";
3634}
3635
florian55085f82012-11-21 00:36:55 +00003636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003637s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3638{
3639 IRTemp cond = newTemp(Ity_I32);
3640
3641 if (r1 == 0) {
3642 } else {
3643 if (r1 == 15) {
3644 always_goto(mkexpr(op2addr));
3645 } else {
3646 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003647 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3648 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003649 }
3650 }
sewardj7ee97522011-05-09 21:45:04 +00003651 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003652 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3653
3654 return "bc";
3655}
3656
florian55085f82012-11-21 00:36:55 +00003657static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003658s390_irgen_BCTR(UChar r1, UChar r2)
3659{
3660 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3661 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003662 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3663 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003664 }
3665
3666 return "bctr";
3667}
3668
florian55085f82012-11-21 00:36:55 +00003669static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003670s390_irgen_BCTGR(UChar r1, UChar r2)
3671{
3672 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3673 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003674 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3675 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003676 }
3677
3678 return "bctgr";
3679}
3680
florian55085f82012-11-21 00:36:55 +00003681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003682s390_irgen_BCT(UChar r1, IRTemp op2addr)
3683{
3684 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003685 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3686 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003687
3688 return "bct";
3689}
3690
florian55085f82012-11-21 00:36:55 +00003691static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003692s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3693{
3694 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003695 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3696 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003697
3698 return "bctg";
3699}
3700
florian55085f82012-11-21 00:36:55 +00003701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003702s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3703{
3704 IRTemp value = newTemp(Ity_I32);
3705
3706 assign(value, get_gpr_w1(r3 | 1));
3707 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003708 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3709 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003710
3711 return "bxh";
3712}
3713
florian55085f82012-11-21 00:36:55 +00003714static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003715s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3716{
3717 IRTemp value = newTemp(Ity_I64);
3718
3719 assign(value, get_gpr_dw0(r3 | 1));
3720 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003721 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3722 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003723
3724 return "bxhg";
3725}
3726
florian55085f82012-11-21 00:36:55 +00003727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003728s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3729{
3730 IRTemp value = newTemp(Ity_I32);
3731
3732 assign(value, get_gpr_w1(r3 | 1));
3733 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003734 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3735 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003736
3737 return "bxle";
3738}
3739
florian55085f82012-11-21 00:36:55 +00003740static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003741s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3742{
3743 IRTemp value = newTemp(Ity_I64);
3744
3745 assign(value, get_gpr_dw0(r3 | 1));
3746 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003747 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3748 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003749
3750 return "bxleg";
3751}
3752
florian55085f82012-11-21 00:36:55 +00003753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003754s390_irgen_BRAS(UChar r1, UShort i2)
3755{
3756 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003757 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003758
3759 return "bras";
3760}
3761
florian55085f82012-11-21 00:36:55 +00003762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003763s390_irgen_BRASL(UChar r1, UInt i2)
3764{
3765 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003766 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003767
3768 return "brasl";
3769}
3770
florian55085f82012-11-21 00:36:55 +00003771static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003772s390_irgen_BRC(UChar r1, UShort i2)
3773{
3774 IRTemp cond = newTemp(Ity_I32);
3775
3776 if (r1 == 0) {
3777 } else {
3778 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003779 always_goto_and_chase(
3780 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003781 } else {
3782 assign(cond, s390_call_calculate_cond(r1));
3783 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3784 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3785
3786 }
3787 }
sewardj7ee97522011-05-09 21:45:04 +00003788 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003789 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3790
3791 return "brc";
3792}
3793
florian55085f82012-11-21 00:36:55 +00003794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003795s390_irgen_BRCL(UChar r1, UInt i2)
3796{
3797 IRTemp cond = newTemp(Ity_I32);
3798
3799 if (r1 == 0) {
3800 } else {
3801 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003802 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003803 } else {
3804 assign(cond, s390_call_calculate_cond(r1));
3805 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3806 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3807 }
3808 }
sewardj7ee97522011-05-09 21:45:04 +00003809 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003810 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3811
3812 return "brcl";
3813}
3814
florian55085f82012-11-21 00:36:55 +00003815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003816s390_irgen_BRCT(UChar r1, UShort i2)
3817{
3818 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3819 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3820 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3821
3822 return "brct";
3823}
3824
florian55085f82012-11-21 00:36:55 +00003825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003826s390_irgen_BRCTG(UChar r1, UShort i2)
3827{
3828 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3829 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3830 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3831
3832 return "brctg";
3833}
3834
florian55085f82012-11-21 00:36:55 +00003835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003836s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3837{
3838 IRTemp value = newTemp(Ity_I32);
3839
3840 assign(value, get_gpr_w1(r3 | 1));
3841 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3842 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3843 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3844
3845 return "brxh";
3846}
3847
florian55085f82012-11-21 00:36:55 +00003848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003849s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3850{
3851 IRTemp value = newTemp(Ity_I64);
3852
3853 assign(value, get_gpr_dw0(r3 | 1));
3854 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3855 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3856 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3857
3858 return "brxhg";
3859}
3860
florian55085f82012-11-21 00:36:55 +00003861static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003862s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3863{
3864 IRTemp value = newTemp(Ity_I32);
3865
3866 assign(value, get_gpr_w1(r3 | 1));
3867 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3868 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3869 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3870
3871 return "brxle";
3872}
3873
florian55085f82012-11-21 00:36:55 +00003874static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003875s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3876{
3877 IRTemp value = newTemp(Ity_I64);
3878
3879 assign(value, get_gpr_dw0(r3 | 1));
3880 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3881 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3882 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3883
3884 return "brxlg";
3885}
3886
florian55085f82012-11-21 00:36:55 +00003887static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003888s390_irgen_CR(UChar r1, UChar r2)
3889{
3890 IRTemp op1 = newTemp(Ity_I32);
3891 IRTemp op2 = newTemp(Ity_I32);
3892
3893 assign(op1, get_gpr_w1(r1));
3894 assign(op2, get_gpr_w1(r2));
3895 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3896
3897 return "cr";
3898}
3899
florian55085f82012-11-21 00:36:55 +00003900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003901s390_irgen_CGR(UChar r1, UChar r2)
3902{
3903 IRTemp op1 = newTemp(Ity_I64);
3904 IRTemp op2 = newTemp(Ity_I64);
3905
3906 assign(op1, get_gpr_dw0(r1));
3907 assign(op2, get_gpr_dw0(r2));
3908 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3909
3910 return "cgr";
3911}
3912
florian55085f82012-11-21 00:36:55 +00003913static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003914s390_irgen_CGFR(UChar r1, UChar r2)
3915{
3916 IRTemp op1 = newTemp(Ity_I64);
3917 IRTemp op2 = newTemp(Ity_I64);
3918
3919 assign(op1, get_gpr_dw0(r1));
3920 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3921 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3922
3923 return "cgfr";
3924}
3925
florian55085f82012-11-21 00:36:55 +00003926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003927s390_irgen_C(UChar r1, IRTemp op2addr)
3928{
3929 IRTemp op1 = newTemp(Ity_I32);
3930 IRTemp op2 = newTemp(Ity_I32);
3931
3932 assign(op1, get_gpr_w1(r1));
3933 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3934 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3935
3936 return "c";
3937}
3938
florian55085f82012-11-21 00:36:55 +00003939static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003940s390_irgen_CY(UChar r1, IRTemp op2addr)
3941{
3942 IRTemp op1 = newTemp(Ity_I32);
3943 IRTemp op2 = newTemp(Ity_I32);
3944
3945 assign(op1, get_gpr_w1(r1));
3946 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3947 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3948
3949 return "cy";
3950}
3951
florian55085f82012-11-21 00:36:55 +00003952static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003953s390_irgen_CG(UChar r1, IRTemp op2addr)
3954{
3955 IRTemp op1 = newTemp(Ity_I64);
3956 IRTemp op2 = newTemp(Ity_I64);
3957
3958 assign(op1, get_gpr_dw0(r1));
3959 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3960 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3961
3962 return "cg";
3963}
3964
florian55085f82012-11-21 00:36:55 +00003965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003966s390_irgen_CGF(UChar r1, IRTemp op2addr)
3967{
3968 IRTemp op1 = newTemp(Ity_I64);
3969 IRTemp op2 = newTemp(Ity_I64);
3970
3971 assign(op1, get_gpr_dw0(r1));
3972 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3973 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3974
3975 return "cgf";
3976}
3977
florian55085f82012-11-21 00:36:55 +00003978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003979s390_irgen_CFI(UChar r1, UInt i2)
3980{
3981 IRTemp op1 = newTemp(Ity_I32);
3982 Int op2;
3983
3984 assign(op1, get_gpr_w1(r1));
3985 op2 = (Int)i2;
3986 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3987 mkU32((UInt)op2)));
3988
3989 return "cfi";
3990}
3991
florian55085f82012-11-21 00:36:55 +00003992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003993s390_irgen_CGFI(UChar r1, UInt i2)
3994{
3995 IRTemp op1 = newTemp(Ity_I64);
3996 Long op2;
3997
3998 assign(op1, get_gpr_dw0(r1));
3999 op2 = (Long)(Int)i2;
4000 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4001 mkU64((ULong)op2)));
4002
4003 return "cgfi";
4004}
4005
florian55085f82012-11-21 00:36:55 +00004006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004007s390_irgen_CRL(UChar r1, UInt i2)
4008{
4009 IRTemp op1 = newTemp(Ity_I32);
4010 IRTemp op2 = newTemp(Ity_I32);
4011
4012 assign(op1, get_gpr_w1(r1));
4013 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4014 i2 << 1))));
4015 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4016
4017 return "crl";
4018}
4019
florian55085f82012-11-21 00:36:55 +00004020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004021s390_irgen_CGRL(UChar r1, UInt i2)
4022{
4023 IRTemp op1 = newTemp(Ity_I64);
4024 IRTemp op2 = newTemp(Ity_I64);
4025
4026 assign(op1, get_gpr_dw0(r1));
4027 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4028 i2 << 1))));
4029 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4030
4031 return "cgrl";
4032}
4033
florian55085f82012-11-21 00:36:55 +00004034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004035s390_irgen_CGFRL(UChar r1, UInt i2)
4036{
4037 IRTemp op1 = newTemp(Ity_I64);
4038 IRTemp op2 = newTemp(Ity_I64);
4039
4040 assign(op1, get_gpr_dw0(r1));
4041 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4042 ((ULong)(Long)(Int)i2 << 1)))));
4043 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4044
4045 return "cgfrl";
4046}
4047
florian55085f82012-11-21 00:36:55 +00004048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004049s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4050{
4051 IRTemp op1 = newTemp(Ity_I32);
4052 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004053 IRTemp cond = newTemp(Ity_I32);
4054
4055 if (m3 == 0) {
4056 } else {
4057 if (m3 == 14) {
4058 always_goto(mkexpr(op4addr));
4059 } else {
4060 assign(op1, get_gpr_w1(r1));
4061 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004062 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4063 op1, op2));
florianf321da72012-07-21 20:32:57 +00004064 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4065 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004066 }
4067 }
4068
4069 return "crb";
4070}
4071
florian55085f82012-11-21 00:36:55 +00004072static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004073s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4074{
4075 IRTemp op1 = newTemp(Ity_I64);
4076 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004077 IRTemp cond = newTemp(Ity_I32);
4078
4079 if (m3 == 0) {
4080 } else {
4081 if (m3 == 14) {
4082 always_goto(mkexpr(op4addr));
4083 } else {
4084 assign(op1, get_gpr_dw0(r1));
4085 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004086 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4087 op1, op2));
florianf321da72012-07-21 20:32:57 +00004088 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4089 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004090 }
4091 }
4092
4093 return "cgrb";
4094}
4095
florian55085f82012-11-21 00:36:55 +00004096static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004097s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4098{
4099 IRTemp op1 = newTemp(Ity_I32);
4100 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004101 IRTemp cond = newTemp(Ity_I32);
4102
4103 if (m3 == 0) {
4104 } else {
4105 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004106 always_goto_and_chase(
4107 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004108 } else {
4109 assign(op1, get_gpr_w1(r1));
4110 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004111 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4112 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004113 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4114 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4115
4116 }
4117 }
4118
4119 return "crj";
4120}
4121
florian55085f82012-11-21 00:36:55 +00004122static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004123s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4124{
4125 IRTemp op1 = newTemp(Ity_I64);
4126 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004127 IRTemp cond = newTemp(Ity_I32);
4128
4129 if (m3 == 0) {
4130 } else {
4131 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004132 always_goto_and_chase(
4133 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004134 } else {
4135 assign(op1, get_gpr_dw0(r1));
4136 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004137 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4138 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004139 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4140 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4141
4142 }
4143 }
4144
4145 return "cgrj";
4146}
4147
florian55085f82012-11-21 00:36:55 +00004148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004149s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4150{
4151 IRTemp op1 = newTemp(Ity_I32);
4152 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004153 IRTemp cond = newTemp(Ity_I32);
4154
4155 if (m3 == 0) {
4156 } else {
4157 if (m3 == 14) {
4158 always_goto(mkexpr(op4addr));
4159 } else {
4160 assign(op1, get_gpr_w1(r1));
4161 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004162 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4163 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004164 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4165 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004166 }
4167 }
4168
4169 return "cib";
4170}
4171
florian55085f82012-11-21 00:36:55 +00004172static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004173s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4174{
4175 IRTemp op1 = newTemp(Ity_I64);
4176 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004177 IRTemp cond = newTemp(Ity_I32);
4178
4179 if (m3 == 0) {
4180 } else {
4181 if (m3 == 14) {
4182 always_goto(mkexpr(op4addr));
4183 } else {
4184 assign(op1, get_gpr_dw0(r1));
4185 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004186 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4187 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004188 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4189 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004190 }
4191 }
4192
4193 return "cgib";
4194}
4195
florian55085f82012-11-21 00:36:55 +00004196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004197s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4198{
4199 IRTemp op1 = newTemp(Ity_I32);
4200 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004201 IRTemp cond = newTemp(Ity_I32);
4202
4203 if (m3 == 0) {
4204 } else {
4205 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004206 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004207 } else {
4208 assign(op1, get_gpr_w1(r1));
4209 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004210 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4211 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004212 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4213 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4214
4215 }
4216 }
4217
4218 return "cij";
4219}
4220
florian55085f82012-11-21 00:36:55 +00004221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004222s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4223{
4224 IRTemp op1 = newTemp(Ity_I64);
4225 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004226 IRTemp cond = newTemp(Ity_I32);
4227
4228 if (m3 == 0) {
4229 } else {
4230 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004231 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004232 } else {
4233 assign(op1, get_gpr_dw0(r1));
4234 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004235 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4236 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004237 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4238 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4239
4240 }
4241 }
4242
4243 return "cgij";
4244}
4245
florian55085f82012-11-21 00:36:55 +00004246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004247s390_irgen_CH(UChar r1, IRTemp op2addr)
4248{
4249 IRTemp op1 = newTemp(Ity_I32);
4250 IRTemp op2 = newTemp(Ity_I32);
4251
4252 assign(op1, get_gpr_w1(r1));
4253 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4254 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4255
4256 return "ch";
4257}
4258
florian55085f82012-11-21 00:36:55 +00004259static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004260s390_irgen_CHY(UChar r1, IRTemp op2addr)
4261{
4262 IRTemp op1 = newTemp(Ity_I32);
4263 IRTemp op2 = newTemp(Ity_I32);
4264
4265 assign(op1, get_gpr_w1(r1));
4266 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4267 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4268
4269 return "chy";
4270}
4271
florian55085f82012-11-21 00:36:55 +00004272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004273s390_irgen_CGH(UChar r1, IRTemp op2addr)
4274{
4275 IRTemp op1 = newTemp(Ity_I64);
4276 IRTemp op2 = newTemp(Ity_I64);
4277
4278 assign(op1, get_gpr_dw0(r1));
4279 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4280 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4281
4282 return "cgh";
4283}
4284
florian55085f82012-11-21 00:36:55 +00004285static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004286s390_irgen_CHI(UChar r1, UShort i2)
4287{
4288 IRTemp op1 = newTemp(Ity_I32);
4289 Int op2;
4290
4291 assign(op1, get_gpr_w1(r1));
4292 op2 = (Int)(Short)i2;
4293 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4294 mkU32((UInt)op2)));
4295
4296 return "chi";
4297}
4298
florian55085f82012-11-21 00:36:55 +00004299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004300s390_irgen_CGHI(UChar r1, UShort i2)
4301{
4302 IRTemp op1 = newTemp(Ity_I64);
4303 Long op2;
4304
4305 assign(op1, get_gpr_dw0(r1));
4306 op2 = (Long)(Short)i2;
4307 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4308 mkU64((ULong)op2)));
4309
4310 return "cghi";
4311}
4312
florian55085f82012-11-21 00:36:55 +00004313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004314s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4315{
4316 IRTemp op1 = newTemp(Ity_I16);
4317 Short op2;
4318
4319 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4320 op2 = (Short)i2;
4321 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4322 mkU16((UShort)op2)));
4323
4324 return "chhsi";
4325}
4326
florian55085f82012-11-21 00:36:55 +00004327static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004328s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4329{
4330 IRTemp op1 = newTemp(Ity_I32);
4331 Int op2;
4332
4333 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4334 op2 = (Int)(Short)i2;
4335 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4336 mkU32((UInt)op2)));
4337
4338 return "chsi";
4339}
4340
florian55085f82012-11-21 00:36:55 +00004341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004342s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4343{
4344 IRTemp op1 = newTemp(Ity_I64);
4345 Long op2;
4346
4347 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4348 op2 = (Long)(Short)i2;
4349 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4350 mkU64((ULong)op2)));
4351
4352 return "cghsi";
4353}
4354
florian55085f82012-11-21 00:36:55 +00004355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004356s390_irgen_CHRL(UChar r1, UInt i2)
4357{
4358 IRTemp op1 = newTemp(Ity_I32);
4359 IRTemp op2 = newTemp(Ity_I32);
4360
4361 assign(op1, get_gpr_w1(r1));
4362 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4363 ((ULong)(Long)(Int)i2 << 1)))));
4364 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4365
4366 return "chrl";
4367}
4368
florian55085f82012-11-21 00:36:55 +00004369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004370s390_irgen_CGHRL(UChar r1, UInt i2)
4371{
4372 IRTemp op1 = newTemp(Ity_I64);
4373 IRTemp op2 = newTemp(Ity_I64);
4374
4375 assign(op1, get_gpr_dw0(r1));
4376 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4377 ((ULong)(Long)(Int)i2 << 1)))));
4378 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4379
4380 return "cghrl";
4381}
4382
florian55085f82012-11-21 00:36:55 +00004383static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004384s390_irgen_CHHR(UChar r1, UChar r2)
4385{
4386 IRTemp op1 = newTemp(Ity_I32);
4387 IRTemp op2 = newTemp(Ity_I32);
4388
4389 assign(op1, get_gpr_w0(r1));
4390 assign(op2, get_gpr_w0(r2));
4391 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4392
4393 return "chhr";
4394}
4395
florian55085f82012-11-21 00:36:55 +00004396static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004397s390_irgen_CHLR(UChar r1, UChar r2)
4398{
4399 IRTemp op1 = newTemp(Ity_I32);
4400 IRTemp op2 = newTemp(Ity_I32);
4401
4402 assign(op1, get_gpr_w0(r1));
4403 assign(op2, get_gpr_w1(r2));
4404 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4405
4406 return "chlr";
4407}
4408
florian55085f82012-11-21 00:36:55 +00004409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004410s390_irgen_CHF(UChar r1, IRTemp op2addr)
4411{
4412 IRTemp op1 = newTemp(Ity_I32);
4413 IRTemp op2 = newTemp(Ity_I32);
4414
4415 assign(op1, get_gpr_w0(r1));
4416 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4417 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4418
4419 return "chf";
4420}
4421
florian55085f82012-11-21 00:36:55 +00004422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004423s390_irgen_CIH(UChar r1, UInt i2)
4424{
4425 IRTemp op1 = newTemp(Ity_I32);
4426 Int op2;
4427
4428 assign(op1, get_gpr_w0(r1));
4429 op2 = (Int)i2;
4430 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4431 mkU32((UInt)op2)));
4432
4433 return "cih";
4434}
4435
florian55085f82012-11-21 00:36:55 +00004436static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004437s390_irgen_CLR(UChar r1, UChar r2)
4438{
4439 IRTemp op1 = newTemp(Ity_I32);
4440 IRTemp op2 = newTemp(Ity_I32);
4441
4442 assign(op1, get_gpr_w1(r1));
4443 assign(op2, get_gpr_w1(r2));
4444 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4445
4446 return "clr";
4447}
4448
florian55085f82012-11-21 00:36:55 +00004449static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004450s390_irgen_CLGR(UChar r1, UChar r2)
4451{
4452 IRTemp op1 = newTemp(Ity_I64);
4453 IRTemp op2 = newTemp(Ity_I64);
4454
4455 assign(op1, get_gpr_dw0(r1));
4456 assign(op2, get_gpr_dw0(r2));
4457 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4458
4459 return "clgr";
4460}
4461
florian55085f82012-11-21 00:36:55 +00004462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004463s390_irgen_CLGFR(UChar r1, UChar r2)
4464{
4465 IRTemp op1 = newTemp(Ity_I64);
4466 IRTemp op2 = newTemp(Ity_I64);
4467
4468 assign(op1, get_gpr_dw0(r1));
4469 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4470 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4471
4472 return "clgfr";
4473}
4474
florian55085f82012-11-21 00:36:55 +00004475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004476s390_irgen_CL(UChar r1, IRTemp op2addr)
4477{
4478 IRTemp op1 = newTemp(Ity_I32);
4479 IRTemp op2 = newTemp(Ity_I32);
4480
4481 assign(op1, get_gpr_w1(r1));
4482 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4483 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4484
4485 return "cl";
4486}
4487
florian55085f82012-11-21 00:36:55 +00004488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004489s390_irgen_CLY(UChar r1, IRTemp op2addr)
4490{
4491 IRTemp op1 = newTemp(Ity_I32);
4492 IRTemp op2 = newTemp(Ity_I32);
4493
4494 assign(op1, get_gpr_w1(r1));
4495 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4496 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4497
4498 return "cly";
4499}
4500
florian55085f82012-11-21 00:36:55 +00004501static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004502s390_irgen_CLG(UChar r1, IRTemp op2addr)
4503{
4504 IRTemp op1 = newTemp(Ity_I64);
4505 IRTemp op2 = newTemp(Ity_I64);
4506
4507 assign(op1, get_gpr_dw0(r1));
4508 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4509 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4510
4511 return "clg";
4512}
4513
florian55085f82012-11-21 00:36:55 +00004514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004515s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4516{
4517 IRTemp op1 = newTemp(Ity_I64);
4518 IRTemp op2 = newTemp(Ity_I64);
4519
4520 assign(op1, get_gpr_dw0(r1));
4521 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4522 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4523
4524 return "clgf";
4525}
4526
florian55085f82012-11-21 00:36:55 +00004527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004528s390_irgen_CLFI(UChar r1, UInt i2)
4529{
4530 IRTemp op1 = newTemp(Ity_I32);
4531 UInt op2;
4532
4533 assign(op1, get_gpr_w1(r1));
4534 op2 = i2;
4535 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4536 mkU32(op2)));
4537
4538 return "clfi";
4539}
4540
florian55085f82012-11-21 00:36:55 +00004541static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004542s390_irgen_CLGFI(UChar r1, UInt i2)
4543{
4544 IRTemp op1 = newTemp(Ity_I64);
4545 ULong op2;
4546
4547 assign(op1, get_gpr_dw0(r1));
4548 op2 = (ULong)i2;
4549 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4550 mkU64(op2)));
4551
4552 return "clgfi";
4553}
4554
florian55085f82012-11-21 00:36:55 +00004555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004556s390_irgen_CLI(UChar i2, IRTemp op1addr)
4557{
4558 IRTemp op1 = newTemp(Ity_I8);
4559 UChar op2;
4560
4561 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4562 op2 = i2;
4563 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4564 mkU8(op2)));
4565
4566 return "cli";
4567}
4568
florian55085f82012-11-21 00:36:55 +00004569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004570s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4571{
4572 IRTemp op1 = newTemp(Ity_I8);
4573 UChar op2;
4574
4575 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4576 op2 = i2;
4577 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4578 mkU8(op2)));
4579
4580 return "cliy";
4581}
4582
florian55085f82012-11-21 00:36:55 +00004583static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004584s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4585{
4586 IRTemp op1 = newTemp(Ity_I32);
4587 UInt op2;
4588
4589 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4590 op2 = (UInt)i2;
4591 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4592 mkU32(op2)));
4593
4594 return "clfhsi";
4595}
4596
florian55085f82012-11-21 00:36:55 +00004597static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004598s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4599{
4600 IRTemp op1 = newTemp(Ity_I64);
4601 ULong op2;
4602
4603 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4604 op2 = (ULong)i2;
4605 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4606 mkU64(op2)));
4607
4608 return "clghsi";
4609}
4610
florian55085f82012-11-21 00:36:55 +00004611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004612s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4613{
4614 IRTemp op1 = newTemp(Ity_I16);
4615 UShort op2;
4616
4617 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4618 op2 = i2;
4619 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4620 mkU16(op2)));
4621
4622 return "clhhsi";
4623}
4624
florian55085f82012-11-21 00:36:55 +00004625static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004626s390_irgen_CLRL(UChar r1, UInt i2)
4627{
4628 IRTemp op1 = newTemp(Ity_I32);
4629 IRTemp op2 = newTemp(Ity_I32);
4630
4631 assign(op1, get_gpr_w1(r1));
4632 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4633 i2 << 1))));
4634 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4635
4636 return "clrl";
4637}
4638
florian55085f82012-11-21 00:36:55 +00004639static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004640s390_irgen_CLGRL(UChar r1, UInt i2)
4641{
4642 IRTemp op1 = newTemp(Ity_I64);
4643 IRTemp op2 = newTemp(Ity_I64);
4644
4645 assign(op1, get_gpr_dw0(r1));
4646 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4647 i2 << 1))));
4648 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4649
4650 return "clgrl";
4651}
4652
florian55085f82012-11-21 00:36:55 +00004653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004654s390_irgen_CLGFRL(UChar r1, UInt i2)
4655{
4656 IRTemp op1 = newTemp(Ity_I64);
4657 IRTemp op2 = newTemp(Ity_I64);
4658
4659 assign(op1, get_gpr_dw0(r1));
4660 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4661 ((ULong)(Long)(Int)i2 << 1)))));
4662 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4663
4664 return "clgfrl";
4665}
4666
florian55085f82012-11-21 00:36:55 +00004667static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004668s390_irgen_CLHRL(UChar r1, UInt i2)
4669{
4670 IRTemp op1 = newTemp(Ity_I32);
4671 IRTemp op2 = newTemp(Ity_I32);
4672
4673 assign(op1, get_gpr_w1(r1));
4674 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4675 ((ULong)(Long)(Int)i2 << 1)))));
4676 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4677
4678 return "clhrl";
4679}
4680
florian55085f82012-11-21 00:36:55 +00004681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004682s390_irgen_CLGHRL(UChar r1, UInt i2)
4683{
4684 IRTemp op1 = newTemp(Ity_I64);
4685 IRTemp op2 = newTemp(Ity_I64);
4686
4687 assign(op1, get_gpr_dw0(r1));
4688 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4689 ((ULong)(Long)(Int)i2 << 1)))));
4690 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4691
4692 return "clghrl";
4693}
4694
florian55085f82012-11-21 00:36:55 +00004695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004696s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4697{
4698 IRTemp op1 = newTemp(Ity_I32);
4699 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004700 IRTemp cond = newTemp(Ity_I32);
4701
4702 if (m3 == 0) {
4703 } else {
4704 if (m3 == 14) {
4705 always_goto(mkexpr(op4addr));
4706 } else {
4707 assign(op1, get_gpr_w1(r1));
4708 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004709 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4710 op1, op2));
florianf321da72012-07-21 20:32:57 +00004711 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4712 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004713 }
4714 }
4715
4716 return "clrb";
4717}
4718
florian55085f82012-11-21 00:36:55 +00004719static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004720s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4721{
4722 IRTemp op1 = newTemp(Ity_I64);
4723 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004724 IRTemp cond = newTemp(Ity_I32);
4725
4726 if (m3 == 0) {
4727 } else {
4728 if (m3 == 14) {
4729 always_goto(mkexpr(op4addr));
4730 } else {
4731 assign(op1, get_gpr_dw0(r1));
4732 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004733 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4734 op1, op2));
florianf321da72012-07-21 20:32:57 +00004735 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4736 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004737 }
4738 }
4739
4740 return "clgrb";
4741}
4742
florian55085f82012-11-21 00:36:55 +00004743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004744s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4745{
4746 IRTemp op1 = newTemp(Ity_I32);
4747 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004748 IRTemp cond = newTemp(Ity_I32);
4749
4750 if (m3 == 0) {
4751 } else {
4752 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004753 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004754 } else {
4755 assign(op1, get_gpr_w1(r1));
4756 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004757 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4758 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004759 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4760 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4761
4762 }
4763 }
4764
4765 return "clrj";
4766}
4767
florian55085f82012-11-21 00:36:55 +00004768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004769s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4770{
4771 IRTemp op1 = newTemp(Ity_I64);
4772 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004773 IRTemp cond = newTemp(Ity_I32);
4774
4775 if (m3 == 0) {
4776 } else {
4777 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004778 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004779 } else {
4780 assign(op1, get_gpr_dw0(r1));
4781 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004782 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4783 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004784 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4785 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4786
4787 }
4788 }
4789
4790 return "clgrj";
4791}
4792
florian55085f82012-11-21 00:36:55 +00004793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004794s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4795{
4796 IRTemp op1 = newTemp(Ity_I32);
4797 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004798 IRTemp cond = newTemp(Ity_I32);
4799
4800 if (m3 == 0) {
4801 } else {
4802 if (m3 == 14) {
4803 always_goto(mkexpr(op4addr));
4804 } else {
4805 assign(op1, get_gpr_w1(r1));
4806 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004807 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4808 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004809 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4810 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004811 }
4812 }
4813
4814 return "clib";
4815}
4816
florian55085f82012-11-21 00:36:55 +00004817static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004818s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4819{
4820 IRTemp op1 = newTemp(Ity_I64);
4821 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004822 IRTemp cond = newTemp(Ity_I32);
4823
4824 if (m3 == 0) {
4825 } else {
4826 if (m3 == 14) {
4827 always_goto(mkexpr(op4addr));
4828 } else {
4829 assign(op1, get_gpr_dw0(r1));
4830 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004831 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4832 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004833 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4834 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004835 }
4836 }
4837
4838 return "clgib";
4839}
4840
florian55085f82012-11-21 00:36:55 +00004841static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004842s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4843{
4844 IRTemp op1 = newTemp(Ity_I32);
4845 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004846 IRTemp cond = newTemp(Ity_I32);
4847
4848 if (m3 == 0) {
4849 } else {
4850 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004851 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004852 } else {
4853 assign(op1, get_gpr_w1(r1));
4854 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004855 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4856 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004857 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4858 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4859
4860 }
4861 }
4862
4863 return "clij";
4864}
4865
florian55085f82012-11-21 00:36:55 +00004866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004867s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4868{
4869 IRTemp op1 = newTemp(Ity_I64);
4870 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004871 IRTemp cond = newTemp(Ity_I32);
4872
4873 if (m3 == 0) {
4874 } else {
4875 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004876 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004877 } else {
4878 assign(op1, get_gpr_dw0(r1));
4879 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004880 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4881 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004882 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4883 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4884
4885 }
4886 }
4887
4888 return "clgij";
4889}
4890
florian55085f82012-11-21 00:36:55 +00004891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004892s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4893{
4894 IRTemp op1 = newTemp(Ity_I32);
4895 IRTemp op2 = newTemp(Ity_I32);
4896 IRTemp b0 = newTemp(Ity_I32);
4897 IRTemp b1 = newTemp(Ity_I32);
4898 IRTemp b2 = newTemp(Ity_I32);
4899 IRTemp b3 = newTemp(Ity_I32);
4900 IRTemp c0 = newTemp(Ity_I32);
4901 IRTemp c1 = newTemp(Ity_I32);
4902 IRTemp c2 = newTemp(Ity_I32);
4903 IRTemp c3 = newTemp(Ity_I32);
4904 UChar n;
4905
4906 n = 0;
4907 if ((r3 & 8) != 0) {
4908 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4909 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4910 n = n + 1;
4911 } else {
4912 assign(b0, mkU32(0));
4913 assign(c0, mkU32(0));
4914 }
4915 if ((r3 & 4) != 0) {
4916 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4917 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4918 mkU64(n)))));
4919 n = n + 1;
4920 } else {
4921 assign(b1, mkU32(0));
4922 assign(c1, mkU32(0));
4923 }
4924 if ((r3 & 2) != 0) {
4925 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4926 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4927 mkU64(n)))));
4928 n = n + 1;
4929 } else {
4930 assign(b2, mkU32(0));
4931 assign(c2, mkU32(0));
4932 }
4933 if ((r3 & 1) != 0) {
4934 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4935 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4936 mkU64(n)))));
4937 n = n + 1;
4938 } else {
4939 assign(b3, mkU32(0));
4940 assign(c3, mkU32(0));
4941 }
4942 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4943 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4944 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4945 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4946 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4947 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4948 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4949
4950 return "clm";
4951}
4952
florian55085f82012-11-21 00:36:55 +00004953static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004954s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4955{
4956 IRTemp op1 = newTemp(Ity_I32);
4957 IRTemp op2 = newTemp(Ity_I32);
4958 IRTemp b0 = newTemp(Ity_I32);
4959 IRTemp b1 = newTemp(Ity_I32);
4960 IRTemp b2 = newTemp(Ity_I32);
4961 IRTemp b3 = newTemp(Ity_I32);
4962 IRTemp c0 = newTemp(Ity_I32);
4963 IRTemp c1 = newTemp(Ity_I32);
4964 IRTemp c2 = newTemp(Ity_I32);
4965 IRTemp c3 = newTemp(Ity_I32);
4966 UChar n;
4967
4968 n = 0;
4969 if ((r3 & 8) != 0) {
4970 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4971 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4972 n = n + 1;
4973 } else {
4974 assign(b0, mkU32(0));
4975 assign(c0, mkU32(0));
4976 }
4977 if ((r3 & 4) != 0) {
4978 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4979 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4980 mkU64(n)))));
4981 n = n + 1;
4982 } else {
4983 assign(b1, mkU32(0));
4984 assign(c1, mkU32(0));
4985 }
4986 if ((r3 & 2) != 0) {
4987 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4988 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4989 mkU64(n)))));
4990 n = n + 1;
4991 } else {
4992 assign(b2, mkU32(0));
4993 assign(c2, mkU32(0));
4994 }
4995 if ((r3 & 1) != 0) {
4996 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4997 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4998 mkU64(n)))));
4999 n = n + 1;
5000 } else {
5001 assign(b3, mkU32(0));
5002 assign(c3, mkU32(0));
5003 }
5004 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5005 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5006 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5007 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5008 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5009 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5010 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5011
5012 return "clmy";
5013}
5014
florian55085f82012-11-21 00:36:55 +00005015static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005016s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5017{
5018 IRTemp op1 = newTemp(Ity_I32);
5019 IRTemp op2 = newTemp(Ity_I32);
5020 IRTemp b0 = newTemp(Ity_I32);
5021 IRTemp b1 = newTemp(Ity_I32);
5022 IRTemp b2 = newTemp(Ity_I32);
5023 IRTemp b3 = newTemp(Ity_I32);
5024 IRTemp c0 = newTemp(Ity_I32);
5025 IRTemp c1 = newTemp(Ity_I32);
5026 IRTemp c2 = newTemp(Ity_I32);
5027 IRTemp c3 = newTemp(Ity_I32);
5028 UChar n;
5029
5030 n = 0;
5031 if ((r3 & 8) != 0) {
5032 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5033 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5034 n = n + 1;
5035 } else {
5036 assign(b0, mkU32(0));
5037 assign(c0, mkU32(0));
5038 }
5039 if ((r3 & 4) != 0) {
5040 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5041 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5042 mkU64(n)))));
5043 n = n + 1;
5044 } else {
5045 assign(b1, mkU32(0));
5046 assign(c1, mkU32(0));
5047 }
5048 if ((r3 & 2) != 0) {
5049 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5050 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5051 mkU64(n)))));
5052 n = n + 1;
5053 } else {
5054 assign(b2, mkU32(0));
5055 assign(c2, mkU32(0));
5056 }
5057 if ((r3 & 1) != 0) {
5058 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5059 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5060 mkU64(n)))));
5061 n = n + 1;
5062 } else {
5063 assign(b3, mkU32(0));
5064 assign(c3, mkU32(0));
5065 }
5066 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5067 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5068 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5069 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5070 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5071 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5072 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5073
5074 return "clmh";
5075}
5076
florian55085f82012-11-21 00:36:55 +00005077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005078s390_irgen_CLHHR(UChar r1, UChar r2)
5079{
5080 IRTemp op1 = newTemp(Ity_I32);
5081 IRTemp op2 = newTemp(Ity_I32);
5082
5083 assign(op1, get_gpr_w0(r1));
5084 assign(op2, get_gpr_w0(r2));
5085 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5086
5087 return "clhhr";
5088}
5089
florian55085f82012-11-21 00:36:55 +00005090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005091s390_irgen_CLHLR(UChar r1, UChar r2)
5092{
5093 IRTemp op1 = newTemp(Ity_I32);
5094 IRTemp op2 = newTemp(Ity_I32);
5095
5096 assign(op1, get_gpr_w0(r1));
5097 assign(op2, get_gpr_w1(r2));
5098 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5099
5100 return "clhlr";
5101}
5102
florian55085f82012-11-21 00:36:55 +00005103static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005104s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5105{
5106 IRTemp op1 = newTemp(Ity_I32);
5107 IRTemp op2 = newTemp(Ity_I32);
5108
5109 assign(op1, get_gpr_w0(r1));
5110 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5111 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5112
5113 return "clhf";
5114}
5115
florian55085f82012-11-21 00:36:55 +00005116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005117s390_irgen_CLIH(UChar r1, UInt i2)
5118{
5119 IRTemp op1 = newTemp(Ity_I32);
5120 UInt op2;
5121
5122 assign(op1, get_gpr_w0(r1));
5123 op2 = i2;
5124 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5125 mkU32(op2)));
5126
5127 return "clih";
5128}
5129
florian55085f82012-11-21 00:36:55 +00005130static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005131s390_irgen_CPYA(UChar r1, UChar r2)
5132{
5133 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005134 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005135 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5136
5137 return "cpya";
5138}
5139
florian55085f82012-11-21 00:36:55 +00005140static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005141s390_irgen_XR(UChar r1, UChar r2)
5142{
5143 IRTemp op1 = newTemp(Ity_I32);
5144 IRTemp op2 = newTemp(Ity_I32);
5145 IRTemp result = newTemp(Ity_I32);
5146
5147 if (r1 == r2) {
5148 assign(result, mkU32(0));
5149 } else {
5150 assign(op1, get_gpr_w1(r1));
5151 assign(op2, get_gpr_w1(r2));
5152 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5153 }
5154 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5155 put_gpr_w1(r1, mkexpr(result));
5156
5157 return "xr";
5158}
5159
florian55085f82012-11-21 00:36:55 +00005160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005161s390_irgen_XGR(UChar r1, UChar r2)
5162{
5163 IRTemp op1 = newTemp(Ity_I64);
5164 IRTemp op2 = newTemp(Ity_I64);
5165 IRTemp result = newTemp(Ity_I64);
5166
5167 if (r1 == r2) {
5168 assign(result, mkU64(0));
5169 } else {
5170 assign(op1, get_gpr_dw0(r1));
5171 assign(op2, get_gpr_dw0(r2));
5172 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5173 }
5174 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5175 put_gpr_dw0(r1, mkexpr(result));
5176
5177 return "xgr";
5178}
5179
florian55085f82012-11-21 00:36:55 +00005180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005181s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5182{
5183 IRTemp op2 = newTemp(Ity_I32);
5184 IRTemp op3 = newTemp(Ity_I32);
5185 IRTemp result = newTemp(Ity_I32);
5186
5187 assign(op2, get_gpr_w1(r2));
5188 assign(op3, get_gpr_w1(r3));
5189 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5190 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5191 put_gpr_w1(r1, mkexpr(result));
5192
5193 return "xrk";
5194}
5195
florian55085f82012-11-21 00:36:55 +00005196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005197s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5198{
5199 IRTemp op2 = newTemp(Ity_I64);
5200 IRTemp op3 = newTemp(Ity_I64);
5201 IRTemp result = newTemp(Ity_I64);
5202
5203 assign(op2, get_gpr_dw0(r2));
5204 assign(op3, get_gpr_dw0(r3));
5205 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5206 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5207 put_gpr_dw0(r1, mkexpr(result));
5208
5209 return "xgrk";
5210}
5211
florian55085f82012-11-21 00:36:55 +00005212static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005213s390_irgen_X(UChar r1, IRTemp op2addr)
5214{
5215 IRTemp op1 = newTemp(Ity_I32);
5216 IRTemp op2 = newTemp(Ity_I32);
5217 IRTemp result = newTemp(Ity_I32);
5218
5219 assign(op1, get_gpr_w1(r1));
5220 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5221 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5222 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5223 put_gpr_w1(r1, mkexpr(result));
5224
5225 return "x";
5226}
5227
florian55085f82012-11-21 00:36:55 +00005228static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005229s390_irgen_XY(UChar r1, IRTemp op2addr)
5230{
5231 IRTemp op1 = newTemp(Ity_I32);
5232 IRTemp op2 = newTemp(Ity_I32);
5233 IRTemp result = newTemp(Ity_I32);
5234
5235 assign(op1, get_gpr_w1(r1));
5236 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5237 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5238 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5239 put_gpr_w1(r1, mkexpr(result));
5240
5241 return "xy";
5242}
5243
florian55085f82012-11-21 00:36:55 +00005244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005245s390_irgen_XG(UChar r1, IRTemp op2addr)
5246{
5247 IRTemp op1 = newTemp(Ity_I64);
5248 IRTemp op2 = newTemp(Ity_I64);
5249 IRTemp result = newTemp(Ity_I64);
5250
5251 assign(op1, get_gpr_dw0(r1));
5252 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5253 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5254 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5255 put_gpr_dw0(r1, mkexpr(result));
5256
5257 return "xg";
5258}
5259
florian55085f82012-11-21 00:36:55 +00005260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005261s390_irgen_XI(UChar i2, IRTemp op1addr)
5262{
5263 IRTemp op1 = newTemp(Ity_I8);
5264 UChar op2;
5265 IRTemp result = newTemp(Ity_I8);
5266
5267 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5268 op2 = i2;
5269 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5270 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5271 store(mkexpr(op1addr), mkexpr(result));
5272
5273 return "xi";
5274}
5275
florian55085f82012-11-21 00:36:55 +00005276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005277s390_irgen_XIY(UChar i2, IRTemp op1addr)
5278{
5279 IRTemp op1 = newTemp(Ity_I8);
5280 UChar op2;
5281 IRTemp result = newTemp(Ity_I8);
5282
5283 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5284 op2 = i2;
5285 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5286 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5287 store(mkexpr(op1addr), mkexpr(result));
5288
5289 return "xiy";
5290}
5291
florian55085f82012-11-21 00:36:55 +00005292static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005293s390_irgen_XIHF(UChar r1, UInt i2)
5294{
5295 IRTemp op1 = newTemp(Ity_I32);
5296 UInt op2;
5297 IRTemp result = newTemp(Ity_I32);
5298
5299 assign(op1, get_gpr_w0(r1));
5300 op2 = i2;
5301 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5302 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5303 put_gpr_w0(r1, mkexpr(result));
5304
5305 return "xihf";
5306}
5307
florian55085f82012-11-21 00:36:55 +00005308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005309s390_irgen_XILF(UChar r1, UInt i2)
5310{
5311 IRTemp op1 = newTemp(Ity_I32);
5312 UInt op2;
5313 IRTemp result = newTemp(Ity_I32);
5314
5315 assign(op1, get_gpr_w1(r1));
5316 op2 = i2;
5317 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5318 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5319 put_gpr_w1(r1, mkexpr(result));
5320
5321 return "xilf";
5322}
5323
florian55085f82012-11-21 00:36:55 +00005324static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005325s390_irgen_EAR(UChar r1, UChar r2)
5326{
5327 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005328 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005329 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5330
5331 return "ear";
5332}
5333
florian55085f82012-11-21 00:36:55 +00005334static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005335s390_irgen_IC(UChar r1, IRTemp op2addr)
5336{
5337 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5338
5339 return "ic";
5340}
5341
florian55085f82012-11-21 00:36:55 +00005342static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005343s390_irgen_ICY(UChar r1, IRTemp op2addr)
5344{
5345 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5346
5347 return "icy";
5348}
5349
florian55085f82012-11-21 00:36:55 +00005350static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005351s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5352{
5353 UChar n;
5354 IRTemp result = newTemp(Ity_I32);
5355 UInt mask;
5356
5357 n = 0;
5358 mask = (UInt)r3;
5359 if ((mask & 8) != 0) {
5360 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5361 n = n + 1;
5362 }
5363 if ((mask & 4) != 0) {
5364 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5365
5366 n = n + 1;
5367 }
5368 if ((mask & 2) != 0) {
5369 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5370
5371 n = n + 1;
5372 }
5373 if ((mask & 1) != 0) {
5374 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5375
5376 n = n + 1;
5377 }
5378 assign(result, get_gpr_w1(r1));
5379 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5380 mkU32(mask)));
5381
5382 return "icm";
5383}
5384
florian55085f82012-11-21 00:36:55 +00005385static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005386s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5387{
5388 UChar n;
5389 IRTemp result = newTemp(Ity_I32);
5390 UInt mask;
5391
5392 n = 0;
5393 mask = (UInt)r3;
5394 if ((mask & 8) != 0) {
5395 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5396 n = n + 1;
5397 }
5398 if ((mask & 4) != 0) {
5399 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5400
5401 n = n + 1;
5402 }
5403 if ((mask & 2) != 0) {
5404 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5405
5406 n = n + 1;
5407 }
5408 if ((mask & 1) != 0) {
5409 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5410
5411 n = n + 1;
5412 }
5413 assign(result, get_gpr_w1(r1));
5414 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5415 mkU32(mask)));
5416
5417 return "icmy";
5418}
5419
florian55085f82012-11-21 00:36:55 +00005420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005421s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5422{
5423 UChar n;
5424 IRTemp result = newTemp(Ity_I32);
5425 UInt mask;
5426
5427 n = 0;
5428 mask = (UInt)r3;
5429 if ((mask & 8) != 0) {
5430 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5431 n = n + 1;
5432 }
5433 if ((mask & 4) != 0) {
5434 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5435
5436 n = n + 1;
5437 }
5438 if ((mask & 2) != 0) {
5439 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5440
5441 n = n + 1;
5442 }
5443 if ((mask & 1) != 0) {
5444 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5445
5446 n = n + 1;
5447 }
5448 assign(result, get_gpr_w0(r1));
5449 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5450 mkU32(mask)));
5451
5452 return "icmh";
5453}
5454
florian55085f82012-11-21 00:36:55 +00005455static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005456s390_irgen_IIHF(UChar r1, UInt i2)
5457{
5458 put_gpr_w0(r1, mkU32(i2));
5459
5460 return "iihf";
5461}
5462
florian55085f82012-11-21 00:36:55 +00005463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005464s390_irgen_IIHH(UChar r1, UShort i2)
5465{
5466 put_gpr_hw0(r1, mkU16(i2));
5467
5468 return "iihh";
5469}
5470
florian55085f82012-11-21 00:36:55 +00005471static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005472s390_irgen_IIHL(UChar r1, UShort i2)
5473{
5474 put_gpr_hw1(r1, mkU16(i2));
5475
5476 return "iihl";
5477}
5478
florian55085f82012-11-21 00:36:55 +00005479static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005480s390_irgen_IILF(UChar r1, UInt i2)
5481{
5482 put_gpr_w1(r1, mkU32(i2));
5483
5484 return "iilf";
5485}
5486
florian55085f82012-11-21 00:36:55 +00005487static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005488s390_irgen_IILH(UChar r1, UShort i2)
5489{
5490 put_gpr_hw2(r1, mkU16(i2));
5491
5492 return "iilh";
5493}
5494
florian55085f82012-11-21 00:36:55 +00005495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005496s390_irgen_IILL(UChar r1, UShort i2)
5497{
5498 put_gpr_hw3(r1, mkU16(i2));
5499
5500 return "iill";
5501}
5502
florian55085f82012-11-21 00:36:55 +00005503static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005504s390_irgen_LR(UChar r1, UChar r2)
5505{
5506 put_gpr_w1(r1, get_gpr_w1(r2));
5507
5508 return "lr";
5509}
5510
florian55085f82012-11-21 00:36:55 +00005511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005512s390_irgen_LGR(UChar r1, UChar r2)
5513{
5514 put_gpr_dw0(r1, get_gpr_dw0(r2));
5515
5516 return "lgr";
5517}
5518
florian55085f82012-11-21 00:36:55 +00005519static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005520s390_irgen_LGFR(UChar r1, UChar r2)
5521{
5522 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5523
5524 return "lgfr";
5525}
5526
florian55085f82012-11-21 00:36:55 +00005527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005528s390_irgen_L(UChar r1, IRTemp op2addr)
5529{
5530 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5531
5532 return "l";
5533}
5534
florian55085f82012-11-21 00:36:55 +00005535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005536s390_irgen_LY(UChar r1, IRTemp op2addr)
5537{
5538 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5539
5540 return "ly";
5541}
5542
florian55085f82012-11-21 00:36:55 +00005543static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005544s390_irgen_LG(UChar r1, IRTemp op2addr)
5545{
5546 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5547
5548 return "lg";
5549}
5550
florian55085f82012-11-21 00:36:55 +00005551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005552s390_irgen_LGF(UChar r1, IRTemp op2addr)
5553{
5554 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5555
5556 return "lgf";
5557}
5558
florian55085f82012-11-21 00:36:55 +00005559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005560s390_irgen_LGFI(UChar r1, UInt i2)
5561{
5562 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5563
5564 return "lgfi";
5565}
5566
florian55085f82012-11-21 00:36:55 +00005567static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005568s390_irgen_LRL(UChar r1, UInt i2)
5569{
5570 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5571 i2 << 1))));
5572
5573 return "lrl";
5574}
5575
florian55085f82012-11-21 00:36:55 +00005576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005577s390_irgen_LGRL(UChar r1, UInt i2)
5578{
5579 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5580 i2 << 1))));
5581
5582 return "lgrl";
5583}
5584
florian55085f82012-11-21 00:36:55 +00005585static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005586s390_irgen_LGFRL(UChar r1, UInt i2)
5587{
5588 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5589 ((ULong)(Long)(Int)i2 << 1)))));
5590
5591 return "lgfrl";
5592}
5593
florian55085f82012-11-21 00:36:55 +00005594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005595s390_irgen_LA(UChar r1, IRTemp op2addr)
5596{
5597 put_gpr_dw0(r1, mkexpr(op2addr));
5598
5599 return "la";
5600}
5601
florian55085f82012-11-21 00:36:55 +00005602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005603s390_irgen_LAY(UChar r1, IRTemp op2addr)
5604{
5605 put_gpr_dw0(r1, mkexpr(op2addr));
5606
5607 return "lay";
5608}
5609
florian55085f82012-11-21 00:36:55 +00005610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005611s390_irgen_LAE(UChar r1, IRTemp op2addr)
5612{
5613 put_gpr_dw0(r1, mkexpr(op2addr));
5614
5615 return "lae";
5616}
5617
florian55085f82012-11-21 00:36:55 +00005618static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005619s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5620{
5621 put_gpr_dw0(r1, mkexpr(op2addr));
5622
5623 return "laey";
5624}
5625
florian55085f82012-11-21 00:36:55 +00005626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005627s390_irgen_LARL(UChar r1, UInt i2)
5628{
5629 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5630
5631 return "larl";
5632}
5633
floriana265ee72012-12-02 20:58:17 +00005634/* The IR representation of LAA and friends is an approximation of what
5635 happens natively. Essentially a loop containing a compare-and-swap is
5636 constructed which will iterate until the CAS succeeds. As a consequence,
5637 instrumenters may see more memory accesses than happen natively. See also
5638 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005639static void
5640s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005641{
floriana265ee72012-12-02 20:58:17 +00005642 IRCAS *cas;
5643 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005644 IRTemp op2 = newTemp(Ity_I32);
5645 IRTemp op3 = newTemp(Ity_I32);
5646 IRTemp result = newTemp(Ity_I32);
5647
5648 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5649 assign(op3, get_gpr_w1(r3));
5650 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005651
5652 /* Place the addition of second operand and third operand at the
5653 second-operand location everytime */
5654 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5655 Iend_BE, mkexpr(op2addr),
5656 NULL, mkexpr(op2), /* expected value */
5657 NULL, mkexpr(result) /* new value */);
5658 stmt(IRStmt_CAS(cas));
5659
florianffc94012012-12-02 21:31:15 +00005660 /* Set CC according to 32-bit addition */
5661 if (is_signed) {
5662 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5663 } else {
5664 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5665 }
floriana265ee72012-12-02 20:58:17 +00005666
5667 /* If old_mem contains the expected value, then the CAS succeeded.
5668 Otherwise, it did not */
5669 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5670 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005671}
5672
5673static void
5674s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5675{
5676 IRCAS *cas;
5677 IRTemp old_mem = newTemp(Ity_I64);
5678 IRTemp op2 = newTemp(Ity_I64);
5679 IRTemp op3 = newTemp(Ity_I64);
5680 IRTemp result = newTemp(Ity_I64);
5681
5682 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5683 assign(op3, get_gpr_dw0(r3));
5684 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5685
5686 /* Place the addition of second operand and third operand at the
5687 second-operand location everytime */
5688 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5689 Iend_BE, mkexpr(op2addr),
5690 NULL, mkexpr(op2), /* expected value */
5691 NULL, mkexpr(result) /* new value */);
5692 stmt(IRStmt_CAS(cas));
5693
5694 /* Set CC according to 64-bit addition */
5695 if (is_signed) {
5696 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5697 } else {
5698 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5699 }
5700
5701 /* If old_mem contains the expected value, then the CAS succeeded.
5702 Otherwise, it did not */
5703 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5704 put_gpr_dw0(r1, mkexpr(old_mem));
5705}
5706
5707static void
5708s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5709{
5710 IRCAS *cas;
5711 IRTemp old_mem = newTemp(Ity_I32);
5712 IRTemp op2 = newTemp(Ity_I32);
5713 IRTemp op3 = newTemp(Ity_I32);
5714 IRTemp result = newTemp(Ity_I32);
5715
5716 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5717 assign(op3, get_gpr_w1(r3));
5718 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5719
5720 /* Place the addition of second operand and third operand at the
5721 second-operand location everytime */
5722 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5723 Iend_BE, mkexpr(op2addr),
5724 NULL, mkexpr(op2), /* expected value */
5725 NULL, mkexpr(result) /* new value */);
5726 stmt(IRStmt_CAS(cas));
5727
5728 /* Set CC according to bitwise operation */
5729 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5730
5731 /* If old_mem contains the expected value, then the CAS succeeded.
5732 Otherwise, it did not */
5733 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5734 put_gpr_w1(r1, mkexpr(old_mem));
5735}
5736
5737static void
5738s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5739{
5740 IRCAS *cas;
5741 IRTemp old_mem = newTemp(Ity_I64);
5742 IRTemp op2 = newTemp(Ity_I64);
5743 IRTemp op3 = newTemp(Ity_I64);
5744 IRTemp result = newTemp(Ity_I64);
5745
5746 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5747 assign(op3, get_gpr_dw0(r3));
5748 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5749
5750 /* Place the addition of second operand and third operand at the
5751 second-operand location everytime */
5752 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5753 Iend_BE, mkexpr(op2addr),
5754 NULL, mkexpr(op2), /* expected value */
5755 NULL, mkexpr(result) /* new value */);
5756 stmt(IRStmt_CAS(cas));
5757
5758 /* Set CC according to bitwise operation */
5759 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5760
5761 /* If old_mem contains the expected value, then the CAS succeeded.
5762 Otherwise, it did not */
5763 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5764 put_gpr_dw0(r1, mkexpr(old_mem));
5765}
5766
5767static const HChar *
5768s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5769{
5770 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005771
5772 return "laa";
5773}
5774
florian55085f82012-11-21 00:36:55 +00005775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005776s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5777{
florianffc94012012-12-02 21:31:15 +00005778 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005779
5780 return "laag";
5781}
5782
florian55085f82012-11-21 00:36:55 +00005783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005784s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5785{
florianffc94012012-12-02 21:31:15 +00005786 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005787
5788 return "laal";
5789}
5790
florian55085f82012-11-21 00:36:55 +00005791static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005792s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5793{
florianffc94012012-12-02 21:31:15 +00005794 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005795
5796 return "laalg";
5797}
5798
florian55085f82012-11-21 00:36:55 +00005799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005800s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5801{
florianffc94012012-12-02 21:31:15 +00005802 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005803
5804 return "lan";
5805}
5806
florian55085f82012-11-21 00:36:55 +00005807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005808s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5809{
florianffc94012012-12-02 21:31:15 +00005810 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005811
5812 return "lang";
5813}
5814
florian55085f82012-11-21 00:36:55 +00005815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005816s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5817{
florianffc94012012-12-02 21:31:15 +00005818 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005819
5820 return "lax";
5821}
5822
florian55085f82012-11-21 00:36:55 +00005823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005824s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5825{
florianffc94012012-12-02 21:31:15 +00005826 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005827
5828 return "laxg";
5829}
5830
florian55085f82012-11-21 00:36:55 +00005831static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005832s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5833{
florianffc94012012-12-02 21:31:15 +00005834 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005835
5836 return "lao";
5837}
5838
florian55085f82012-11-21 00:36:55 +00005839static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005840s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5841{
florianffc94012012-12-02 21:31:15 +00005842 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005843
5844 return "laog";
5845}
5846
florian55085f82012-11-21 00:36:55 +00005847static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005848s390_irgen_LTR(UChar r1, UChar r2)
5849{
5850 IRTemp op2 = newTemp(Ity_I32);
5851
5852 assign(op2, get_gpr_w1(r2));
5853 put_gpr_w1(r1, mkexpr(op2));
5854 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5855
5856 return "ltr";
5857}
5858
florian55085f82012-11-21 00:36:55 +00005859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005860s390_irgen_LTGR(UChar r1, UChar r2)
5861{
5862 IRTemp op2 = newTemp(Ity_I64);
5863
5864 assign(op2, get_gpr_dw0(r2));
5865 put_gpr_dw0(r1, mkexpr(op2));
5866 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5867
5868 return "ltgr";
5869}
5870
florian55085f82012-11-21 00:36:55 +00005871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005872s390_irgen_LTGFR(UChar r1, UChar r2)
5873{
5874 IRTemp op2 = newTemp(Ity_I64);
5875
5876 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5877 put_gpr_dw0(r1, mkexpr(op2));
5878 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5879
5880 return "ltgfr";
5881}
5882
florian55085f82012-11-21 00:36:55 +00005883static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005884s390_irgen_LT(UChar r1, IRTemp op2addr)
5885{
5886 IRTemp op2 = newTemp(Ity_I32);
5887
5888 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5889 put_gpr_w1(r1, mkexpr(op2));
5890 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5891
5892 return "lt";
5893}
5894
florian55085f82012-11-21 00:36:55 +00005895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005896s390_irgen_LTG(UChar r1, IRTemp op2addr)
5897{
5898 IRTemp op2 = newTemp(Ity_I64);
5899
5900 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5901 put_gpr_dw0(r1, mkexpr(op2));
5902 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5903
5904 return "ltg";
5905}
5906
florian55085f82012-11-21 00:36:55 +00005907static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005908s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5909{
5910 IRTemp op2 = newTemp(Ity_I64);
5911
5912 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5913 put_gpr_dw0(r1, mkexpr(op2));
5914 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5915
5916 return "ltgf";
5917}
5918
florian55085f82012-11-21 00:36:55 +00005919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005920s390_irgen_LBR(UChar r1, UChar r2)
5921{
5922 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5923
5924 return "lbr";
5925}
5926
florian55085f82012-11-21 00:36:55 +00005927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005928s390_irgen_LGBR(UChar r1, UChar r2)
5929{
5930 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5931
5932 return "lgbr";
5933}
5934
florian55085f82012-11-21 00:36:55 +00005935static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005936s390_irgen_LB(UChar r1, IRTemp op2addr)
5937{
5938 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5939
5940 return "lb";
5941}
5942
florian55085f82012-11-21 00:36:55 +00005943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005944s390_irgen_LGB(UChar r1, IRTemp op2addr)
5945{
5946 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5947
5948 return "lgb";
5949}
5950
florian55085f82012-11-21 00:36:55 +00005951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005952s390_irgen_LBH(UChar r1, IRTemp op2addr)
5953{
5954 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5955
5956 return "lbh";
5957}
5958
florian55085f82012-11-21 00:36:55 +00005959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005960s390_irgen_LCR(UChar r1, UChar r2)
5961{
5962 Int op1;
5963 IRTemp op2 = newTemp(Ity_I32);
5964 IRTemp result = newTemp(Ity_I32);
5965
5966 op1 = 0;
5967 assign(op2, get_gpr_w1(r2));
5968 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5969 put_gpr_w1(r1, mkexpr(result));
5970 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5971 op1)), op2);
5972
5973 return "lcr";
5974}
5975
florian55085f82012-11-21 00:36:55 +00005976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005977s390_irgen_LCGR(UChar r1, UChar r2)
5978{
5979 Long op1;
5980 IRTemp op2 = newTemp(Ity_I64);
5981 IRTemp result = newTemp(Ity_I64);
5982
5983 op1 = 0ULL;
5984 assign(op2, get_gpr_dw0(r2));
5985 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5986 put_gpr_dw0(r1, mkexpr(result));
5987 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5988 op1)), op2);
5989
5990 return "lcgr";
5991}
5992
florian55085f82012-11-21 00:36:55 +00005993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005994s390_irgen_LCGFR(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, unop(Iop_32Sto64, get_gpr_w1(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 "lcgfr";
6008}
6009
florian55085f82012-11-21 00:36:55 +00006010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006011s390_irgen_LHR(UChar r1, UChar r2)
6012{
6013 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6014
6015 return "lhr";
6016}
6017
florian55085f82012-11-21 00:36:55 +00006018static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006019s390_irgen_LGHR(UChar r1, UChar r2)
6020{
6021 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6022
6023 return "lghr";
6024}
6025
florian55085f82012-11-21 00:36:55 +00006026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006027s390_irgen_LH(UChar r1, IRTemp op2addr)
6028{
6029 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6030
6031 return "lh";
6032}
6033
florian55085f82012-11-21 00:36:55 +00006034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006035s390_irgen_LHY(UChar r1, IRTemp op2addr)
6036{
6037 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6038
6039 return "lhy";
6040}
6041
florian55085f82012-11-21 00:36:55 +00006042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006043s390_irgen_LGH(UChar r1, IRTemp op2addr)
6044{
6045 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6046
6047 return "lgh";
6048}
6049
florian55085f82012-11-21 00:36:55 +00006050static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006051s390_irgen_LHI(UChar r1, UShort i2)
6052{
6053 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6054
6055 return "lhi";
6056}
6057
florian55085f82012-11-21 00:36:55 +00006058static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006059s390_irgen_LGHI(UChar r1, UShort i2)
6060{
6061 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6062
6063 return "lghi";
6064}
6065
florian55085f82012-11-21 00:36:55 +00006066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006067s390_irgen_LHRL(UChar r1, UInt i2)
6068{
6069 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6070 ((ULong)(Long)(Int)i2 << 1)))));
6071
6072 return "lhrl";
6073}
6074
florian55085f82012-11-21 00:36:55 +00006075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006076s390_irgen_LGHRL(UChar r1, UInt i2)
6077{
6078 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6079 ((ULong)(Long)(Int)i2 << 1)))));
6080
6081 return "lghrl";
6082}
6083
florian55085f82012-11-21 00:36:55 +00006084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006085s390_irgen_LHH(UChar r1, IRTemp op2addr)
6086{
6087 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6088
6089 return "lhh";
6090}
6091
florian55085f82012-11-21 00:36:55 +00006092static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006093s390_irgen_LFH(UChar r1, IRTemp op2addr)
6094{
6095 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6096
6097 return "lfh";
6098}
6099
florian55085f82012-11-21 00:36:55 +00006100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006101s390_irgen_LLGFR(UChar r1, UChar r2)
6102{
6103 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6104
6105 return "llgfr";
6106}
6107
florian55085f82012-11-21 00:36:55 +00006108static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006109s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6110{
6111 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6112
6113 return "llgf";
6114}
6115
florian55085f82012-11-21 00:36:55 +00006116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006117s390_irgen_LLGFRL(UChar r1, UInt i2)
6118{
6119 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6120 ((ULong)(Long)(Int)i2 << 1)))));
6121
6122 return "llgfrl";
6123}
6124
florian55085f82012-11-21 00:36:55 +00006125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006126s390_irgen_LLCR(UChar r1, UChar r2)
6127{
6128 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6129
6130 return "llcr";
6131}
6132
florian55085f82012-11-21 00:36:55 +00006133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006134s390_irgen_LLGCR(UChar r1, UChar r2)
6135{
6136 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6137
6138 return "llgcr";
6139}
6140
florian55085f82012-11-21 00:36:55 +00006141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006142s390_irgen_LLC(UChar r1, IRTemp op2addr)
6143{
6144 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6145
6146 return "llc";
6147}
6148
florian55085f82012-11-21 00:36:55 +00006149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006150s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6151{
6152 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6153
6154 return "llgc";
6155}
6156
florian55085f82012-11-21 00:36:55 +00006157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006158s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6159{
6160 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6161
6162 return "llch";
6163}
6164
florian55085f82012-11-21 00:36:55 +00006165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006166s390_irgen_LLHR(UChar r1, UChar r2)
6167{
6168 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6169
6170 return "llhr";
6171}
6172
florian55085f82012-11-21 00:36:55 +00006173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006174s390_irgen_LLGHR(UChar r1, UChar r2)
6175{
6176 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6177
6178 return "llghr";
6179}
6180
florian55085f82012-11-21 00:36:55 +00006181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006182s390_irgen_LLH(UChar r1, IRTemp op2addr)
6183{
6184 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6185
6186 return "llh";
6187}
6188
florian55085f82012-11-21 00:36:55 +00006189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006190s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6191{
6192 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6193
6194 return "llgh";
6195}
6196
florian55085f82012-11-21 00:36:55 +00006197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006198s390_irgen_LLHRL(UChar r1, UInt i2)
6199{
6200 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6201 ((ULong)(Long)(Int)i2 << 1)))));
6202
6203 return "llhrl";
6204}
6205
florian55085f82012-11-21 00:36:55 +00006206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006207s390_irgen_LLGHRL(UChar r1, UInt i2)
6208{
6209 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6210 ((ULong)(Long)(Int)i2 << 1)))));
6211
6212 return "llghrl";
6213}
6214
florian55085f82012-11-21 00:36:55 +00006215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006216s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6217{
6218 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6219
6220 return "llhh";
6221}
6222
florian55085f82012-11-21 00:36:55 +00006223static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006224s390_irgen_LLIHF(UChar r1, UInt i2)
6225{
6226 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6227
6228 return "llihf";
6229}
6230
florian55085f82012-11-21 00:36:55 +00006231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006232s390_irgen_LLIHH(UChar r1, UShort i2)
6233{
6234 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6235
6236 return "llihh";
6237}
6238
florian55085f82012-11-21 00:36:55 +00006239static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006240s390_irgen_LLIHL(UChar r1, UShort i2)
6241{
6242 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6243
6244 return "llihl";
6245}
6246
florian55085f82012-11-21 00:36:55 +00006247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006248s390_irgen_LLILF(UChar r1, UInt i2)
6249{
6250 put_gpr_dw0(r1, mkU64(i2));
6251
6252 return "llilf";
6253}
6254
florian55085f82012-11-21 00:36:55 +00006255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006256s390_irgen_LLILH(UChar r1, UShort i2)
6257{
6258 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6259
6260 return "llilh";
6261}
6262
florian55085f82012-11-21 00:36:55 +00006263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006264s390_irgen_LLILL(UChar r1, UShort i2)
6265{
6266 put_gpr_dw0(r1, mkU64(i2));
6267
6268 return "llill";
6269}
6270
florian55085f82012-11-21 00:36:55 +00006271static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006272s390_irgen_LLGTR(UChar r1, UChar r2)
6273{
6274 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6275 mkU32(2147483647))));
6276
6277 return "llgtr";
6278}
6279
florian55085f82012-11-21 00:36:55 +00006280static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006281s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6282{
6283 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6284 mkexpr(op2addr)), mkU32(2147483647))));
6285
6286 return "llgt";
6287}
6288
florian55085f82012-11-21 00:36:55 +00006289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006290s390_irgen_LNR(UChar r1, UChar r2)
6291{
6292 IRTemp op2 = newTemp(Ity_I32);
6293 IRTemp result = newTemp(Ity_I32);
6294
6295 assign(op2, get_gpr_w1(r2));
6296 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6297 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6298 put_gpr_w1(r1, mkexpr(result));
6299 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6300
6301 return "lnr";
6302}
6303
florian55085f82012-11-21 00:36:55 +00006304static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006305s390_irgen_LNGR(UChar r1, UChar r2)
6306{
6307 IRTemp op2 = newTemp(Ity_I64);
6308 IRTemp result = newTemp(Ity_I64);
6309
6310 assign(op2, get_gpr_dw0(r2));
6311 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6312 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6313 put_gpr_dw0(r1, mkexpr(result));
6314 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6315
6316 return "lngr";
6317}
6318
florian55085f82012-11-21 00:36:55 +00006319static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006320s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6321{
6322 IRTemp op2 = newTemp(Ity_I64);
6323 IRTemp result = newTemp(Ity_I64);
6324
6325 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6326 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6327 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6328 put_gpr_dw0(r1, mkexpr(result));
6329 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6330
6331 return "lngfr";
6332}
6333
florian55085f82012-11-21 00:36:55 +00006334static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006335s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6336{
florian6820ba52012-07-26 02:01:50 +00006337 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006338 put_gpr_w1(r1, get_gpr_w1(r2));
6339
6340 return "locr";
6341}
6342
florian55085f82012-11-21 00:36:55 +00006343static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006344s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6345{
florian6820ba52012-07-26 02:01:50 +00006346 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006347 put_gpr_dw0(r1, get_gpr_dw0(r2));
6348
6349 return "locgr";
6350}
6351
florian55085f82012-11-21 00:36:55 +00006352static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006353s390_irgen_LOC(UChar r1, IRTemp op2addr)
6354{
6355 /* condition is checked in format handler */
6356 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6357
6358 return "loc";
6359}
6360
florian55085f82012-11-21 00:36:55 +00006361static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006362s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6363{
6364 /* condition is checked in format handler */
6365 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6366
6367 return "locg";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006371s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6372{
6373 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6374 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6375 ));
6376
6377 return "lpq";
6378}
6379
florian55085f82012-11-21 00:36:55 +00006380static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006381s390_irgen_LPR(UChar r1, UChar r2)
6382{
6383 IRTemp op2 = newTemp(Ity_I32);
6384 IRTemp result = newTemp(Ity_I32);
6385
6386 assign(op2, get_gpr_w1(r2));
6387 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6388 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6389 put_gpr_w1(r1, mkexpr(result));
6390 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6391
6392 return "lpr";
6393}
6394
florian55085f82012-11-21 00:36:55 +00006395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006396s390_irgen_LPGR(UChar r1, UChar r2)
6397{
6398 IRTemp op2 = newTemp(Ity_I64);
6399 IRTemp result = newTemp(Ity_I64);
6400
6401 assign(op2, get_gpr_dw0(r2));
6402 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6403 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6404 put_gpr_dw0(r1, mkexpr(result));
6405 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6406
6407 return "lpgr";
6408}
6409
florian55085f82012-11-21 00:36:55 +00006410static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006411s390_irgen_LPGFR(UChar r1, UChar r2)
6412{
6413 IRTemp op2 = newTemp(Ity_I64);
6414 IRTemp result = newTemp(Ity_I64);
6415
6416 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6417 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6418 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6419 put_gpr_dw0(r1, mkexpr(result));
6420 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6421
6422 return "lpgfr";
6423}
6424
florian55085f82012-11-21 00:36:55 +00006425static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006426s390_irgen_LRVR(UChar r1, UChar r2)
6427{
6428 IRTemp b0 = newTemp(Ity_I8);
6429 IRTemp b1 = newTemp(Ity_I8);
6430 IRTemp b2 = newTemp(Ity_I8);
6431 IRTemp b3 = newTemp(Ity_I8);
6432
6433 assign(b3, get_gpr_b7(r2));
6434 assign(b2, get_gpr_b6(r2));
6435 assign(b1, get_gpr_b5(r2));
6436 assign(b0, get_gpr_b4(r2));
6437 put_gpr_b4(r1, mkexpr(b3));
6438 put_gpr_b5(r1, mkexpr(b2));
6439 put_gpr_b6(r1, mkexpr(b1));
6440 put_gpr_b7(r1, mkexpr(b0));
6441
6442 return "lrvr";
6443}
6444
florian55085f82012-11-21 00:36:55 +00006445static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006446s390_irgen_LRVGR(UChar r1, UChar r2)
6447{
6448 IRTemp b0 = newTemp(Ity_I8);
6449 IRTemp b1 = newTemp(Ity_I8);
6450 IRTemp b2 = newTemp(Ity_I8);
6451 IRTemp b3 = newTemp(Ity_I8);
6452 IRTemp b4 = newTemp(Ity_I8);
6453 IRTemp b5 = newTemp(Ity_I8);
6454 IRTemp b6 = newTemp(Ity_I8);
6455 IRTemp b7 = newTemp(Ity_I8);
6456
6457 assign(b7, get_gpr_b7(r2));
6458 assign(b6, get_gpr_b6(r2));
6459 assign(b5, get_gpr_b5(r2));
6460 assign(b4, get_gpr_b4(r2));
6461 assign(b3, get_gpr_b3(r2));
6462 assign(b2, get_gpr_b2(r2));
6463 assign(b1, get_gpr_b1(r2));
6464 assign(b0, get_gpr_b0(r2));
6465 put_gpr_b0(r1, mkexpr(b7));
6466 put_gpr_b1(r1, mkexpr(b6));
6467 put_gpr_b2(r1, mkexpr(b5));
6468 put_gpr_b3(r1, mkexpr(b4));
6469 put_gpr_b4(r1, mkexpr(b3));
6470 put_gpr_b5(r1, mkexpr(b2));
6471 put_gpr_b6(r1, mkexpr(b1));
6472 put_gpr_b7(r1, mkexpr(b0));
6473
6474 return "lrvgr";
6475}
6476
florian55085f82012-11-21 00:36:55 +00006477static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006478s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6479{
6480 IRTemp op2 = newTemp(Ity_I16);
6481
6482 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6483 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6484 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6485
6486 return "lrvh";
6487}
6488
florian55085f82012-11-21 00:36:55 +00006489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006490s390_irgen_LRV(UChar r1, IRTemp op2addr)
6491{
6492 IRTemp op2 = newTemp(Ity_I32);
6493
6494 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6495 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6496 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6497 mkU8(8)), mkU32(255))));
6498 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6499 mkU8(16)), mkU32(255))));
6500 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6501 mkU8(24)), mkU32(255))));
6502
6503 return "lrv";
6504}
6505
florian55085f82012-11-21 00:36:55 +00006506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006507s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6508{
6509 IRTemp op2 = newTemp(Ity_I64);
6510
6511 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6512 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6513 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6514 mkU8(8)), mkU64(255))));
6515 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6516 mkU8(16)), mkU64(255))));
6517 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6518 mkU8(24)), mkU64(255))));
6519 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6520 mkU8(32)), mkU64(255))));
6521 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6522 mkU8(40)), mkU64(255))));
6523 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6524 mkU8(48)), mkU64(255))));
6525 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6526 mkU8(56)), mkU64(255))));
6527
6528 return "lrvg";
6529}
6530
florian55085f82012-11-21 00:36:55 +00006531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006532s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6533{
6534 store(mkexpr(op1addr), mkU16(i2));
6535
6536 return "mvhhi";
6537}
6538
florian55085f82012-11-21 00:36:55 +00006539static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006540s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6541{
6542 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6543
6544 return "mvhi";
6545}
6546
florian55085f82012-11-21 00:36:55 +00006547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006548s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6549{
6550 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6551
6552 return "mvghi";
6553}
6554
florian55085f82012-11-21 00:36:55 +00006555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006556s390_irgen_MVI(UChar i2, IRTemp op1addr)
6557{
6558 store(mkexpr(op1addr), mkU8(i2));
6559
6560 return "mvi";
6561}
6562
florian55085f82012-11-21 00:36:55 +00006563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006564s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6565{
6566 store(mkexpr(op1addr), mkU8(i2));
6567
6568 return "mviy";
6569}
6570
florian55085f82012-11-21 00:36:55 +00006571static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006572s390_irgen_MR(UChar r1, UChar r2)
6573{
6574 IRTemp op1 = newTemp(Ity_I32);
6575 IRTemp op2 = newTemp(Ity_I32);
6576 IRTemp result = newTemp(Ity_I64);
6577
6578 assign(op1, get_gpr_w1(r1 + 1));
6579 assign(op2, get_gpr_w1(r2));
6580 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6581 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6582 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6583
6584 return "mr";
6585}
6586
florian55085f82012-11-21 00:36:55 +00006587static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006588s390_irgen_M(UChar r1, IRTemp op2addr)
6589{
6590 IRTemp op1 = newTemp(Ity_I32);
6591 IRTemp op2 = newTemp(Ity_I32);
6592 IRTemp result = newTemp(Ity_I64);
6593
6594 assign(op1, get_gpr_w1(r1 + 1));
6595 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6596 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6597 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6598 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6599
6600 return "m";
6601}
6602
florian55085f82012-11-21 00:36:55 +00006603static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006604s390_irgen_MFY(UChar r1, IRTemp op2addr)
6605{
6606 IRTemp op1 = newTemp(Ity_I32);
6607 IRTemp op2 = newTemp(Ity_I32);
6608 IRTemp result = newTemp(Ity_I64);
6609
6610 assign(op1, get_gpr_w1(r1 + 1));
6611 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6612 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6613 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6614 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6615
6616 return "mfy";
6617}
6618
florian55085f82012-11-21 00:36:55 +00006619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006620s390_irgen_MH(UChar r1, IRTemp op2addr)
6621{
6622 IRTemp op1 = newTemp(Ity_I32);
6623 IRTemp op2 = newTemp(Ity_I16);
6624 IRTemp result = newTemp(Ity_I64);
6625
6626 assign(op1, get_gpr_w1(r1));
6627 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6628 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6629 ));
6630 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6631
6632 return "mh";
6633}
6634
florian55085f82012-11-21 00:36:55 +00006635static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006636s390_irgen_MHY(UChar r1, IRTemp op2addr)
6637{
6638 IRTemp op1 = newTemp(Ity_I32);
6639 IRTemp op2 = newTemp(Ity_I16);
6640 IRTemp result = newTemp(Ity_I64);
6641
6642 assign(op1, get_gpr_w1(r1));
6643 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6644 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6645 ));
6646 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6647
6648 return "mhy";
6649}
6650
florian55085f82012-11-21 00:36:55 +00006651static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006652s390_irgen_MHI(UChar r1, UShort i2)
6653{
6654 IRTemp op1 = newTemp(Ity_I32);
6655 Short op2;
6656 IRTemp result = newTemp(Ity_I64);
6657
6658 assign(op1, get_gpr_w1(r1));
6659 op2 = (Short)i2;
6660 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6661 mkU16((UShort)op2))));
6662 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6663
6664 return "mhi";
6665}
6666
florian55085f82012-11-21 00:36:55 +00006667static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006668s390_irgen_MGHI(UChar r1, UShort i2)
6669{
6670 IRTemp op1 = newTemp(Ity_I64);
6671 Short op2;
6672 IRTemp result = newTemp(Ity_I128);
6673
6674 assign(op1, get_gpr_dw0(r1));
6675 op2 = (Short)i2;
6676 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6677 mkU16((UShort)op2))));
6678 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6679
6680 return "mghi";
6681}
6682
florian55085f82012-11-21 00:36:55 +00006683static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006684s390_irgen_MLR(UChar r1, UChar r2)
6685{
6686 IRTemp op1 = newTemp(Ity_I32);
6687 IRTemp op2 = newTemp(Ity_I32);
6688 IRTemp result = newTemp(Ity_I64);
6689
6690 assign(op1, get_gpr_w1(r1 + 1));
6691 assign(op2, get_gpr_w1(r2));
6692 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6693 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6694 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6695
6696 return "mlr";
6697}
6698
florian55085f82012-11-21 00:36:55 +00006699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006700s390_irgen_MLGR(UChar r1, UChar r2)
6701{
6702 IRTemp op1 = newTemp(Ity_I64);
6703 IRTemp op2 = newTemp(Ity_I64);
6704 IRTemp result = newTemp(Ity_I128);
6705
6706 assign(op1, get_gpr_dw0(r1 + 1));
6707 assign(op2, get_gpr_dw0(r2));
6708 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6709 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6710 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6711
6712 return "mlgr";
6713}
6714
florian55085f82012-11-21 00:36:55 +00006715static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006716s390_irgen_ML(UChar r1, IRTemp op2addr)
6717{
6718 IRTemp op1 = newTemp(Ity_I32);
6719 IRTemp op2 = newTemp(Ity_I32);
6720 IRTemp result = newTemp(Ity_I64);
6721
6722 assign(op1, get_gpr_w1(r1 + 1));
6723 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6724 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6725 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6726 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6727
6728 return "ml";
6729}
6730
florian55085f82012-11-21 00:36:55 +00006731static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006732s390_irgen_MLG(UChar r1, IRTemp op2addr)
6733{
6734 IRTemp op1 = newTemp(Ity_I64);
6735 IRTemp op2 = newTemp(Ity_I64);
6736 IRTemp result = newTemp(Ity_I128);
6737
6738 assign(op1, get_gpr_dw0(r1 + 1));
6739 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6740 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6741 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6742 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6743
6744 return "mlg";
6745}
6746
florian55085f82012-11-21 00:36:55 +00006747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006748s390_irgen_MSR(UChar r1, UChar r2)
6749{
6750 IRTemp op1 = newTemp(Ity_I32);
6751 IRTemp op2 = newTemp(Ity_I32);
6752 IRTemp result = newTemp(Ity_I64);
6753
6754 assign(op1, get_gpr_w1(r1));
6755 assign(op2, get_gpr_w1(r2));
6756 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6757 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6758
6759 return "msr";
6760}
6761
florian55085f82012-11-21 00:36:55 +00006762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006763s390_irgen_MSGR(UChar r1, UChar r2)
6764{
6765 IRTemp op1 = newTemp(Ity_I64);
6766 IRTemp op2 = newTemp(Ity_I64);
6767 IRTemp result = newTemp(Ity_I128);
6768
6769 assign(op1, get_gpr_dw0(r1));
6770 assign(op2, get_gpr_dw0(r2));
6771 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6772 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6773
6774 return "msgr";
6775}
6776
florian55085f82012-11-21 00:36:55 +00006777static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006778s390_irgen_MSGFR(UChar r1, UChar r2)
6779{
6780 IRTemp op1 = newTemp(Ity_I64);
6781 IRTemp op2 = newTemp(Ity_I32);
6782 IRTemp result = newTemp(Ity_I128);
6783
6784 assign(op1, get_gpr_dw0(r1));
6785 assign(op2, get_gpr_w1(r2));
6786 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6787 ));
6788 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6789
6790 return "msgfr";
6791}
6792
florian55085f82012-11-21 00:36:55 +00006793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006794s390_irgen_MS(UChar r1, IRTemp op2addr)
6795{
6796 IRTemp op1 = newTemp(Ity_I32);
6797 IRTemp op2 = newTemp(Ity_I32);
6798 IRTemp result = newTemp(Ity_I64);
6799
6800 assign(op1, get_gpr_w1(r1));
6801 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6802 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6803 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6804
6805 return "ms";
6806}
6807
florian55085f82012-11-21 00:36:55 +00006808static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006809s390_irgen_MSY(UChar r1, IRTemp op2addr)
6810{
6811 IRTemp op1 = newTemp(Ity_I32);
6812 IRTemp op2 = newTemp(Ity_I32);
6813 IRTemp result = newTemp(Ity_I64);
6814
6815 assign(op1, get_gpr_w1(r1));
6816 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6817 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6818 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6819
6820 return "msy";
6821}
6822
florian55085f82012-11-21 00:36:55 +00006823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006824s390_irgen_MSG(UChar r1, IRTemp op2addr)
6825{
6826 IRTemp op1 = newTemp(Ity_I64);
6827 IRTemp op2 = newTemp(Ity_I64);
6828 IRTemp result = newTemp(Ity_I128);
6829
6830 assign(op1, get_gpr_dw0(r1));
6831 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6832 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6833 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6834
6835 return "msg";
6836}
6837
florian55085f82012-11-21 00:36:55 +00006838static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006839s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6840{
6841 IRTemp op1 = newTemp(Ity_I64);
6842 IRTemp op2 = newTemp(Ity_I32);
6843 IRTemp result = newTemp(Ity_I128);
6844
6845 assign(op1, get_gpr_dw0(r1));
6846 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6847 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6848 ));
6849 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6850
6851 return "msgf";
6852}
6853
florian55085f82012-11-21 00:36:55 +00006854static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006855s390_irgen_MSFI(UChar r1, UInt i2)
6856{
6857 IRTemp op1 = newTemp(Ity_I32);
6858 Int op2;
6859 IRTemp result = newTemp(Ity_I64);
6860
6861 assign(op1, get_gpr_w1(r1));
6862 op2 = (Int)i2;
6863 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6864 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6865
6866 return "msfi";
6867}
6868
florian55085f82012-11-21 00:36:55 +00006869static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006870s390_irgen_MSGFI(UChar r1, UInt i2)
6871{
6872 IRTemp op1 = newTemp(Ity_I64);
6873 Int op2;
6874 IRTemp result = newTemp(Ity_I128);
6875
6876 assign(op1, get_gpr_dw0(r1));
6877 op2 = (Int)i2;
6878 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6879 op2))));
6880 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6881
6882 return "msgfi";
6883}
6884
florian55085f82012-11-21 00:36:55 +00006885static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006886s390_irgen_OR(UChar r1, UChar r2)
6887{
6888 IRTemp op1 = newTemp(Ity_I32);
6889 IRTemp op2 = newTemp(Ity_I32);
6890 IRTemp result = newTemp(Ity_I32);
6891
6892 assign(op1, get_gpr_w1(r1));
6893 assign(op2, get_gpr_w1(r2));
6894 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6895 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6896 put_gpr_w1(r1, mkexpr(result));
6897
6898 return "or";
6899}
6900
florian55085f82012-11-21 00:36:55 +00006901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006902s390_irgen_OGR(UChar r1, UChar r2)
6903{
6904 IRTemp op1 = newTemp(Ity_I64);
6905 IRTemp op2 = newTemp(Ity_I64);
6906 IRTemp result = newTemp(Ity_I64);
6907
6908 assign(op1, get_gpr_dw0(r1));
6909 assign(op2, get_gpr_dw0(r2));
6910 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6911 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6912 put_gpr_dw0(r1, mkexpr(result));
6913
6914 return "ogr";
6915}
6916
florian55085f82012-11-21 00:36:55 +00006917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006918s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6919{
6920 IRTemp op2 = newTemp(Ity_I32);
6921 IRTemp op3 = newTemp(Ity_I32);
6922 IRTemp result = newTemp(Ity_I32);
6923
6924 assign(op2, get_gpr_w1(r2));
6925 assign(op3, get_gpr_w1(r3));
6926 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6927 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6928 put_gpr_w1(r1, mkexpr(result));
6929
6930 return "ork";
6931}
6932
florian55085f82012-11-21 00:36:55 +00006933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006934s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6935{
6936 IRTemp op2 = newTemp(Ity_I64);
6937 IRTemp op3 = newTemp(Ity_I64);
6938 IRTemp result = newTemp(Ity_I64);
6939
6940 assign(op2, get_gpr_dw0(r2));
6941 assign(op3, get_gpr_dw0(r3));
6942 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6943 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6944 put_gpr_dw0(r1, mkexpr(result));
6945
6946 return "ogrk";
6947}
6948
florian55085f82012-11-21 00:36:55 +00006949static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006950s390_irgen_O(UChar r1, IRTemp op2addr)
6951{
6952 IRTemp op1 = newTemp(Ity_I32);
6953 IRTemp op2 = newTemp(Ity_I32);
6954 IRTemp result = newTemp(Ity_I32);
6955
6956 assign(op1, get_gpr_w1(r1));
6957 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6958 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6959 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6960 put_gpr_w1(r1, mkexpr(result));
6961
6962 return "o";
6963}
6964
florian55085f82012-11-21 00:36:55 +00006965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006966s390_irgen_OY(UChar r1, IRTemp op2addr)
6967{
6968 IRTemp op1 = newTemp(Ity_I32);
6969 IRTemp op2 = newTemp(Ity_I32);
6970 IRTemp result = newTemp(Ity_I32);
6971
6972 assign(op1, get_gpr_w1(r1));
6973 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6974 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6975 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6976 put_gpr_w1(r1, mkexpr(result));
6977
6978 return "oy";
6979}
6980
florian55085f82012-11-21 00:36:55 +00006981static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006982s390_irgen_OG(UChar r1, IRTemp op2addr)
6983{
6984 IRTemp op1 = newTemp(Ity_I64);
6985 IRTemp op2 = newTemp(Ity_I64);
6986 IRTemp result = newTemp(Ity_I64);
6987
6988 assign(op1, get_gpr_dw0(r1));
6989 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6990 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6991 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6992 put_gpr_dw0(r1, mkexpr(result));
6993
6994 return "og";
6995}
6996
florian55085f82012-11-21 00:36:55 +00006997static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006998s390_irgen_OI(UChar i2, IRTemp op1addr)
6999{
7000 IRTemp op1 = newTemp(Ity_I8);
7001 UChar op2;
7002 IRTemp result = newTemp(Ity_I8);
7003
7004 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7005 op2 = i2;
7006 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7007 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7008 store(mkexpr(op1addr), mkexpr(result));
7009
7010 return "oi";
7011}
7012
florian55085f82012-11-21 00:36:55 +00007013static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007014s390_irgen_OIY(UChar i2, IRTemp op1addr)
7015{
7016 IRTemp op1 = newTemp(Ity_I8);
7017 UChar op2;
7018 IRTemp result = newTemp(Ity_I8);
7019
7020 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7021 op2 = i2;
7022 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7023 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7024 store(mkexpr(op1addr), mkexpr(result));
7025
7026 return "oiy";
7027}
7028
florian55085f82012-11-21 00:36:55 +00007029static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007030s390_irgen_OIHF(UChar r1, UInt i2)
7031{
7032 IRTemp op1 = newTemp(Ity_I32);
7033 UInt op2;
7034 IRTemp result = newTemp(Ity_I32);
7035
7036 assign(op1, get_gpr_w0(r1));
7037 op2 = i2;
7038 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7039 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7040 put_gpr_w0(r1, mkexpr(result));
7041
7042 return "oihf";
7043}
7044
florian55085f82012-11-21 00:36:55 +00007045static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007046s390_irgen_OIHH(UChar r1, UShort i2)
7047{
7048 IRTemp op1 = newTemp(Ity_I16);
7049 UShort op2;
7050 IRTemp result = newTemp(Ity_I16);
7051
7052 assign(op1, get_gpr_hw0(r1));
7053 op2 = i2;
7054 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7055 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7056 put_gpr_hw0(r1, mkexpr(result));
7057
7058 return "oihh";
7059}
7060
florian55085f82012-11-21 00:36:55 +00007061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007062s390_irgen_OIHL(UChar r1, UShort i2)
7063{
7064 IRTemp op1 = newTemp(Ity_I16);
7065 UShort op2;
7066 IRTemp result = newTemp(Ity_I16);
7067
7068 assign(op1, get_gpr_hw1(r1));
7069 op2 = i2;
7070 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7071 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7072 put_gpr_hw1(r1, mkexpr(result));
7073
7074 return "oihl";
7075}
7076
florian55085f82012-11-21 00:36:55 +00007077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007078s390_irgen_OILF(UChar r1, UInt i2)
7079{
7080 IRTemp op1 = newTemp(Ity_I32);
7081 UInt op2;
7082 IRTemp result = newTemp(Ity_I32);
7083
7084 assign(op1, get_gpr_w1(r1));
7085 op2 = i2;
7086 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7087 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7088 put_gpr_w1(r1, mkexpr(result));
7089
7090 return "oilf";
7091}
7092
florian55085f82012-11-21 00:36:55 +00007093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007094s390_irgen_OILH(UChar r1, UShort i2)
7095{
7096 IRTemp op1 = newTemp(Ity_I16);
7097 UShort op2;
7098 IRTemp result = newTemp(Ity_I16);
7099
7100 assign(op1, get_gpr_hw2(r1));
7101 op2 = i2;
7102 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7103 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7104 put_gpr_hw2(r1, mkexpr(result));
7105
7106 return "oilh";
7107}
7108
florian55085f82012-11-21 00:36:55 +00007109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007110s390_irgen_OILL(UChar r1, UShort i2)
7111{
7112 IRTemp op1 = newTemp(Ity_I16);
7113 UShort op2;
7114 IRTemp result = newTemp(Ity_I16);
7115
7116 assign(op1, get_gpr_hw3(r1));
7117 op2 = i2;
7118 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7119 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7120 put_gpr_hw3(r1, mkexpr(result));
7121
7122 return "oill";
7123}
7124
florian55085f82012-11-21 00:36:55 +00007125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007126s390_irgen_PFD(void)
7127{
7128
7129 return "pfd";
7130}
7131
florian55085f82012-11-21 00:36:55 +00007132static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007133s390_irgen_PFDRL(void)
7134{
7135
7136 return "pfdrl";
7137}
7138
florian78d5ef72013-05-11 15:02:58 +00007139static IRExpr *
7140get_rounding_mode_from_gr0(void)
7141{
7142 IRTemp rm_bits = newTemp(Ity_I32);
7143 IRExpr *s390rm;
7144 IRExpr *irrm;
7145
7146 vassert(s390_host_has_pfpo);
7147 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7148 when PFPO insn is called. So, extract the bits at [60:63] */
7149 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7150 s390rm = mkexpr(rm_bits);
7151 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7152 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7153 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7154 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7155 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7156 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7157 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7158 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7159 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7160 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7161 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7162 mkexpr(encode_dfp_rounding_mode(
7163 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7164 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7165 mkexpr(encode_dfp_rounding_mode(
7166 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7167 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7168 mkexpr(encode_dfp_rounding_mode(
7169 S390_DFP_ROUND_AWAY_0)),
7170 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7171 mkexpr(encode_dfp_rounding_mode(
7172 S390_DFP_ROUND_PREPARE_SHORT_15)),
7173 /* if rounding mode is 0 or invalid (2-7)
7174 set S390_DFP_ROUND_PER_FPC_0 */
7175 mkexpr(encode_dfp_rounding_mode(
7176 S390_DFP_ROUND_PER_FPC_0)))))))))));
7177
7178 return irrm;
7179}
7180
7181static IRExpr *
7182s390_call_pfpo_helper(IRExpr *gr0)
7183{
7184 IRExpr **args, *call;
7185
7186 args = mkIRExprVec_1(gr0);
7187 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7188 "s390_do_pfpo", &s390_do_pfpo, args);
7189 /* Nothing is excluded from definedness checking. */
7190 call->Iex.CCall.cee->mcx_mask = 0;
7191
7192 return call;
7193}
7194
7195static const HChar *
7196s390_irgen_PFPO(void)
7197{
7198 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
7199 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7200 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
7201 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
florian7ab421d2013-06-17 21:03:56 +00007202 IRTemp src1 = newTemp(Ity_F32);
7203 IRTemp dst1 = newTemp(Ity_D32);
7204 IRTemp src2 = newTemp(Ity_F32);
7205 IRTemp dst2 = newTemp(Ity_D64);
7206 IRTemp src3 = newTemp(Ity_F32);
florian78d5ef72013-05-11 15:02:58 +00007207 IRTemp dst3 = newTemp(Ity_D128);
florian7ab421d2013-06-17 21:03:56 +00007208 IRTemp src4 = newTemp(Ity_F64);
7209 IRTemp dst4 = newTemp(Ity_D32);
7210 IRTemp src5 = newTemp(Ity_F64);
7211 IRTemp dst5 = newTemp(Ity_D64);
7212 IRTemp src6 = newTemp(Ity_F64);
7213 IRTemp dst6 = newTemp(Ity_D128);
7214 IRTemp src7 = newTemp(Ity_F128);
7215 IRTemp dst7 = newTemp(Ity_D32);
7216 IRTemp src8 = newTemp(Ity_F128);
7217 IRTemp dst8 = newTemp(Ity_D64);
7218 IRTemp src9 = newTemp(Ity_F128);
7219 IRTemp dst9 = newTemp(Ity_D128);
7220 IRTemp src10 = newTemp(Ity_D32);
7221 IRTemp dst10 = newTemp(Ity_F32);
7222 IRTemp src11 = newTemp(Ity_D32);
7223 IRTemp dst11 = newTemp(Ity_F64);
7224 IRTemp src12 = newTemp(Ity_D32);
7225 IRTemp dst12 = newTemp(Ity_F128);
7226 IRTemp src13 = newTemp(Ity_D64);
7227 IRTemp dst13 = newTemp(Ity_F32);
7228 IRTemp src14 = newTemp(Ity_D64);
7229 IRTemp dst14 = newTemp(Ity_F64);
7230 IRTemp src15 = newTemp(Ity_D64);
7231 IRTemp dst15 = newTemp(Ity_F128);
7232 IRTemp src16 = newTemp(Ity_D128);
7233 IRTemp dst16 = newTemp(Ity_F32);
7234 IRTemp src17 = newTemp(Ity_D128);
7235 IRTemp dst17 = newTemp(Ity_F64);
7236 IRTemp src18 = newTemp(Ity_D128);
7237 IRTemp dst18 = newTemp(Ity_F128);
florian78d5ef72013-05-11 15:02:58 +00007238 IRExpr *irrm;
7239
7240 vassert(s390_host_has_pfpo);
7241
7242 assign(gr0, get_gpr_w1(0));
7243 /* get function code */
7244 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7245 mkU32(0x7fffff)));
7246 /* get validity test bit */
7247 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7248 mkU32(0x1)));
7249 irrm = get_rounding_mode_from_gr0();
7250
7251 /* test_bit is 1 */
florian7ab421d2013-06-17 21:03:56 +00007252 assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
florian78d5ef72013-05-11 15:02:58 +00007253 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7254
7255 /* Return code set in GR1 is usually 0. Non-zero value is set only
7256 when exceptions are raised. See Programming Notes point 5 in the
7257 instrcution description of pfpo in POP. Since valgrind does not
7258 model exception, it might be safe to just set 0 to GR 1. */
7259 put_gpr_w1(1, mkU32(0x0));
7260 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7261
7262 /* Check validity of function code in GR 0 */
7263 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
7264
7265 /* fixs390: Function emulation_failure can be used if it takes argument as
7266 IRExpr * instead of VexEmNote. */
7267 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkexpr(ef)));
7268 dis_res->whatNext = Dis_StopHere;
7269 dis_res->jk_StopHere = Ijk_EmFail;
7270
7271 stmt(
7272 IRStmt_Exit(
7273 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7274 Ijk_EmFail,
7275 IRConst_U64(guest_IA_next_instr),
7276 S390X_GUEST_OFFSET(guest_IA)
7277 )
7278 );
7279
florian7ab421d2013-06-17 21:03:56 +00007280 /* F32 -> D32 */
florian78d5ef72013-05-11 15:02:58 +00007281 /* get source from FPR 4,6 - already set in src1 */
florian7ab421d2013-06-17 21:03:56 +00007282 assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7283 put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007284 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007285 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7286 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
florian78d5ef72013-05-11 15:02:58 +00007287
florian7ab421d2013-06-17 21:03:56 +00007288 /* F32 -> D64 */
7289 assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7290 assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7291 put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007292 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007293 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7294 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007295
florian7ab421d2013-06-17 21:03:56 +00007296 /* F32 -> D128 */
7297 assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7298 assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
florian78d5ef72013-05-11 15:02:58 +00007299 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7300 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007301 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7302 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7303
7304 /* F64 -> D32 */
7305 assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7306 assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7307 put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7308 put_gpr_w1(1, mkU32(0x0));
7309 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7310 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7311
7312 /* F64 -> D64 */
7313 assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7314 assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7315 put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7316 put_gpr_w1(1, mkU32(0x0));
7317 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7318 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7319
7320 /* F64 -> D128 */
7321 assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7322 assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7323 put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7324 put_gpr_w1(1, mkU32(0x0));
7325 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
florian78d5ef72013-05-11 15:02:58 +00007326 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7327
florian7ab421d2013-06-17 21:03:56 +00007328 /* F128 -> D32 */
7329 assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7330 assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7331 put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007332 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007333 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7334 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7335
7336 /* F128 -> D64 */
7337 assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7338 assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7339 put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7340 put_gpr_w1(1, mkU32(0x0));
7341 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7342 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007343
7344 /* F128 -> D128 */
florian7ab421d2013-06-17 21:03:56 +00007345 assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7346 assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7347 put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007348 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007349 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
florian78d5ef72013-05-11 15:02:58 +00007350 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7351
florian7ab421d2013-06-17 21:03:56 +00007352 /* D32 -> F32 */
7353 assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7354 assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7355 put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007356 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007357 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7358 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7359
7360 /* D32 -> F64 */
7361 assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7362 assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7363 put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7364 put_gpr_w1(1, mkU32(0x0));
7365 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7366 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7367
7368 /* D32 -> F128 */
7369 assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7370 assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7371 put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7372 put_gpr_w1(1, mkU32(0x0));
7373 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7374 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7375
7376 /* D64 -> F32 */
7377 assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7378 assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7379 put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7380 put_gpr_w1(1, mkU32(0x0));
7381 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7382 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7383
7384 /* D64 -> F64 */
7385 assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7386 assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7387 put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7388 put_gpr_w1(1, mkU32(0x0));
7389 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7390 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7391
7392 /* D64 -> F128 */
7393 assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7394 assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7395 put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7396 put_gpr_w1(1, mkU32(0x0));
7397 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7398 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7399
7400 /* D128 -> F32 */
7401 assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7402 assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7403 put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7404 put_gpr_w1(1, mkU32(0x0));
7405 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7406 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7407
7408 /* D128 -> F64 */
7409 assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7410 assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7411 put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7412 put_gpr_w1(1, mkU32(0x0));
7413 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7414 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7415
7416 /* D128 -> F128 */
7417 assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7418 assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7419 put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7420 put_gpr_w1(1, mkU32(0x0));
7421 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
florian78d5ef72013-05-11 15:02:58 +00007422 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7423
7424 return "pfpo";
7425}
7426
florian55085f82012-11-21 00:36:55 +00007427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007428s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7429{
7430 IRTemp amount = newTemp(Ity_I64);
7431 IRTemp op = newTemp(Ity_I32);
7432
7433 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7434 assign(op, get_gpr_w1(r3));
7435 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7436 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7437 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7438
7439 return "rll";
7440}
7441
florian55085f82012-11-21 00:36:55 +00007442static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007443s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7444{
7445 IRTemp amount = newTemp(Ity_I64);
7446 IRTemp op = newTemp(Ity_I64);
7447
7448 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7449 assign(op, get_gpr_dw0(r3));
7450 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7451 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7452 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7453
7454 return "rllg";
7455}
7456
florian55085f82012-11-21 00:36:55 +00007457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007458s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7459{
7460 UChar from;
7461 UChar to;
7462 UChar rot;
7463 UChar t_bit;
7464 ULong mask;
7465 ULong maskc;
7466 IRTemp result = newTemp(Ity_I64);
7467 IRTemp op2 = newTemp(Ity_I64);
7468
7469 from = i3 & 63;
7470 to = i4 & 63;
7471 rot = i5 & 63;
7472 t_bit = i3 & 128;
7473 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7474 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7475 mkU8(64 - rot))));
7476 if (from <= to) {
7477 mask = ~0ULL;
7478 mask = (mask >> from) & (mask << (63 - to));
7479 maskc = ~mask;
7480 } else {
7481 maskc = ~0ULL;
7482 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7483 mask = ~maskc;
7484 }
7485 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7486 ), mkU64(mask)));
7487 if (t_bit == 0) {
7488 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7489 mkU64(maskc)), mkexpr(result)));
7490 }
7491 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7492
7493 return "rnsbg";
7494}
7495
florian55085f82012-11-21 00:36:55 +00007496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007497s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7498{
7499 UChar from;
7500 UChar to;
7501 UChar rot;
7502 UChar t_bit;
7503 ULong mask;
7504 ULong maskc;
7505 IRTemp result = newTemp(Ity_I64);
7506 IRTemp op2 = newTemp(Ity_I64);
7507
7508 from = i3 & 63;
7509 to = i4 & 63;
7510 rot = i5 & 63;
7511 t_bit = i3 & 128;
7512 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7513 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7514 mkU8(64 - rot))));
7515 if (from <= to) {
7516 mask = ~0ULL;
7517 mask = (mask >> from) & (mask << (63 - to));
7518 maskc = ~mask;
7519 } else {
7520 maskc = ~0ULL;
7521 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7522 mask = ~maskc;
7523 }
7524 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7525 ), mkU64(mask)));
7526 if (t_bit == 0) {
7527 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7528 mkU64(maskc)), mkexpr(result)));
7529 }
7530 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7531
7532 return "rxsbg";
7533}
7534
florian55085f82012-11-21 00:36:55 +00007535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007536s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7537{
7538 UChar from;
7539 UChar to;
7540 UChar rot;
7541 UChar t_bit;
7542 ULong mask;
7543 ULong maskc;
7544 IRTemp result = newTemp(Ity_I64);
7545 IRTemp op2 = newTemp(Ity_I64);
7546
7547 from = i3 & 63;
7548 to = i4 & 63;
7549 rot = i5 & 63;
7550 t_bit = i3 & 128;
7551 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7552 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7553 mkU8(64 - rot))));
7554 if (from <= to) {
7555 mask = ~0ULL;
7556 mask = (mask >> from) & (mask << (63 - to));
7557 maskc = ~mask;
7558 } else {
7559 maskc = ~0ULL;
7560 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7561 mask = ~maskc;
7562 }
7563 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7564 ), mkU64(mask)));
7565 if (t_bit == 0) {
7566 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7567 mkU64(maskc)), mkexpr(result)));
7568 }
7569 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7570
7571 return "rosbg";
7572}
7573
florian55085f82012-11-21 00:36:55 +00007574static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007575s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7576{
7577 UChar from;
7578 UChar to;
7579 UChar rot;
7580 UChar z_bit;
7581 ULong mask;
7582 ULong maskc;
7583 IRTemp op2 = newTemp(Ity_I64);
7584 IRTemp result = newTemp(Ity_I64);
7585
7586 from = i3 & 63;
7587 to = i4 & 63;
7588 rot = i5 & 63;
7589 z_bit = i4 & 128;
7590 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7591 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7592 mkU8(64 - rot))));
7593 if (from <= to) {
7594 mask = ~0ULL;
7595 mask = (mask >> from) & (mask << (63 - to));
7596 maskc = ~mask;
7597 } else {
7598 maskc = ~0ULL;
7599 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7600 mask = ~maskc;
7601 }
7602 if (z_bit == 0) {
7603 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7604 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7605 } else {
7606 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7607 }
7608 assign(result, get_gpr_dw0(r1));
7609 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7610
7611 return "risbg";
7612}
7613
florian55085f82012-11-21 00:36:55 +00007614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007615s390_irgen_SAR(UChar r1, UChar r2)
7616{
7617 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007618 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007619 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7620
7621 return "sar";
7622}
7623
florian55085f82012-11-21 00:36:55 +00007624static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007625s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7626{
7627 IRTemp p1 = newTemp(Ity_I64);
7628 IRTemp p2 = newTemp(Ity_I64);
7629 IRTemp op = newTemp(Ity_I64);
7630 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007631 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007632 IRTemp shift_amount = newTemp(Ity_I64);
7633
7634 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7635 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7636 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7637 ));
7638 sign_mask = 1ULL << 63;
7639 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7640 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007641 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7642 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007643 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7644 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7645 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7646
7647 return "slda";
7648}
7649
florian55085f82012-11-21 00:36:55 +00007650static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007651s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7652{
7653 IRTemp p1 = newTemp(Ity_I64);
7654 IRTemp p2 = newTemp(Ity_I64);
7655 IRTemp result = newTemp(Ity_I64);
7656
7657 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7658 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7659 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7660 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7661 mkexpr(op2addr), mkU64(63)))));
7662 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7663 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7664
7665 return "sldl";
7666}
7667
florian55085f82012-11-21 00:36:55 +00007668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007669s390_irgen_SLA(UChar r1, IRTemp op2addr)
7670{
7671 IRTemp uop = newTemp(Ity_I32);
7672 IRTemp result = newTemp(Ity_I32);
7673 UInt sign_mask;
7674 IRTemp shift_amount = newTemp(Ity_I64);
7675 IRTemp op = newTemp(Ity_I32);
7676
7677 assign(op, get_gpr_w1(r1));
7678 assign(uop, get_gpr_w1(r1));
7679 sign_mask = 2147483648U;
7680 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7681 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7682 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7683 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7684 put_gpr_w1(r1, mkexpr(result));
7685 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7686
7687 return "sla";
7688}
7689
florian55085f82012-11-21 00:36:55 +00007690static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007691s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7692{
7693 IRTemp uop = newTemp(Ity_I32);
7694 IRTemp result = newTemp(Ity_I32);
7695 UInt sign_mask;
7696 IRTemp shift_amount = newTemp(Ity_I64);
7697 IRTemp op = newTemp(Ity_I32);
7698
7699 assign(op, get_gpr_w1(r3));
7700 assign(uop, get_gpr_w1(r3));
7701 sign_mask = 2147483648U;
7702 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7703 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7704 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7705 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7706 put_gpr_w1(r1, mkexpr(result));
7707 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7708
7709 return "slak";
7710}
7711
florian55085f82012-11-21 00:36:55 +00007712static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007713s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7714{
7715 IRTemp uop = newTemp(Ity_I64);
7716 IRTemp result = newTemp(Ity_I64);
7717 ULong sign_mask;
7718 IRTemp shift_amount = newTemp(Ity_I64);
7719 IRTemp op = newTemp(Ity_I64);
7720
7721 assign(op, get_gpr_dw0(r3));
7722 assign(uop, get_gpr_dw0(r3));
7723 sign_mask = 9223372036854775808ULL;
7724 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7725 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7726 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7727 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7728 put_gpr_dw0(r1, mkexpr(result));
7729 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7730
7731 return "slag";
7732}
7733
florian55085f82012-11-21 00:36:55 +00007734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007735s390_irgen_SLL(UChar r1, IRTemp op2addr)
7736{
7737 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7738 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7739
7740 return "sll";
7741}
7742
florian55085f82012-11-21 00:36:55 +00007743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007744s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7745{
7746 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7747 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7748
7749 return "sllk";
7750}
7751
florian55085f82012-11-21 00:36:55 +00007752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007753s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7754{
7755 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7756 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7757
7758 return "sllg";
7759}
7760
florian55085f82012-11-21 00:36:55 +00007761static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007762s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7763{
7764 IRTemp p1 = newTemp(Ity_I64);
7765 IRTemp p2 = newTemp(Ity_I64);
7766 IRTemp result = newTemp(Ity_I64);
7767
7768 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7769 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7770 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7771 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7772 mkexpr(op2addr), mkU64(63)))));
7773 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7774 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7775 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7776
7777 return "srda";
7778}
7779
florian55085f82012-11-21 00:36:55 +00007780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007781s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7782{
7783 IRTemp p1 = newTemp(Ity_I64);
7784 IRTemp p2 = newTemp(Ity_I64);
7785 IRTemp result = newTemp(Ity_I64);
7786
7787 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7788 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7789 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7790 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7791 mkexpr(op2addr), mkU64(63)))));
7792 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7793 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7794
7795 return "srdl";
7796}
7797
florian55085f82012-11-21 00:36:55 +00007798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007799s390_irgen_SRA(UChar r1, IRTemp op2addr)
7800{
7801 IRTemp result = newTemp(Ity_I32);
7802 IRTemp op = newTemp(Ity_I32);
7803
7804 assign(op, get_gpr_w1(r1));
7805 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7806 mkexpr(op2addr), mkU64(63)))));
7807 put_gpr_w1(r1, mkexpr(result));
7808 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7809
7810 return "sra";
7811}
7812
florian55085f82012-11-21 00:36:55 +00007813static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007814s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7815{
7816 IRTemp result = newTemp(Ity_I32);
7817 IRTemp op = newTemp(Ity_I32);
7818
7819 assign(op, get_gpr_w1(r3));
7820 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7821 mkexpr(op2addr), mkU64(63)))));
7822 put_gpr_w1(r1, mkexpr(result));
7823 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7824
7825 return "srak";
7826}
7827
florian55085f82012-11-21 00:36:55 +00007828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007829s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7830{
7831 IRTemp result = newTemp(Ity_I64);
7832 IRTemp op = newTemp(Ity_I64);
7833
7834 assign(op, get_gpr_dw0(r3));
7835 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7836 mkexpr(op2addr), mkU64(63)))));
7837 put_gpr_dw0(r1, mkexpr(result));
7838 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7839
7840 return "srag";
7841}
7842
florian55085f82012-11-21 00:36:55 +00007843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007844s390_irgen_SRL(UChar r1, IRTemp op2addr)
7845{
7846 IRTemp op = newTemp(Ity_I32);
7847
7848 assign(op, get_gpr_w1(r1));
7849 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7850 mkexpr(op2addr), mkU64(63)))));
7851
7852 return "srl";
7853}
7854
florian55085f82012-11-21 00:36:55 +00007855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007856s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7857{
7858 IRTemp op = newTemp(Ity_I32);
7859
7860 assign(op, get_gpr_w1(r3));
7861 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7862 mkexpr(op2addr), mkU64(63)))));
7863
7864 return "srlk";
7865}
7866
florian55085f82012-11-21 00:36:55 +00007867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007868s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7869{
7870 IRTemp op = newTemp(Ity_I64);
7871
7872 assign(op, get_gpr_dw0(r3));
7873 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7874 mkexpr(op2addr), mkU64(63)))));
7875
7876 return "srlg";
7877}
7878
florian55085f82012-11-21 00:36:55 +00007879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007880s390_irgen_ST(UChar r1, IRTemp op2addr)
7881{
7882 store(mkexpr(op2addr), get_gpr_w1(r1));
7883
7884 return "st";
7885}
7886
florian55085f82012-11-21 00:36:55 +00007887static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007888s390_irgen_STY(UChar r1, IRTemp op2addr)
7889{
7890 store(mkexpr(op2addr), get_gpr_w1(r1));
7891
7892 return "sty";
7893}
7894
florian55085f82012-11-21 00:36:55 +00007895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007896s390_irgen_STG(UChar r1, IRTemp op2addr)
7897{
7898 store(mkexpr(op2addr), get_gpr_dw0(r1));
7899
7900 return "stg";
7901}
7902
florian55085f82012-11-21 00:36:55 +00007903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007904s390_irgen_STRL(UChar r1, UInt i2)
7905{
7906 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7907 get_gpr_w1(r1));
7908
7909 return "strl";
7910}
7911
florian55085f82012-11-21 00:36:55 +00007912static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007913s390_irgen_STGRL(UChar r1, UInt i2)
7914{
7915 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7916 get_gpr_dw0(r1));
7917
7918 return "stgrl";
7919}
7920
florian55085f82012-11-21 00:36:55 +00007921static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007922s390_irgen_STC(UChar r1, IRTemp op2addr)
7923{
7924 store(mkexpr(op2addr), get_gpr_b7(r1));
7925
7926 return "stc";
7927}
7928
florian55085f82012-11-21 00:36:55 +00007929static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007930s390_irgen_STCY(UChar r1, IRTemp op2addr)
7931{
7932 store(mkexpr(op2addr), get_gpr_b7(r1));
7933
7934 return "stcy";
7935}
7936
florian55085f82012-11-21 00:36:55 +00007937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007938s390_irgen_STCH(UChar r1, IRTemp op2addr)
7939{
7940 store(mkexpr(op2addr), get_gpr_b3(r1));
7941
7942 return "stch";
7943}
7944
florian55085f82012-11-21 00:36:55 +00007945static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007946s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7947{
7948 UChar mask;
7949 UChar n;
7950
7951 mask = (UChar)r3;
7952 n = 0;
7953 if ((mask & 8) != 0) {
7954 store(mkexpr(op2addr), get_gpr_b4(r1));
7955 n = n + 1;
7956 }
7957 if ((mask & 4) != 0) {
7958 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7959 n = n + 1;
7960 }
7961 if ((mask & 2) != 0) {
7962 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7963 n = n + 1;
7964 }
7965 if ((mask & 1) != 0) {
7966 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7967 }
7968
7969 return "stcm";
7970}
7971
florian55085f82012-11-21 00:36:55 +00007972static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007973s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7974{
7975 UChar mask;
7976 UChar n;
7977
7978 mask = (UChar)r3;
7979 n = 0;
7980 if ((mask & 8) != 0) {
7981 store(mkexpr(op2addr), get_gpr_b4(r1));
7982 n = n + 1;
7983 }
7984 if ((mask & 4) != 0) {
7985 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7986 n = n + 1;
7987 }
7988 if ((mask & 2) != 0) {
7989 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7990 n = n + 1;
7991 }
7992 if ((mask & 1) != 0) {
7993 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7994 }
7995
7996 return "stcmy";
7997}
7998
florian55085f82012-11-21 00:36:55 +00007999static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008000s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8001{
8002 UChar mask;
8003 UChar n;
8004
8005 mask = (UChar)r3;
8006 n = 0;
8007 if ((mask & 8) != 0) {
8008 store(mkexpr(op2addr), get_gpr_b0(r1));
8009 n = n + 1;
8010 }
8011 if ((mask & 4) != 0) {
8012 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8013 n = n + 1;
8014 }
8015 if ((mask & 2) != 0) {
8016 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8017 n = n + 1;
8018 }
8019 if ((mask & 1) != 0) {
8020 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8021 }
8022
8023 return "stcmh";
8024}
8025
florian55085f82012-11-21 00:36:55 +00008026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008027s390_irgen_STH(UChar r1, IRTemp op2addr)
8028{
8029 store(mkexpr(op2addr), get_gpr_hw3(r1));
8030
8031 return "sth";
8032}
8033
florian55085f82012-11-21 00:36:55 +00008034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008035s390_irgen_STHY(UChar r1, IRTemp op2addr)
8036{
8037 store(mkexpr(op2addr), get_gpr_hw3(r1));
8038
8039 return "sthy";
8040}
8041
florian55085f82012-11-21 00:36:55 +00008042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008043s390_irgen_STHRL(UChar r1, UInt i2)
8044{
8045 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8046 get_gpr_hw3(r1));
8047
8048 return "sthrl";
8049}
8050
florian55085f82012-11-21 00:36:55 +00008051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008052s390_irgen_STHH(UChar r1, IRTemp op2addr)
8053{
8054 store(mkexpr(op2addr), get_gpr_hw1(r1));
8055
8056 return "sthh";
8057}
8058
florian55085f82012-11-21 00:36:55 +00008059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008060s390_irgen_STFH(UChar r1, IRTemp op2addr)
8061{
8062 store(mkexpr(op2addr), get_gpr_w0(r1));
8063
8064 return "stfh";
8065}
8066
florian55085f82012-11-21 00:36:55 +00008067static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008068s390_irgen_STOC(UChar r1, IRTemp op2addr)
8069{
8070 /* condition is checked in format handler */
8071 store(mkexpr(op2addr), get_gpr_w1(r1));
8072
8073 return "stoc";
8074}
8075
florian55085f82012-11-21 00:36:55 +00008076static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008077s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8078{
8079 /* condition is checked in format handler */
8080 store(mkexpr(op2addr), get_gpr_dw0(r1));
8081
8082 return "stocg";
8083}
8084
florian55085f82012-11-21 00:36:55 +00008085static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008086s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8087{
8088 store(mkexpr(op2addr), get_gpr_dw0(r1));
8089 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8090
8091 return "stpq";
8092}
8093
florian55085f82012-11-21 00:36:55 +00008094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008095s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8096{
8097 store(mkexpr(op2addr), get_gpr_b7(r1));
8098 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8099
8100 return "strvh";
8101}
8102
florian55085f82012-11-21 00:36:55 +00008103static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008104s390_irgen_STRV(UChar r1, IRTemp op2addr)
8105{
8106 store(mkexpr(op2addr), get_gpr_b7(r1));
8107 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8108 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8109 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8110
8111 return "strv";
8112}
8113
florian55085f82012-11-21 00:36:55 +00008114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008115s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8116{
8117 store(mkexpr(op2addr), get_gpr_b7(r1));
8118 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8119 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8120 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8121 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8122 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8123 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8124 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8125
8126 return "strvg";
8127}
8128
florian55085f82012-11-21 00:36:55 +00008129static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008130s390_irgen_SR(UChar r1, UChar r2)
8131{
8132 IRTemp op1 = newTemp(Ity_I32);
8133 IRTemp op2 = newTemp(Ity_I32);
8134 IRTemp result = newTemp(Ity_I32);
8135
8136 assign(op1, get_gpr_w1(r1));
8137 assign(op2, get_gpr_w1(r2));
8138 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8139 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8140 put_gpr_w1(r1, mkexpr(result));
8141
8142 return "sr";
8143}
8144
florian55085f82012-11-21 00:36:55 +00008145static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008146s390_irgen_SGR(UChar r1, UChar r2)
8147{
8148 IRTemp op1 = newTemp(Ity_I64);
8149 IRTemp op2 = newTemp(Ity_I64);
8150 IRTemp result = newTemp(Ity_I64);
8151
8152 assign(op1, get_gpr_dw0(r1));
8153 assign(op2, get_gpr_dw0(r2));
8154 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8155 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8156 put_gpr_dw0(r1, mkexpr(result));
8157
8158 return "sgr";
8159}
8160
florian55085f82012-11-21 00:36:55 +00008161static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008162s390_irgen_SGFR(UChar r1, UChar r2)
8163{
8164 IRTemp op1 = newTemp(Ity_I64);
8165 IRTemp op2 = newTemp(Ity_I64);
8166 IRTemp result = newTemp(Ity_I64);
8167
8168 assign(op1, get_gpr_dw0(r1));
8169 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8170 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8171 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8172 put_gpr_dw0(r1, mkexpr(result));
8173
8174 return "sgfr";
8175}
8176
florian55085f82012-11-21 00:36:55 +00008177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008178s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8179{
8180 IRTemp op2 = newTemp(Ity_I32);
8181 IRTemp op3 = newTemp(Ity_I32);
8182 IRTemp result = newTemp(Ity_I32);
8183
8184 assign(op2, get_gpr_w1(r2));
8185 assign(op3, get_gpr_w1(r3));
8186 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8187 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8188 put_gpr_w1(r1, mkexpr(result));
8189
8190 return "srk";
8191}
8192
florian55085f82012-11-21 00:36:55 +00008193static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008194s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8195{
8196 IRTemp op2 = newTemp(Ity_I64);
8197 IRTemp op3 = newTemp(Ity_I64);
8198 IRTemp result = newTemp(Ity_I64);
8199
8200 assign(op2, get_gpr_dw0(r2));
8201 assign(op3, get_gpr_dw0(r3));
8202 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8203 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8204 put_gpr_dw0(r1, mkexpr(result));
8205
8206 return "sgrk";
8207}
8208
florian55085f82012-11-21 00:36:55 +00008209static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008210s390_irgen_S(UChar r1, IRTemp op2addr)
8211{
8212 IRTemp op1 = newTemp(Ity_I32);
8213 IRTemp op2 = newTemp(Ity_I32);
8214 IRTemp result = newTemp(Ity_I32);
8215
8216 assign(op1, get_gpr_w1(r1));
8217 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8218 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8219 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8220 put_gpr_w1(r1, mkexpr(result));
8221
8222 return "s";
8223}
8224
florian55085f82012-11-21 00:36:55 +00008225static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008226s390_irgen_SY(UChar r1, IRTemp op2addr)
8227{
8228 IRTemp op1 = newTemp(Ity_I32);
8229 IRTemp op2 = newTemp(Ity_I32);
8230 IRTemp result = newTemp(Ity_I32);
8231
8232 assign(op1, get_gpr_w1(r1));
8233 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8234 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8235 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8236 put_gpr_w1(r1, mkexpr(result));
8237
8238 return "sy";
8239}
8240
florian55085f82012-11-21 00:36:55 +00008241static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008242s390_irgen_SG(UChar r1, IRTemp op2addr)
8243{
8244 IRTemp op1 = newTemp(Ity_I64);
8245 IRTemp op2 = newTemp(Ity_I64);
8246 IRTemp result = newTemp(Ity_I64);
8247
8248 assign(op1, get_gpr_dw0(r1));
8249 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8250 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8251 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8252 put_gpr_dw0(r1, mkexpr(result));
8253
8254 return "sg";
8255}
8256
florian55085f82012-11-21 00:36:55 +00008257static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008258s390_irgen_SGF(UChar r1, IRTemp op2addr)
8259{
8260 IRTemp op1 = newTemp(Ity_I64);
8261 IRTemp op2 = newTemp(Ity_I64);
8262 IRTemp result = newTemp(Ity_I64);
8263
8264 assign(op1, get_gpr_dw0(r1));
8265 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8266 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8267 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8268 put_gpr_dw0(r1, mkexpr(result));
8269
8270 return "sgf";
8271}
8272
florian55085f82012-11-21 00:36:55 +00008273static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008274s390_irgen_SH(UChar r1, IRTemp op2addr)
8275{
8276 IRTemp op1 = newTemp(Ity_I32);
8277 IRTemp op2 = newTemp(Ity_I32);
8278 IRTemp result = newTemp(Ity_I32);
8279
8280 assign(op1, get_gpr_w1(r1));
8281 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8282 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8283 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8284 put_gpr_w1(r1, mkexpr(result));
8285
8286 return "sh";
8287}
8288
florian55085f82012-11-21 00:36:55 +00008289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008290s390_irgen_SHY(UChar r1, IRTemp op2addr)
8291{
8292 IRTemp op1 = newTemp(Ity_I32);
8293 IRTemp op2 = newTemp(Ity_I32);
8294 IRTemp result = newTemp(Ity_I32);
8295
8296 assign(op1, get_gpr_w1(r1));
8297 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8298 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8299 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8300 put_gpr_w1(r1, mkexpr(result));
8301
8302 return "shy";
8303}
8304
florian55085f82012-11-21 00:36:55 +00008305static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008306s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8307{
8308 IRTemp op2 = newTemp(Ity_I32);
8309 IRTemp op3 = newTemp(Ity_I32);
8310 IRTemp result = newTemp(Ity_I32);
8311
8312 assign(op2, get_gpr_w0(r1));
8313 assign(op3, get_gpr_w0(r2));
8314 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8315 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8316 put_gpr_w0(r1, mkexpr(result));
8317
8318 return "shhhr";
8319}
8320
florian55085f82012-11-21 00:36:55 +00008321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008322s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8323{
8324 IRTemp op2 = newTemp(Ity_I32);
8325 IRTemp op3 = newTemp(Ity_I32);
8326 IRTemp result = newTemp(Ity_I32);
8327
8328 assign(op2, get_gpr_w0(r1));
8329 assign(op3, get_gpr_w1(r2));
8330 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8331 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8332 put_gpr_w0(r1, mkexpr(result));
8333
8334 return "shhlr";
8335}
8336
florian55085f82012-11-21 00:36:55 +00008337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008338s390_irgen_SLR(UChar r1, UChar r2)
8339{
8340 IRTemp op1 = newTemp(Ity_I32);
8341 IRTemp op2 = newTemp(Ity_I32);
8342 IRTemp result = newTemp(Ity_I32);
8343
8344 assign(op1, get_gpr_w1(r1));
8345 assign(op2, get_gpr_w1(r2));
8346 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8347 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8348 put_gpr_w1(r1, mkexpr(result));
8349
8350 return "slr";
8351}
8352
florian55085f82012-11-21 00:36:55 +00008353static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008354s390_irgen_SLGR(UChar r1, UChar r2)
8355{
8356 IRTemp op1 = newTemp(Ity_I64);
8357 IRTemp op2 = newTemp(Ity_I64);
8358 IRTemp result = newTemp(Ity_I64);
8359
8360 assign(op1, get_gpr_dw0(r1));
8361 assign(op2, get_gpr_dw0(r2));
8362 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8363 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8364 put_gpr_dw0(r1, mkexpr(result));
8365
8366 return "slgr";
8367}
8368
florian55085f82012-11-21 00:36:55 +00008369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008370s390_irgen_SLGFR(UChar r1, UChar r2)
8371{
8372 IRTemp op1 = newTemp(Ity_I64);
8373 IRTemp op2 = newTemp(Ity_I64);
8374 IRTemp result = newTemp(Ity_I64);
8375
8376 assign(op1, get_gpr_dw0(r1));
8377 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8378 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8379 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8380 put_gpr_dw0(r1, mkexpr(result));
8381
8382 return "slgfr";
8383}
8384
florian55085f82012-11-21 00:36:55 +00008385static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008386s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8387{
8388 IRTemp op2 = newTemp(Ity_I32);
8389 IRTemp op3 = newTemp(Ity_I32);
8390 IRTemp result = newTemp(Ity_I32);
8391
8392 assign(op2, get_gpr_w1(r2));
8393 assign(op3, get_gpr_w1(r3));
8394 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8395 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8396 put_gpr_w1(r1, mkexpr(result));
8397
8398 return "slrk";
8399}
8400
florian55085f82012-11-21 00:36:55 +00008401static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008402s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8403{
8404 IRTemp op2 = newTemp(Ity_I64);
8405 IRTemp op3 = newTemp(Ity_I64);
8406 IRTemp result = newTemp(Ity_I64);
8407
8408 assign(op2, get_gpr_dw0(r2));
8409 assign(op3, get_gpr_dw0(r3));
8410 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8411 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8412 put_gpr_dw0(r1, mkexpr(result));
8413
8414 return "slgrk";
8415}
8416
florian55085f82012-11-21 00:36:55 +00008417static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008418s390_irgen_SL(UChar r1, IRTemp op2addr)
8419{
8420 IRTemp op1 = newTemp(Ity_I32);
8421 IRTemp op2 = newTemp(Ity_I32);
8422 IRTemp result = newTemp(Ity_I32);
8423
8424 assign(op1, get_gpr_w1(r1));
8425 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8426 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8427 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8428 put_gpr_w1(r1, mkexpr(result));
8429
8430 return "sl";
8431}
8432
florian55085f82012-11-21 00:36:55 +00008433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008434s390_irgen_SLY(UChar r1, IRTemp op2addr)
8435{
8436 IRTemp op1 = newTemp(Ity_I32);
8437 IRTemp op2 = newTemp(Ity_I32);
8438 IRTemp result = newTemp(Ity_I32);
8439
8440 assign(op1, get_gpr_w1(r1));
8441 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8442 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8443 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8444 put_gpr_w1(r1, mkexpr(result));
8445
8446 return "sly";
8447}
8448
florian55085f82012-11-21 00:36:55 +00008449static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008450s390_irgen_SLG(UChar r1, IRTemp op2addr)
8451{
8452 IRTemp op1 = newTemp(Ity_I64);
8453 IRTemp op2 = newTemp(Ity_I64);
8454 IRTemp result = newTemp(Ity_I64);
8455
8456 assign(op1, get_gpr_dw0(r1));
8457 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8458 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8459 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8460 put_gpr_dw0(r1, mkexpr(result));
8461
8462 return "slg";
8463}
8464
florian55085f82012-11-21 00:36:55 +00008465static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008466s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8467{
8468 IRTemp op1 = newTemp(Ity_I64);
8469 IRTemp op2 = newTemp(Ity_I64);
8470 IRTemp result = newTemp(Ity_I64);
8471
8472 assign(op1, get_gpr_dw0(r1));
8473 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8474 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8475 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8476 put_gpr_dw0(r1, mkexpr(result));
8477
8478 return "slgf";
8479}
8480
florian55085f82012-11-21 00:36:55 +00008481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008482s390_irgen_SLFI(UChar r1, UInt i2)
8483{
8484 IRTemp op1 = newTemp(Ity_I32);
8485 UInt op2;
8486 IRTemp result = newTemp(Ity_I32);
8487
8488 assign(op1, get_gpr_w1(r1));
8489 op2 = i2;
8490 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8491 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8492 mkU32(op2)));
8493 put_gpr_w1(r1, mkexpr(result));
8494
8495 return "slfi";
8496}
8497
florian55085f82012-11-21 00:36:55 +00008498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008499s390_irgen_SLGFI(UChar r1, UInt i2)
8500{
8501 IRTemp op1 = newTemp(Ity_I64);
8502 ULong op2;
8503 IRTemp result = newTemp(Ity_I64);
8504
8505 assign(op1, get_gpr_dw0(r1));
8506 op2 = (ULong)i2;
8507 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8508 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8509 mkU64(op2)));
8510 put_gpr_dw0(r1, mkexpr(result));
8511
8512 return "slgfi";
8513}
8514
florian55085f82012-11-21 00:36:55 +00008515static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008516s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8517{
8518 IRTemp op2 = newTemp(Ity_I32);
8519 IRTemp op3 = newTemp(Ity_I32);
8520 IRTemp result = newTemp(Ity_I32);
8521
8522 assign(op2, get_gpr_w0(r1));
8523 assign(op3, get_gpr_w0(r2));
8524 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8525 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8526 put_gpr_w0(r1, mkexpr(result));
8527
8528 return "slhhhr";
8529}
8530
florian55085f82012-11-21 00:36:55 +00008531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008532s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8533{
8534 IRTemp op2 = newTemp(Ity_I32);
8535 IRTemp op3 = newTemp(Ity_I32);
8536 IRTemp result = newTemp(Ity_I32);
8537
8538 assign(op2, get_gpr_w0(r1));
8539 assign(op3, get_gpr_w1(r2));
8540 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8541 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8542 put_gpr_w0(r1, mkexpr(result));
8543
8544 return "slhhlr";
8545}
8546
florian55085f82012-11-21 00:36:55 +00008547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008548s390_irgen_SLBR(UChar r1, UChar r2)
8549{
8550 IRTemp op1 = newTemp(Ity_I32);
8551 IRTemp op2 = newTemp(Ity_I32);
8552 IRTemp result = newTemp(Ity_I32);
8553 IRTemp borrow_in = newTemp(Ity_I32);
8554
8555 assign(op1, get_gpr_w1(r1));
8556 assign(op2, get_gpr_w1(r2));
8557 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8558 s390_call_calculate_cc(), mkU8(1))));
8559 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8560 mkexpr(borrow_in)));
8561 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8562 put_gpr_w1(r1, mkexpr(result));
8563
8564 return "slbr";
8565}
8566
florian55085f82012-11-21 00:36:55 +00008567static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008568s390_irgen_SLBGR(UChar r1, UChar r2)
8569{
8570 IRTemp op1 = newTemp(Ity_I64);
8571 IRTemp op2 = newTemp(Ity_I64);
8572 IRTemp result = newTemp(Ity_I64);
8573 IRTemp borrow_in = newTemp(Ity_I64);
8574
8575 assign(op1, get_gpr_dw0(r1));
8576 assign(op2, get_gpr_dw0(r2));
8577 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8578 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8579 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8580 mkexpr(borrow_in)));
8581 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8582 put_gpr_dw0(r1, mkexpr(result));
8583
8584 return "slbgr";
8585}
8586
florian55085f82012-11-21 00:36:55 +00008587static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008588s390_irgen_SLB(UChar r1, IRTemp op2addr)
8589{
8590 IRTemp op1 = newTemp(Ity_I32);
8591 IRTemp op2 = newTemp(Ity_I32);
8592 IRTemp result = newTemp(Ity_I32);
8593 IRTemp borrow_in = newTemp(Ity_I32);
8594
8595 assign(op1, get_gpr_w1(r1));
8596 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8597 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8598 s390_call_calculate_cc(), mkU8(1))));
8599 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8600 mkexpr(borrow_in)));
8601 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8602 put_gpr_w1(r1, mkexpr(result));
8603
8604 return "slb";
8605}
8606
florian55085f82012-11-21 00:36:55 +00008607static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008608s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8609{
8610 IRTemp op1 = newTemp(Ity_I64);
8611 IRTemp op2 = newTemp(Ity_I64);
8612 IRTemp result = newTemp(Ity_I64);
8613 IRTemp borrow_in = newTemp(Ity_I64);
8614
8615 assign(op1, get_gpr_dw0(r1));
8616 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8617 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8618 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8619 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8620 mkexpr(borrow_in)));
8621 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8622 put_gpr_dw0(r1, mkexpr(result));
8623
8624 return "slbg";
8625}
8626
florian55085f82012-11-21 00:36:55 +00008627static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008628s390_irgen_SVC(UChar i)
8629{
8630 IRTemp sysno = newTemp(Ity_I64);
8631
8632 if (i != 0) {
8633 assign(sysno, mkU64(i));
8634 } else {
8635 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8636 }
8637 system_call(mkexpr(sysno));
8638
8639 return "svc";
8640}
8641
florian55085f82012-11-21 00:36:55 +00008642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008643s390_irgen_TM(UChar i2, IRTemp op1addr)
8644{
8645 UChar mask;
8646 IRTemp value = newTemp(Ity_I8);
8647
8648 mask = i2;
8649 assign(value, load(Ity_I8, mkexpr(op1addr)));
8650 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8651 mkU8(mask)));
8652
8653 return "tm";
8654}
8655
florian55085f82012-11-21 00:36:55 +00008656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008657s390_irgen_TMY(UChar i2, IRTemp op1addr)
8658{
8659 UChar mask;
8660 IRTemp value = newTemp(Ity_I8);
8661
8662 mask = i2;
8663 assign(value, load(Ity_I8, mkexpr(op1addr)));
8664 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8665 mkU8(mask)));
8666
8667 return "tmy";
8668}
8669
florian55085f82012-11-21 00:36:55 +00008670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008671s390_irgen_TMHH(UChar r1, UShort i2)
8672{
8673 UShort mask;
8674 IRTemp value = newTemp(Ity_I16);
8675
8676 mask = i2;
8677 assign(value, get_gpr_hw0(r1));
8678 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8679 mkU16(mask)));
8680
8681 return "tmhh";
8682}
8683
florian55085f82012-11-21 00:36:55 +00008684static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008685s390_irgen_TMHL(UChar r1, UShort i2)
8686{
8687 UShort mask;
8688 IRTemp value = newTemp(Ity_I16);
8689
8690 mask = i2;
8691 assign(value, get_gpr_hw1(r1));
8692 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8693 mkU16(mask)));
8694
8695 return "tmhl";
8696}
8697
florian55085f82012-11-21 00:36:55 +00008698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008699s390_irgen_TMLH(UChar r1, UShort i2)
8700{
8701 UShort mask;
8702 IRTemp value = newTemp(Ity_I16);
8703
8704 mask = i2;
8705 assign(value, get_gpr_hw2(r1));
8706 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8707 mkU16(mask)));
8708
8709 return "tmlh";
8710}
8711
florian55085f82012-11-21 00:36:55 +00008712static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008713s390_irgen_TMLL(UChar r1, UShort i2)
8714{
8715 UShort mask;
8716 IRTemp value = newTemp(Ity_I16);
8717
8718 mask = i2;
8719 assign(value, get_gpr_hw3(r1));
8720 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8721 mkU16(mask)));
8722
8723 return "tmll";
8724}
8725
florian55085f82012-11-21 00:36:55 +00008726static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008727s390_irgen_EFPC(UChar r1)
8728{
8729 put_gpr_w1(r1, get_fpc_w0());
8730
8731 return "efpc";
8732}
8733
florian55085f82012-11-21 00:36:55 +00008734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008735s390_irgen_LER(UChar r1, UChar r2)
8736{
8737 put_fpr_w0(r1, get_fpr_w0(r2));
8738
8739 return "ler";
8740}
8741
florian55085f82012-11-21 00:36:55 +00008742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008743s390_irgen_LDR(UChar r1, UChar r2)
8744{
8745 put_fpr_dw0(r1, get_fpr_dw0(r2));
8746
8747 return "ldr";
8748}
8749
florian55085f82012-11-21 00:36:55 +00008750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008751s390_irgen_LXR(UChar r1, UChar r2)
8752{
8753 put_fpr_dw0(r1, get_fpr_dw0(r2));
8754 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8755
8756 return "lxr";
8757}
8758
florian55085f82012-11-21 00:36:55 +00008759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008760s390_irgen_LE(UChar r1, IRTemp op2addr)
8761{
8762 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8763
8764 return "le";
8765}
8766
florian55085f82012-11-21 00:36:55 +00008767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008768s390_irgen_LD(UChar r1, IRTemp op2addr)
8769{
8770 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8771
8772 return "ld";
8773}
8774
florian55085f82012-11-21 00:36:55 +00008775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008776s390_irgen_LEY(UChar r1, IRTemp op2addr)
8777{
8778 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8779
8780 return "ley";
8781}
8782
florian55085f82012-11-21 00:36:55 +00008783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008784s390_irgen_LDY(UChar r1, IRTemp op2addr)
8785{
8786 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8787
8788 return "ldy";
8789}
8790
florian55085f82012-11-21 00:36:55 +00008791static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008792s390_irgen_LFPC(IRTemp op2addr)
8793{
8794 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8795
8796 return "lfpc";
8797}
8798
florian55085f82012-11-21 00:36:55 +00008799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008800s390_irgen_LZER(UChar r1)
8801{
8802 put_fpr_w0(r1, mkF32i(0x0));
8803
8804 return "lzer";
8805}
8806
florian55085f82012-11-21 00:36:55 +00008807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008808s390_irgen_LZDR(UChar r1)
8809{
8810 put_fpr_dw0(r1, mkF64i(0x0));
8811
8812 return "lzdr";
8813}
8814
florian55085f82012-11-21 00:36:55 +00008815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008816s390_irgen_LZXR(UChar r1)
8817{
8818 put_fpr_dw0(r1, mkF64i(0x0));
8819 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8820
8821 return "lzxr";
8822}
8823
florian55085f82012-11-21 00:36:55 +00008824static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008825s390_irgen_SRNM(IRTemp op2addr)
8826{
florianf0fa1be2012-09-18 20:24:38 +00008827 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008828
florianf0fa1be2012-09-18 20:24:38 +00008829 input_mask = 3;
8830 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008831
florianf0fa1be2012-09-18 20:24:38 +00008832 put_fpc_w0(binop(Iop_Or32,
8833 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8834 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8835 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008836 return "srnm";
8837}
8838
florian55085f82012-11-21 00:36:55 +00008839static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008840s390_irgen_SRNMB(IRTemp op2addr)
8841{
8842 UInt input_mask, fpc_mask;
8843
8844 input_mask = 7;
8845 fpc_mask = 7;
8846
8847 put_fpc_w0(binop(Iop_Or32,
8848 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8849 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8850 mkU32(input_mask))));
8851 return "srnmb";
8852}
8853
florian81a4bfe2012-09-20 01:25:28 +00008854static void
florianf0fa1be2012-09-18 20:24:38 +00008855s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8856{
8857 if (b2 == 0) { /* This is the typical case */
8858 if (d2 > 3) {
8859 if (s390_host_has_fpext && d2 == 7) {
8860 /* ok */
8861 } else {
8862 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008863 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008864 }
8865 }
8866 }
8867
8868 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8869}
8870
florian82cdba62013-03-12 01:31:24 +00008871/* Wrapper to validate the parameter as in SRNMB is not required, as all
8872 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8873static const HChar *
8874s390_irgen_SRNMT(IRTemp op2addr)
8875{
8876 UInt input_mask, fpc_mask;
8877
8878 input_mask = 7;
8879 fpc_mask = 0x70;
8880
8881 /* fpc[25:27] <- op2addr[61:63]
8882 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8883 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8884 binop(Iop_Shl32, binop(Iop_And32,
8885 unop(Iop_64to32, mkexpr(op2addr)),
8886 mkU32(input_mask)), mkU8(4))));
8887 return "srnmt";
8888}
8889
florianf0fa1be2012-09-18 20:24:38 +00008890
florian55085f82012-11-21 00:36:55 +00008891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008892s390_irgen_SFPC(UChar r1)
8893{
8894 put_fpc_w0(get_gpr_w1(r1));
8895
8896 return "sfpc";
8897}
8898
florian55085f82012-11-21 00:36:55 +00008899static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008900s390_irgen_STE(UChar r1, IRTemp op2addr)
8901{
8902 store(mkexpr(op2addr), get_fpr_w0(r1));
8903
8904 return "ste";
8905}
8906
florian55085f82012-11-21 00:36:55 +00008907static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008908s390_irgen_STD(UChar r1, IRTemp op2addr)
8909{
8910 store(mkexpr(op2addr), get_fpr_dw0(r1));
8911
8912 return "std";
8913}
8914
florian55085f82012-11-21 00:36:55 +00008915static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008916s390_irgen_STEY(UChar r1, IRTemp op2addr)
8917{
8918 store(mkexpr(op2addr), get_fpr_w0(r1));
8919
8920 return "stey";
8921}
8922
florian55085f82012-11-21 00:36:55 +00008923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008924s390_irgen_STDY(UChar r1, IRTemp op2addr)
8925{
8926 store(mkexpr(op2addr), get_fpr_dw0(r1));
8927
8928 return "stdy";
8929}
8930
florian55085f82012-11-21 00:36:55 +00008931static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008932s390_irgen_STFPC(IRTemp op2addr)
8933{
8934 store(mkexpr(op2addr), get_fpc_w0());
8935
8936 return "stfpc";
8937}
8938
florian55085f82012-11-21 00:36:55 +00008939static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008940s390_irgen_AEBR(UChar r1, UChar r2)
8941{
8942 IRTemp op1 = newTemp(Ity_F32);
8943 IRTemp op2 = newTemp(Ity_F32);
8944 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008945 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008946
8947 assign(op1, get_fpr_w0(r1));
8948 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008949 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008950 mkexpr(op2)));
8951 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8952 put_fpr_w0(r1, mkexpr(result));
8953
8954 return "aebr";
8955}
8956
florian55085f82012-11-21 00:36:55 +00008957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008958s390_irgen_ADBR(UChar r1, UChar r2)
8959{
8960 IRTemp op1 = newTemp(Ity_F64);
8961 IRTemp op2 = newTemp(Ity_F64);
8962 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008963 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008964
8965 assign(op1, get_fpr_dw0(r1));
8966 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008967 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008968 mkexpr(op2)));
8969 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8970 put_fpr_dw0(r1, mkexpr(result));
8971
8972 return "adbr";
8973}
8974
florian55085f82012-11-21 00:36:55 +00008975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008976s390_irgen_AEB(UChar r1, IRTemp op2addr)
8977{
8978 IRTemp op1 = newTemp(Ity_F32);
8979 IRTemp op2 = newTemp(Ity_F32);
8980 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008981 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008982
8983 assign(op1, get_fpr_w0(r1));
8984 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008985 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008986 mkexpr(op2)));
8987 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8988 put_fpr_w0(r1, mkexpr(result));
8989
8990 return "aeb";
8991}
8992
florian55085f82012-11-21 00:36:55 +00008993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008994s390_irgen_ADB(UChar r1, IRTemp op2addr)
8995{
8996 IRTemp op1 = newTemp(Ity_F64);
8997 IRTemp op2 = newTemp(Ity_F64);
8998 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008999 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009000
9001 assign(op1, get_fpr_dw0(r1));
9002 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009003 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009004 mkexpr(op2)));
9005 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9006 put_fpr_dw0(r1, mkexpr(result));
9007
9008 return "adb";
9009}
9010
florian55085f82012-11-21 00:36:55 +00009011static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009012s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9013 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009014{
florian125e20d2012-10-07 15:42:37 +00009015 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009016 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009017 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009018 }
sewardj2019a972011-03-07 16:04:07 +00009019 IRTemp op2 = newTemp(Ity_I32);
9020
9021 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009022 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009023 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009024
9025 return "cefbr";
9026}
9027
florian55085f82012-11-21 00:36:55 +00009028static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009029s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9030 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009031{
9032 IRTemp op2 = newTemp(Ity_I32);
9033
9034 assign(op2, get_gpr_w1(r2));
9035 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9036
9037 return "cdfbr";
9038}
9039
florian55085f82012-11-21 00:36:55 +00009040static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009041s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9042 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009043{
florian125e20d2012-10-07 15:42:37 +00009044 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009045 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009046 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009047 }
sewardj2019a972011-03-07 16:04:07 +00009048 IRTemp op2 = newTemp(Ity_I64);
9049
9050 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009051 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009052 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009053
9054 return "cegbr";
9055}
9056
florian55085f82012-11-21 00:36:55 +00009057static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009058s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9059 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009060{
florian125e20d2012-10-07 15:42:37 +00009061 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009062 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009063 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009064 }
sewardj2019a972011-03-07 16:04:07 +00009065 IRTemp op2 = newTemp(Ity_I64);
9066
9067 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009068 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009069 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009070
9071 return "cdgbr";
9072}
9073
florian55085f82012-11-21 00:36:55 +00009074static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009075s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9076 UChar r1, UChar r2)
9077{
floriane75dafa2012-09-01 17:54:09 +00009078 if (! s390_host_has_fpext) {
9079 emulation_failure(EmFail_S390X_fpext);
9080 } else {
9081 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009082
floriane75dafa2012-09-01 17:54:09 +00009083 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009084 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009085 mkexpr(op2)));
9086 }
florian1c8f7ff2012-09-01 00:12:11 +00009087 return "celfbr";
9088}
9089
florian55085f82012-11-21 00:36:55 +00009090static const HChar *
floriand2129202012-09-01 20:01:39 +00009091s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9092 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00009093{
floriane75dafa2012-09-01 17:54:09 +00009094 if (! s390_host_has_fpext) {
9095 emulation_failure(EmFail_S390X_fpext);
9096 } else {
9097 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009098
floriane75dafa2012-09-01 17:54:09 +00009099 assign(op2, get_gpr_w1(r2));
9100 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9101 }
florian1c8f7ff2012-09-01 00:12:11 +00009102 return "cdlfbr";
9103}
9104
florian55085f82012-11-21 00:36:55 +00009105static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009106s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9107 UChar r1, UChar r2)
9108{
floriane75dafa2012-09-01 17:54:09 +00009109 if (! s390_host_has_fpext) {
9110 emulation_failure(EmFail_S390X_fpext);
9111 } else {
9112 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009113
floriane75dafa2012-09-01 17:54:09 +00009114 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009115 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009116 mkexpr(op2)));
9117 }
florian1c8f7ff2012-09-01 00:12:11 +00009118 return "celgbr";
9119}
9120
florian55085f82012-11-21 00:36:55 +00009121static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009122s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9123 UChar r1, UChar r2)
9124{
floriane75dafa2012-09-01 17:54:09 +00009125 if (! s390_host_has_fpext) {
9126 emulation_failure(EmFail_S390X_fpext);
9127 } else {
9128 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009129
floriane75dafa2012-09-01 17:54:09 +00009130 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009131 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9132 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009133 mkexpr(op2)));
9134 }
florian1c8f7ff2012-09-01 00:12:11 +00009135 return "cdlgbr";
9136}
9137
florian55085f82012-11-21 00:36:55 +00009138static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009139s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9140 UChar r1, UChar r2)
9141{
floriane75dafa2012-09-01 17:54:09 +00009142 if (! s390_host_has_fpext) {
9143 emulation_failure(EmFail_S390X_fpext);
9144 } else {
9145 IRTemp op = newTemp(Ity_F32);
9146 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009147 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009148
floriane75dafa2012-09-01 17:54:09 +00009149 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009150 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009151 mkexpr(op)));
9152 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009153 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009154 }
florian1c8f7ff2012-09-01 00:12:11 +00009155 return "clfebr";
9156}
9157
florian55085f82012-11-21 00:36:55 +00009158static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009159s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9160 UChar r1, UChar r2)
9161{
floriane75dafa2012-09-01 17:54:09 +00009162 if (! s390_host_has_fpext) {
9163 emulation_failure(EmFail_S390X_fpext);
9164 } else {
9165 IRTemp op = newTemp(Ity_F64);
9166 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009167 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009168
floriane75dafa2012-09-01 17:54:09 +00009169 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009170 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009171 mkexpr(op)));
9172 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009173 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009174 }
florian1c8f7ff2012-09-01 00:12:11 +00009175 return "clfdbr";
9176}
9177
florian55085f82012-11-21 00:36:55 +00009178static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009179s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9180 UChar r1, UChar r2)
9181{
floriane75dafa2012-09-01 17:54:09 +00009182 if (! s390_host_has_fpext) {
9183 emulation_failure(EmFail_S390X_fpext);
9184 } else {
9185 IRTemp op = newTemp(Ity_F32);
9186 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009187 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009188
floriane75dafa2012-09-01 17:54:09 +00009189 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009190 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009191 mkexpr(op)));
9192 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009193 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009194 }
florian1c8f7ff2012-09-01 00:12:11 +00009195 return "clgebr";
9196}
9197
florian55085f82012-11-21 00:36:55 +00009198static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009199s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9200 UChar r1, UChar r2)
9201{
floriane75dafa2012-09-01 17:54:09 +00009202 if (! s390_host_has_fpext) {
9203 emulation_failure(EmFail_S390X_fpext);
9204 } else {
9205 IRTemp op = newTemp(Ity_F64);
9206 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009207 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009208
floriane75dafa2012-09-01 17:54:09 +00009209 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009210 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009211 mkexpr(op)));
9212 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009213 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009214 }
florian1c8f7ff2012-09-01 00:12:11 +00009215 return "clgdbr";
9216}
9217
florian55085f82012-11-21 00:36:55 +00009218static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009219s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9220 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009221{
9222 IRTemp op = newTemp(Ity_F32);
9223 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009224 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009225
9226 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009227 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009228 mkexpr(op)));
9229 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009230 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009231
9232 return "cfebr";
9233}
9234
florian55085f82012-11-21 00:36:55 +00009235static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009236s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9237 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009238{
9239 IRTemp op = newTemp(Ity_F64);
9240 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009241 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009242
9243 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009244 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009245 mkexpr(op)));
9246 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009247 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009248
9249 return "cfdbr";
9250}
9251
florian55085f82012-11-21 00:36:55 +00009252static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009253s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9254 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009255{
9256 IRTemp op = newTemp(Ity_F32);
9257 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009258 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009259
9260 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009261 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009262 mkexpr(op)));
9263 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009264 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009265
9266 return "cgebr";
9267}
9268
florian55085f82012-11-21 00:36:55 +00009269static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009270s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9271 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009272{
9273 IRTemp op = newTemp(Ity_F64);
9274 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009275 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009276
9277 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009278 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009279 mkexpr(op)));
9280 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009281 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009282
9283 return "cgdbr";
9284}
9285
florian55085f82012-11-21 00:36:55 +00009286static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009287s390_irgen_DEBR(UChar r1, UChar r2)
9288{
9289 IRTemp op1 = newTemp(Ity_F32);
9290 IRTemp op2 = newTemp(Ity_F32);
9291 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009292 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009293
9294 assign(op1, get_fpr_w0(r1));
9295 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009296 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009297 mkexpr(op2)));
9298 put_fpr_w0(r1, mkexpr(result));
9299
9300 return "debr";
9301}
9302
florian55085f82012-11-21 00:36:55 +00009303static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009304s390_irgen_DDBR(UChar r1, UChar r2)
9305{
9306 IRTemp op1 = newTemp(Ity_F64);
9307 IRTemp op2 = newTemp(Ity_F64);
9308 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009309 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009310
9311 assign(op1, get_fpr_dw0(r1));
9312 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009313 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009314 mkexpr(op2)));
9315 put_fpr_dw0(r1, mkexpr(result));
9316
9317 return "ddbr";
9318}
9319
florian55085f82012-11-21 00:36:55 +00009320static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009321s390_irgen_DEB(UChar r1, IRTemp op2addr)
9322{
9323 IRTemp op1 = newTemp(Ity_F32);
9324 IRTemp op2 = newTemp(Ity_F32);
9325 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009326 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009327
9328 assign(op1, get_fpr_w0(r1));
9329 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009330 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009331 mkexpr(op2)));
9332 put_fpr_w0(r1, mkexpr(result));
9333
9334 return "deb";
9335}
9336
florian55085f82012-11-21 00:36:55 +00009337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009338s390_irgen_DDB(UChar r1, IRTemp op2addr)
9339{
9340 IRTemp op1 = newTemp(Ity_F64);
9341 IRTemp op2 = newTemp(Ity_F64);
9342 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009343 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009344
9345 assign(op1, get_fpr_dw0(r1));
9346 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009347 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009348 mkexpr(op2)));
9349 put_fpr_dw0(r1, mkexpr(result));
9350
9351 return "ddb";
9352}
9353
florian55085f82012-11-21 00:36:55 +00009354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009355s390_irgen_LTEBR(UChar r1, UChar r2)
9356{
9357 IRTemp result = newTemp(Ity_F32);
9358
9359 assign(result, get_fpr_w0(r2));
9360 put_fpr_w0(r1, mkexpr(result));
9361 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9362
9363 return "ltebr";
9364}
9365
florian55085f82012-11-21 00:36:55 +00009366static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009367s390_irgen_LTDBR(UChar r1, UChar r2)
9368{
9369 IRTemp result = newTemp(Ity_F64);
9370
9371 assign(result, get_fpr_dw0(r2));
9372 put_fpr_dw0(r1, mkexpr(result));
9373 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9374
9375 return "ltdbr";
9376}
9377
florian55085f82012-11-21 00:36:55 +00009378static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009379s390_irgen_LCEBR(UChar r1, UChar r2)
9380{
9381 IRTemp result = newTemp(Ity_F32);
9382
9383 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9384 put_fpr_w0(r1, mkexpr(result));
9385 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9386
9387 return "lcebr";
9388}
9389
florian55085f82012-11-21 00:36:55 +00009390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009391s390_irgen_LCDBR(UChar r1, UChar r2)
9392{
9393 IRTemp result = newTemp(Ity_F64);
9394
9395 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9396 put_fpr_dw0(r1, mkexpr(result));
9397 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9398
9399 return "lcdbr";
9400}
9401
florian55085f82012-11-21 00:36:55 +00009402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009403s390_irgen_LDEBR(UChar r1, UChar r2)
9404{
9405 IRTemp op = newTemp(Ity_F32);
9406
9407 assign(op, get_fpr_w0(r2));
9408 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9409
9410 return "ldebr";
9411}
9412
florian55085f82012-11-21 00:36:55 +00009413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009414s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9415{
9416 IRTemp op = newTemp(Ity_F32);
9417
9418 assign(op, load(Ity_F32, mkexpr(op2addr)));
9419 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9420
9421 return "ldeb";
9422}
9423
florian55085f82012-11-21 00:36:55 +00009424static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009425s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9426 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009427{
florian125e20d2012-10-07 15:42:37 +00009428 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009429 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009430 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009431 }
sewardj2019a972011-03-07 16:04:07 +00009432 IRTemp op = newTemp(Ity_F64);
9433
9434 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009435 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009436 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009437
9438 return "ledbr";
9439}
9440
florian55085f82012-11-21 00:36:55 +00009441static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009442s390_irgen_MEEBR(UChar r1, UChar r2)
9443{
9444 IRTemp op1 = newTemp(Ity_F32);
9445 IRTemp op2 = newTemp(Ity_F32);
9446 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009447 IRRoundingMode rounding_mode =
9448 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009449
9450 assign(op1, get_fpr_w0(r1));
9451 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009452 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009453 mkexpr(op2)));
9454 put_fpr_w0(r1, mkexpr(result));
9455
9456 return "meebr";
9457}
9458
florian55085f82012-11-21 00:36:55 +00009459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009460s390_irgen_MDBR(UChar r1, UChar r2)
9461{
9462 IRTemp op1 = newTemp(Ity_F64);
9463 IRTemp op2 = newTemp(Ity_F64);
9464 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009465 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009466
9467 assign(op1, get_fpr_dw0(r1));
9468 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009469 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009470 mkexpr(op2)));
9471 put_fpr_dw0(r1, mkexpr(result));
9472
9473 return "mdbr";
9474}
9475
florian55085f82012-11-21 00:36:55 +00009476static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009477s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9478{
9479 IRTemp op1 = newTemp(Ity_F32);
9480 IRTemp op2 = newTemp(Ity_F32);
9481 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009482 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009483
9484 assign(op1, get_fpr_w0(r1));
9485 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009486 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009487 mkexpr(op2)));
9488 put_fpr_w0(r1, mkexpr(result));
9489
9490 return "meeb";
9491}
9492
florian55085f82012-11-21 00:36:55 +00009493static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009494s390_irgen_MDB(UChar r1, IRTemp op2addr)
9495{
9496 IRTemp op1 = newTemp(Ity_F64);
9497 IRTemp op2 = newTemp(Ity_F64);
9498 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009499 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009500
9501 assign(op1, get_fpr_dw0(r1));
9502 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009503 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009504 mkexpr(op2)));
9505 put_fpr_dw0(r1, mkexpr(result));
9506
9507 return "mdb";
9508}
9509
florian55085f82012-11-21 00:36:55 +00009510static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009511s390_irgen_SEBR(UChar r1, UChar r2)
9512{
9513 IRTemp op1 = newTemp(Ity_F32);
9514 IRTemp op2 = newTemp(Ity_F32);
9515 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009516 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009517
9518 assign(op1, get_fpr_w0(r1));
9519 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009520 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009521 mkexpr(op2)));
9522 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9523 put_fpr_w0(r1, mkexpr(result));
9524
9525 return "sebr";
9526}
9527
florian55085f82012-11-21 00:36:55 +00009528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009529s390_irgen_SDBR(UChar r1, UChar r2)
9530{
9531 IRTemp op1 = newTemp(Ity_F64);
9532 IRTemp op2 = newTemp(Ity_F64);
9533 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009534 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009535
9536 assign(op1, get_fpr_dw0(r1));
9537 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009538 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009539 mkexpr(op2)));
9540 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9541 put_fpr_dw0(r1, mkexpr(result));
9542
9543 return "sdbr";
9544}
9545
florian55085f82012-11-21 00:36:55 +00009546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009547s390_irgen_SEB(UChar r1, IRTemp op2addr)
9548{
9549 IRTemp op1 = newTemp(Ity_F32);
9550 IRTemp op2 = newTemp(Ity_F32);
9551 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009552 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009553
9554 assign(op1, get_fpr_w0(r1));
9555 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009556 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009557 mkexpr(op2)));
9558 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9559 put_fpr_w0(r1, mkexpr(result));
9560
9561 return "seb";
9562}
9563
florian55085f82012-11-21 00:36:55 +00009564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009565s390_irgen_SDB(UChar r1, IRTemp op2addr)
9566{
9567 IRTemp op1 = newTemp(Ity_F64);
9568 IRTemp op2 = newTemp(Ity_F64);
9569 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009570 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009571
9572 assign(op1, get_fpr_dw0(r1));
9573 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009574 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009575 mkexpr(op2)));
9576 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9577 put_fpr_dw0(r1, mkexpr(result));
9578
9579 return "sdb";
9580}
9581
florian55085f82012-11-21 00:36:55 +00009582static const HChar *
florian12390202012-11-10 22:34:14 +00009583s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9584{
9585 IRTemp op1 = newTemp(Ity_D64);
9586 IRTemp op2 = newTemp(Ity_D64);
9587 IRTemp result = newTemp(Ity_D64);
9588 IRTemp rounding_mode;
9589
9590 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009591
9592 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9593 emulation_warning(EmWarn_S390X_fpext_rounding);
9594 m4 = S390_DFP_ROUND_PER_FPC_0;
9595 }
9596
florian12390202012-11-10 22:34:14 +00009597 rounding_mode = encode_dfp_rounding_mode(m4);
9598 assign(op1, get_dpr_dw0(r2));
9599 assign(op2, get_dpr_dw0(r3));
9600 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9601 mkexpr(op2)));
9602 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9603 put_dpr_dw0(r1, mkexpr(result));
9604
9605 return (m4 == 0) ? "adtr" : "adtra";
9606}
9607
florian55085f82012-11-21 00:36:55 +00009608static const HChar *
floriane38f6412012-12-21 17:32:12 +00009609s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9610{
9611 IRTemp op1 = newTemp(Ity_D128);
9612 IRTemp op2 = newTemp(Ity_D128);
9613 IRTemp result = newTemp(Ity_D128);
9614 IRTemp rounding_mode;
9615
9616 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009617
9618 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9619 emulation_warning(EmWarn_S390X_fpext_rounding);
9620 m4 = S390_DFP_ROUND_PER_FPC_0;
9621 }
9622
floriane38f6412012-12-21 17:32:12 +00009623 rounding_mode = encode_dfp_rounding_mode(m4);
9624 assign(op1, get_dpr_pair(r2));
9625 assign(op2, get_dpr_pair(r3));
9626 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9627 mkexpr(op2)));
9628 put_dpr_pair(r1, mkexpr(result));
9629
9630 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9631
9632 return (m4 == 0) ? "axtr" : "axtra";
9633}
9634
9635static const HChar *
9636s390_irgen_CDTR(UChar r1, UChar r2)
9637{
9638 IRTemp op1 = newTemp(Ity_D64);
9639 IRTemp op2 = newTemp(Ity_D64);
9640 IRTemp cc_vex = newTemp(Ity_I32);
9641 IRTemp cc_s390 = newTemp(Ity_I32);
9642
9643 assign(op1, get_dpr_dw0(r1));
9644 assign(op2, get_dpr_dw0(r2));
9645 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9646
florian2d3d87f2012-12-21 21:05:17 +00009647 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009648 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9649
9650 return "cdtr";
9651}
9652
9653static const HChar *
9654s390_irgen_CXTR(UChar r1, UChar r2)
9655{
9656 IRTemp op1 = newTemp(Ity_D128);
9657 IRTemp op2 = newTemp(Ity_D128);
9658 IRTemp cc_vex = newTemp(Ity_I32);
9659 IRTemp cc_s390 = newTemp(Ity_I32);
9660
9661 assign(op1, get_dpr_pair(r1));
9662 assign(op2, get_dpr_pair(r2));
9663 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9664
florian2d3d87f2012-12-21 21:05:17 +00009665 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009666 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9667
9668 return "cxtr";
9669}
9670
9671static const HChar *
florian5f034622013-01-13 02:29:05 +00009672s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9673 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9674{
9675 vassert(s390_host_has_dfp);
9676
9677 if (! s390_host_has_fpext) {
9678 emulation_failure(EmFail_S390X_fpext);
9679 } else {
9680 IRTemp op2 = newTemp(Ity_I32);
9681
9682 assign(op2, get_gpr_w1(r2));
9683 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9684 }
9685 return "cdftr";
9686}
9687
9688static const HChar *
9689s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9690 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9691{
9692 vassert(s390_host_has_dfp);
9693
9694 if (! s390_host_has_fpext) {
9695 emulation_failure(EmFail_S390X_fpext);
9696 } else {
9697 IRTemp op2 = newTemp(Ity_I32);
9698
9699 assign(op2, get_gpr_w1(r2));
9700 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9701 }
9702 return "cxftr";
9703}
9704
9705static const HChar *
floriana887acd2013-02-08 23:32:54 +00009706s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9707 UChar r1, UChar r2)
9708{
9709 IRTemp op2 = newTemp(Ity_I64);
9710
9711 vassert(s390_host_has_dfp);
9712 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9713 emulation_warning(EmWarn_S390X_fpext_rounding);
9714 m3 = S390_DFP_ROUND_PER_FPC_0;
9715 }
9716
9717 assign(op2, get_gpr_dw0(r2));
9718 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9719 mkexpr(op2)));
9720
9721 return (m3 == 0) ? "cdgtr" : "cdgtra";
9722}
9723
9724static const HChar *
9725s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9726 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9727{
9728 IRTemp op2 = newTemp(Ity_I64);
9729
9730 vassert(s390_host_has_dfp);
9731
florian1bb7f6f2013-02-11 00:03:27 +00009732 /* No emulation warning here about an non-zero m3 on hosts without
9733 floating point extension facility. No rounding is performed */
9734
floriana887acd2013-02-08 23:32:54 +00009735 assign(op2, get_gpr_dw0(r2));
9736 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9737
9738 return "cxgtr";
9739}
9740
9741static const HChar *
florian5f034622013-01-13 02:29:05 +00009742s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9743 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9744{
9745 vassert(s390_host_has_dfp);
9746
9747 if (! s390_host_has_fpext) {
9748 emulation_failure(EmFail_S390X_fpext);
9749 } else {
9750 IRTemp op2 = newTemp(Ity_I32);
9751
9752 assign(op2, get_gpr_w1(r2));
9753 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9754 }
9755 return "cdlftr";
9756}
9757
9758static const HChar *
9759s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9760 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9761{
9762 vassert(s390_host_has_dfp);
9763
9764 if (! s390_host_has_fpext) {
9765 emulation_failure(EmFail_S390X_fpext);
9766 } else {
9767 IRTemp op2 = newTemp(Ity_I32);
9768
9769 assign(op2, get_gpr_w1(r2));
9770 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9771 }
9772 return "cxlftr";
9773}
9774
9775static const HChar *
9776s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9777 UChar r1, UChar r2)
9778{
9779 vassert(s390_host_has_dfp);
9780
9781 if (! s390_host_has_fpext) {
9782 emulation_failure(EmFail_S390X_fpext);
9783 } else {
9784 IRTemp op2 = newTemp(Ity_I64);
9785
9786 assign(op2, get_gpr_dw0(r2));
9787 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9788 mkexpr(encode_dfp_rounding_mode(m3)),
9789 mkexpr(op2)));
9790 }
9791 return "cdlgtr";
9792}
9793
9794static const HChar *
9795s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9796 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9797{
9798 vassert(s390_host_has_dfp);
9799
9800 if (! s390_host_has_fpext) {
9801 emulation_failure(EmFail_S390X_fpext);
9802 } else {
9803 IRTemp op2 = newTemp(Ity_I64);
9804
9805 assign(op2, get_gpr_dw0(r2));
9806 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9807 }
9808 return "cxlgtr";
9809}
9810
9811static const HChar *
9812s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9813 UChar r1, UChar r2)
9814{
9815 vassert(s390_host_has_dfp);
9816
9817 if (! s390_host_has_fpext) {
9818 emulation_failure(EmFail_S390X_fpext);
9819 } else {
9820 IRTemp op = newTemp(Ity_D64);
9821 IRTemp result = newTemp(Ity_I32);
9822 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9823
9824 assign(op, get_dpr_dw0(r2));
9825 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9826 mkexpr(op)));
9827 put_gpr_w1(r1, mkexpr(result));
9828 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9829 }
9830 return "cfdtr";
9831}
9832
9833static const HChar *
9834s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9835 UChar r1, UChar r2)
9836{
9837 vassert(s390_host_has_dfp);
9838
9839 if (! s390_host_has_fpext) {
9840 emulation_failure(EmFail_S390X_fpext);
9841 } else {
9842 IRTemp op = newTemp(Ity_D128);
9843 IRTemp result = newTemp(Ity_I32);
9844 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9845
9846 assign(op, get_dpr_pair(r2));
9847 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9848 mkexpr(op)));
9849 put_gpr_w1(r1, mkexpr(result));
9850 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9851 }
9852 return "cfxtr";
9853}
9854
9855static const HChar *
floriana887acd2013-02-08 23:32:54 +00009856s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9857 UChar r1, UChar r2)
9858{
9859 IRTemp op = newTemp(Ity_D64);
9860 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9861
9862 vassert(s390_host_has_dfp);
9863
9864 /* If fpext is not installed and m3 is in 1:7,
9865 rounding mode performed is unpredictable */
9866 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9867 emulation_warning(EmWarn_S390X_fpext_rounding);
9868 m3 = S390_DFP_ROUND_PER_FPC_0;
9869 }
9870
9871 assign(op, get_dpr_dw0(r2));
9872 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9873 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9874
9875 return "cgdtr";
9876}
9877
9878static const HChar *
9879s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9880 UChar r1, UChar r2)
9881{
9882 IRTemp op = newTemp(Ity_D128);
9883 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9884
9885 vassert(s390_host_has_dfp);
9886
9887 /* If fpext is not installed and m3 is in 1:7,
9888 rounding mode performed is unpredictable */
9889 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9890 emulation_warning(EmWarn_S390X_fpext_rounding);
9891 m3 = S390_DFP_ROUND_PER_FPC_0;
9892 }
9893 assign(op, get_dpr_pair(r2));
9894 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9895 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9896
9897 return "cgxtr";
9898}
9899
9900static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009901s390_irgen_CEDTR(UChar r1, UChar r2)
9902{
9903 IRTemp op1 = newTemp(Ity_D64);
9904 IRTemp op2 = newTemp(Ity_D64);
9905 IRTemp cc_vex = newTemp(Ity_I32);
9906 IRTemp cc_s390 = newTemp(Ity_I32);
9907
9908 vassert(s390_host_has_dfp);
9909 assign(op1, get_dpr_dw0(r1));
9910 assign(op2, get_dpr_dw0(r2));
9911 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9912
9913 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9914 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9915
9916 return "cedtr";
9917}
9918
9919static const HChar *
9920s390_irgen_CEXTR(UChar r1, UChar r2)
9921{
9922 IRTemp op1 = newTemp(Ity_D128);
9923 IRTemp op2 = newTemp(Ity_D128);
9924 IRTemp cc_vex = newTemp(Ity_I32);
9925 IRTemp cc_s390 = newTemp(Ity_I32);
9926
9927 vassert(s390_host_has_dfp);
9928 assign(op1, get_dpr_pair(r1));
9929 assign(op2, get_dpr_pair(r2));
9930 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9931
9932 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9933 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9934
9935 return "cextr";
9936}
9937
9938static const HChar *
florian5f034622013-01-13 02:29:05 +00009939s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9940 UChar r1, UChar r2)
9941{
9942 vassert(s390_host_has_dfp);
9943
9944 if (! s390_host_has_fpext) {
9945 emulation_failure(EmFail_S390X_fpext);
9946 } else {
9947 IRTemp op = newTemp(Ity_D64);
9948 IRTemp result = newTemp(Ity_I32);
9949 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9950
9951 assign(op, get_dpr_dw0(r2));
9952 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9953 mkexpr(op)));
9954 put_gpr_w1(r1, mkexpr(result));
9955 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9956 }
9957 return "clfdtr";
9958}
9959
9960static const HChar *
9961s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9962 UChar r1, UChar r2)
9963{
9964 vassert(s390_host_has_dfp);
9965
9966 if (! s390_host_has_fpext) {
9967 emulation_failure(EmFail_S390X_fpext);
9968 } else {
9969 IRTemp op = newTemp(Ity_D128);
9970 IRTemp result = newTemp(Ity_I32);
9971 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9972
9973 assign(op, get_dpr_pair(r2));
9974 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9975 mkexpr(op)));
9976 put_gpr_w1(r1, mkexpr(result));
9977 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9978 }
9979 return "clfxtr";
9980}
9981
9982static const HChar *
9983s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9984 UChar r1, UChar r2)
9985{
9986 vassert(s390_host_has_dfp);
9987
9988 if (! s390_host_has_fpext) {
9989 emulation_failure(EmFail_S390X_fpext);
9990 } else {
9991 IRTemp op = newTemp(Ity_D64);
9992 IRTemp result = newTemp(Ity_I64);
9993 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9994
9995 assign(op, get_dpr_dw0(r2));
9996 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
9997 mkexpr(op)));
9998 put_gpr_dw0(r1, mkexpr(result));
9999 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10000 }
10001 return "clgdtr";
10002}
10003
10004static const HChar *
10005s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10006 UChar r1, UChar r2)
10007{
10008 vassert(s390_host_has_dfp);
10009
10010 if (! s390_host_has_fpext) {
10011 emulation_failure(EmFail_S390X_fpext);
10012 } else {
10013 IRTemp op = newTemp(Ity_D128);
10014 IRTemp result = newTemp(Ity_I64);
10015 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10016
10017 assign(op, get_dpr_pair(r2));
10018 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10019 mkexpr(op)));
10020 put_gpr_dw0(r1, mkexpr(result));
10021 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10022 rounding_mode);
10023 }
10024 return "clgxtr";
10025}
10026
10027static const HChar *
florian12390202012-11-10 22:34:14 +000010028s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10029{
10030 IRTemp op1 = newTemp(Ity_D64);
10031 IRTemp op2 = newTemp(Ity_D64);
10032 IRTemp result = newTemp(Ity_D64);
10033 IRTemp rounding_mode;
10034
10035 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010036
10037 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10038 emulation_warning(EmWarn_S390X_fpext_rounding);
10039 m4 = S390_DFP_ROUND_PER_FPC_0;
10040 }
10041
florian12390202012-11-10 22:34:14 +000010042 rounding_mode = encode_dfp_rounding_mode(m4);
10043 assign(op1, get_dpr_dw0(r2));
10044 assign(op2, get_dpr_dw0(r3));
10045 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10046 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010047 put_dpr_dw0(r1, mkexpr(result));
10048
10049 return (m4 == 0) ? "ddtr" : "ddtra";
10050}
10051
florian55085f82012-11-21 00:36:55 +000010052static const HChar *
floriane38f6412012-12-21 17:32:12 +000010053s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10054{
10055 IRTemp op1 = newTemp(Ity_D128);
10056 IRTemp op2 = newTemp(Ity_D128);
10057 IRTemp result = newTemp(Ity_D128);
10058 IRTemp rounding_mode;
10059
10060 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010061
10062 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10063 emulation_warning(EmWarn_S390X_fpext_rounding);
10064 m4 = S390_DFP_ROUND_PER_FPC_0;
10065 }
10066
floriane38f6412012-12-21 17:32:12 +000010067 rounding_mode = encode_dfp_rounding_mode(m4);
10068 assign(op1, get_dpr_pair(r2));
10069 assign(op2, get_dpr_pair(r3));
10070 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10071 mkexpr(op2)));
10072 put_dpr_pair(r1, mkexpr(result));
10073
10074 return (m4 == 0) ? "dxtr" : "dxtra";
10075}
10076
10077static const HChar *
florian5c539732013-02-14 14:27:12 +000010078s390_irgen_EEDTR(UChar r1, UChar r2)
10079{
10080 vassert(s390_host_has_dfp);
10081
10082 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10083 return "eedtr";
10084}
10085
10086static const HChar *
10087s390_irgen_EEXTR(UChar r1, UChar r2)
10088{
10089 vassert(s390_host_has_dfp);
10090
10091 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10092 return "eextr";
10093}
10094
10095static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010096s390_irgen_ESDTR(UChar r1, UChar r2)
10097{
10098 vassert(s390_host_has_dfp);
10099 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10100 return "esdtr";
10101}
10102
10103static const HChar *
10104s390_irgen_ESXTR(UChar r1, UChar r2)
10105{
10106 vassert(s390_host_has_dfp);
10107 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10108 return "esxtr";
10109}
10110
10111static const HChar *
florian5c539732013-02-14 14:27:12 +000010112s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10113{
10114 IRTemp op1 = newTemp(Ity_I64);
10115 IRTemp op2 = newTemp(Ity_D64);
10116 IRTemp result = newTemp(Ity_D64);
10117
10118 vassert(s390_host_has_dfp);
10119
10120 assign(op1, get_gpr_dw0(r2));
10121 assign(op2, get_dpr_dw0(r3));
10122 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10123 put_dpr_dw0(r1, mkexpr(result));
10124
10125 return "iedtr";
10126}
10127
10128static const HChar *
10129s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10130{
10131 IRTemp op1 = newTemp(Ity_I64);
10132 IRTemp op2 = newTemp(Ity_D128);
10133 IRTemp result = newTemp(Ity_D128);
10134
10135 vassert(s390_host_has_dfp);
10136
10137 assign(op1, get_gpr_dw0(r2));
10138 assign(op2, get_dpr_pair(r3));
10139 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10140 put_dpr_pair(r1, mkexpr(result));
10141
10142 return "iextr";
10143}
10144
10145static const HChar *
floriane38f6412012-12-21 17:32:12 +000010146s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10147{
10148 IRTemp op = newTemp(Ity_D32);
10149
10150 vassert(s390_host_has_dfp);
10151
10152 assign(op, get_dpr_w0(r2));
10153 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10154
10155 return "ldetr";
10156}
10157
10158static const HChar *
10159s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10160{
10161 IRTemp op = newTemp(Ity_D64);
10162
10163 assign(op, get_dpr_dw0(r2));
10164 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10165
10166 return "lxdtr";
10167}
10168
10169static const HChar *
10170s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10171 UChar r1, UChar r2)
10172{
10173 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010174
10175 /* If fpext is not installed and m3 is in 1:7,
10176 rounding mode performed is unpredictable */
10177 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010178 emulation_warning(EmWarn_S390X_fpext_rounding);
10179 m3 = S390_DFP_ROUND_PER_FPC_0;
10180 }
10181 IRTemp result = newTemp(Ity_D64);
10182
10183 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10184 get_dpr_pair(r2)));
10185 put_dpr_dw0(r1, mkexpr(result));
10186
10187 return "ldxtr";
10188}
10189
10190static const HChar *
10191s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10192 UChar r1, UChar r2)
10193{
10194 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010195
10196 /* If fpext is not installed and m3 is in 1:7,
10197 rounding mode performed is unpredictable */
10198 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010199 emulation_warning(EmWarn_S390X_fpext_rounding);
10200 m3 = S390_DFP_ROUND_PER_FPC_0;
10201 }
10202 IRTemp op = newTemp(Ity_D64);
10203
10204 assign(op, get_dpr_dw0(r2));
10205 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10206 mkexpr(op)));
10207
10208 return "ledtr";
10209}
10210
10211static const HChar *
10212s390_irgen_LTDTR(UChar r1, UChar r2)
10213{
10214 IRTemp result = newTemp(Ity_D64);
10215
10216 assign(result, get_dpr_dw0(r2));
10217 put_dpr_dw0(r1, mkexpr(result));
10218 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10219
10220 return "ltdtr";
10221}
10222
10223static const HChar *
10224s390_irgen_LTXTR(UChar r1, UChar r2)
10225{
10226 IRTemp result = newTemp(Ity_D128);
10227
10228 assign(result, get_dpr_pair(r2));
10229 put_dpr_pair(r1, mkexpr(result));
10230 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10231
10232 return "ltxtr";
10233}
10234
10235static const HChar *
florian12390202012-11-10 22:34:14 +000010236s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10237{
10238 IRTemp op1 = newTemp(Ity_D64);
10239 IRTemp op2 = newTemp(Ity_D64);
10240 IRTemp result = newTemp(Ity_D64);
10241 IRTemp rounding_mode;
10242
10243 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010244
10245 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10246 emulation_warning(EmWarn_S390X_fpext_rounding);
10247 m4 = S390_DFP_ROUND_PER_FPC_0;
10248 }
10249
florian12390202012-11-10 22:34:14 +000010250 rounding_mode = encode_dfp_rounding_mode(m4);
10251 assign(op1, get_dpr_dw0(r2));
10252 assign(op2, get_dpr_dw0(r3));
10253 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10254 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010255 put_dpr_dw0(r1, mkexpr(result));
10256
10257 return (m4 == 0) ? "mdtr" : "mdtra";
10258}
10259
florian55085f82012-11-21 00:36:55 +000010260static const HChar *
floriane38f6412012-12-21 17:32:12 +000010261s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10262{
10263 IRTemp op1 = newTemp(Ity_D128);
10264 IRTemp op2 = newTemp(Ity_D128);
10265 IRTemp result = newTemp(Ity_D128);
10266 IRTemp rounding_mode;
10267
10268 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010269
10270 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10271 emulation_warning(EmWarn_S390X_fpext_rounding);
10272 m4 = S390_DFP_ROUND_PER_FPC_0;
10273 }
10274
floriane38f6412012-12-21 17:32:12 +000010275 rounding_mode = encode_dfp_rounding_mode(m4);
10276 assign(op1, get_dpr_pair(r2));
10277 assign(op2, get_dpr_pair(r3));
10278 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10279 mkexpr(op2)));
10280 put_dpr_pair(r1, mkexpr(result));
10281
10282 return (m4 == 0) ? "mxtr" : "mxtra";
10283}
10284
10285static const HChar *
florian5c539732013-02-14 14:27:12 +000010286s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10287{
10288 IRTemp op1 = newTemp(Ity_D64);
10289 IRTemp op2 = newTemp(Ity_D64);
10290 IRTemp result = newTemp(Ity_D64);
10291 IRTemp rounding_mode;
10292
10293 vassert(s390_host_has_dfp);
10294 /* If fpext is not installed and m4 is in 1:7,
10295 rounding mode performed is unpredictable */
10296 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10297 emulation_warning(EmWarn_S390X_fpext_rounding);
10298 m4 = S390_DFP_ROUND_PER_FPC_0;
10299 }
10300
10301 rounding_mode = encode_dfp_rounding_mode(m4);
10302 assign(op1, get_dpr_dw0(r2));
10303 assign(op2, get_dpr_dw0(r3));
10304 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10305 mkexpr(op2)));
10306 put_dpr_dw0(r1, mkexpr(result));
10307
10308 return "qadtr";
10309}
10310
10311static const HChar *
10312s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10313{
10314 IRTemp op1 = newTemp(Ity_D128);
10315 IRTemp op2 = newTemp(Ity_D128);
10316 IRTemp result = newTemp(Ity_D128);
10317 IRTemp rounding_mode;
10318
10319 vassert(s390_host_has_dfp);
10320 /* If fpext is not installed and m4 is in 1:7,
10321 rounding mode performed is unpredictable */
10322 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10323 emulation_warning(EmWarn_S390X_fpext_rounding);
10324 m4 = S390_DFP_ROUND_PER_FPC_0;
10325 }
10326
10327 rounding_mode = encode_dfp_rounding_mode(m4);
10328 assign(op1, get_dpr_pair(r2));
10329 assign(op2, get_dpr_pair(r3));
10330 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10331 mkexpr(op2)));
10332 put_dpr_pair(r1, mkexpr(result));
10333
10334 return "qaxtr";
10335}
10336
10337static const HChar *
10338s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10339{
10340 IRTemp op1 = newTemp(Ity_I8);
10341 IRTemp op2 = newTemp(Ity_D64);
10342 IRTemp result = newTemp(Ity_D64);
10343 IRTemp rounding_mode;
10344
10345 vassert(s390_host_has_dfp);
10346 /* If fpext is not installed and m4 is in 1:7,
10347 rounding mode performed is unpredictable */
10348 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10349 emulation_warning(EmWarn_S390X_fpext_rounding);
10350 m4 = S390_DFP_ROUND_PER_FPC_0;
10351 }
10352
10353 rounding_mode = encode_dfp_rounding_mode(m4);
10354 assign(op1, get_gpr_b7(r2));
10355 assign(op2, get_dpr_dw0(r3));
10356 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10357 mkexpr(op1), mkexpr(op2)));
10358 put_dpr_dw0(r1, mkexpr(result));
10359
10360 return "rrdtr";
10361}
10362
10363static const HChar *
10364s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10365{
10366 IRTemp op1 = newTemp(Ity_I8);
10367 IRTemp op2 = newTemp(Ity_D128);
10368 IRTemp result = newTemp(Ity_D128);
10369 IRTemp rounding_mode;
10370
10371 vassert(s390_host_has_dfp);
10372 /* If fpext is not installed and m4 is in 1:7,
10373 rounding mode performed is unpredictable */
10374 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10375 emulation_warning(EmWarn_S390X_fpext_rounding);
10376 m4 = S390_DFP_ROUND_PER_FPC_0;
10377 }
10378
10379 rounding_mode = encode_dfp_rounding_mode(m4);
10380 assign(op1, get_gpr_b7(r2));
10381 assign(op2, get_dpr_pair(r3));
10382 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10383 mkexpr(op1), mkexpr(op2)));
10384 put_dpr_pair(r1, mkexpr(result));
10385
10386 return "rrxtr";
10387}
10388
10389static const HChar *
florian12390202012-11-10 22:34:14 +000010390s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10391{
10392 IRTemp op1 = newTemp(Ity_D64);
10393 IRTemp op2 = newTemp(Ity_D64);
10394 IRTemp result = newTemp(Ity_D64);
10395 IRTemp rounding_mode;
10396
10397 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010398
10399 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10400 emulation_warning(EmWarn_S390X_fpext_rounding);
10401 m4 = S390_DFP_ROUND_PER_FPC_0;
10402 }
10403
florian12390202012-11-10 22:34:14 +000010404 rounding_mode = encode_dfp_rounding_mode(m4);
10405 assign(op1, get_dpr_dw0(r2));
10406 assign(op2, get_dpr_dw0(r3));
10407 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10408 mkexpr(op2)));
10409 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10410 put_dpr_dw0(r1, mkexpr(result));
10411
10412 return (m4 == 0) ? "sdtr" : "sdtra";
10413}
10414
floriane38f6412012-12-21 17:32:12 +000010415static const HChar *
10416s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10417{
10418 IRTemp op1 = newTemp(Ity_D128);
10419 IRTemp op2 = newTemp(Ity_D128);
10420 IRTemp result = newTemp(Ity_D128);
10421 IRTemp rounding_mode;
10422
10423 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010424
10425 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10426 emulation_warning(EmWarn_S390X_fpext_rounding);
10427 m4 = S390_DFP_ROUND_PER_FPC_0;
10428 }
10429
floriane38f6412012-12-21 17:32:12 +000010430 rounding_mode = encode_dfp_rounding_mode(m4);
10431 assign(op1, get_dpr_pair(r2));
10432 assign(op2, get_dpr_pair(r3));
10433 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10434 mkexpr(op2)));
10435 put_dpr_pair(r1, mkexpr(result));
10436
10437 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10438
10439 return (m4 == 0) ? "sxtr" : "sxtra";
10440}
sewardj2019a972011-03-07 16:04:07 +000010441
florian55085f82012-11-21 00:36:55 +000010442static const HChar *
florian1b901d42013-01-01 22:19:24 +000010443s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10444{
10445 IRTemp op = newTemp(Ity_D64);
10446
10447 vassert(s390_host_has_dfp);
10448
10449 assign(op, get_dpr_dw0(r3));
10450 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
10451 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10452
10453 return "sldt";
10454}
10455
10456static const HChar *
10457s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10458{
10459 IRTemp op = newTemp(Ity_D128);
10460
10461 vassert(s390_host_has_dfp);
10462
10463 assign(op, get_dpr_pair(r3));
10464 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
10465 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10466
10467 return "slxt";
10468}
10469
10470static const HChar *
10471s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10472{
10473 IRTemp op = newTemp(Ity_D64);
10474
10475 vassert(s390_host_has_dfp);
10476
10477 assign(op, get_dpr_dw0(r3));
10478 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
10479 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10480
10481 return "srdt";
10482}
10483
10484static const HChar *
10485s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10486{
10487 IRTemp op = newTemp(Ity_D128);
10488
10489 vassert(s390_host_has_dfp);
10490
10491 assign(op, get_dpr_pair(r3));
10492 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
10493 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10494
10495 return "srxt";
10496}
10497
10498static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010499s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10500{
10501 IRTemp value = newTemp(Ity_D32);
10502
10503 vassert(s390_host_has_dfp);
10504 assign(value, get_dpr_w0(r1));
10505
10506 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10507
10508 return "tdcet";
10509}
10510
10511static const HChar *
10512s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10513{
10514 IRTemp value = newTemp(Ity_D64);
10515
10516 vassert(s390_host_has_dfp);
10517 assign(value, get_dpr_dw0(r1));
10518
10519 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10520
10521 return "tdcdt";
10522}
10523
10524static const HChar *
10525s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10526{
10527 IRTemp value = newTemp(Ity_D128);
10528
10529 vassert(s390_host_has_dfp);
10530 assign(value, get_dpr_pair(r1));
10531
10532 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10533
10534 return "tdcxt";
10535}
10536
10537static const HChar *
10538s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10539{
10540 IRTemp value = newTemp(Ity_D32);
10541
10542 vassert(s390_host_has_dfp);
10543 assign(value, get_dpr_w0(r1));
10544
10545 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10546
10547 return "tdget";
10548}
10549
10550static const HChar *
10551s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10552{
10553 IRTemp value = newTemp(Ity_D64);
10554
10555 vassert(s390_host_has_dfp);
10556 assign(value, get_dpr_dw0(r1));
10557
10558 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10559
10560 return "tdgdt";
10561}
10562
10563static const HChar *
10564s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10565{
10566 IRTemp value = newTemp(Ity_D128);
10567
10568 vassert(s390_host_has_dfp);
10569 assign(value, get_dpr_pair(r1));
10570
10571 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10572
10573 return "tdgxt";
10574}
10575
10576static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010577s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10578{
florian79e839e2012-05-05 02:20:30 +000010579 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010580
florian79e839e2012-05-05 02:20:30 +000010581 assign(len, mkU64(length));
10582 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010583
10584 return "clc";
10585}
10586
florian55085f82012-11-21 00:36:55 +000010587static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010588s390_irgen_CLCL(UChar r1, UChar r2)
10589{
10590 IRTemp addr1 = newTemp(Ity_I64);
10591 IRTemp addr2 = newTemp(Ity_I64);
10592 IRTemp addr1_load = newTemp(Ity_I64);
10593 IRTemp addr2_load = newTemp(Ity_I64);
10594 IRTemp len1 = newTemp(Ity_I32);
10595 IRTemp len2 = newTemp(Ity_I32);
10596 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10597 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10598 IRTemp single1 = newTemp(Ity_I8);
10599 IRTemp single2 = newTemp(Ity_I8);
10600 IRTemp pad = newTemp(Ity_I8);
10601
10602 assign(addr1, get_gpr_dw0(r1));
10603 assign(r1p1, get_gpr_w1(r1 + 1));
10604 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10605 assign(addr2, get_gpr_dw0(r2));
10606 assign(r2p1, get_gpr_w1(r2 + 1));
10607 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10608 assign(pad, get_gpr_b4(r2 + 1));
10609
10610 /* len1 == 0 and len2 == 0? Exit */
10611 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010612 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10613 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010614
10615 /* Because mkite evaluates both the then-clause and the else-clause
10616 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10617 may be NULL and loading from there would segfault. So we provide a
10618 valid dummy address in that case. Loading from there does no harm and
10619 the value will be discarded at runtime. */
10620 assign(addr1_load,
10621 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10622 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10623 assign(single1,
10624 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10625 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10626
10627 assign(addr2_load,
10628 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10629 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10630 assign(single2,
10631 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10632 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10633
10634 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10635 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010636 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010637
10638 /* Update len1 and addr1, unless len1 == 0. */
10639 put_gpr_dw0(r1,
10640 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10641 mkexpr(addr1),
10642 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10643
10644 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10645 put_gpr_w1(r1 + 1,
10646 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10647 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10648 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10649
10650 /* Update len2 and addr2, unless len2 == 0. */
10651 put_gpr_dw0(r2,
10652 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10653 mkexpr(addr2),
10654 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10655
10656 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10657 put_gpr_w1(r2 + 1,
10658 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10659 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10660 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10661
florian6820ba52012-07-26 02:01:50 +000010662 iterate();
florianb0c9a132011-09-08 15:37:39 +000010663
10664 return "clcl";
10665}
10666
florian55085f82012-11-21 00:36:55 +000010667static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010668s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10669{
10670 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10671
10672 addr1 = newTemp(Ity_I64);
10673 addr3 = newTemp(Ity_I64);
10674 addr1_load = newTemp(Ity_I64);
10675 addr3_load = newTemp(Ity_I64);
10676 len1 = newTemp(Ity_I64);
10677 len3 = newTemp(Ity_I64);
10678 single1 = newTemp(Ity_I8);
10679 single3 = newTemp(Ity_I8);
10680
10681 assign(addr1, get_gpr_dw0(r1));
10682 assign(len1, get_gpr_dw0(r1 + 1));
10683 assign(addr3, get_gpr_dw0(r3));
10684 assign(len3, get_gpr_dw0(r3 + 1));
10685
10686 /* len1 == 0 and len3 == 0? Exit */
10687 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010688 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10689 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010690
10691 /* A mux requires both ways to be possible. This is a way to prevent clcle
10692 from reading from addr1 if it should read from the pad. Since the pad
10693 has no address, just read from the instruction, we discard that anyway */
10694 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010695 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10696 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010697
10698 /* same for addr3 */
10699 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010700 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10701 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010702
10703 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010704 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10705 unop(Iop_64to8, mkexpr(pad2)),
10706 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010707
10708 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010709 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10710 unop(Iop_64to8, mkexpr(pad2)),
10711 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010712
10713 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10714 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010715 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010716
10717 /* If a length in 0 we must not change this length and the address */
10718 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010719 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10720 mkexpr(addr1),
10721 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010722
10723 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010724 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10725 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010726
10727 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010728 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10729 mkexpr(addr3),
10730 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010731
10732 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010733 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10734 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010735
florian6820ba52012-07-26 02:01:50 +000010736 iterate();
sewardj2019a972011-03-07 16:04:07 +000010737
10738 return "clcle";
10739}
floriana64c2432011-07-16 02:11:50 +000010740
florianb0bf6602012-05-05 00:01:16 +000010741
sewardj2019a972011-03-07 16:04:07 +000010742static void
10743s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10744{
florianb0bf6602012-05-05 00:01:16 +000010745 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10746}
sewardj2019a972011-03-07 16:04:07 +000010747
sewardj2019a972011-03-07 16:04:07 +000010748
florianb0bf6602012-05-05 00:01:16 +000010749static void
10750s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10751{
10752 s390_irgen_xonc(Iop_And8, length, start1, start2);
10753}
sewardj2019a972011-03-07 16:04:07 +000010754
sewardj2019a972011-03-07 16:04:07 +000010755
florianb0bf6602012-05-05 00:01:16 +000010756static void
10757s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10758{
10759 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010760}
10761
10762
10763static void
10764s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10765{
10766 IRTemp current1 = newTemp(Ity_I8);
10767 IRTemp current2 = newTemp(Ity_I8);
10768 IRTemp counter = newTemp(Ity_I64);
10769
10770 assign(counter, get_counter_dw0());
10771 put_counter_dw0(mkU64(0));
10772
10773 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10774 mkexpr(counter))));
10775 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10776 mkexpr(counter))));
10777 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10778 False);
10779
10780 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010781 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010782
10783 /* Check for end of field */
10784 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010785 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010786 put_counter_dw0(mkU64(0));
10787}
10788
10789static void
10790s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10791{
10792 IRTemp counter = newTemp(Ity_I64);
10793
10794 assign(counter, get_counter_dw0());
10795
10796 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10797 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10798
10799 /* Check for end of field */
10800 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010801 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010802 put_counter_dw0(mkU64(0));
10803}
10804
florianf87d4fb2012-05-05 02:55:24 +000010805static void
10806s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10807{
10808 IRTemp op = newTemp(Ity_I8);
10809 IRTemp op1 = newTemp(Ity_I8);
10810 IRTemp result = newTemp(Ity_I64);
10811 IRTemp counter = newTemp(Ity_I64);
10812
10813 assign(counter, get_counter_dw0());
10814
10815 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10816
10817 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10818
10819 assign(op1, load(Ity_I8, mkexpr(result)));
10820 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10821
10822 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010823 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010824 put_counter_dw0(mkU64(0));
10825}
sewardj2019a972011-03-07 16:04:07 +000010826
10827
10828static void
10829s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010830 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010831 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010832{
10833 struct SS {
10834 unsigned int op : 8;
10835 unsigned int l : 8;
10836 unsigned int b1 : 4;
10837 unsigned int d1 : 12;
10838 unsigned int b2 : 4;
10839 unsigned int d2 : 12;
10840 };
10841 union {
10842 struct SS dec;
10843 unsigned long bytes;
10844 } ss;
10845 IRTemp cond;
10846 IRDirty *d;
10847 IRTemp torun;
10848
10849 IRTemp start1 = newTemp(Ity_I64);
10850 IRTemp start2 = newTemp(Ity_I64);
10851 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10852 cond = newTemp(Ity_I1);
10853 torun = newTemp(Ity_I64);
10854
10855 assign(torun, load(Ity_I64, mkexpr(addr2)));
10856 /* Start with a check that the saved code is still correct */
10857 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10858 /* If not, save the new value */
10859 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10860 mkIRExprVec_1(mkexpr(torun)));
10861 d->guard = mkexpr(cond);
10862 stmt(IRStmt_Dirty(d));
10863
10864 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010865 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10866 mkU64(guest_IA_curr_instr)));
10867 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010868 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010869
10870 ss.bytes = last_execute_target;
10871 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10872 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10873 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10874 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10875 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10876 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10877 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010878
sewardj2019a972011-03-07 16:04:07 +000010879 last_execute_target = 0;
10880}
10881
florian55085f82012-11-21 00:36:55 +000010882static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010883s390_irgen_EX(UChar r1, IRTemp addr2)
10884{
10885 switch(last_execute_target & 0xff00000000000000ULL) {
10886 case 0:
10887 {
10888 /* no code information yet */
10889 IRDirty *d;
10890
10891 /* so safe the code... */
10892 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10893 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10894 stmt(IRStmt_Dirty(d));
10895 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010896 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10897 mkU64(guest_IA_curr_instr)));
10898 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010899 restart_if(IRExpr_Const(IRConst_U1(True)));
10900
sewardj2019a972011-03-07 16:04:07 +000010901 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010902 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010903 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000010904 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000010905 break;
10906 }
10907
10908 case 0xd200000000000000ULL:
10909 /* special case MVC */
10910 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010911 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010912
10913 case 0xd500000000000000ULL:
10914 /* special case CLC */
10915 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010916 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010917
10918 case 0xd700000000000000ULL:
10919 /* special case XC */
10920 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010921 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010922
florianb0bf6602012-05-05 00:01:16 +000010923 case 0xd600000000000000ULL:
10924 /* special case OC */
10925 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010926 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010927
10928 case 0xd400000000000000ULL:
10929 /* special case NC */
10930 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010931 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010932
florianf87d4fb2012-05-05 02:55:24 +000010933 case 0xdc00000000000000ULL:
10934 /* special case TR */
10935 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010936 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010937
sewardj2019a972011-03-07 16:04:07 +000010938 default:
10939 {
10940 /* everything else will get a self checking prefix that also checks the
10941 register content */
10942 IRDirty *d;
10943 UChar *bytes;
10944 IRTemp cond;
10945 IRTemp orperand;
10946 IRTemp torun;
10947
10948 cond = newTemp(Ity_I1);
10949 orperand = newTemp(Ity_I64);
10950 torun = newTemp(Ity_I64);
10951
10952 if (r1 == 0)
10953 assign(orperand, mkU64(0));
10954 else
10955 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10956 /* This code is going to be translated */
10957 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10958 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10959
10960 /* Start with a check that saved code is still correct */
10961 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10962 mkU64(last_execute_target)));
10963 /* If not, save the new value */
10964 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10965 mkIRExprVec_1(mkexpr(torun)));
10966 d->guard = mkexpr(cond);
10967 stmt(IRStmt_Dirty(d));
10968
10969 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010970 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10971 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010972 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010973
10974 /* Now comes the actual translation */
10975 bytes = (UChar *) &last_execute_target;
10976 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10977 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010978 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010979 vex_printf(" which was executed by\n");
10980 /* dont make useless translations in the next execute */
10981 last_execute_target = 0;
10982 }
10983 }
10984 return "ex";
10985}
10986
florian55085f82012-11-21 00:36:55 +000010987static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010988s390_irgen_EXRL(UChar r1, UInt offset)
10989{
10990 IRTemp addr = newTemp(Ity_I64);
10991 /* we might save one round trip because we know the target */
10992 if (!last_execute_target)
10993 last_execute_target = *(ULong *)(HWord)
10994 (guest_IA_curr_instr + offset * 2UL);
10995 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10996 s390_irgen_EX(r1, addr);
10997 return "exrl";
10998}
10999
florian55085f82012-11-21 00:36:55 +000011000static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011001s390_irgen_IPM(UChar r1)
11002{
11003 // As long as we dont support SPM, lets just assume 0 as program mask
11004 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11005 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11006
11007 return "ipm";
11008}
11009
11010
florian55085f82012-11-21 00:36:55 +000011011static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011012s390_irgen_SRST(UChar r1, UChar r2)
11013{
11014 IRTemp address = newTemp(Ity_I64);
11015 IRTemp next = newTemp(Ity_I64);
11016 IRTemp delim = newTemp(Ity_I8);
11017 IRTemp counter = newTemp(Ity_I64);
11018 IRTemp byte = newTemp(Ity_I8);
11019
11020 assign(address, get_gpr_dw0(r2));
11021 assign(next, get_gpr_dw0(r1));
11022
11023 assign(counter, get_counter_dw0());
11024 put_counter_dw0(mkU64(0));
11025
11026 // start = next? CC=2 and out r1 and r2 unchanged
11027 s390_cc_set(2);
11028 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011029 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000011030
11031 assign(byte, load(Ity_I8, mkexpr(address)));
11032 assign(delim, get_gpr_b7(0));
11033
11034 // byte = delim? CC=1, R1=address
11035 s390_cc_set(1);
11036 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000011037 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011038
11039 // else: all equal, no end yet, loop
11040 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11041 put_gpr_dw0(r1, mkexpr(next));
11042 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011043
florian6820ba52012-07-26 02:01:50 +000011044 iterate();
sewardj2019a972011-03-07 16:04:07 +000011045
11046 return "srst";
11047}
11048
florian55085f82012-11-21 00:36:55 +000011049static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011050s390_irgen_CLST(UChar r1, UChar r2)
11051{
11052 IRTemp address1 = newTemp(Ity_I64);
11053 IRTemp address2 = newTemp(Ity_I64);
11054 IRTemp end = newTemp(Ity_I8);
11055 IRTemp counter = newTemp(Ity_I64);
11056 IRTemp byte1 = newTemp(Ity_I8);
11057 IRTemp byte2 = newTemp(Ity_I8);
11058
11059 assign(address1, get_gpr_dw0(r1));
11060 assign(address2, get_gpr_dw0(r2));
11061 assign(end, get_gpr_b7(0));
11062 assign(counter, get_counter_dw0());
11063 put_counter_dw0(mkU64(0));
11064 assign(byte1, load(Ity_I8, mkexpr(address1)));
11065 assign(byte2, load(Ity_I8, mkexpr(address2)));
11066
11067 // end in both? all equal, reset r1 and r2 to start values
11068 s390_cc_set(0);
11069 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11070 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011071 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11072 binop(Iop_Or8,
11073 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11074 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000011075
11076 put_gpr_dw0(r1, mkexpr(address1));
11077 put_gpr_dw0(r2, mkexpr(address2));
11078
11079 // End found in string1
11080 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011081 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000011082
11083 // End found in string2
11084 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011085 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000011086
11087 // string1 < string2
11088 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011089 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11090 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000011091
11092 // string2 < string1
11093 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011094 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11095 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000011096
11097 // else: all equal, no end yet, loop
11098 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11099 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11100 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011101
florian6820ba52012-07-26 02:01:50 +000011102 iterate();
sewardj2019a972011-03-07 16:04:07 +000011103
11104 return "clst";
11105}
11106
11107static void
11108s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11109{
11110 UChar reg;
11111 IRTemp addr = newTemp(Ity_I64);
11112
11113 assign(addr, mkexpr(op2addr));
11114 reg = r1;
11115 do {
11116 IRTemp old = addr;
11117
11118 reg %= 16;
11119 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11120 addr = newTemp(Ity_I64);
11121 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11122 reg++;
11123 } while (reg != (r3 + 1));
11124}
11125
florian55085f82012-11-21 00:36:55 +000011126static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011127s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11128{
11129 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11130
11131 return "lm";
11132}
11133
florian55085f82012-11-21 00:36:55 +000011134static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011135s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11136{
11137 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11138
11139 return "lmy";
11140}
11141
florian55085f82012-11-21 00:36:55 +000011142static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011143s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11144{
11145 UChar reg;
11146 IRTemp addr = newTemp(Ity_I64);
11147
11148 assign(addr, mkexpr(op2addr));
11149 reg = r1;
11150 do {
11151 IRTemp old = addr;
11152
11153 reg %= 16;
11154 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11155 addr = newTemp(Ity_I64);
11156 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11157 reg++;
11158 } while (reg != (r3 + 1));
11159
11160 return "lmh";
11161}
11162
florian55085f82012-11-21 00:36:55 +000011163static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011164s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11165{
11166 UChar reg;
11167 IRTemp addr = newTemp(Ity_I64);
11168
11169 assign(addr, mkexpr(op2addr));
11170 reg = r1;
11171 do {
11172 IRTemp old = addr;
11173
11174 reg %= 16;
11175 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11176 addr = newTemp(Ity_I64);
11177 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11178 reg++;
11179 } while (reg != (r3 + 1));
11180
11181 return "lmg";
11182}
11183
11184static void
11185s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11186{
11187 UChar reg;
11188 IRTemp addr = newTemp(Ity_I64);
11189
11190 assign(addr, mkexpr(op2addr));
11191 reg = r1;
11192 do {
11193 IRTemp old = addr;
11194
11195 reg %= 16;
11196 store(mkexpr(addr), get_gpr_w1(reg));
11197 addr = newTemp(Ity_I64);
11198 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11199 reg++;
11200 } while( reg != (r3 + 1));
11201}
11202
florian55085f82012-11-21 00:36:55 +000011203static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011204s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11205{
11206 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11207
11208 return "stm";
11209}
11210
florian55085f82012-11-21 00:36:55 +000011211static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011212s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11213{
11214 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11215
11216 return "stmy";
11217}
11218
florian55085f82012-11-21 00:36:55 +000011219static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011220s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11221{
11222 UChar reg;
11223 IRTemp addr = newTemp(Ity_I64);
11224
11225 assign(addr, mkexpr(op2addr));
11226 reg = r1;
11227 do {
11228 IRTemp old = addr;
11229
11230 reg %= 16;
11231 store(mkexpr(addr), get_gpr_w0(reg));
11232 addr = newTemp(Ity_I64);
11233 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11234 reg++;
11235 } while( reg != (r3 + 1));
11236
11237 return "stmh";
11238}
11239
florian55085f82012-11-21 00:36:55 +000011240static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011241s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11242{
11243 UChar reg;
11244 IRTemp addr = newTemp(Ity_I64);
11245
11246 assign(addr, mkexpr(op2addr));
11247 reg = r1;
11248 do {
11249 IRTemp old = addr;
11250
11251 reg %= 16;
11252 store(mkexpr(addr), get_gpr_dw0(reg));
11253 addr = newTemp(Ity_I64);
11254 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11255 reg++;
11256 } while( reg != (r3 + 1));
11257
11258 return "stmg";
11259}
11260
11261static void
florianb0bf6602012-05-05 00:01:16 +000011262s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000011263{
11264 IRTemp old1 = newTemp(Ity_I8);
11265 IRTemp old2 = newTemp(Ity_I8);
11266 IRTemp new1 = newTemp(Ity_I8);
11267 IRTemp counter = newTemp(Ity_I32);
11268 IRTemp addr1 = newTemp(Ity_I64);
11269
11270 assign(counter, get_counter_w0());
11271
11272 assign(addr1, binop(Iop_Add64, mkexpr(start1),
11273 unop(Iop_32Uto64, mkexpr(counter))));
11274
11275 assign(old1, load(Ity_I8, mkexpr(addr1)));
11276 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11277 unop(Iop_32Uto64,mkexpr(counter)))));
11278 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11279
11280 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000011281 if (op == Iop_Xor8) {
11282 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000011283 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11284 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000011285 } else
11286 store(mkexpr(addr1), mkexpr(new1));
11287 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11288 get_counter_w1()));
11289
11290 /* Check for end of field */
11291 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011292 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000011293 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11294 False);
11295 put_counter_dw0(mkU64(0));
11296}
11297
florian55085f82012-11-21 00:36:55 +000011298static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011299s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11300{
florianb0bf6602012-05-05 00:01:16 +000011301 IRTemp len = newTemp(Ity_I32);
11302
11303 assign(len, mkU32(length));
11304 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011305
11306 return "xc";
11307}
11308
sewardjb63967e2011-03-24 08:50:04 +000011309static void
11310s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11311{
11312 IRTemp counter = newTemp(Ity_I32);
11313 IRTemp start = newTemp(Ity_I64);
11314 IRTemp addr = newTemp(Ity_I64);
11315
11316 assign(start,
11317 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11318
11319 if (length < 8) {
11320 UInt i;
11321
11322 for (i = 0; i <= length; ++i) {
11323 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11324 }
11325 } else {
11326 assign(counter, get_counter_w0());
11327
11328 assign(addr, binop(Iop_Add64, mkexpr(start),
11329 unop(Iop_32Uto64, mkexpr(counter))));
11330
11331 store(mkexpr(addr), mkU8(0));
11332
11333 /* Check for end of field */
11334 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011335 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011336
11337 /* Reset counter */
11338 put_counter_dw0(mkU64(0));
11339 }
11340
11341 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11342
sewardj7ee97522011-05-09 21:45:04 +000011343 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011344 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11345}
11346
florian55085f82012-11-21 00:36:55 +000011347static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011348s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11349{
florianb0bf6602012-05-05 00:01:16 +000011350 IRTemp len = newTemp(Ity_I32);
11351
11352 assign(len, mkU32(length));
11353 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011354
11355 return "nc";
11356}
11357
florian55085f82012-11-21 00:36:55 +000011358static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011359s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11360{
florianb0bf6602012-05-05 00:01:16 +000011361 IRTemp len = newTemp(Ity_I32);
11362
11363 assign(len, mkU32(length));
11364 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011365
11366 return "oc";
11367}
11368
11369
florian55085f82012-11-21 00:36:55 +000011370static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011371s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11372{
florian79e839e2012-05-05 02:20:30 +000011373 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011374
florian79e839e2012-05-05 02:20:30 +000011375 assign(len, mkU64(length));
11376 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011377
11378 return "mvc";
11379}
11380
florian55085f82012-11-21 00:36:55 +000011381static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011382s390_irgen_MVCL(UChar r1, UChar r2)
11383{
11384 IRTemp addr1 = newTemp(Ity_I64);
11385 IRTemp addr2 = newTemp(Ity_I64);
11386 IRTemp addr2_load = newTemp(Ity_I64);
11387 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11388 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11389 IRTemp len1 = newTemp(Ity_I32);
11390 IRTemp len2 = newTemp(Ity_I32);
11391 IRTemp pad = newTemp(Ity_I8);
11392 IRTemp single = newTemp(Ity_I8);
11393
11394 assign(addr1, get_gpr_dw0(r1));
11395 assign(r1p1, get_gpr_w1(r1 + 1));
11396 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11397 assign(addr2, get_gpr_dw0(r2));
11398 assign(r2p1, get_gpr_w1(r2 + 1));
11399 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11400 assign(pad, get_gpr_b4(r2 + 1));
11401
11402 /* len1 == 0 ? */
11403 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011404 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011405
11406 /* Check for destructive overlap:
11407 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11408 s390_cc_set(3);
11409 IRTemp cond1 = newTemp(Ity_I32);
11410 assign(cond1, unop(Iop_1Uto32,
11411 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11412 IRTemp cond2 = newTemp(Ity_I32);
11413 assign(cond2, unop(Iop_1Uto32,
11414 binop(Iop_CmpLT64U, mkexpr(addr1),
11415 binop(Iop_Add64, mkexpr(addr2),
11416 unop(Iop_32Uto64, mkexpr(len1))))));
11417 IRTemp cond3 = newTemp(Ity_I32);
11418 assign(cond3, unop(Iop_1Uto32,
11419 binop(Iop_CmpLT64U,
11420 mkexpr(addr1),
11421 binop(Iop_Add64, mkexpr(addr2),
11422 unop(Iop_32Uto64, mkexpr(len2))))));
11423
florian6820ba52012-07-26 02:01:50 +000011424 next_insn_if(binop(Iop_CmpEQ32,
11425 binop(Iop_And32,
11426 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11427 mkexpr(cond3)),
11428 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011429
11430 /* See s390_irgen_CLCL for explanation why we cannot load directly
11431 and need two steps. */
11432 assign(addr2_load,
11433 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11434 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11435 assign(single,
11436 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11437 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11438
11439 store(mkexpr(addr1), mkexpr(single));
11440
11441 /* Update addr1 and len1 */
11442 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11443 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11444
11445 /* Update addr2 and len2 */
11446 put_gpr_dw0(r2,
11447 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11448 mkexpr(addr2),
11449 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11450
11451 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11452 put_gpr_w1(r2 + 1,
11453 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11454 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11455 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11456
11457 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011458 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011459
11460 return "mvcl";
11461}
11462
11463
florian55085f82012-11-21 00:36:55 +000011464static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011465s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11466{
11467 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11468
11469 addr1 = newTemp(Ity_I64);
11470 addr3 = newTemp(Ity_I64);
11471 addr3_load = newTemp(Ity_I64);
11472 len1 = newTemp(Ity_I64);
11473 len3 = newTemp(Ity_I64);
11474 single = newTemp(Ity_I8);
11475
11476 assign(addr1, get_gpr_dw0(r1));
11477 assign(len1, get_gpr_dw0(r1 + 1));
11478 assign(addr3, get_gpr_dw0(r3));
11479 assign(len3, get_gpr_dw0(r3 + 1));
11480
11481 // len1 == 0 ?
11482 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011483 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011484
11485 /* This is a hack to prevent mvcle from reading from addr3 if it
11486 should read from the pad. Since the pad has no address, just
11487 read from the instruction, we discard that anyway */
11488 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011489 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11490 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011491
11492 assign(single,
florian6ad49522011-09-09 02:38:55 +000011493 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11494 unop(Iop_64to8, mkexpr(pad2)),
11495 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011496 store(mkexpr(addr1), mkexpr(single));
11497
11498 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11499
11500 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11501
11502 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011503 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11504 mkexpr(addr3),
11505 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011506
11507 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011508 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11509 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011510
sewardj2019a972011-03-07 16:04:07 +000011511 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011512 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011513
11514 return "mvcle";
11515}
11516
florian55085f82012-11-21 00:36:55 +000011517static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011518s390_irgen_MVST(UChar r1, UChar r2)
11519{
11520 IRTemp addr1 = newTemp(Ity_I64);
11521 IRTemp addr2 = newTemp(Ity_I64);
11522 IRTemp end = newTemp(Ity_I8);
11523 IRTemp byte = newTemp(Ity_I8);
11524 IRTemp counter = newTemp(Ity_I64);
11525
11526 assign(addr1, get_gpr_dw0(r1));
11527 assign(addr2, get_gpr_dw0(r2));
11528 assign(counter, get_counter_dw0());
11529 assign(end, get_gpr_b7(0));
11530 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11531 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11532
11533 // We use unlimited as cpu-determined number
11534 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011535 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011536
11537 // and always set cc=1 at the end + update r1
11538 s390_cc_set(1);
11539 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11540 put_counter_dw0(mkU64(0));
11541
11542 return "mvst";
11543}
11544
11545static void
11546s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11547{
11548 IRTemp op1 = newTemp(Ity_I64);
11549 IRTemp result = newTemp(Ity_I64);
11550
11551 assign(op1, binop(Iop_32HLto64,
11552 get_gpr_w1(r1), // high 32 bits
11553 get_gpr_w1(r1 + 1))); // low 32 bits
11554 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11555 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11556 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11557}
11558
11559static void
11560s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11561{
11562 IRTemp op1 = newTemp(Ity_I128);
11563 IRTemp result = newTemp(Ity_I128);
11564
11565 assign(op1, binop(Iop_64HLto128,
11566 get_gpr_dw0(r1), // high 64 bits
11567 get_gpr_dw0(r1 + 1))); // low 64 bits
11568 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11569 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11570 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11571}
11572
11573static void
11574s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11575{
11576 IRTemp op1 = newTemp(Ity_I64);
11577 IRTemp result = newTemp(Ity_I128);
11578
11579 assign(op1, get_gpr_dw0(r1 + 1));
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
florian55085f82012-11-21 00:36:55 +000011585static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011586s390_irgen_DR(UChar r1, UChar r2)
11587{
11588 IRTemp op2 = newTemp(Ity_I32);
11589
11590 assign(op2, get_gpr_w1(r2));
11591
11592 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11593
11594 return "dr";
11595}
11596
florian55085f82012-11-21 00:36:55 +000011597static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011598s390_irgen_D(UChar r1, IRTemp op2addr)
11599{
11600 IRTemp op2 = newTemp(Ity_I32);
11601
11602 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11603
11604 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11605
11606 return "d";
11607}
11608
florian55085f82012-11-21 00:36:55 +000011609static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011610s390_irgen_DLR(UChar r1, UChar r2)
11611{
11612 IRTemp op2 = newTemp(Ity_I32);
11613
11614 assign(op2, get_gpr_w1(r2));
11615
11616 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11617
florian7cd1cde2012-08-16 23:57:43 +000011618 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011619}
11620
florian55085f82012-11-21 00:36:55 +000011621static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011622s390_irgen_DL(UChar r1, IRTemp op2addr)
11623{
11624 IRTemp op2 = newTemp(Ity_I32);
11625
11626 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11627
11628 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11629
11630 return "dl";
11631}
11632
florian55085f82012-11-21 00:36:55 +000011633static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011634s390_irgen_DLG(UChar r1, IRTemp op2addr)
11635{
11636 IRTemp op2 = newTemp(Ity_I64);
11637
11638 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11639
11640 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11641
11642 return "dlg";
11643}
11644
florian55085f82012-11-21 00:36:55 +000011645static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011646s390_irgen_DLGR(UChar r1, UChar r2)
11647{
11648 IRTemp op2 = newTemp(Ity_I64);
11649
11650 assign(op2, get_gpr_dw0(r2));
11651
11652 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11653
11654 return "dlgr";
11655}
11656
florian55085f82012-11-21 00:36:55 +000011657static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011658s390_irgen_DSGR(UChar r1, UChar r2)
11659{
11660 IRTemp op2 = newTemp(Ity_I64);
11661
11662 assign(op2, get_gpr_dw0(r2));
11663
11664 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11665
11666 return "dsgr";
11667}
11668
florian55085f82012-11-21 00:36:55 +000011669static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011670s390_irgen_DSG(UChar r1, IRTemp op2addr)
11671{
11672 IRTemp op2 = newTemp(Ity_I64);
11673
11674 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11675
11676 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11677
11678 return "dsg";
11679}
11680
florian55085f82012-11-21 00:36:55 +000011681static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011682s390_irgen_DSGFR(UChar r1, UChar r2)
11683{
11684 IRTemp op2 = newTemp(Ity_I64);
11685
11686 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11687
11688 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11689
11690 return "dsgfr";
11691}
11692
florian55085f82012-11-21 00:36:55 +000011693static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011694s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11695{
11696 IRTemp op2 = newTemp(Ity_I64);
11697
11698 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11699
11700 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11701
11702 return "dsgf";
11703}
11704
11705static void
11706s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11707{
11708 UChar reg;
11709 IRTemp addr = newTemp(Ity_I64);
11710
11711 assign(addr, mkexpr(op2addr));
11712 reg = r1;
11713 do {
11714 IRTemp old = addr;
11715
11716 reg %= 16;
11717 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11718 addr = newTemp(Ity_I64);
11719 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11720 reg++;
11721 } while (reg != (r3 + 1));
11722}
11723
florian55085f82012-11-21 00:36:55 +000011724static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011725s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11726{
11727 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11728
11729 return "lam";
11730}
11731
florian55085f82012-11-21 00:36:55 +000011732static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011733s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11734{
11735 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11736
11737 return "lamy";
11738}
11739
11740static void
11741s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11742{
11743 UChar reg;
11744 IRTemp addr = newTemp(Ity_I64);
11745
11746 assign(addr, mkexpr(op2addr));
11747 reg = r1;
11748 do {
11749 IRTemp old = addr;
11750
11751 reg %= 16;
11752 store(mkexpr(addr), get_ar_w0(reg));
11753 addr = newTemp(Ity_I64);
11754 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11755 reg++;
11756 } while (reg != (r3 + 1));
11757}
11758
florian55085f82012-11-21 00:36:55 +000011759static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011760s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11761{
11762 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11763
11764 return "stam";
11765}
11766
florian55085f82012-11-21 00:36:55 +000011767static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011768s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11769{
11770 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11771
11772 return "stamy";
11773}
11774
11775
11776/* Implementation for 32-bit compare-and-swap */
11777static void
11778s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11779{
11780 IRCAS *cas;
11781 IRTemp op1 = newTemp(Ity_I32);
11782 IRTemp old_mem = newTemp(Ity_I32);
11783 IRTemp op3 = newTemp(Ity_I32);
11784 IRTemp result = newTemp(Ity_I32);
11785 IRTemp nequal = newTemp(Ity_I1);
11786
11787 assign(op1, get_gpr_w1(r1));
11788 assign(op3, get_gpr_w1(r3));
11789
11790 /* The first and second operands are compared. If they are equal,
11791 the third operand is stored at the second- operand location. */
11792 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11793 Iend_BE, mkexpr(op2addr),
11794 NULL, mkexpr(op1), /* expected value */
11795 NULL, mkexpr(op3) /* new value */);
11796 stmt(IRStmt_CAS(cas));
11797
11798 /* Set CC. Operands compared equal -> 0, else 1. */
11799 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11800 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11801
11802 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11803 Otherwise, store the old_value from memory in r1 and yield. */
11804 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11805 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011806 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011807}
11808
florian55085f82012-11-21 00:36:55 +000011809static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011810s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11811{
11812 s390_irgen_cas_32(r1, r3, op2addr);
11813
11814 return "cs";
11815}
11816
florian55085f82012-11-21 00:36:55 +000011817static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011818s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11819{
11820 s390_irgen_cas_32(r1, r3, op2addr);
11821
11822 return "csy";
11823}
11824
florian55085f82012-11-21 00:36:55 +000011825static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011826s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11827{
11828 IRCAS *cas;
11829 IRTemp op1 = newTemp(Ity_I64);
11830 IRTemp old_mem = newTemp(Ity_I64);
11831 IRTemp op3 = newTemp(Ity_I64);
11832 IRTemp result = newTemp(Ity_I64);
11833 IRTemp nequal = newTemp(Ity_I1);
11834
11835 assign(op1, get_gpr_dw0(r1));
11836 assign(op3, get_gpr_dw0(r3));
11837
11838 /* The first and second operands are compared. If they are equal,
11839 the third operand is stored at the second- operand location. */
11840 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11841 Iend_BE, mkexpr(op2addr),
11842 NULL, mkexpr(op1), /* expected value */
11843 NULL, mkexpr(op3) /* new value */);
11844 stmt(IRStmt_CAS(cas));
11845
11846 /* Set CC. Operands compared equal -> 0, else 1. */
11847 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11848 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11849
11850 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11851 Otherwise, store the old_value from memory in r1 and yield. */
11852 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11853 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011854 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011855
11856 return "csg";
11857}
11858
florian448cbba2012-06-06 02:26:01 +000011859/* Implementation for 32-bit compare-double-and-swap */
11860static void
11861s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11862{
11863 IRCAS *cas;
11864 IRTemp op1_high = newTemp(Ity_I32);
11865 IRTemp op1_low = newTemp(Ity_I32);
11866 IRTemp old_mem_high = newTemp(Ity_I32);
11867 IRTemp old_mem_low = newTemp(Ity_I32);
11868 IRTemp op3_high = newTemp(Ity_I32);
11869 IRTemp op3_low = newTemp(Ity_I32);
11870 IRTemp result = newTemp(Ity_I32);
11871 IRTemp nequal = newTemp(Ity_I1);
11872
11873 assign(op1_high, get_gpr_w1(r1));
11874 assign(op1_low, get_gpr_w1(r1+1));
11875 assign(op3_high, get_gpr_w1(r3));
11876 assign(op3_low, get_gpr_w1(r3+1));
11877
11878 /* The first and second operands are compared. If they are equal,
11879 the third operand is stored at the second-operand location. */
11880 cas = mkIRCAS(old_mem_high, old_mem_low,
11881 Iend_BE, mkexpr(op2addr),
11882 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11883 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11884 stmt(IRStmt_CAS(cas));
11885
11886 /* Set CC. Operands compared equal -> 0, else 1. */
11887 assign(result, unop(Iop_1Uto32,
11888 binop(Iop_CmpNE32,
11889 binop(Iop_Or32,
11890 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11891 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11892 mkU32(0))));
11893
11894 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11895
11896 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11897 Otherwise, store the old_value from memory in r1 and yield. */
11898 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11899 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11900 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011901 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011902}
11903
florian55085f82012-11-21 00:36:55 +000011904static const HChar *
florian448cbba2012-06-06 02:26:01 +000011905s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11906{
11907 s390_irgen_cdas_32(r1, r3, op2addr);
11908
11909 return "cds";
11910}
11911
florian55085f82012-11-21 00:36:55 +000011912static const HChar *
florian448cbba2012-06-06 02:26:01 +000011913s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11914{
11915 s390_irgen_cdas_32(r1, r3, op2addr);
11916
11917 return "cdsy";
11918}
11919
florian55085f82012-11-21 00:36:55 +000011920static const HChar *
florian448cbba2012-06-06 02:26:01 +000011921s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11922{
11923 IRCAS *cas;
11924 IRTemp op1_high = newTemp(Ity_I64);
11925 IRTemp op1_low = newTemp(Ity_I64);
11926 IRTemp old_mem_high = newTemp(Ity_I64);
11927 IRTemp old_mem_low = newTemp(Ity_I64);
11928 IRTemp op3_high = newTemp(Ity_I64);
11929 IRTemp op3_low = newTemp(Ity_I64);
11930 IRTemp result = newTemp(Ity_I64);
11931 IRTemp nequal = newTemp(Ity_I1);
11932
11933 assign(op1_high, get_gpr_dw0(r1));
11934 assign(op1_low, get_gpr_dw0(r1+1));
11935 assign(op3_high, get_gpr_dw0(r3));
11936 assign(op3_low, get_gpr_dw0(r3+1));
11937
11938 /* The first and second operands are compared. If they are equal,
11939 the third operand is stored at the second-operand location. */
11940 cas = mkIRCAS(old_mem_high, old_mem_low,
11941 Iend_BE, mkexpr(op2addr),
11942 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11943 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11944 stmt(IRStmt_CAS(cas));
11945
11946 /* Set CC. Operands compared equal -> 0, else 1. */
11947 assign(result, unop(Iop_1Uto64,
11948 binop(Iop_CmpNE64,
11949 binop(Iop_Or64,
11950 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11951 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11952 mkU64(0))));
11953
11954 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11955
11956 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11957 Otherwise, store the old_value from memory in r1 and yield. */
11958 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11959 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11960 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011961 yield_if(mkexpr(nequal));
11962
florian448cbba2012-06-06 02:26:01 +000011963 return "cdsg";
11964}
11965
sewardj2019a972011-03-07 16:04:07 +000011966
11967/* Binary floating point */
11968
florian55085f82012-11-21 00:36:55 +000011969static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011970s390_irgen_AXBR(UChar r1, UChar r2)
11971{
11972 IRTemp op1 = newTemp(Ity_F128);
11973 IRTemp op2 = newTemp(Ity_F128);
11974 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011975 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011976
11977 assign(op1, get_fpr_pair(r1));
11978 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011979 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011980 mkexpr(op2)));
11981 put_fpr_pair(r1, mkexpr(result));
11982
11983 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11984
11985 return "axbr";
11986}
11987
florian55085f82012-11-21 00:36:55 +000011988static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011989s390_irgen_CEBR(UChar r1, UChar r2)
11990{
11991 IRTemp op1 = newTemp(Ity_F32);
11992 IRTemp op2 = newTemp(Ity_F32);
11993 IRTemp cc_vex = newTemp(Ity_I32);
11994 IRTemp cc_s390 = newTemp(Ity_I32);
11995
11996 assign(op1, get_fpr_w0(r1));
11997 assign(op2, get_fpr_w0(r2));
11998 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11999
florian2d3d87f2012-12-21 21:05:17 +000012000 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012001 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12002
12003 return "cebr";
12004}
12005
florian55085f82012-11-21 00:36:55 +000012006static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012007s390_irgen_CDBR(UChar r1, UChar r2)
12008{
12009 IRTemp op1 = newTemp(Ity_F64);
12010 IRTemp op2 = newTemp(Ity_F64);
12011 IRTemp cc_vex = newTemp(Ity_I32);
12012 IRTemp cc_s390 = newTemp(Ity_I32);
12013
12014 assign(op1, get_fpr_dw0(r1));
12015 assign(op2, get_fpr_dw0(r2));
12016 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12017
florian2d3d87f2012-12-21 21:05:17 +000012018 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012019 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12020
12021 return "cdbr";
12022}
12023
florian55085f82012-11-21 00:36:55 +000012024static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012025s390_irgen_CXBR(UChar r1, UChar r2)
12026{
12027 IRTemp op1 = newTemp(Ity_F128);
12028 IRTemp op2 = newTemp(Ity_F128);
12029 IRTemp cc_vex = newTemp(Ity_I32);
12030 IRTemp cc_s390 = newTemp(Ity_I32);
12031
12032 assign(op1, get_fpr_pair(r1));
12033 assign(op2, get_fpr_pair(r2));
12034 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12035
florian2d3d87f2012-12-21 21:05:17 +000012036 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012037 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12038
12039 return "cxbr";
12040}
12041
florian55085f82012-11-21 00:36:55 +000012042static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012043s390_irgen_CEB(UChar r1, IRTemp op2addr)
12044{
12045 IRTemp op1 = newTemp(Ity_F32);
12046 IRTemp op2 = newTemp(Ity_F32);
12047 IRTemp cc_vex = newTemp(Ity_I32);
12048 IRTemp cc_s390 = newTemp(Ity_I32);
12049
12050 assign(op1, get_fpr_w0(r1));
12051 assign(op2, load(Ity_F32, mkexpr(op2addr)));
12052 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12053
florian2d3d87f2012-12-21 21:05:17 +000012054 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012055 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12056
12057 return "ceb";
12058}
12059
florian55085f82012-11-21 00:36:55 +000012060static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012061s390_irgen_CDB(UChar r1, IRTemp op2addr)
12062{
12063 IRTemp op1 = newTemp(Ity_F64);
12064 IRTemp op2 = newTemp(Ity_F64);
12065 IRTemp cc_vex = newTemp(Ity_I32);
12066 IRTemp cc_s390 = newTemp(Ity_I32);
12067
12068 assign(op1, get_fpr_dw0(r1));
12069 assign(op2, load(Ity_F64, mkexpr(op2addr)));
12070 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12071
florian2d3d87f2012-12-21 21:05:17 +000012072 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012073 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12074
12075 return "cdb";
12076}
12077
florian55085f82012-11-21 00:36:55 +000012078static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012079s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12080 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012081{
12082 IRTemp op2 = newTemp(Ity_I32);
12083
12084 assign(op2, get_gpr_w1(r2));
12085 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12086
12087 return "cxfbr";
12088}
12089
florian55085f82012-11-21 00:36:55 +000012090static const HChar *
floriand2129202012-09-01 20:01:39 +000012091s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12092 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012093{
floriane75dafa2012-09-01 17:54:09 +000012094 if (! s390_host_has_fpext) {
12095 emulation_failure(EmFail_S390X_fpext);
12096 } else {
12097 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000012098
floriane75dafa2012-09-01 17:54:09 +000012099 assign(op2, get_gpr_w1(r2));
12100 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12101 }
florian1c8f7ff2012-09-01 00:12:11 +000012102 return "cxlfbr";
12103}
12104
12105
florian55085f82012-11-21 00:36:55 +000012106static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012107s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12108 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012109{
12110 IRTemp op2 = newTemp(Ity_I64);
12111
12112 assign(op2, get_gpr_dw0(r2));
12113 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12114
12115 return "cxgbr";
12116}
12117
florian55085f82012-11-21 00:36:55 +000012118static const HChar *
floriand2129202012-09-01 20:01:39 +000012119s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12120 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012121{
floriane75dafa2012-09-01 17:54:09 +000012122 if (! s390_host_has_fpext) {
12123 emulation_failure(EmFail_S390X_fpext);
12124 } else {
12125 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000012126
floriane75dafa2012-09-01 17:54:09 +000012127 assign(op2, get_gpr_dw0(r2));
12128 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12129 }
florian1c8f7ff2012-09-01 00:12:11 +000012130 return "cxlgbr";
12131}
12132
florian55085f82012-11-21 00:36:55 +000012133static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012134s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12135 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012136{
12137 IRTemp op = newTemp(Ity_F128);
12138 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012139 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012140
12141 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012142 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012143 mkexpr(op)));
12144 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012145 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012146
12147 return "cfxbr";
12148}
12149
florian55085f82012-11-21 00:36:55 +000012150static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012151s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12152 UChar r1, UChar r2)
12153{
floriane75dafa2012-09-01 17:54:09 +000012154 if (! s390_host_has_fpext) {
12155 emulation_failure(EmFail_S390X_fpext);
12156 } else {
12157 IRTemp op = newTemp(Ity_F128);
12158 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012159 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012160
floriane75dafa2012-09-01 17:54:09 +000012161 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012162 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012163 mkexpr(op)));
12164 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012165 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012166 }
florian1c8f7ff2012-09-01 00:12:11 +000012167 return "clfxbr";
12168}
12169
12170
florian55085f82012-11-21 00:36:55 +000012171static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012172s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12173 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012174{
12175 IRTemp op = newTemp(Ity_F128);
12176 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012177 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012178
12179 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012180 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012181 mkexpr(op)));
12182 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012183 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012184
12185 return "cgxbr";
12186}
12187
florian55085f82012-11-21 00:36:55 +000012188static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012189s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12190 UChar r1, UChar r2)
12191{
floriane75dafa2012-09-01 17:54:09 +000012192 if (! s390_host_has_fpext) {
12193 emulation_failure(EmFail_S390X_fpext);
12194 } else {
12195 IRTemp op = newTemp(Ity_F128);
12196 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012197 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012198
floriane75dafa2012-09-01 17:54:09 +000012199 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012200 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012201 mkexpr(op)));
12202 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012203 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12204 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012205 }
florian1c8f7ff2012-09-01 00:12:11 +000012206 return "clgxbr";
12207}
12208
florian55085f82012-11-21 00:36:55 +000012209static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012210s390_irgen_DXBR(UChar r1, UChar r2)
12211{
12212 IRTemp op1 = newTemp(Ity_F128);
12213 IRTemp op2 = newTemp(Ity_F128);
12214 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012215 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012216
12217 assign(op1, get_fpr_pair(r1));
12218 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012219 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012220 mkexpr(op2)));
12221 put_fpr_pair(r1, mkexpr(result));
12222
12223 return "dxbr";
12224}
12225
florian55085f82012-11-21 00:36:55 +000012226static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012227s390_irgen_LTXBR(UChar r1, UChar r2)
12228{
12229 IRTemp result = newTemp(Ity_F128);
12230
12231 assign(result, get_fpr_pair(r2));
12232 put_fpr_pair(r1, mkexpr(result));
12233 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12234
12235 return "ltxbr";
12236}
12237
florian55085f82012-11-21 00:36:55 +000012238static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012239s390_irgen_LCXBR(UChar r1, UChar r2)
12240{
12241 IRTemp result = newTemp(Ity_F128);
12242
12243 assign(result, unop(Iop_NegF128, 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 "lcxbr";
12248}
12249
florian55085f82012-11-21 00:36:55 +000012250static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012251s390_irgen_LXDBR(UChar r1, UChar r2)
12252{
12253 IRTemp op = newTemp(Ity_F64);
12254
12255 assign(op, get_fpr_dw0(r2));
12256 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12257
12258 return "lxdbr";
12259}
12260
florian55085f82012-11-21 00:36:55 +000012261static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012262s390_irgen_LXEBR(UChar r1, UChar r2)
12263{
12264 IRTemp op = newTemp(Ity_F32);
12265
12266 assign(op, get_fpr_w0(r2));
12267 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12268
12269 return "lxebr";
12270}
12271
florian55085f82012-11-21 00:36:55 +000012272static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012273s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12274{
12275 IRTemp op = newTemp(Ity_F64);
12276
12277 assign(op, load(Ity_F64, mkexpr(op2addr)));
12278 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12279
12280 return "lxdb";
12281}
12282
florian55085f82012-11-21 00:36:55 +000012283static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012284s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12285{
12286 IRTemp op = newTemp(Ity_F32);
12287
12288 assign(op, load(Ity_F32, mkexpr(op2addr)));
12289 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12290
12291 return "lxeb";
12292}
12293
florian55085f82012-11-21 00:36:55 +000012294static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012295s390_irgen_LNEBR(UChar r1, UChar r2)
12296{
12297 IRTemp result = newTemp(Ity_F32);
12298
12299 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12300 put_fpr_w0(r1, mkexpr(result));
12301 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12302
12303 return "lnebr";
12304}
12305
florian55085f82012-11-21 00:36:55 +000012306static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012307s390_irgen_LNDBR(UChar r1, UChar r2)
12308{
12309 IRTemp result = newTemp(Ity_F64);
12310
12311 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12312 put_fpr_dw0(r1, mkexpr(result));
12313 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12314
12315 return "lndbr";
12316}
12317
florian55085f82012-11-21 00:36:55 +000012318static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012319s390_irgen_LNXBR(UChar r1, UChar r2)
12320{
12321 IRTemp result = newTemp(Ity_F128);
12322
12323 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12324 put_fpr_pair(r1, mkexpr(result));
12325 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12326
12327 return "lnxbr";
12328}
12329
florian55085f82012-11-21 00:36:55 +000012330static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012331s390_irgen_LPEBR(UChar r1, UChar r2)
12332{
12333 IRTemp result = newTemp(Ity_F32);
12334
12335 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12336 put_fpr_w0(r1, mkexpr(result));
12337 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12338
12339 return "lpebr";
12340}
12341
florian55085f82012-11-21 00:36:55 +000012342static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012343s390_irgen_LPDBR(UChar r1, UChar r2)
12344{
12345 IRTemp result = newTemp(Ity_F64);
12346
12347 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12348 put_fpr_dw0(r1, mkexpr(result));
12349 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12350
12351 return "lpdbr";
12352}
12353
florian55085f82012-11-21 00:36:55 +000012354static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012355s390_irgen_LPXBR(UChar r1, UChar r2)
12356{
12357 IRTemp result = newTemp(Ity_F128);
12358
12359 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12360 put_fpr_pair(r1, mkexpr(result));
12361 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12362
12363 return "lpxbr";
12364}
12365
florian55085f82012-11-21 00:36:55 +000012366static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012367s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12368 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012369{
florian125e20d2012-10-07 15:42:37 +000012370 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012371 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012372 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012373 }
sewardj2019a972011-03-07 16:04:07 +000012374 IRTemp result = newTemp(Ity_F64);
12375
floriandb4fcaa2012-09-05 19:54:08 +000012376 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012377 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012378 put_fpr_dw0(r1, mkexpr(result));
12379
12380 return "ldxbr";
12381}
12382
florian55085f82012-11-21 00:36:55 +000012383static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012384s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12385 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012386{
florian125e20d2012-10-07 15:42:37 +000012387 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012388 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012389 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012390 }
sewardj2019a972011-03-07 16:04:07 +000012391 IRTemp result = newTemp(Ity_F32);
12392
floriandb4fcaa2012-09-05 19:54:08 +000012393 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012394 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012395 put_fpr_w0(r1, mkexpr(result));
12396
12397 return "lexbr";
12398}
12399
florian55085f82012-11-21 00:36:55 +000012400static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012401s390_irgen_MXBR(UChar r1, UChar r2)
12402{
12403 IRTemp op1 = newTemp(Ity_F128);
12404 IRTemp op2 = newTemp(Ity_F128);
12405 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012406 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012407
12408 assign(op1, get_fpr_pair(r1));
12409 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012410 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012411 mkexpr(op2)));
12412 put_fpr_pair(r1, mkexpr(result));
12413
12414 return "mxbr";
12415}
12416
florian55085f82012-11-21 00:36:55 +000012417static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012418s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12419{
florian125e20d2012-10-07 15:42:37 +000012420 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012421
floriandb4fcaa2012-09-05 19:54:08 +000012422 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012423 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012424
12425 return "maebr";
12426}
12427
florian55085f82012-11-21 00:36:55 +000012428static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012429s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12430{
florian125e20d2012-10-07 15:42:37 +000012431 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012432
floriandb4fcaa2012-09-05 19:54:08 +000012433 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012434 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012435
12436 return "madbr";
12437}
12438
florian55085f82012-11-21 00:36:55 +000012439static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012440s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12441{
12442 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012443 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012444
floriandb4fcaa2012-09-05 19:54:08 +000012445 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012446 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012447
12448 return "maeb";
12449}
12450
florian55085f82012-11-21 00:36:55 +000012451static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012452s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12453{
12454 IRExpr *op2 = load(Ity_F64, 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_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012458 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012459
12460 return "madb";
12461}
12462
florian55085f82012-11-21 00:36:55 +000012463static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012464s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12465{
florian125e20d2012-10-07 15:42:37 +000012466 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012467
floriandb4fcaa2012-09-05 19:54:08 +000012468 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012469 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012470
12471 return "msebr";
12472}
12473
florian55085f82012-11-21 00:36:55 +000012474static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012475s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12476{
florian125e20d2012-10-07 15:42:37 +000012477 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012478
floriandb4fcaa2012-09-05 19:54:08 +000012479 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012480 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012481
12482 return "msdbr";
12483}
12484
florian55085f82012-11-21 00:36:55 +000012485static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012486s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12487{
12488 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012489 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012490
floriandb4fcaa2012-09-05 19:54:08 +000012491 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012492 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012493
12494 return "mseb";
12495}
12496
florian55085f82012-11-21 00:36:55 +000012497static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012498s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12499{
12500 IRExpr *op2 = load(Ity_F64, 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_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012504 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012505
12506 return "msdb";
12507}
12508
florian55085f82012-11-21 00:36:55 +000012509static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012510s390_irgen_SQEBR(UChar r1, UChar r2)
12511{
12512 IRTemp result = newTemp(Ity_F32);
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 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012516 put_fpr_w0(r1, mkexpr(result));
12517
12518 return "sqebr";
12519}
12520
florian55085f82012-11-21 00:36:55 +000012521static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012522s390_irgen_SQDBR(UChar r1, UChar r2)
12523{
12524 IRTemp result = newTemp(Ity_F64);
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_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012528 put_fpr_dw0(r1, mkexpr(result));
12529
12530 return "sqdbr";
12531}
12532
florian55085f82012-11-21 00:36:55 +000012533static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012534s390_irgen_SQXBR(UChar r1, UChar r2)
12535{
12536 IRTemp result = newTemp(Ity_F128);
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_SqrtF128, mkexpr(rounding_mode),
12540 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012541 put_fpr_pair(r1, mkexpr(result));
12542
12543 return "sqxbr";
12544}
12545
florian55085f82012-11-21 00:36:55 +000012546static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012547s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12548{
12549 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012550 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012551
12552 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012553 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012554
12555 return "sqeb";
12556}
12557
florian55085f82012-11-21 00:36:55 +000012558static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012559s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12560{
12561 IRTemp op = newTemp(Ity_F64);
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_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012565 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012566
12567 return "sqdb";
12568}
12569
florian55085f82012-11-21 00:36:55 +000012570static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012571s390_irgen_SXBR(UChar r1, UChar r2)
12572{
12573 IRTemp op1 = newTemp(Ity_F128);
12574 IRTemp op2 = newTemp(Ity_F128);
12575 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012576 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012577
12578 assign(op1, get_fpr_pair(r1));
12579 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012580 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012581 mkexpr(op2)));
12582 put_fpr_pair(r1, mkexpr(result));
12583 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12584
12585 return "sxbr";
12586}
12587
florian55085f82012-11-21 00:36:55 +000012588static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012589s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12590{
12591 IRTemp value = newTemp(Ity_F32);
12592
12593 assign(value, get_fpr_w0(r1));
12594
12595 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12596
12597 return "tceb";
12598}
12599
florian55085f82012-11-21 00:36:55 +000012600static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012601s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12602{
12603 IRTemp value = newTemp(Ity_F64);
12604
12605 assign(value, get_fpr_dw0(r1));
12606
12607 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12608
12609 return "tcdb";
12610}
12611
florian55085f82012-11-21 00:36:55 +000012612static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012613s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12614{
12615 IRTemp value = newTemp(Ity_F128);
12616
12617 assign(value, get_fpr_pair(r1));
12618
12619 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12620
12621 return "tcxb";
12622}
12623
florian55085f82012-11-21 00:36:55 +000012624static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012625s390_irgen_LCDFR(UChar r1, UChar r2)
12626{
12627 IRTemp result = newTemp(Ity_F64);
12628
12629 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12630 put_fpr_dw0(r1, mkexpr(result));
12631
12632 return "lcdfr";
12633}
12634
florian55085f82012-11-21 00:36:55 +000012635static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012636s390_irgen_LNDFR(UChar r1, UChar r2)
12637{
12638 IRTemp result = newTemp(Ity_F64);
12639
12640 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12641 put_fpr_dw0(r1, mkexpr(result));
12642
12643 return "lndfr";
12644}
12645
florian55085f82012-11-21 00:36:55 +000012646static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012647s390_irgen_LPDFR(UChar r1, UChar r2)
12648{
12649 IRTemp result = newTemp(Ity_F64);
12650
12651 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12652 put_fpr_dw0(r1, mkexpr(result));
12653
12654 return "lpdfr";
12655}
12656
florian55085f82012-11-21 00:36:55 +000012657static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012658s390_irgen_LDGR(UChar r1, UChar r2)
12659{
12660 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12661
12662 return "ldgr";
12663}
12664
florian55085f82012-11-21 00:36:55 +000012665static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012666s390_irgen_LGDR(UChar r1, UChar r2)
12667{
12668 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12669
12670 return "lgdr";
12671}
12672
12673
florian55085f82012-11-21 00:36:55 +000012674static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012675s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12676{
12677 IRTemp sign = newTemp(Ity_I64);
12678 IRTemp value = newTemp(Ity_I64);
12679
12680 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12681 mkU64(1ULL << 63)));
12682 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12683 mkU64((1ULL << 63) - 1)));
12684 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12685 mkexpr(sign))));
12686
12687 return "cpsdr";
12688}
12689
12690
sewardj2019a972011-03-07 16:04:07 +000012691static IRExpr *
12692s390_call_cvb(IRExpr *in)
12693{
12694 IRExpr **args, *call;
12695
12696 args = mkIRExprVec_1(in);
12697 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12698 "s390_do_cvb", &s390_do_cvb, args);
12699
12700 /* Nothing is excluded from definedness checking. */
12701 call->Iex.CCall.cee->mcx_mask = 0;
12702
12703 return call;
12704}
12705
florian55085f82012-11-21 00:36:55 +000012706static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012707s390_irgen_CVB(UChar r1, IRTemp op2addr)
12708{
12709 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12710
12711 return "cvb";
12712}
12713
florian55085f82012-11-21 00:36:55 +000012714static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012715s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12716{
12717 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12718
12719 return "cvby";
12720}
12721
12722
sewardj2019a972011-03-07 16:04:07 +000012723static IRExpr *
12724s390_call_cvd(IRExpr *in)
12725{
12726 IRExpr **args, *call;
12727
12728 args = mkIRExprVec_1(in);
12729 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12730 "s390_do_cvd", &s390_do_cvd, args);
12731
12732 /* Nothing is excluded from definedness checking. */
12733 call->Iex.CCall.cee->mcx_mask = 0;
12734
12735 return call;
12736}
12737
florian55085f82012-11-21 00:36:55 +000012738static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012739s390_irgen_CVD(UChar r1, IRTemp op2addr)
12740{
florian11b8ee82012-08-06 13:35:33 +000012741 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012742
12743 return "cvd";
12744}
12745
florian55085f82012-11-21 00:36:55 +000012746static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012747s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12748{
12749 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12750
12751 return "cvdy";
12752}
12753
florian55085f82012-11-21 00:36:55 +000012754static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012755s390_irgen_FLOGR(UChar r1, UChar r2)
12756{
12757 IRTemp input = newTemp(Ity_I64);
12758 IRTemp not_zero = newTemp(Ity_I64);
12759 IRTemp tmpnum = newTemp(Ity_I64);
12760 IRTemp num = newTemp(Ity_I64);
12761 IRTemp shift_amount = newTemp(Ity_I8);
12762
12763 /* We use the "count leading zeroes" operator because the number of
12764 leading zeroes is identical with the bit position of the first '1' bit.
12765 However, that operator does not work when the input value is zero.
12766 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12767 the modified value. If input == 0, then the result is 64. Otherwise,
12768 the result of Clz64 is what we want. */
12769
12770 assign(input, get_gpr_dw0(r2));
12771 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12772 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12773
12774 /* num = (input == 0) ? 64 : tmpnum */
12775 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12776 /* == 0 */ mkU64(64),
12777 /* != 0 */ mkexpr(tmpnum)));
12778
12779 put_gpr_dw0(r1, mkexpr(num));
12780
12781 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12782 is to first shift the input value by NUM + 1 bits to the left which
12783 causes the leftmost '1' bit to disappear. Then we shift logically to
12784 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12785 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12786 the width of the value-to-be-shifted, we need to special case
12787 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12788 For both such INPUT values the result will be 0. */
12789
12790 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12791 mkU64(1))));
12792
12793 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012794 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12795 /* == 0 || == 1*/ mkU64(0),
12796 /* otherwise */
12797 binop(Iop_Shr64,
12798 binop(Iop_Shl64, mkexpr(input),
12799 mkexpr(shift_amount)),
12800 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012801
12802 /* Compare the original value as an unsigned integer with 0. */
12803 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12804 mktemp(Ity_I64, mkU64(0)), False);
12805
12806 return "flogr";
12807}
12808
florian55085f82012-11-21 00:36:55 +000012809static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012810s390_irgen_STCK(IRTemp op2addr)
12811{
12812 IRDirty *d;
12813 IRTemp cc = newTemp(Ity_I64);
12814
12815 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12816 &s390x_dirtyhelper_STCK,
12817 mkIRExprVec_1(mkexpr(op2addr)));
12818 d->mFx = Ifx_Write;
12819 d->mAddr = mkexpr(op2addr);
12820 d->mSize = 8;
12821 stmt(IRStmt_Dirty(d));
12822 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12823 mkexpr(cc), mkU64(0), mkU64(0));
12824 return "stck";
12825}
12826
florian55085f82012-11-21 00:36:55 +000012827static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012828s390_irgen_STCKF(IRTemp op2addr)
12829{
florianc5c669b2012-08-26 14:32:28 +000012830 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012831 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012832 } else {
12833 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012834
florianc5c669b2012-08-26 14:32:28 +000012835 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12836 &s390x_dirtyhelper_STCKF,
12837 mkIRExprVec_1(mkexpr(op2addr)));
12838 d->mFx = Ifx_Write;
12839 d->mAddr = mkexpr(op2addr);
12840 d->mSize = 8;
12841 stmt(IRStmt_Dirty(d));
12842 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12843 mkexpr(cc), mkU64(0), mkU64(0));
12844 }
sewardj1e5fea62011-05-17 16:18:36 +000012845 return "stckf";
12846}
12847
florian55085f82012-11-21 00:36:55 +000012848static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012849s390_irgen_STCKE(IRTemp op2addr)
12850{
12851 IRDirty *d;
12852 IRTemp cc = newTemp(Ity_I64);
12853
12854 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12855 &s390x_dirtyhelper_STCKE,
12856 mkIRExprVec_1(mkexpr(op2addr)));
12857 d->mFx = Ifx_Write;
12858 d->mAddr = mkexpr(op2addr);
12859 d->mSize = 16;
12860 stmt(IRStmt_Dirty(d));
12861 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12862 mkexpr(cc), mkU64(0), mkU64(0));
12863 return "stcke";
12864}
12865
florian55085f82012-11-21 00:36:55 +000012866static const HChar *
florian933065d2011-07-11 01:48:02 +000012867s390_irgen_STFLE(IRTemp op2addr)
12868{
florian4e0083e2012-08-26 03:41:56 +000012869 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012870 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012871 return "stfle";
12872 }
12873
florian933065d2011-07-11 01:48:02 +000012874 IRDirty *d;
12875 IRTemp cc = newTemp(Ity_I64);
12876
12877 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12878 &s390x_dirtyhelper_STFLE,
12879 mkIRExprVec_1(mkexpr(op2addr)));
12880
12881 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
12882
sewardjc9069f22012-06-01 16:09:50 +000012883 d->nFxState = 1;
12884 vex_bzero(&d->fxState, sizeof(d->fxState));
12885
florian933065d2011-07-11 01:48:02 +000012886 d->fxState[0].fx = Ifx_Modify; /* read then write */
12887 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12888 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012889
12890 d->mAddr = mkexpr(op2addr);
12891 /* Pretend all double words are written */
12892 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12893 d->mFx = Ifx_Write;
12894
12895 stmt(IRStmt_Dirty(d));
12896
12897 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12898
12899 return "stfle";
12900}
12901
florian55085f82012-11-21 00:36:55 +000012902static const HChar *
floriana4384a32011-08-11 16:58:45 +000012903s390_irgen_CKSM(UChar r1,UChar r2)
12904{
12905 IRTemp addr = newTemp(Ity_I64);
12906 IRTemp op = newTemp(Ity_I32);
12907 IRTemp len = newTemp(Ity_I64);
12908 IRTemp oldval = newTemp(Ity_I32);
12909 IRTemp mask = newTemp(Ity_I32);
12910 IRTemp newop = newTemp(Ity_I32);
12911 IRTemp result = newTemp(Ity_I32);
12912 IRTemp result1 = newTemp(Ity_I32);
12913 IRTemp inc = newTemp(Ity_I64);
12914
12915 assign(oldval, get_gpr_w1(r1));
12916 assign(addr, get_gpr_dw0(r2));
12917 assign(len, get_gpr_dw0(r2+1));
12918
12919 /* Condition code is always zero. */
12920 s390_cc_set(0);
12921
12922 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012923 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012924
12925 /* Assiging the increment variable to adjust address and length
12926 later on. */
12927 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12928 mkexpr(len), mkU64(4)));
12929
12930 /* If length < 4 the final 4-byte 2nd operand value is computed by
12931 appending the remaining bytes to the right with 0. This is done
12932 by AND'ing the 4 bytes loaded from memory with an appropriate
12933 mask. If length >= 4, that mask is simply 0xffffffff. */
12934
12935 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12936 /* Mask computation when len < 4:
12937 0xffffffff << (32 - (len % 4)*8) */
12938 binop(Iop_Shl32, mkU32(0xffffffff),
12939 unop(Iop_32to8,
12940 binop(Iop_Sub32, mkU32(32),
12941 binop(Iop_Shl32,
12942 unop(Iop_64to32,
12943 binop(Iop_And64,
12944 mkexpr(len), mkU64(3))),
12945 mkU8(3))))),
12946 mkU32(0xffffffff)));
12947
12948 assign(op, load(Ity_I32, mkexpr(addr)));
12949 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12950 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12951
12952 /* Checking for carry */
12953 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12954 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12955 mkexpr(result)));
12956
12957 put_gpr_w1(r1, mkexpr(result1));
12958 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12959 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12960
florian6820ba52012-07-26 02:01:50 +000012961 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012962
12963 return "cksm";
12964}
12965
florian55085f82012-11-21 00:36:55 +000012966static const HChar *
florian9af37692012-01-15 21:01:16 +000012967s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12968{
12969 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12970 src_addr = newTemp(Ity_I64);
12971 des_addr = newTemp(Ity_I64);
12972 tab_addr = newTemp(Ity_I64);
12973 test_byte = newTemp(Ity_I8);
12974 src_len = newTemp(Ity_I64);
12975
12976 assign(src_addr, get_gpr_dw0(r2));
12977 assign(des_addr, get_gpr_dw0(r1));
12978 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012979 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012980 assign(test_byte, get_gpr_b7(0));
12981
12982 IRTemp op = newTemp(Ity_I8);
12983 IRTemp op1 = newTemp(Ity_I8);
12984 IRTemp result = newTemp(Ity_I64);
12985
12986 /* End of source string? We're done; proceed to next insn */
12987 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012988 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012989
12990 /* Load character from source string, index translation table and
12991 store translated character in op1. */
12992 assign(op, load(Ity_I8, mkexpr(src_addr)));
12993
12994 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12995 mkexpr(tab_addr)));
12996 assign(op1, load(Ity_I8, mkexpr(result)));
12997
12998 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12999 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013000 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000013001 }
13002 store(get_gpr_dw0(r1), mkexpr(op1));
13003
13004 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13005 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13006 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13007
florian6820ba52012-07-26 02:01:50 +000013008 iterate();
florian9af37692012-01-15 21:01:16 +000013009
13010 return "troo";
13011}
13012
florian55085f82012-11-21 00:36:55 +000013013static const HChar *
florian730448f2012-02-04 17:07:07 +000013014s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13015{
13016 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13017 src_addr = newTemp(Ity_I64);
13018 des_addr = newTemp(Ity_I64);
13019 tab_addr = newTemp(Ity_I64);
13020 test_byte = newTemp(Ity_I8);
13021 src_len = newTemp(Ity_I64);
13022
13023 assign(src_addr, get_gpr_dw0(r2));
13024 assign(des_addr, get_gpr_dw0(r1));
13025 assign(tab_addr, get_gpr_dw0(1));
13026 assign(src_len, get_gpr_dw0(r1+1));
13027 assign(test_byte, get_gpr_b7(0));
13028
13029 IRTemp op = newTemp(Ity_I16);
13030 IRTemp op1 = newTemp(Ity_I8);
13031 IRTemp result = newTemp(Ity_I64);
13032
13033 /* End of source string? We're done; proceed to next insn */
13034 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013035 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013036
13037 /* Load character from source string, index translation table and
13038 store translated character in op1. */
13039 assign(op, load(Ity_I16, mkexpr(src_addr)));
13040
13041 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13042 mkexpr(tab_addr)));
13043
13044 assign(op1, load(Ity_I8, mkexpr(result)));
13045
13046 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13047 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013048 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013049 }
13050 store(get_gpr_dw0(r1), mkexpr(op1));
13051
13052 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13053 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13054 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13055
florian6820ba52012-07-26 02:01:50 +000013056 iterate();
florian730448f2012-02-04 17:07:07 +000013057
13058 return "trto";
13059}
13060
florian55085f82012-11-21 00:36:55 +000013061static const HChar *
florian730448f2012-02-04 17:07:07 +000013062s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13063{
13064 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13065 src_addr = newTemp(Ity_I64);
13066 des_addr = newTemp(Ity_I64);
13067 tab_addr = newTemp(Ity_I64);
13068 test_byte = newTemp(Ity_I16);
13069 src_len = newTemp(Ity_I64);
13070
13071 assign(src_addr, get_gpr_dw0(r2));
13072 assign(des_addr, get_gpr_dw0(r1));
13073 assign(tab_addr, get_gpr_dw0(1));
13074 assign(src_len, get_gpr_dw0(r1+1));
13075 assign(test_byte, get_gpr_hw3(0));
13076
13077 IRTemp op = newTemp(Ity_I8);
13078 IRTemp op1 = newTemp(Ity_I16);
13079 IRTemp result = newTemp(Ity_I64);
13080
13081 /* End of source string? We're done; proceed to next insn */
13082 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013083 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013084
13085 /* Load character from source string, index translation table and
13086 store translated character in op1. */
13087 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13088
13089 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13090 mkexpr(tab_addr)));
13091 assign(op1, load(Ity_I16, mkexpr(result)));
13092
13093 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13094 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013095 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013096 }
13097 store(get_gpr_dw0(r1), mkexpr(op1));
13098
13099 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13100 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13101 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13102
florian6820ba52012-07-26 02:01:50 +000013103 iterate();
florian730448f2012-02-04 17:07:07 +000013104
13105 return "trot";
13106}
13107
florian55085f82012-11-21 00:36:55 +000013108static const HChar *
florian730448f2012-02-04 17:07:07 +000013109s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13110{
13111 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13112 src_addr = newTemp(Ity_I64);
13113 des_addr = newTemp(Ity_I64);
13114 tab_addr = newTemp(Ity_I64);
13115 test_byte = newTemp(Ity_I16);
13116 src_len = newTemp(Ity_I64);
13117
13118 assign(src_addr, get_gpr_dw0(r2));
13119 assign(des_addr, get_gpr_dw0(r1));
13120 assign(tab_addr, get_gpr_dw0(1));
13121 assign(src_len, get_gpr_dw0(r1+1));
13122 assign(test_byte, get_gpr_hw3(0));
13123
13124 IRTemp op = newTemp(Ity_I16);
13125 IRTemp op1 = newTemp(Ity_I16);
13126 IRTemp result = newTemp(Ity_I64);
13127
13128 /* End of source string? We're done; proceed to next insn */
13129 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013130 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013131
13132 /* Load character from source string, index translation table and
13133 store translated character in op1. */
13134 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13135
13136 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13137 mkexpr(tab_addr)));
13138 assign(op1, load(Ity_I16, mkexpr(result)));
13139
13140 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13141 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013142 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013143 }
13144
13145 store(get_gpr_dw0(r1), mkexpr(op1));
13146
13147 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13148 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13149 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13150
florian6820ba52012-07-26 02:01:50 +000013151 iterate();
florian730448f2012-02-04 17:07:07 +000013152
13153 return "trtt";
13154}
13155
florian55085f82012-11-21 00:36:55 +000013156static const HChar *
florian730448f2012-02-04 17:07:07 +000013157s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13158{
florianf87d4fb2012-05-05 02:55:24 +000013159 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000013160
florianf87d4fb2012-05-05 02:55:24 +000013161 assign(len, mkU64(length));
13162 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000013163
13164 return "tr";
13165}
13166
florian55085f82012-11-21 00:36:55 +000013167static const HChar *
florian730448f2012-02-04 17:07:07 +000013168s390_irgen_TRE(UChar r1,UChar r2)
13169{
13170 IRTemp src_addr, tab_addr, src_len, test_byte;
13171 src_addr = newTemp(Ity_I64);
13172 tab_addr = newTemp(Ity_I64);
13173 src_len = newTemp(Ity_I64);
13174 test_byte = newTemp(Ity_I8);
13175
13176 assign(src_addr, get_gpr_dw0(r1));
13177 assign(src_len, get_gpr_dw0(r1+1));
13178 assign(tab_addr, get_gpr_dw0(r2));
13179 assign(test_byte, get_gpr_b7(0));
13180
13181 IRTemp op = newTemp(Ity_I8);
13182 IRTemp op1 = newTemp(Ity_I8);
13183 IRTemp result = newTemp(Ity_I64);
13184
13185 /* End of source string? We're done; proceed to next insn */
13186 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013187 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013188
13189 /* Load character from source string and compare with test byte */
13190 assign(op, load(Ity_I8, mkexpr(src_addr)));
13191
13192 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013193 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013194
13195 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13196 mkexpr(tab_addr)));
13197
13198 assign(op1, load(Ity_I8, mkexpr(result)));
13199
13200 store(get_gpr_dw0(r1), mkexpr(op1));
13201 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13202 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13203
florian6820ba52012-07-26 02:01:50 +000013204 iterate();
florian730448f2012-02-04 17:07:07 +000013205
13206 return "tre";
13207}
13208
floriana0100c92012-07-20 00:06:35 +000013209static IRExpr *
13210s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13211{
13212 IRExpr **args, *call;
13213 args = mkIRExprVec_2(srcval, low_surrogate);
13214 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13215 "s390_do_cu21", &s390_do_cu21, args);
13216
13217 /* Nothing is excluded from definedness checking. */
13218 call->Iex.CCall.cee->mcx_mask = 0;
13219
13220 return call;
13221}
13222
florian55085f82012-11-21 00:36:55 +000013223static const HChar *
floriana0100c92012-07-20 00:06:35 +000013224s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13225{
13226 IRTemp addr1 = newTemp(Ity_I64);
13227 IRTemp addr2 = newTemp(Ity_I64);
13228 IRTemp len1 = newTemp(Ity_I64);
13229 IRTemp len2 = newTemp(Ity_I64);
13230
13231 assign(addr1, get_gpr_dw0(r1));
13232 assign(addr2, get_gpr_dw0(r2));
13233 assign(len1, get_gpr_dw0(r1 + 1));
13234 assign(len2, get_gpr_dw0(r2 + 1));
13235
13236 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13237 there are less than 2 bytes left, then the 2nd operand is exhausted
13238 and we're done here. cc = 0 */
13239 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013240 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000013241
13242 /* There are at least two bytes there. Read them. */
13243 IRTemp srcval = newTemp(Ity_I32);
13244 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13245
13246 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13247 inside the interval [0xd800 - 0xdbff] */
13248 IRTemp is_high_surrogate = newTemp(Ity_I32);
13249 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13250 mkU32(1), mkU32(0));
13251 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13252 mkU32(1), mkU32(0));
13253 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13254
13255 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13256 then the 2nd operand is exhausted and we're done here. cc = 0 */
13257 IRExpr *not_enough_bytes =
13258 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13259
florian6820ba52012-07-26 02:01:50 +000013260 next_insn_if(binop(Iop_CmpEQ32,
13261 binop(Iop_And32, mkexpr(is_high_surrogate),
13262 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000013263
13264 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13265 surrogate, read the next two bytes (low surrogate). */
13266 IRTemp low_surrogate = newTemp(Ity_I32);
13267 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13268
13269 assign(low_surrogate,
13270 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13271 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13272 mkU32(0))); // any value is fine; it will not be used
13273
13274 /* Call the helper */
13275 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013276 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13277 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000013278
13279 /* Before we can test whether the 1st operand is exhausted we need to
13280 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13281 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13282 IRExpr *invalid_low_surrogate =
13283 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13284
13285 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013286 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000013287 }
13288
13289 /* Now test whether the 1st operand is exhausted */
13290 IRTemp num_bytes = newTemp(Ity_I64);
13291 assign(num_bytes, binop(Iop_And64,
13292 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13293 mkU64(0xff)));
13294 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013295 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000013296
13297 /* Extract the bytes to be stored at addr1 */
13298 IRTemp data = newTemp(Ity_I64);
13299 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13300
13301 /* To store the bytes construct 4 dirty helper calls. The helper calls
13302 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13303 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013304 UInt i;
floriana0100c92012-07-20 00:06:35 +000013305 for (i = 1; i <= 4; ++i) {
13306 IRDirty *d;
13307
13308 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13309 &s390x_dirtyhelper_CUxy,
13310 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13311 mkexpr(num_bytes)));
13312 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13313 d->mFx = Ifx_Write;
13314 d->mAddr = mkexpr(addr1);
13315 d->mSize = i;
13316 stmt(IRStmt_Dirty(d));
13317 }
13318
13319 /* Update source address and length */
13320 IRTemp num_src_bytes = newTemp(Ity_I64);
13321 assign(num_src_bytes,
13322 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13323 mkU64(4), mkU64(2)));
13324 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13325 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13326
13327 /* Update destination address and length */
13328 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13329 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13330
florian6820ba52012-07-26 02:01:50 +000013331 iterate();
floriana0100c92012-07-20 00:06:35 +000013332
13333 return "cu21";
13334}
13335
florian2a415a12012-07-21 17:41:36 +000013336static IRExpr *
13337s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13338{
13339 IRExpr **args, *call;
13340 args = mkIRExprVec_2(srcval, low_surrogate);
13341 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13342 "s390_do_cu24", &s390_do_cu24, args);
13343
13344 /* Nothing is excluded from definedness checking. */
13345 call->Iex.CCall.cee->mcx_mask = 0;
13346
13347 return call;
13348}
13349
florian55085f82012-11-21 00:36:55 +000013350static const HChar *
florian2a415a12012-07-21 17:41:36 +000013351s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13352{
13353 IRTemp addr1 = newTemp(Ity_I64);
13354 IRTemp addr2 = newTemp(Ity_I64);
13355 IRTemp len1 = newTemp(Ity_I64);
13356 IRTemp len2 = newTemp(Ity_I64);
13357
13358 assign(addr1, get_gpr_dw0(r1));
13359 assign(addr2, get_gpr_dw0(r2));
13360 assign(len1, get_gpr_dw0(r1 + 1));
13361 assign(len2, get_gpr_dw0(r2 + 1));
13362
13363 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13364 there are less than 2 bytes left, then the 2nd operand is exhausted
13365 and we're done here. cc = 0 */
13366 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013367 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013368
13369 /* There are at least two bytes there. Read them. */
13370 IRTemp srcval = newTemp(Ity_I32);
13371 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13372
13373 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13374 inside the interval [0xd800 - 0xdbff] */
13375 IRTemp is_high_surrogate = newTemp(Ity_I32);
13376 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13377 mkU32(1), mkU32(0));
13378 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13379 mkU32(1), mkU32(0));
13380 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13381
13382 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13383 then the 2nd operand is exhausted and we're done here. cc = 0 */
13384 IRExpr *not_enough_bytes =
13385 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13386
florian6820ba52012-07-26 02:01:50 +000013387 next_insn_if(binop(Iop_CmpEQ32,
13388 binop(Iop_And32, mkexpr(is_high_surrogate),
13389 not_enough_bytes),
13390 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013391
13392 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13393 surrogate, read the next two bytes (low surrogate). */
13394 IRTemp low_surrogate = newTemp(Ity_I32);
13395 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13396
13397 assign(low_surrogate,
13398 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13399 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13400 mkU32(0))); // any value is fine; it will not be used
13401
13402 /* Call the helper */
13403 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013404 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13405 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013406
13407 /* Before we can test whether the 1st operand is exhausted we need to
13408 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13409 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13410 IRExpr *invalid_low_surrogate =
13411 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13412
13413 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013414 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013415 }
13416
13417 /* Now test whether the 1st operand is exhausted */
13418 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013419 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013420
13421 /* Extract the bytes to be stored at addr1 */
13422 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13423
13424 store(mkexpr(addr1), data);
13425
13426 /* Update source address and length */
13427 IRTemp num_src_bytes = newTemp(Ity_I64);
13428 assign(num_src_bytes,
13429 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13430 mkU64(4), mkU64(2)));
13431 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13432 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13433
13434 /* Update destination address and length */
13435 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13436 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13437
florian6820ba52012-07-26 02:01:50 +000013438 iterate();
florian2a415a12012-07-21 17:41:36 +000013439
13440 return "cu24";
13441}
floriana4384a32011-08-11 16:58:45 +000013442
florian956194b2012-07-28 22:18:32 +000013443static IRExpr *
13444s390_call_cu42(IRExpr *srcval)
13445{
13446 IRExpr **args, *call;
13447 args = mkIRExprVec_1(srcval);
13448 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13449 "s390_do_cu42", &s390_do_cu42, args);
13450
13451 /* Nothing is excluded from definedness checking. */
13452 call->Iex.CCall.cee->mcx_mask = 0;
13453
13454 return call;
13455}
13456
florian55085f82012-11-21 00:36:55 +000013457static const HChar *
florian956194b2012-07-28 22:18:32 +000013458s390_irgen_CU42(UChar r1, UChar r2)
13459{
13460 IRTemp addr1 = newTemp(Ity_I64);
13461 IRTemp addr2 = newTemp(Ity_I64);
13462 IRTemp len1 = newTemp(Ity_I64);
13463 IRTemp len2 = newTemp(Ity_I64);
13464
13465 assign(addr1, get_gpr_dw0(r1));
13466 assign(addr2, get_gpr_dw0(r2));
13467 assign(len1, get_gpr_dw0(r1 + 1));
13468 assign(len2, get_gpr_dw0(r2 + 1));
13469
13470 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13471 there are less than 4 bytes left, then the 2nd operand is exhausted
13472 and we're done here. cc = 0 */
13473 s390_cc_set(0);
13474 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13475
13476 /* Read the 2nd operand. */
13477 IRTemp srcval = newTemp(Ity_I32);
13478 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13479
13480 /* Call the helper */
13481 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013482 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013483
13484 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13485 cc=2 outranks cc=1 (1st operand exhausted) */
13486 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13487
13488 s390_cc_set(2);
13489 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13490
13491 /* Now test whether the 1st operand is exhausted */
13492 IRTemp num_bytes = newTemp(Ity_I64);
13493 assign(num_bytes, binop(Iop_And64,
13494 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13495 mkU64(0xff)));
13496 s390_cc_set(1);
13497 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13498
13499 /* Extract the bytes to be stored at addr1 */
13500 IRTemp data = newTemp(Ity_I64);
13501 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13502
13503 /* To store the bytes construct 2 dirty helper calls. The helper calls
13504 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13505 that only one of them will be called at runtime. */
13506
13507 Int i;
13508 for (i = 2; i <= 4; ++i) {
13509 IRDirty *d;
13510
13511 if (i == 3) continue; // skip this one
13512
13513 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13514 &s390x_dirtyhelper_CUxy,
13515 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13516 mkexpr(num_bytes)));
13517 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13518 d->mFx = Ifx_Write;
13519 d->mAddr = mkexpr(addr1);
13520 d->mSize = i;
13521 stmt(IRStmt_Dirty(d));
13522 }
13523
13524 /* Update source address and length */
13525 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13526 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13527
13528 /* Update destination address and length */
13529 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13530 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13531
13532 iterate();
13533
13534 return "cu42";
13535}
13536
florian6d9b9b22012-08-03 18:35:39 +000013537static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013538s390_call_cu41(IRExpr *srcval)
13539{
13540 IRExpr **args, *call;
13541 args = mkIRExprVec_1(srcval);
13542 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13543 "s390_do_cu41", &s390_do_cu41, args);
13544
13545 /* Nothing is excluded from definedness checking. */
13546 call->Iex.CCall.cee->mcx_mask = 0;
13547
13548 return call;
13549}
13550
florian55085f82012-11-21 00:36:55 +000013551static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013552s390_irgen_CU41(UChar r1, UChar r2)
13553{
13554 IRTemp addr1 = newTemp(Ity_I64);
13555 IRTemp addr2 = newTemp(Ity_I64);
13556 IRTemp len1 = newTemp(Ity_I64);
13557 IRTemp len2 = newTemp(Ity_I64);
13558
13559 assign(addr1, get_gpr_dw0(r1));
13560 assign(addr2, get_gpr_dw0(r2));
13561 assign(len1, get_gpr_dw0(r1 + 1));
13562 assign(len2, get_gpr_dw0(r2 + 1));
13563
13564 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13565 there are less than 4 bytes left, then the 2nd operand is exhausted
13566 and we're done here. cc = 0 */
13567 s390_cc_set(0);
13568 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13569
13570 /* Read the 2nd operand. */
13571 IRTemp srcval = newTemp(Ity_I32);
13572 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13573
13574 /* Call the helper */
13575 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013576 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013577
13578 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13579 cc=2 outranks cc=1 (1st operand exhausted) */
13580 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13581
13582 s390_cc_set(2);
13583 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13584
13585 /* Now test whether the 1st operand is exhausted */
13586 IRTemp num_bytes = newTemp(Ity_I64);
13587 assign(num_bytes, binop(Iop_And64,
13588 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13589 mkU64(0xff)));
13590 s390_cc_set(1);
13591 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13592
13593 /* Extract the bytes to be stored at addr1 */
13594 IRTemp data = newTemp(Ity_I64);
13595 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13596
13597 /* To store the bytes construct 4 dirty helper calls. The helper calls
13598 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13599 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013600 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013601 for (i = 1; i <= 4; ++i) {
13602 IRDirty *d;
13603
13604 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13605 &s390x_dirtyhelper_CUxy,
13606 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13607 mkexpr(num_bytes)));
13608 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13609 d->mFx = Ifx_Write;
13610 d->mAddr = mkexpr(addr1);
13611 d->mSize = i;
13612 stmt(IRStmt_Dirty(d));
13613 }
13614
13615 /* Update source address and length */
13616 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13617 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13618
13619 /* Update destination address and length */
13620 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13621 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13622
13623 iterate();
13624
13625 return "cu41";
13626}
13627
13628static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013629s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013630{
13631 IRExpr **args, *call;
13632 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013633 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13634 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013635
13636 /* Nothing is excluded from definedness checking. */
13637 call->Iex.CCall.cee->mcx_mask = 0;
13638
13639 return call;
13640}
13641
13642static IRExpr *
13643s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13644 IRExpr *byte4, IRExpr *stuff)
13645{
13646 IRExpr **args, *call;
13647 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13648 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13649 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13650
13651 /* Nothing is excluded from definedness checking. */
13652 call->Iex.CCall.cee->mcx_mask = 0;
13653
13654 return call;
13655}
13656
florian3f8a96a2012-08-05 02:59:55 +000013657static IRExpr *
13658s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13659 IRExpr *byte4, IRExpr *stuff)
13660{
13661 IRExpr **args, *call;
13662 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13663 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13664 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13665
13666 /* Nothing is excluded from definedness checking. */
13667 call->Iex.CCall.cee->mcx_mask = 0;
13668
13669 return call;
13670}
13671
13672static void
13673s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013674{
13675 IRTemp addr1 = newTemp(Ity_I64);
13676 IRTemp addr2 = newTemp(Ity_I64);
13677 IRTemp len1 = newTemp(Ity_I64);
13678 IRTemp len2 = newTemp(Ity_I64);
13679
13680 assign(addr1, get_gpr_dw0(r1));
13681 assign(addr2, get_gpr_dw0(r2));
13682 assign(len1, get_gpr_dw0(r1 + 1));
13683 assign(len2, get_gpr_dw0(r2 + 1));
13684
13685 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13686
13687 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13688 there is less than 1 byte left, then the 2nd operand is exhausted
13689 and we're done here. cc = 0 */
13690 s390_cc_set(0);
13691 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13692
13693 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013694 IRTemp byte1 = newTemp(Ity_I64);
13695 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013696
13697 /* Call the helper to get number of bytes and invalid byte indicator */
13698 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013699 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013700 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013701
13702 /* Check for invalid 1st byte */
13703 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13704 s390_cc_set(2);
13705 next_insn_if(is_invalid);
13706
13707 /* How many bytes do we have to read? */
13708 IRTemp num_src_bytes = newTemp(Ity_I64);
13709 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13710
13711 /* Now test whether the 2nd operand is exhausted */
13712 s390_cc_set(0);
13713 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13714
13715 /* Read the remaining bytes */
13716 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13717
13718 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13719 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013720 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013721 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13722 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013723 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013724 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13725 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013726 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013727
13728 /* Call the helper to get the converted value and invalid byte indicator.
13729 We can pass at most 5 arguments; therefore some encoding is needed
13730 here */
13731 IRExpr *stuff = binop(Iop_Or64,
13732 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13733 mkU64(extended_checking));
13734 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013735
13736 if (is_cu12) {
13737 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13738 byte4, stuff));
13739 } else {
13740 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13741 byte4, stuff));
13742 }
florian6d9b9b22012-08-03 18:35:39 +000013743
13744 /* Check for invalid character */
13745 s390_cc_set(2);
13746 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13747 next_insn_if(is_invalid);
13748
13749 /* Now test whether the 1st operand is exhausted */
13750 IRTemp num_bytes = newTemp(Ity_I64);
13751 assign(num_bytes, binop(Iop_And64,
13752 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13753 mkU64(0xff)));
13754 s390_cc_set(1);
13755 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13756
13757 /* Extract the bytes to be stored at addr1 */
13758 IRTemp data = newTemp(Ity_I64);
13759 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13760
florian3f8a96a2012-08-05 02:59:55 +000013761 if (is_cu12) {
13762 /* To store the bytes construct 2 dirty helper calls. The helper calls
13763 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13764 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013765
florian3f8a96a2012-08-05 02:59:55 +000013766 Int i;
13767 for (i = 2; i <= 4; ++i) {
13768 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013769
florian3f8a96a2012-08-05 02:59:55 +000013770 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013771
florian3f8a96a2012-08-05 02:59:55 +000013772 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13773 &s390x_dirtyhelper_CUxy,
13774 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13775 mkexpr(num_bytes)));
13776 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13777 d->mFx = Ifx_Write;
13778 d->mAddr = mkexpr(addr1);
13779 d->mSize = i;
13780 stmt(IRStmt_Dirty(d));
13781 }
13782 } else {
13783 // cu14
13784 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013785 }
13786
13787 /* Update source address and length */
13788 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13789 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13790
13791 /* Update destination address and length */
13792 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13793 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13794
13795 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013796}
13797
florian55085f82012-11-21 00:36:55 +000013798static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013799s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13800{
13801 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013802
13803 return "cu12";
13804}
13805
florian55085f82012-11-21 00:36:55 +000013806static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013807s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13808{
13809 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13810
13811 return "cu14";
13812}
13813
florian8c88cb62012-08-26 18:58:13 +000013814static IRExpr *
13815s390_call_ecag(IRExpr *op2addr)
13816{
13817 IRExpr **args, *call;
13818
13819 args = mkIRExprVec_1(op2addr);
13820 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13821 "s390_do_ecag", &s390_do_ecag, args);
13822
13823 /* Nothing is excluded from definedness checking. */
13824 call->Iex.CCall.cee->mcx_mask = 0;
13825
13826 return call;
13827}
13828
florian55085f82012-11-21 00:36:55 +000013829static const HChar *
floriand2129202012-09-01 20:01:39 +000013830s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013831{
13832 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013833 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013834 } else {
13835 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13836 }
13837
13838 return "ecag";
13839}
13840
13841
florianb7def222012-12-04 04:45:32 +000013842/* New insns are added here.
13843 If an insn is contingent on a facility being installed also
13844 check whether the list of supported facilities in function
13845 s390x_dirtyhelper_STFLE needs updating */
13846
sewardj2019a972011-03-07 16:04:07 +000013847/*------------------------------------------------------------*/
13848/*--- Build IR for special instructions ---*/
13849/*------------------------------------------------------------*/
13850
florianb4df7682011-07-05 02:09:01 +000013851static void
sewardj2019a972011-03-07 16:04:07 +000013852s390_irgen_client_request(void)
13853{
13854 if (0)
13855 vex_printf("%%R3 = client_request ( %%R2 )\n");
13856
florianf9e1ed72012-04-17 02:41:56 +000013857 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13858 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013859
florianf9e1ed72012-04-17 02:41:56 +000013860 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013861 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013862
13863 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013864}
13865
florianb4df7682011-07-05 02:09:01 +000013866static void
sewardj2019a972011-03-07 16:04:07 +000013867s390_irgen_guest_NRADDR(void)
13868{
13869 if (0)
13870 vex_printf("%%R3 = guest_NRADDR\n");
13871
floriane88b3c92011-07-05 02:48:39 +000013872 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013873}
13874
florianb4df7682011-07-05 02:09:01 +000013875static void
sewardj2019a972011-03-07 16:04:07 +000013876s390_irgen_call_noredir(void)
13877{
florianf9e1ed72012-04-17 02:41:56 +000013878 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13879 + S390_SPECIAL_OP_SIZE;
13880
sewardj2019a972011-03-07 16:04:07 +000013881 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013882 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013883
13884 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013885 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013886
13887 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013888 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013889}
13890
13891/* Force proper alignment for the structures below. */
13892#pragma pack(1)
13893
13894
13895static s390_decode_t
13896s390_decode_2byte_and_irgen(UChar *bytes)
13897{
13898 typedef union {
13899 struct {
13900 unsigned int op : 16;
13901 } E;
13902 struct {
13903 unsigned int op : 8;
13904 unsigned int i : 8;
13905 } I;
13906 struct {
13907 unsigned int op : 8;
13908 unsigned int r1 : 4;
13909 unsigned int r2 : 4;
13910 } RR;
13911 } formats;
13912 union {
13913 formats fmt;
13914 UShort value;
13915 } ovl;
13916
13917 vassert(sizeof(formats) == 2);
13918
florianffbd84d2012-12-09 02:06:29 +000013919 ((UChar *)(&ovl.value))[0] = bytes[0];
13920 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013921
13922 switch (ovl.value & 0xffff) {
13923 case 0x0101: /* PR */ goto unimplemented;
13924 case 0x0102: /* UPT */ goto unimplemented;
13925 case 0x0104: /* PTFF */ goto unimplemented;
13926 case 0x0107: /* SCKPF */ goto unimplemented;
florian78d5ef72013-05-11 15:02:58 +000013927 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013928 case 0x010b: /* TAM */ goto unimplemented;
13929 case 0x010c: /* SAM24 */ goto unimplemented;
13930 case 0x010d: /* SAM31 */ goto unimplemented;
13931 case 0x010e: /* SAM64 */ goto unimplemented;
13932 case 0x01ff: /* TRAP2 */ goto unimplemented;
13933 }
13934
13935 switch ((ovl.value & 0xff00) >> 8) {
13936 case 0x04: /* SPM */ goto unimplemented;
13937 case 0x05: /* BALR */ goto unimplemented;
13938 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13939 goto ok;
13940 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13941 goto ok;
13942 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13943 case 0x0b: /* BSM */ goto unimplemented;
13944 case 0x0c: /* BASSM */ goto unimplemented;
13945 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13946 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013947 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13948 goto ok;
13949 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13950 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013951 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13952 goto ok;
13953 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13954 goto ok;
13955 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13956 goto ok;
13957 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13958 goto ok;
13959 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13960 goto ok;
13961 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13962 goto ok;
13963 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13964 goto ok;
13965 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13966 goto ok;
13967 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13968 goto ok;
13969 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13970 goto ok;
13971 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13972 goto ok;
13973 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13974 goto ok;
13975 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13976 goto ok;
13977 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13978 goto ok;
13979 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13980 goto ok;
13981 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13982 goto ok;
13983 case 0x20: /* LPDR */ goto unimplemented;
13984 case 0x21: /* LNDR */ goto unimplemented;
13985 case 0x22: /* LTDR */ goto unimplemented;
13986 case 0x23: /* LCDR */ goto unimplemented;
13987 case 0x24: /* HDR */ goto unimplemented;
13988 case 0x25: /* LDXR */ goto unimplemented;
13989 case 0x26: /* MXR */ goto unimplemented;
13990 case 0x27: /* MXDR */ goto unimplemented;
13991 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13992 goto ok;
13993 case 0x29: /* CDR */ goto unimplemented;
13994 case 0x2a: /* ADR */ goto unimplemented;
13995 case 0x2b: /* SDR */ goto unimplemented;
13996 case 0x2c: /* MDR */ goto unimplemented;
13997 case 0x2d: /* DDR */ goto unimplemented;
13998 case 0x2e: /* AWR */ goto unimplemented;
13999 case 0x2f: /* SWR */ goto unimplemented;
14000 case 0x30: /* LPER */ goto unimplemented;
14001 case 0x31: /* LNER */ goto unimplemented;
14002 case 0x32: /* LTER */ goto unimplemented;
14003 case 0x33: /* LCER */ goto unimplemented;
14004 case 0x34: /* HER */ goto unimplemented;
14005 case 0x35: /* LEDR */ goto unimplemented;
14006 case 0x36: /* AXR */ goto unimplemented;
14007 case 0x37: /* SXR */ goto unimplemented;
14008 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14009 goto ok;
14010 case 0x39: /* CER */ goto unimplemented;
14011 case 0x3a: /* AER */ goto unimplemented;
14012 case 0x3b: /* SER */ goto unimplemented;
14013 case 0x3c: /* MDER */ goto unimplemented;
14014 case 0x3d: /* DER */ goto unimplemented;
14015 case 0x3e: /* AUR */ goto unimplemented;
14016 case 0x3f: /* SUR */ goto unimplemented;
14017 }
14018
14019 return S390_DECODE_UNKNOWN_INSN;
14020
14021ok:
14022 return S390_DECODE_OK;
14023
14024unimplemented:
14025 return S390_DECODE_UNIMPLEMENTED_INSN;
14026}
14027
14028static s390_decode_t
14029s390_decode_4byte_and_irgen(UChar *bytes)
14030{
14031 typedef union {
14032 struct {
14033 unsigned int op1 : 8;
14034 unsigned int r1 : 4;
14035 unsigned int op2 : 4;
14036 unsigned int i2 : 16;
14037 } RI;
14038 struct {
14039 unsigned int op : 16;
14040 unsigned int : 8;
14041 unsigned int r1 : 4;
14042 unsigned int r2 : 4;
14043 } RRE;
14044 struct {
14045 unsigned int op : 16;
14046 unsigned int r1 : 4;
14047 unsigned int : 4;
14048 unsigned int r3 : 4;
14049 unsigned int r2 : 4;
14050 } RRF;
14051 struct {
14052 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000014053 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000014054 unsigned int m4 : 4;
14055 unsigned int r1 : 4;
14056 unsigned int r2 : 4;
14057 } RRF2;
14058 struct {
14059 unsigned int op : 16;
14060 unsigned int r3 : 4;
14061 unsigned int : 4;
14062 unsigned int r1 : 4;
14063 unsigned int r2 : 4;
14064 } RRF3;
14065 struct {
14066 unsigned int op : 16;
14067 unsigned int r3 : 4;
14068 unsigned int : 4;
14069 unsigned int r1 : 4;
14070 unsigned int r2 : 4;
14071 } RRR;
14072 struct {
14073 unsigned int op : 16;
14074 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000014075 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000014076 unsigned int r1 : 4;
14077 unsigned int r2 : 4;
14078 } RRF4;
14079 struct {
floriane38f6412012-12-21 17:32:12 +000014080 unsigned int op : 16;
14081 unsigned int : 4;
14082 unsigned int m4 : 4;
14083 unsigned int r1 : 4;
14084 unsigned int r2 : 4;
14085 } RRF5;
14086 struct {
sewardj2019a972011-03-07 16:04:07 +000014087 unsigned int op : 8;
14088 unsigned int r1 : 4;
14089 unsigned int r3 : 4;
14090 unsigned int b2 : 4;
14091 unsigned int d2 : 12;
14092 } RS;
14093 struct {
14094 unsigned int op : 8;
14095 unsigned int r1 : 4;
14096 unsigned int r3 : 4;
14097 unsigned int i2 : 16;
14098 } RSI;
14099 struct {
14100 unsigned int op : 8;
14101 unsigned int r1 : 4;
14102 unsigned int x2 : 4;
14103 unsigned int b2 : 4;
14104 unsigned int d2 : 12;
14105 } RX;
14106 struct {
14107 unsigned int op : 16;
14108 unsigned int b2 : 4;
14109 unsigned int d2 : 12;
14110 } S;
14111 struct {
14112 unsigned int op : 8;
14113 unsigned int i2 : 8;
14114 unsigned int b1 : 4;
14115 unsigned int d1 : 12;
14116 } SI;
14117 } formats;
14118 union {
14119 formats fmt;
14120 UInt value;
14121 } ovl;
14122
14123 vassert(sizeof(formats) == 4);
14124
florianffbd84d2012-12-09 02:06:29 +000014125 ((UChar *)(&ovl.value))[0] = bytes[0];
14126 ((UChar *)(&ovl.value))[1] = bytes[1];
14127 ((UChar *)(&ovl.value))[2] = bytes[2];
14128 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000014129
14130 switch ((ovl.value & 0xff0f0000) >> 16) {
14131 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14132 ovl.fmt.RI.i2); goto ok;
14133 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14134 ovl.fmt.RI.i2); goto ok;
14135 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14136 ovl.fmt.RI.i2); goto ok;
14137 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14138 ovl.fmt.RI.i2); goto ok;
14139 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14140 ovl.fmt.RI.i2); goto ok;
14141 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14142 ovl.fmt.RI.i2); goto ok;
14143 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14144 ovl.fmt.RI.i2); goto ok;
14145 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14146 ovl.fmt.RI.i2); goto ok;
14147 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14148 ovl.fmt.RI.i2); goto ok;
14149 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14150 ovl.fmt.RI.i2); goto ok;
14151 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14152 ovl.fmt.RI.i2); goto ok;
14153 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14154 ovl.fmt.RI.i2); goto ok;
14155 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14156 ovl.fmt.RI.i2); goto ok;
14157 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14158 ovl.fmt.RI.i2); goto ok;
14159 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14160 ovl.fmt.RI.i2); goto ok;
14161 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14162 ovl.fmt.RI.i2); goto ok;
14163 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14164 ovl.fmt.RI.i2); goto ok;
14165 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14166 ovl.fmt.RI.i2); goto ok;
14167 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14168 ovl.fmt.RI.i2); goto ok;
14169 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14170 ovl.fmt.RI.i2); goto ok;
14171 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14172 goto ok;
14173 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14174 ovl.fmt.RI.i2); goto ok;
14175 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14176 ovl.fmt.RI.i2); goto ok;
14177 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14178 ovl.fmt.RI.i2); goto ok;
14179 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14180 goto ok;
14181 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14182 ovl.fmt.RI.i2); goto ok;
14183 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14184 goto ok;
14185 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14186 ovl.fmt.RI.i2); goto ok;
14187 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14188 goto ok;
14189 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14190 ovl.fmt.RI.i2); goto ok;
14191 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14192 goto ok;
14193 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14194 ovl.fmt.RI.i2); goto ok;
14195 }
14196
14197 switch ((ovl.value & 0xffff0000) >> 16) {
14198 case 0x8000: /* SSM */ goto unimplemented;
14199 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014200 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014201 case 0xb202: /* STIDP */ goto unimplemented;
14202 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014203 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14204 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014205 case 0xb206: /* SCKC */ goto unimplemented;
14206 case 0xb207: /* STCKC */ goto unimplemented;
14207 case 0xb208: /* SPT */ goto unimplemented;
14208 case 0xb209: /* STPT */ goto unimplemented;
14209 case 0xb20a: /* SPKA */ goto unimplemented;
14210 case 0xb20b: /* IPK */ goto unimplemented;
14211 case 0xb20d: /* PTLB */ goto unimplemented;
14212 case 0xb210: /* SPX */ goto unimplemented;
14213 case 0xb211: /* STPX */ goto unimplemented;
14214 case 0xb212: /* STAP */ goto unimplemented;
14215 case 0xb214: /* SIE */ goto unimplemented;
14216 case 0xb218: /* PC */ goto unimplemented;
14217 case 0xb219: /* SAC */ goto unimplemented;
14218 case 0xb21a: /* CFC */ goto unimplemented;
14219 case 0xb221: /* IPTE */ goto unimplemented;
14220 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
14221 case 0xb223: /* IVSK */ goto unimplemented;
14222 case 0xb224: /* IAC */ goto unimplemented;
14223 case 0xb225: /* SSAR */ goto unimplemented;
14224 case 0xb226: /* EPAR */ goto unimplemented;
14225 case 0xb227: /* ESAR */ goto unimplemented;
14226 case 0xb228: /* PT */ goto unimplemented;
14227 case 0xb229: /* ISKE */ goto unimplemented;
14228 case 0xb22a: /* RRBE */ goto unimplemented;
14229 case 0xb22b: /* SSKE */ goto unimplemented;
14230 case 0xb22c: /* TB */ goto unimplemented;
14231 case 0xb22d: /* DXR */ goto unimplemented;
14232 case 0xb22e: /* PGIN */ goto unimplemented;
14233 case 0xb22f: /* PGOUT */ goto unimplemented;
14234 case 0xb230: /* CSCH */ goto unimplemented;
14235 case 0xb231: /* HSCH */ goto unimplemented;
14236 case 0xb232: /* MSCH */ goto unimplemented;
14237 case 0xb233: /* SSCH */ goto unimplemented;
14238 case 0xb234: /* STSCH */ goto unimplemented;
14239 case 0xb235: /* TSCH */ goto unimplemented;
14240 case 0xb236: /* TPI */ goto unimplemented;
14241 case 0xb237: /* SAL */ goto unimplemented;
14242 case 0xb238: /* RSCH */ goto unimplemented;
14243 case 0xb239: /* STCRW */ goto unimplemented;
14244 case 0xb23a: /* STCPS */ goto unimplemented;
14245 case 0xb23b: /* RCHP */ goto unimplemented;
14246 case 0xb23c: /* SCHM */ goto unimplemented;
14247 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000014248 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14249 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014250 case 0xb244: /* SQDR */ goto unimplemented;
14251 case 0xb245: /* SQER */ goto unimplemented;
14252 case 0xb246: /* STURA */ goto unimplemented;
14253 case 0xb247: /* MSTA */ goto unimplemented;
14254 case 0xb248: /* PALB */ goto unimplemented;
14255 case 0xb249: /* EREG */ goto unimplemented;
14256 case 0xb24a: /* ESTA */ goto unimplemented;
14257 case 0xb24b: /* LURA */ goto unimplemented;
14258 case 0xb24c: /* TAR */ goto unimplemented;
14259 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14260 ovl.fmt.RRE.r2); goto ok;
14261 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14262 goto ok;
14263 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14264 goto ok;
14265 case 0xb250: /* CSP */ goto unimplemented;
14266 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14267 ovl.fmt.RRE.r2); goto ok;
14268 case 0xb254: /* MVPG */ goto unimplemented;
14269 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14270 ovl.fmt.RRE.r2); goto ok;
14271 case 0xb257: /* CUSE */ goto unimplemented;
14272 case 0xb258: /* BSG */ goto unimplemented;
14273 case 0xb25a: /* BSA */ goto unimplemented;
14274 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14275 ovl.fmt.RRE.r2); goto ok;
14276 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14277 ovl.fmt.RRE.r2); goto ok;
14278 case 0xb263: /* CMPSC */ goto unimplemented;
14279 case 0xb274: /* SIGA */ goto unimplemented;
14280 case 0xb276: /* XSCH */ goto unimplemented;
14281 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014282 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 +000014283 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014284 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 +000014285 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014286 case 0xb280: /* LPP */ goto unimplemented;
14287 case 0xb284: /* LCCTL */ goto unimplemented;
14288 case 0xb285: /* LPCTL */ goto unimplemented;
14289 case 0xb286: /* QSI */ goto unimplemented;
14290 case 0xb287: /* LSCTL */ goto unimplemented;
14291 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014292 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14293 goto ok;
14294 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14295 goto ok;
14296 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14297 goto ok;
florian730448f2012-02-04 17:07:07 +000014298 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 +000014299 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14300 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14301 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000014302 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14303 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14304 goto ok;
florian933065d2011-07-11 01:48:02 +000014305 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14306 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014307 case 0xb2b1: /* STFL */ goto unimplemented;
14308 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000014309 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14310 goto ok;
florian82cdba62013-03-12 01:31:24 +000014311 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14312 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014313 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014314 case 0xb2e0: /* SCCTR */ goto unimplemented;
14315 case 0xb2e1: /* SPCTR */ goto unimplemented;
14316 case 0xb2e4: /* ECCTR */ goto unimplemented;
14317 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014318 case 0xb2e8: /* PPA */ goto unimplemented;
14319 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014320 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014321 case 0xb2f8: /* TEND */ goto unimplemented;
14322 case 0xb2fa: /* NIAI */ goto unimplemented;
14323 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014324 case 0xb2ff: /* TRAP4 */ goto unimplemented;
14325 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14326 ovl.fmt.RRE.r2); goto ok;
14327 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14328 ovl.fmt.RRE.r2); goto ok;
14329 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14330 ovl.fmt.RRE.r2); goto ok;
14331 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14332 ovl.fmt.RRE.r2); goto ok;
14333 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14334 ovl.fmt.RRE.r2); goto ok;
14335 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14336 ovl.fmt.RRE.r2); goto ok;
14337 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14338 ovl.fmt.RRE.r2); goto ok;
14339 case 0xb307: /* MXDBR */ goto unimplemented;
14340 case 0xb308: /* KEBR */ goto unimplemented;
14341 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14342 ovl.fmt.RRE.r2); goto ok;
14343 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14344 ovl.fmt.RRE.r2); goto ok;
14345 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14346 ovl.fmt.RRE.r2); goto ok;
14347 case 0xb30c: /* MDEBR */ goto unimplemented;
14348 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14349 ovl.fmt.RRE.r2); goto ok;
14350 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14351 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14352 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14353 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14354 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14355 ovl.fmt.RRE.r2); goto ok;
14356 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14357 ovl.fmt.RRE.r2); goto ok;
14358 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14359 ovl.fmt.RRE.r2); goto ok;
14360 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14361 ovl.fmt.RRE.r2); goto ok;
14362 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14363 ovl.fmt.RRE.r2); goto ok;
14364 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14365 ovl.fmt.RRE.r2); goto ok;
14366 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14367 ovl.fmt.RRE.r2); goto ok;
14368 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14369 ovl.fmt.RRE.r2); goto ok;
14370 case 0xb318: /* KDBR */ goto unimplemented;
14371 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14372 ovl.fmt.RRE.r2); goto ok;
14373 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14374 ovl.fmt.RRE.r2); goto ok;
14375 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14376 ovl.fmt.RRE.r2); goto ok;
14377 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14378 ovl.fmt.RRE.r2); goto ok;
14379 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14380 ovl.fmt.RRE.r2); goto ok;
14381 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14382 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14383 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14384 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14385 case 0xb324: /* LDER */ goto unimplemented;
14386 case 0xb325: /* LXDR */ goto unimplemented;
14387 case 0xb326: /* LXER */ goto unimplemented;
14388 case 0xb32e: /* MAER */ goto unimplemented;
14389 case 0xb32f: /* MSER */ goto unimplemented;
14390 case 0xb336: /* SQXR */ goto unimplemented;
14391 case 0xb337: /* MEER */ goto unimplemented;
14392 case 0xb338: /* MAYLR */ goto unimplemented;
14393 case 0xb339: /* MYLR */ goto unimplemented;
14394 case 0xb33a: /* MAYR */ goto unimplemented;
14395 case 0xb33b: /* MYR */ goto unimplemented;
14396 case 0xb33c: /* MAYHR */ goto unimplemented;
14397 case 0xb33d: /* MYHR */ goto unimplemented;
14398 case 0xb33e: /* MADR */ goto unimplemented;
14399 case 0xb33f: /* MSDR */ goto unimplemented;
14400 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14401 ovl.fmt.RRE.r2); goto ok;
14402 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14403 ovl.fmt.RRE.r2); goto ok;
14404 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14405 ovl.fmt.RRE.r2); goto ok;
14406 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14407 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014408 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14409 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14410 ovl.fmt.RRF2.r2); goto ok;
14411 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14412 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14413 ovl.fmt.RRF2.r2); goto ok;
14414 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14415 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14416 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014417 case 0xb347: /* FIXBR */ goto unimplemented;
14418 case 0xb348: /* KXBR */ goto unimplemented;
14419 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14420 ovl.fmt.RRE.r2); goto ok;
14421 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14422 ovl.fmt.RRE.r2); goto ok;
14423 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14424 ovl.fmt.RRE.r2); goto ok;
14425 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14426 ovl.fmt.RRE.r2); goto ok;
14427 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14428 ovl.fmt.RRE.r2); goto ok;
14429 case 0xb350: /* TBEDR */ goto unimplemented;
14430 case 0xb351: /* TBDR */ goto unimplemented;
14431 case 0xb353: /* DIEBR */ goto unimplemented;
14432 case 0xb357: /* FIEBR */ goto unimplemented;
14433 case 0xb358: /* THDER */ goto unimplemented;
14434 case 0xb359: /* THDR */ goto unimplemented;
14435 case 0xb35b: /* DIDBR */ goto unimplemented;
14436 case 0xb35f: /* FIDBR */ goto unimplemented;
14437 case 0xb360: /* LPXR */ goto unimplemented;
14438 case 0xb361: /* LNXR */ goto unimplemented;
14439 case 0xb362: /* LTXR */ goto unimplemented;
14440 case 0xb363: /* LCXR */ goto unimplemented;
14441 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14442 ovl.fmt.RRE.r2); goto ok;
14443 case 0xb366: /* LEXR */ goto unimplemented;
14444 case 0xb367: /* FIXR */ goto unimplemented;
14445 case 0xb369: /* CXR */ goto unimplemented;
14446 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14447 ovl.fmt.RRE.r2); goto ok;
14448 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14449 ovl.fmt.RRE.r2); goto ok;
14450 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14451 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14452 goto ok;
14453 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14454 ovl.fmt.RRE.r2); goto ok;
14455 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14456 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14457 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14458 case 0xb377: /* FIER */ goto unimplemented;
14459 case 0xb37f: /* FIDR */ goto unimplemented;
14460 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14461 case 0xb385: /* SFASR */ goto unimplemented;
14462 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014463 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14464 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14465 ovl.fmt.RRF2.r2); goto ok;
14466 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14467 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14468 ovl.fmt.RRF2.r2); goto ok;
14469 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14470 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14471 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014472 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14473 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14474 ovl.fmt.RRF2.r2); goto ok;
14475 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14476 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14477 ovl.fmt.RRF2.r2); goto ok;
14478 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14479 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14480 ovl.fmt.RRF2.r2); goto ok;
14481 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14482 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14483 ovl.fmt.RRF2.r2); goto ok;
14484 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14485 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14486 ovl.fmt.RRF2.r2); goto ok;
14487 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14488 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14489 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014490 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14491 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14492 ovl.fmt.RRF2.r2); goto ok;
14493 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14494 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14495 ovl.fmt.RRF2.r2); goto ok;
14496 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14497 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14498 ovl.fmt.RRF2.r2); goto ok;
14499 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14500 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14501 ovl.fmt.RRF2.r2); goto ok;
14502 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14503 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14504 ovl.fmt.RRF2.r2); goto ok;
14505 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14506 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14507 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014508 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14509 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14510 ovl.fmt.RRF2.r2); goto ok;
14511 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14512 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14513 ovl.fmt.RRF2.r2); goto ok;
14514 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14515 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14516 ovl.fmt.RRF2.r2); goto ok;
14517 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14518 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14519 ovl.fmt.RRF2.r2); goto ok;
14520 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14521 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14522 ovl.fmt.RRF2.r2); goto ok;
14523 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14524 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14525 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014526 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14527 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14528 ovl.fmt.RRF2.r2); goto ok;
14529 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14530 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14531 ovl.fmt.RRF2.r2); goto ok;
14532 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14533 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14534 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014535 case 0xb3b4: /* CEFR */ goto unimplemented;
14536 case 0xb3b5: /* CDFR */ goto unimplemented;
14537 case 0xb3b6: /* CXFR */ goto unimplemented;
14538 case 0xb3b8: /* CFER */ goto unimplemented;
14539 case 0xb3b9: /* CFDR */ goto unimplemented;
14540 case 0xb3ba: /* CFXR */ goto unimplemented;
14541 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14542 ovl.fmt.RRE.r2); goto ok;
14543 case 0xb3c4: /* CEGR */ goto unimplemented;
14544 case 0xb3c5: /* CDGR */ goto unimplemented;
14545 case 0xb3c6: /* CXGR */ goto unimplemented;
14546 case 0xb3c8: /* CGER */ goto unimplemented;
14547 case 0xb3c9: /* CGDR */ goto unimplemented;
14548 case 0xb3ca: /* CGXR */ goto unimplemented;
14549 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14550 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014551 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14552 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14553 ovl.fmt.RRF4.r2); goto ok;
14554 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14555 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14556 ovl.fmt.RRF4.r2); goto ok;
14557 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14558 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14559 ovl.fmt.RRF4.r2); goto ok;
14560 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14561 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14562 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014563 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14564 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14565 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14566 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14567 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014568 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14569 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014570 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014571 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14572 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14573 ovl.fmt.RRF4.r2); goto ok;
14574 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14575 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14576 ovl.fmt.RRF4.r2); goto ok;
14577 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14578 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14579 ovl.fmt.RRF4.r2); goto ok;
14580 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14581 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14582 ovl.fmt.RRF4.r2); goto ok;
14583 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14584 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14585 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14586 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14587 ovl.fmt.RRF2.r2); goto ok;
14588 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14589 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014590 case 0xb3df: /* FIXTR */ goto unimplemented;
14591 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014592 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14593 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14594 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014595 case 0xb3e2: /* CUDTR */ goto unimplemented;
14596 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014597 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14598 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014599 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14600 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014601 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14602 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014603 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014604 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14605 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14606 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014607 case 0xb3ea: /* CUXTR */ goto unimplemented;
14608 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014609 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14610 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014611 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14612 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014613 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14614 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014615 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, 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 0xb3f2: /* CDUTR */ goto unimplemented;
14619 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014620 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14621 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014622 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14623 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14624 ovl.fmt.RRF4.r2); goto ok;
14625 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14626 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14627 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14628 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14629 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014630 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14631 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14632 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014633 case 0xb3fa: /* CXUTR */ goto unimplemented;
14634 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014635 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14636 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014637 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14638 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14639 ovl.fmt.RRF4.r2); goto ok;
14640 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14641 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14642 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14643 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14644 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014645 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14646 ovl.fmt.RRE.r2); goto ok;
14647 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14648 ovl.fmt.RRE.r2); goto ok;
14649 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14650 ovl.fmt.RRE.r2); goto ok;
14651 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14652 ovl.fmt.RRE.r2); goto ok;
14653 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14654 ovl.fmt.RRE.r2); goto ok;
14655 case 0xb905: /* LURAG */ goto unimplemented;
14656 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14657 ovl.fmt.RRE.r2); goto ok;
14658 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14659 ovl.fmt.RRE.r2); goto ok;
14660 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14661 ovl.fmt.RRE.r2); goto ok;
14662 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14663 ovl.fmt.RRE.r2); goto ok;
14664 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14665 ovl.fmt.RRE.r2); goto ok;
14666 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14667 ovl.fmt.RRE.r2); goto ok;
14668 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14669 ovl.fmt.RRE.r2); goto ok;
14670 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14671 ovl.fmt.RRE.r2); goto ok;
14672 case 0xb90e: /* EREGG */ goto unimplemented;
14673 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14674 ovl.fmt.RRE.r2); goto ok;
14675 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14676 ovl.fmt.RRE.r2); goto ok;
14677 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14678 ovl.fmt.RRE.r2); goto ok;
14679 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14680 ovl.fmt.RRE.r2); goto ok;
14681 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14682 ovl.fmt.RRE.r2); goto ok;
14683 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14684 ovl.fmt.RRE.r2); goto ok;
14685 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14686 ovl.fmt.RRE.r2); goto ok;
14687 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14688 ovl.fmt.RRE.r2); goto ok;
14689 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14690 ovl.fmt.RRE.r2); goto ok;
14691 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14692 ovl.fmt.RRE.r2); goto ok;
14693 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14694 ovl.fmt.RRE.r2); goto ok;
14695 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14696 ovl.fmt.RRE.r2); goto ok;
14697 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14698 ovl.fmt.RRE.r2); goto ok;
14699 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14700 ovl.fmt.RRE.r2); goto ok;
14701 case 0xb91e: /* KMAC */ goto unimplemented;
14702 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14703 ovl.fmt.RRE.r2); goto ok;
14704 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14705 ovl.fmt.RRE.r2); goto ok;
14706 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14707 ovl.fmt.RRE.r2); goto ok;
14708 case 0xb925: /* STURG */ goto unimplemented;
14709 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14710 ovl.fmt.RRE.r2); goto ok;
14711 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14712 ovl.fmt.RRE.r2); goto ok;
14713 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014714 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014715 case 0xb92b: /* KMO */ goto unimplemented;
14716 case 0xb92c: /* PCC */ goto unimplemented;
14717 case 0xb92d: /* KMCTR */ goto unimplemented;
14718 case 0xb92e: /* KM */ goto unimplemented;
14719 case 0xb92f: /* KMC */ goto unimplemented;
14720 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14721 ovl.fmt.RRE.r2); goto ok;
14722 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14723 ovl.fmt.RRE.r2); goto ok;
14724 case 0xb93e: /* KIMD */ goto unimplemented;
14725 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014726 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14727 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14728 ovl.fmt.RRF2.r2); goto ok;
14729 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14730 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14731 ovl.fmt.RRF2.r2); goto ok;
14732 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14733 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14734 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014735 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14736 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014737 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14738 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14739 ovl.fmt.RRF2.r2); goto ok;
14740 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14741 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14742 ovl.fmt.RRF2.r2); goto ok;
14743 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14744 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14745 ovl.fmt.RRF2.r2); goto ok;
14746 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14747 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14748 ovl.fmt.RRF2.r2); goto ok;
14749 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14750 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14751 ovl.fmt.RRF2.r2); goto ok;
14752 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14753 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14754 ovl.fmt.RRF2.r2); goto ok;
14755 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14756 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14757 ovl.fmt.RRF2.r2); goto ok;
14758 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14759 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14760 ovl.fmt.RRF2.r2); goto ok;
14761 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14762 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14763 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014764 case 0xb960: /* CGRT */ goto unimplemented;
14765 case 0xb961: /* CLGRT */ goto unimplemented;
14766 case 0xb972: /* CRT */ goto unimplemented;
14767 case 0xb973: /* CLRT */ goto unimplemented;
14768 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14769 ovl.fmt.RRE.r2); goto ok;
14770 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14771 ovl.fmt.RRE.r2); goto ok;
14772 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14773 ovl.fmt.RRE.r2); goto ok;
14774 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14775 ovl.fmt.RRE.r2); goto ok;
14776 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14777 ovl.fmt.RRE.r2); goto ok;
14778 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14779 ovl.fmt.RRE.r2); goto ok;
14780 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14781 ovl.fmt.RRE.r2); goto ok;
14782 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14783 ovl.fmt.RRE.r2); goto ok;
14784 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14785 ovl.fmt.RRE.r2); goto ok;
14786 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14787 ovl.fmt.RRE.r2); goto ok;
14788 case 0xb98a: /* CSPG */ goto unimplemented;
14789 case 0xb98d: /* EPSW */ goto unimplemented;
14790 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014791 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014792 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14793 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14794 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14795 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14796 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14797 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014798 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14799 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014800 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14801 ovl.fmt.RRE.r2); goto ok;
14802 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14803 ovl.fmt.RRE.r2); goto ok;
14804 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14805 ovl.fmt.RRE.r2); goto ok;
14806 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14807 ovl.fmt.RRE.r2); goto ok;
14808 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14809 ovl.fmt.RRE.r2); goto ok;
14810 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14811 ovl.fmt.RRE.r2); goto ok;
14812 case 0xb99a: /* EPAIR */ goto unimplemented;
14813 case 0xb99b: /* ESAIR */ goto unimplemented;
14814 case 0xb99d: /* ESEA */ goto unimplemented;
14815 case 0xb99e: /* PTI */ goto unimplemented;
14816 case 0xb99f: /* SSAIR */ goto unimplemented;
14817 case 0xb9a2: /* PTF */ goto unimplemented;
14818 case 0xb9aa: /* LPTEA */ goto unimplemented;
14819 case 0xb9ae: /* RRBM */ goto unimplemented;
14820 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014821 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14822 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14823 goto ok;
florian2a415a12012-07-21 17:41:36 +000014824 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14825 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14826 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014827 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14828 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014829 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14830 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014831 case 0xb9bd: /* TRTRE */ goto unimplemented;
14832 case 0xb9be: /* SRSTU */ goto unimplemented;
14833 case 0xb9bf: /* TRTE */ goto unimplemented;
14834 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14835 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14836 goto ok;
14837 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14838 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14839 goto ok;
14840 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14841 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14842 goto ok;
14843 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14844 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14845 goto ok;
14846 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14847 ovl.fmt.RRE.r2); goto ok;
14848 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14849 ovl.fmt.RRE.r2); goto ok;
14850 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14851 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14852 goto ok;
14853 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14854 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14855 goto ok;
14856 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14857 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14858 goto ok;
14859 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14860 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14861 goto ok;
14862 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14863 ovl.fmt.RRE.r2); goto ok;
14864 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14865 ovl.fmt.RRE.r2); goto ok;
14866 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014867 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14868 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14869 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014870 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14871 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14872 goto ok;
14873 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14874 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14875 goto ok;
14876 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14877 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14878 goto ok;
14879 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14880 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14881 goto ok;
14882 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14883 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14884 goto ok;
14885 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14886 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14887 goto ok;
14888 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14889 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14890 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014891 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14892 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14893 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014894 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14895 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14896 goto ok;
14897 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14898 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14899 goto ok;
14900 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14901 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14902 goto ok;
14903 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14904 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14905 goto ok;
14906 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14907 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14908 goto ok;
14909 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14910 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14911 goto ok;
14912 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14913 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14914 goto ok;
14915 }
14916
14917 switch ((ovl.value & 0xff000000) >> 24) {
14918 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14919 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14920 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14921 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14922 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14923 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14924 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14925 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14926 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14927 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14928 case 0x45: /* BAL */ goto unimplemented;
14929 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14930 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14931 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14932 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14933 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14934 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14935 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14936 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14937 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14938 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14939 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14940 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14941 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14942 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14943 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14944 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14945 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14946 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14947 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14948 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14949 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14950 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14951 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14952 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14953 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14954 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14955 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14956 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14957 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14958 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14959 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14960 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14961 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14962 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14963 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14964 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14965 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14966 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14967 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14968 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14969 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14970 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14971 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14972 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14973 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14974 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14975 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14976 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14977 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14978 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14979 case 0x67: /* MXD */ goto unimplemented;
14980 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14981 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14982 case 0x69: /* CD */ goto unimplemented;
14983 case 0x6a: /* AD */ goto unimplemented;
14984 case 0x6b: /* SD */ goto unimplemented;
14985 case 0x6c: /* MD */ goto unimplemented;
14986 case 0x6d: /* DD */ goto unimplemented;
14987 case 0x6e: /* AW */ goto unimplemented;
14988 case 0x6f: /* SW */ goto unimplemented;
14989 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14990 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14991 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14992 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14993 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14994 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14995 case 0x79: /* CE */ goto unimplemented;
14996 case 0x7a: /* AE */ goto unimplemented;
14997 case 0x7b: /* SE */ goto unimplemented;
14998 case 0x7c: /* MDE */ goto unimplemented;
14999 case 0x7d: /* DE */ goto unimplemented;
15000 case 0x7e: /* AU */ goto unimplemented;
15001 case 0x7f: /* SU */ goto unimplemented;
15002 case 0x83: /* DIAG */ goto unimplemented;
15003 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15004 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15005 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15006 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15007 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15008 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15009 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15010 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15011 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15012 ovl.fmt.RS.d2); goto ok;
15013 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15014 ovl.fmt.RS.d2); goto ok;
15015 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15016 ovl.fmt.RS.d2); goto ok;
15017 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15018 ovl.fmt.RS.d2); goto ok;
15019 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15020 ovl.fmt.RS.d2); goto ok;
15021 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15022 ovl.fmt.RS.d2); goto ok;
15023 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15024 ovl.fmt.RS.d2); goto ok;
15025 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15026 ovl.fmt.RS.d2); goto ok;
15027 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15028 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15029 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15030 ovl.fmt.SI.d1); goto ok;
15031 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15032 ovl.fmt.SI.d1); goto ok;
15033 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15034 ovl.fmt.SI.d1); goto ok;
15035 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15036 ovl.fmt.SI.d1); goto ok;
15037 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15038 ovl.fmt.SI.d1); goto ok;
15039 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15040 ovl.fmt.SI.d1); goto ok;
15041 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15042 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15043 case 0x99: /* TRACE */ goto unimplemented;
15044 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15045 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15046 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15047 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15048 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15049 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15050 goto ok;
15051 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15052 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15053 goto ok;
15054 case 0xac: /* STNSM */ goto unimplemented;
15055 case 0xad: /* STOSM */ goto unimplemented;
15056 case 0xae: /* SIGP */ goto unimplemented;
15057 case 0xaf: /* MC */ goto unimplemented;
15058 case 0xb1: /* LRA */ goto unimplemented;
15059 case 0xb6: /* STCTL */ goto unimplemented;
15060 case 0xb7: /* LCTL */ goto unimplemented;
15061 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15062 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015063 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15064 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015065 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15066 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15067 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15068 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15069 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15070 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15071 }
15072
15073 return S390_DECODE_UNKNOWN_INSN;
15074
15075ok:
15076 return S390_DECODE_OK;
15077
15078unimplemented:
15079 return S390_DECODE_UNIMPLEMENTED_INSN;
15080}
15081
15082static s390_decode_t
15083s390_decode_6byte_and_irgen(UChar *bytes)
15084{
15085 typedef union {
15086 struct {
15087 unsigned int op1 : 8;
15088 unsigned int r1 : 4;
15089 unsigned int r3 : 4;
15090 unsigned int i2 : 16;
15091 unsigned int : 8;
15092 unsigned int op2 : 8;
15093 } RIE;
15094 struct {
15095 unsigned int op1 : 8;
15096 unsigned int r1 : 4;
15097 unsigned int r2 : 4;
15098 unsigned int i3 : 8;
15099 unsigned int i4 : 8;
15100 unsigned int i5 : 8;
15101 unsigned int op2 : 8;
15102 } RIE_RRUUU;
15103 struct {
15104 unsigned int op1 : 8;
15105 unsigned int r1 : 4;
15106 unsigned int : 4;
15107 unsigned int i2 : 16;
15108 unsigned int m3 : 4;
15109 unsigned int : 4;
15110 unsigned int op2 : 8;
15111 } RIEv1;
15112 struct {
15113 unsigned int op1 : 8;
15114 unsigned int r1 : 4;
15115 unsigned int r2 : 4;
15116 unsigned int i4 : 16;
15117 unsigned int m3 : 4;
15118 unsigned int : 4;
15119 unsigned int op2 : 8;
15120 } RIE_RRPU;
15121 struct {
15122 unsigned int op1 : 8;
15123 unsigned int r1 : 4;
15124 unsigned int m3 : 4;
15125 unsigned int i4 : 16;
15126 unsigned int i2 : 8;
15127 unsigned int op2 : 8;
15128 } RIEv3;
15129 struct {
15130 unsigned int op1 : 8;
15131 unsigned int r1 : 4;
15132 unsigned int op2 : 4;
15133 unsigned int i2 : 32;
15134 } RIL;
15135 struct {
15136 unsigned int op1 : 8;
15137 unsigned int r1 : 4;
15138 unsigned int m3 : 4;
15139 unsigned int b4 : 4;
15140 unsigned int d4 : 12;
15141 unsigned int i2 : 8;
15142 unsigned int op2 : 8;
15143 } RIS;
15144 struct {
15145 unsigned int op1 : 8;
15146 unsigned int r1 : 4;
15147 unsigned int r2 : 4;
15148 unsigned int b4 : 4;
15149 unsigned int d4 : 12;
15150 unsigned int m3 : 4;
15151 unsigned int : 4;
15152 unsigned int op2 : 8;
15153 } RRS;
15154 struct {
15155 unsigned int op1 : 8;
15156 unsigned int l1 : 4;
15157 unsigned int : 4;
15158 unsigned int b1 : 4;
15159 unsigned int d1 : 12;
15160 unsigned int : 8;
15161 unsigned int op2 : 8;
15162 } RSL;
15163 struct {
15164 unsigned int op1 : 8;
15165 unsigned int r1 : 4;
15166 unsigned int r3 : 4;
15167 unsigned int b2 : 4;
15168 unsigned int dl2 : 12;
15169 unsigned int dh2 : 8;
15170 unsigned int op2 : 8;
15171 } RSY;
15172 struct {
15173 unsigned int op1 : 8;
15174 unsigned int r1 : 4;
15175 unsigned int x2 : 4;
15176 unsigned int b2 : 4;
15177 unsigned int d2 : 12;
15178 unsigned int : 8;
15179 unsigned int op2 : 8;
15180 } RXE;
15181 struct {
15182 unsigned int op1 : 8;
15183 unsigned int r3 : 4;
15184 unsigned int x2 : 4;
15185 unsigned int b2 : 4;
15186 unsigned int d2 : 12;
15187 unsigned int r1 : 4;
15188 unsigned int : 4;
15189 unsigned int op2 : 8;
15190 } RXF;
15191 struct {
15192 unsigned int op1 : 8;
15193 unsigned int r1 : 4;
15194 unsigned int x2 : 4;
15195 unsigned int b2 : 4;
15196 unsigned int dl2 : 12;
15197 unsigned int dh2 : 8;
15198 unsigned int op2 : 8;
15199 } RXY;
15200 struct {
15201 unsigned int op1 : 8;
15202 unsigned int i2 : 8;
15203 unsigned int b1 : 4;
15204 unsigned int dl1 : 12;
15205 unsigned int dh1 : 8;
15206 unsigned int op2 : 8;
15207 } SIY;
15208 struct {
15209 unsigned int op : 8;
15210 unsigned int l : 8;
15211 unsigned int b1 : 4;
15212 unsigned int d1 : 12;
15213 unsigned int b2 : 4;
15214 unsigned int d2 : 12;
15215 } SS;
15216 struct {
15217 unsigned int op : 8;
15218 unsigned int l1 : 4;
15219 unsigned int l2 : 4;
15220 unsigned int b1 : 4;
15221 unsigned int d1 : 12;
15222 unsigned int b2 : 4;
15223 unsigned int d2 : 12;
15224 } SS_LLRDRD;
15225 struct {
15226 unsigned int op : 8;
15227 unsigned int r1 : 4;
15228 unsigned int r3 : 4;
15229 unsigned int b2 : 4;
15230 unsigned int d2 : 12;
15231 unsigned int b4 : 4;
15232 unsigned int d4 : 12;
15233 } SS_RRRDRD2;
15234 struct {
15235 unsigned int op : 16;
15236 unsigned int b1 : 4;
15237 unsigned int d1 : 12;
15238 unsigned int b2 : 4;
15239 unsigned int d2 : 12;
15240 } SSE;
15241 struct {
15242 unsigned int op1 : 8;
15243 unsigned int r3 : 4;
15244 unsigned int op2 : 4;
15245 unsigned int b1 : 4;
15246 unsigned int d1 : 12;
15247 unsigned int b2 : 4;
15248 unsigned int d2 : 12;
15249 } SSF;
15250 struct {
15251 unsigned int op : 16;
15252 unsigned int b1 : 4;
15253 unsigned int d1 : 12;
15254 unsigned int i2 : 16;
15255 } SIL;
15256 } formats;
15257 union {
15258 formats fmt;
15259 ULong value;
15260 } ovl;
15261
15262 vassert(sizeof(formats) == 6);
15263
florianffbd84d2012-12-09 02:06:29 +000015264 ((UChar *)(&ovl.value))[0] = bytes[0];
15265 ((UChar *)(&ovl.value))[1] = bytes[1];
15266 ((UChar *)(&ovl.value))[2] = bytes[2];
15267 ((UChar *)(&ovl.value))[3] = bytes[3];
15268 ((UChar *)(&ovl.value))[4] = bytes[4];
15269 ((UChar *)(&ovl.value))[5] = bytes[5];
15270 ((UChar *)(&ovl.value))[6] = 0x0;
15271 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000015272
15273 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15274 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15275 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15276 ovl.fmt.RXY.dl2,
15277 ovl.fmt.RXY.dh2); goto ok;
15278 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15279 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15280 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15281 ovl.fmt.RXY.dl2,
15282 ovl.fmt.RXY.dh2); goto ok;
15283 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15284 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15285 ovl.fmt.RXY.dl2,
15286 ovl.fmt.RXY.dh2); goto ok;
15287 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15288 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15289 ovl.fmt.RXY.dl2,
15290 ovl.fmt.RXY.dh2); goto ok;
15291 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15292 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15293 ovl.fmt.RXY.dl2,
15294 ovl.fmt.RXY.dh2); goto ok;
15295 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15296 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15297 ovl.fmt.RXY.dl2,
15298 ovl.fmt.RXY.dh2); goto ok;
15299 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15300 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15301 ovl.fmt.RXY.dl2,
15302 ovl.fmt.RXY.dh2); goto ok;
15303 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15304 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15305 ovl.fmt.RXY.dl2,
15306 ovl.fmt.RXY.dh2); goto ok;
15307 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15308 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15309 ovl.fmt.RXY.dl2,
15310 ovl.fmt.RXY.dh2); goto ok;
15311 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15312 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15313 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15314 ovl.fmt.RXY.dl2,
15315 ovl.fmt.RXY.dh2); goto ok;
15316 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15317 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15318 ovl.fmt.RXY.dl2,
15319 ovl.fmt.RXY.dh2); goto ok;
15320 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15321 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15322 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15323 ovl.fmt.RXY.dl2,
15324 ovl.fmt.RXY.dh2); goto ok;
15325 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15326 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15327 ovl.fmt.RXY.dl2,
15328 ovl.fmt.RXY.dh2); goto ok;
15329 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15330 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15331 ovl.fmt.RXY.dl2,
15332 ovl.fmt.RXY.dh2); goto ok;
15333 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15334 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15335 ovl.fmt.RXY.dl2,
15336 ovl.fmt.RXY.dh2); goto ok;
15337 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15338 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15339 ovl.fmt.RXY.dl2,
15340 ovl.fmt.RXY.dh2); goto ok;
15341 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15342 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15343 ovl.fmt.RXY.dl2,
15344 ovl.fmt.RXY.dh2); goto ok;
15345 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15346 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15347 ovl.fmt.RXY.dl2,
15348 ovl.fmt.RXY.dh2); goto ok;
15349 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15350 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15351 ovl.fmt.RXY.dl2,
15352 ovl.fmt.RXY.dh2); goto ok;
15353 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15354 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15355 ovl.fmt.RXY.dl2,
15356 ovl.fmt.RXY.dh2); goto ok;
15357 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15358 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15359 ovl.fmt.RXY.dl2,
15360 ovl.fmt.RXY.dh2); goto ok;
15361 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15362 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15363 ovl.fmt.RXY.dl2,
15364 ovl.fmt.RXY.dh2); goto ok;
15365 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15366 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15367 ovl.fmt.RXY.dl2,
15368 ovl.fmt.RXY.dh2); goto ok;
15369 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15370 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15371 ovl.fmt.RXY.dl2,
15372 ovl.fmt.RXY.dh2); goto ok;
15373 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15374 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15375 ovl.fmt.RXY.dl2,
15376 ovl.fmt.RXY.dh2); goto ok;
15377 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15378 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15379 ovl.fmt.RXY.dl2,
15380 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015381 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015382 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15383 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15384 ovl.fmt.RXY.dl2,
15385 ovl.fmt.RXY.dh2); goto ok;
15386 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15387 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15388 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15389 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15390 ovl.fmt.RXY.dh2); goto ok;
15391 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15392 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15393 ovl.fmt.RXY.dl2,
15394 ovl.fmt.RXY.dh2); goto ok;
15395 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15396 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15397 ovl.fmt.RXY.dl2,
15398 ovl.fmt.RXY.dh2); goto ok;
15399 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15400 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15401 ovl.fmt.RXY.dl2,
15402 ovl.fmt.RXY.dh2); goto ok;
15403 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15404 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15405 ovl.fmt.RXY.dl2,
15406 ovl.fmt.RXY.dh2); goto ok;
15407 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15408 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15409 ovl.fmt.RXY.dl2,
15410 ovl.fmt.RXY.dh2); goto ok;
15411 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15412 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15413 ovl.fmt.RXY.dl2,
15414 ovl.fmt.RXY.dh2); goto ok;
15415 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15416 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15417 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15418 ovl.fmt.RXY.dh2); goto ok;
15419 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15420 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15421 ovl.fmt.RXY.dl2,
15422 ovl.fmt.RXY.dh2); goto ok;
15423 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15424 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15425 ovl.fmt.RXY.dl2,
15426 ovl.fmt.RXY.dh2); goto ok;
15427 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15428 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15429 ovl.fmt.RXY.dl2,
15430 ovl.fmt.RXY.dh2); goto ok;
15431 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15432 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15433 ovl.fmt.RXY.dl2,
15434 ovl.fmt.RXY.dh2); goto ok;
15435 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15436 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15437 ovl.fmt.RXY.dl2,
15438 ovl.fmt.RXY.dh2); goto ok;
15439 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15440 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15441 ovl.fmt.RXY.dl2,
15442 ovl.fmt.RXY.dh2); goto ok;
15443 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15444 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15445 ovl.fmt.RXY.dl2,
15446 ovl.fmt.RXY.dh2); goto ok;
15447 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15448 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15449 ovl.fmt.RXY.dl2,
15450 ovl.fmt.RXY.dh2); goto ok;
15451 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15452 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15453 ovl.fmt.RXY.dl2,
15454 ovl.fmt.RXY.dh2); goto ok;
15455 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15456 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15457 ovl.fmt.RXY.dl2,
15458 ovl.fmt.RXY.dh2); goto ok;
15459 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15460 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15461 ovl.fmt.RXY.dl2,
15462 ovl.fmt.RXY.dh2); goto ok;
15463 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15464 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15465 ovl.fmt.RXY.dl2,
15466 ovl.fmt.RXY.dh2); goto ok;
15467 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15468 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15469 ovl.fmt.RXY.dl2,
15470 ovl.fmt.RXY.dh2); goto ok;
15471 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15472 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15473 ovl.fmt.RXY.dl2,
15474 ovl.fmt.RXY.dh2); goto ok;
15475 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15476 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15477 ovl.fmt.RXY.dl2,
15478 ovl.fmt.RXY.dh2); goto ok;
15479 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15480 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15481 ovl.fmt.RXY.dl2,
15482 ovl.fmt.RXY.dh2); goto ok;
15483 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15484 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15485 ovl.fmt.RXY.dl2,
15486 ovl.fmt.RXY.dh2); goto ok;
15487 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15488 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15489 ovl.fmt.RXY.dl2,
15490 ovl.fmt.RXY.dh2); goto ok;
15491 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15492 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15493 ovl.fmt.RXY.dl2,
15494 ovl.fmt.RXY.dh2); goto ok;
15495 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15496 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15497 ovl.fmt.RXY.dl2,
15498 ovl.fmt.RXY.dh2); goto ok;
15499 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15500 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15501 ovl.fmt.RXY.dl2,
15502 ovl.fmt.RXY.dh2); goto ok;
15503 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15504 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15505 ovl.fmt.RXY.dl2,
15506 ovl.fmt.RXY.dh2); goto ok;
15507 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15508 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15509 ovl.fmt.RXY.dl2,
15510 ovl.fmt.RXY.dh2); goto ok;
15511 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15512 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15513 ovl.fmt.RXY.dl2,
15514 ovl.fmt.RXY.dh2); goto ok;
15515 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15516 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15517 ovl.fmt.RXY.dl2,
15518 ovl.fmt.RXY.dh2); goto ok;
15519 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15520 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15521 ovl.fmt.RXY.dl2,
15522 ovl.fmt.RXY.dh2); goto ok;
15523 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15524 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15525 ovl.fmt.RXY.dl2,
15526 ovl.fmt.RXY.dh2); goto ok;
15527 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15528 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15529 ovl.fmt.RXY.dl2,
15530 ovl.fmt.RXY.dh2); goto ok;
15531 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15532 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15533 ovl.fmt.RXY.dl2,
15534 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015535 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015536 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15537 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15538 ovl.fmt.RXY.dl2,
15539 ovl.fmt.RXY.dh2); goto ok;
15540 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15541 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15542 ovl.fmt.RXY.dl2,
15543 ovl.fmt.RXY.dh2); goto ok;
15544 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15545 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15546 ovl.fmt.RXY.dl2,
15547 ovl.fmt.RXY.dh2); goto ok;
15548 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15549 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15550 ovl.fmt.RXY.dl2,
15551 ovl.fmt.RXY.dh2); goto ok;
15552 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15553 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15554 ovl.fmt.RXY.dl2,
15555 ovl.fmt.RXY.dh2); goto ok;
15556 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15557 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15558 ovl.fmt.RXY.dl2,
15559 ovl.fmt.RXY.dh2); goto ok;
15560 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15561 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15562 ovl.fmt.RXY.dl2,
15563 ovl.fmt.RXY.dh2); goto ok;
15564 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15565 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15566 ovl.fmt.RXY.dl2,
15567 ovl.fmt.RXY.dh2); goto ok;
15568 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15569 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15570 ovl.fmt.RXY.dl2,
15571 ovl.fmt.RXY.dh2); goto ok;
15572 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15573 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15574 ovl.fmt.RXY.dl2,
15575 ovl.fmt.RXY.dh2); goto ok;
15576 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15577 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15578 ovl.fmt.RXY.dl2,
15579 ovl.fmt.RXY.dh2); goto ok;
15580 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15581 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15582 ovl.fmt.RXY.dl2,
15583 ovl.fmt.RXY.dh2); goto ok;
15584 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15585 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15586 ovl.fmt.RXY.dl2,
15587 ovl.fmt.RXY.dh2); goto ok;
15588 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15589 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15590 ovl.fmt.RXY.dl2,
15591 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015592 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15593 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15594 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015595 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, 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 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, 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;
15603 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15604 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15605 ovl.fmt.RXY.dl2,
15606 ovl.fmt.RXY.dh2); goto ok;
15607 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15608 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15609 ovl.fmt.RXY.dl2,
15610 ovl.fmt.RXY.dh2); goto ok;
15611 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15612 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15613 ovl.fmt.RXY.dl2,
15614 ovl.fmt.RXY.dh2); goto ok;
15615 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15616 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15617 ovl.fmt.RXY.dl2,
15618 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015619 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015620 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15621 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15622 ovl.fmt.RXY.dl2,
15623 ovl.fmt.RXY.dh2); goto ok;
15624 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15625 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15626 ovl.fmt.RXY.dl2,
15627 ovl.fmt.RXY.dh2); goto ok;
15628 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15629 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15630 ovl.fmt.RXY.dl2,
15631 ovl.fmt.RXY.dh2); goto ok;
15632 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15633 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15634 ovl.fmt.RXY.dl2,
15635 ovl.fmt.RXY.dh2); goto ok;
15636 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15637 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15638 ovl.fmt.RSY.dl2,
15639 ovl.fmt.RSY.dh2); goto ok;
15640 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15641 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15642 ovl.fmt.RSY.dl2,
15643 ovl.fmt.RSY.dh2); goto ok;
15644 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15645 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15646 ovl.fmt.RSY.dl2,
15647 ovl.fmt.RSY.dh2); goto ok;
15648 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15649 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15650 ovl.fmt.RSY.dl2,
15651 ovl.fmt.RSY.dh2); goto ok;
15652 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15653 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15654 ovl.fmt.RSY.dl2,
15655 ovl.fmt.RSY.dh2); goto ok;
15656 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15657 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15658 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15659 ovl.fmt.RSY.dl2,
15660 ovl.fmt.RSY.dh2); goto ok;
15661 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15662 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15663 ovl.fmt.RSY.dl2,
15664 ovl.fmt.RSY.dh2); goto ok;
15665 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15666 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15667 ovl.fmt.RSY.dl2,
15668 ovl.fmt.RSY.dh2); goto ok;
15669 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15670 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15671 ovl.fmt.RSY.dl2,
15672 ovl.fmt.RSY.dh2); goto ok;
15673 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15674 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15675 ovl.fmt.RSY.dl2,
15676 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015677 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015678 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15679 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15680 ovl.fmt.RSY.dl2,
15681 ovl.fmt.RSY.dh2); goto ok;
15682 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15683 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15684 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15685 ovl.fmt.RSY.dl2,
15686 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015687 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015688 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15689 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15690 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15691 ovl.fmt.RSY.dh2); goto ok;
15692 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15693 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15694 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15695 ovl.fmt.RSY.dh2); goto ok;
15696 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15697 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15698 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15699 ovl.fmt.RSY.dl2,
15700 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015701 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15702 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15703 ovl.fmt.RSY.dl2,
15704 ovl.fmt.RSY.dh2); goto ok;
15705 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15706 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15707 ovl.fmt.RSY.dl2,
15708 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015709 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15710 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15711 ovl.fmt.RSY.dl2,
15712 ovl.fmt.RSY.dh2); goto ok;
15713 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15714 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15715 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15716 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015717 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15718 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15719 ovl.fmt.RSY.dl2,
15720 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015721 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15722 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15723 ovl.fmt.SIY.dh1); goto ok;
15724 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15725 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15726 ovl.fmt.SIY.dh1); goto ok;
15727 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15728 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15729 ovl.fmt.SIY.dh1); goto ok;
15730 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15731 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15732 ovl.fmt.SIY.dh1); goto ok;
15733 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15734 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15735 ovl.fmt.SIY.dh1); goto ok;
15736 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15737 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15738 ovl.fmt.SIY.dh1); goto ok;
15739 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15740 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15741 ovl.fmt.SIY.dh1); goto ok;
15742 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15743 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15744 ovl.fmt.SIY.dh1); goto ok;
15745 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15746 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15747 ovl.fmt.SIY.dh1); goto ok;
15748 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15749 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15750 ovl.fmt.SIY.dh1); goto ok;
15751 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15752 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15753 ovl.fmt.RSY.dl2,
15754 ovl.fmt.RSY.dh2); goto ok;
15755 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15756 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15757 ovl.fmt.RSY.dl2,
15758 ovl.fmt.RSY.dh2); goto ok;
15759 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15760 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15761 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15762 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15763 ovl.fmt.RSY.dl2,
15764 ovl.fmt.RSY.dh2); goto ok;
15765 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15766 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15767 ovl.fmt.RSY.dl2,
15768 ovl.fmt.RSY.dh2); goto ok;
15769 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15770 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15771 ovl.fmt.RSY.dl2,
15772 ovl.fmt.RSY.dh2); goto ok;
15773 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15774 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15775 ovl.fmt.RSY.dl2,
15776 ovl.fmt.RSY.dh2); goto ok;
15777 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15778 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15779 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15780 ovl.fmt.RSY.dh2); goto ok;
15781 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15782 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15783 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15784 ovl.fmt.RSY.dl2,
15785 ovl.fmt.RSY.dh2); goto ok;
15786 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15787 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15788 ovl.fmt.RSY.dl2,
15789 ovl.fmt.RSY.dh2); goto ok;
15790 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15791 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15792 ovl.fmt.RSY.dl2,
15793 ovl.fmt.RSY.dh2); goto ok;
15794 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15795 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15796 ovl.fmt.RSY.dl2,
15797 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015798 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15799 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15800 ovl.fmt.RSY.dl2,
15801 ovl.fmt.RSY.dh2,
15802 S390_XMNM_LOCG); goto ok;
15803 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15804 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15805 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15806 ovl.fmt.RSY.dh2,
15807 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015808 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15809 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15810 ovl.fmt.RSY.dl2,
15811 ovl.fmt.RSY.dh2); goto ok;
15812 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15813 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15814 ovl.fmt.RSY.dl2,
15815 ovl.fmt.RSY.dh2); goto ok;
15816 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15817 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15818 ovl.fmt.RSY.dl2,
15819 ovl.fmt.RSY.dh2); goto ok;
15820 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15821 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15822 ovl.fmt.RSY.dl2,
15823 ovl.fmt.RSY.dh2); goto ok;
15824 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15825 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15826 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15827 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015828 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15829 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15830 ovl.fmt.RSY.dl2,
15831 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15832 goto ok;
15833 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15834 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15835 ovl.fmt.RSY.dl2,
15836 ovl.fmt.RSY.dh2,
15837 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015838 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15839 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15840 ovl.fmt.RSY.dl2,
15841 ovl.fmt.RSY.dh2); goto ok;
15842 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15843 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15844 ovl.fmt.RSY.dl2,
15845 ovl.fmt.RSY.dh2); goto ok;
15846 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15847 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15848 ovl.fmt.RSY.dl2,
15849 ovl.fmt.RSY.dh2); goto ok;
15850 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15851 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15852 ovl.fmt.RSY.dl2,
15853 ovl.fmt.RSY.dh2); goto ok;
15854 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15855 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15856 ovl.fmt.RSY.dl2,
15857 ovl.fmt.RSY.dh2); goto ok;
15858 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15859 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15860 goto ok;
15861 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15862 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15863 goto ok;
15864 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15865 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15866 ovl.fmt.RIE_RRUUU.r1,
15867 ovl.fmt.RIE_RRUUU.r2,
15868 ovl.fmt.RIE_RRUUU.i3,
15869 ovl.fmt.RIE_RRUUU.i4,
15870 ovl.fmt.RIE_RRUUU.i5);
15871 goto ok;
15872 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15873 ovl.fmt.RIE_RRUUU.r1,
15874 ovl.fmt.RIE_RRUUU.r2,
15875 ovl.fmt.RIE_RRUUU.i3,
15876 ovl.fmt.RIE_RRUUU.i4,
15877 ovl.fmt.RIE_RRUUU.i5);
15878 goto ok;
15879 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15880 ovl.fmt.RIE_RRUUU.r1,
15881 ovl.fmt.RIE_RRUUU.r2,
15882 ovl.fmt.RIE_RRUUU.i3,
15883 ovl.fmt.RIE_RRUUU.i4,
15884 ovl.fmt.RIE_RRUUU.i5);
15885 goto ok;
15886 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15887 ovl.fmt.RIE_RRUUU.r1,
15888 ovl.fmt.RIE_RRUUU.r2,
15889 ovl.fmt.RIE_RRUUU.i3,
15890 ovl.fmt.RIE_RRUUU.i4,
15891 ovl.fmt.RIE_RRUUU.i5);
15892 goto ok;
florian2289cd42012-12-05 04:23:42 +000015893 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015894 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15895 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15896 ovl.fmt.RIE_RRPU.r1,
15897 ovl.fmt.RIE_RRPU.r2,
15898 ovl.fmt.RIE_RRPU.i4,
15899 ovl.fmt.RIE_RRPU.m3); goto ok;
15900 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15901 ovl.fmt.RIE_RRPU.r1,
15902 ovl.fmt.RIE_RRPU.r2,
15903 ovl.fmt.RIE_RRPU.i4,
15904 ovl.fmt.RIE_RRPU.m3); goto ok;
15905 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15906 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15907 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15908 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15909 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15910 ovl.fmt.RIE_RRPU.r1,
15911 ovl.fmt.RIE_RRPU.r2,
15912 ovl.fmt.RIE_RRPU.i4,
15913 ovl.fmt.RIE_RRPU.m3); goto ok;
15914 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15915 ovl.fmt.RIE_RRPU.r1,
15916 ovl.fmt.RIE_RRPU.r2,
15917 ovl.fmt.RIE_RRPU.i4,
15918 ovl.fmt.RIE_RRPU.m3); goto ok;
15919 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15920 ovl.fmt.RIEv3.r1,
15921 ovl.fmt.RIEv3.m3,
15922 ovl.fmt.RIEv3.i4,
15923 ovl.fmt.RIEv3.i2); goto ok;
15924 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15925 ovl.fmt.RIEv3.r1,
15926 ovl.fmt.RIEv3.m3,
15927 ovl.fmt.RIEv3.i4,
15928 ovl.fmt.RIEv3.i2); goto ok;
15929 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15930 ovl.fmt.RIEv3.r1,
15931 ovl.fmt.RIEv3.m3,
15932 ovl.fmt.RIEv3.i4,
15933 ovl.fmt.RIEv3.i2); goto ok;
15934 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15935 ovl.fmt.RIEv3.r1,
15936 ovl.fmt.RIEv3.m3,
15937 ovl.fmt.RIEv3.i4,
15938 ovl.fmt.RIEv3.i2); goto ok;
15939 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15940 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15941 goto ok;
15942 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15943 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15944 ovl.fmt.RIE.i2); goto ok;
15945 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15946 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15947 ovl.fmt.RIE.i2); goto ok;
15948 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15949 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15950 ovl.fmt.RIE.i2); goto ok;
15951 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15952 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15953 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15954 goto ok;
15955 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15956 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15957 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15958 goto ok;
15959 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15960 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15961 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15962 goto ok;
15963 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15964 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15965 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15966 goto ok;
15967 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15968 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15969 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15970 ovl.fmt.RIS.i2); goto ok;
15971 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15972 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15973 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15974 ovl.fmt.RIS.i2); goto ok;
15975 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15976 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15977 ovl.fmt.RIS.d4,
15978 ovl.fmt.RIS.i2); goto ok;
15979 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15980 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15981 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15982 ovl.fmt.RIS.i2); goto ok;
15983 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15984 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15985 ovl.fmt.RXE.d2); goto ok;
15986 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15987 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15988 ovl.fmt.RXE.d2); goto ok;
15989 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15990 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15991 ovl.fmt.RXE.d2); goto ok;
15992 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15993 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15994 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15995 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15996 ovl.fmt.RXE.d2); goto ok;
15997 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15998 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15999 ovl.fmt.RXE.d2); goto ok;
16000 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16001 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16002 ovl.fmt.RXE.d2); goto ok;
16003 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16004 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16005 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16006 ovl.fmt.RXE.d2); goto ok;
16007 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16008 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16009 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16010 ovl.fmt.RXF.r1); goto ok;
16011 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16012 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16013 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16014 ovl.fmt.RXF.r1); goto ok;
16015 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16016 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16017 ovl.fmt.RXE.d2); goto ok;
16018 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16019 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16020 ovl.fmt.RXE.d2); goto ok;
16021 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16022 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16023 ovl.fmt.RXE.d2); goto ok;
16024 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16025 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16026 ovl.fmt.RXE.d2); goto ok;
16027 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16028 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16029 ovl.fmt.RXE.d2); goto ok;
16030 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16031 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16032 ovl.fmt.RXE.d2); goto ok;
16033 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16034 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16035 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16036 ovl.fmt.RXE.d2); goto ok;
16037 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16038 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16039 ovl.fmt.RXE.d2); goto ok;
16040 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16041 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16042 ovl.fmt.RXE.d2); goto ok;
16043 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16044 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16045 ovl.fmt.RXE.d2); goto ok;
16046 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16047 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16048 ovl.fmt.RXE.d2); goto ok;
16049 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16050 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16051 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16052 ovl.fmt.RXF.r1); goto ok;
16053 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16054 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16055 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16056 ovl.fmt.RXF.r1); goto ok;
16057 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
16058 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16059 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16060 case 0xed000000002eULL: /* MAE */ goto unimplemented;
16061 case 0xed000000002fULL: /* MSE */ goto unimplemented;
16062 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16063 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16064 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16065 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16066 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16067 case 0xed000000003aULL: /* MAY */ goto unimplemented;
16068 case 0xed000000003bULL: /* MY */ goto unimplemented;
16069 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16070 case 0xed000000003dULL: /* MYH */ goto unimplemented;
16071 case 0xed000000003eULL: /* MAD */ goto unimplemented;
16072 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000016073 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16074 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16075 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16076 ovl.fmt.RXF.r1); goto ok;
16077 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16078 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16079 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16080 ovl.fmt.RXF.r1); goto ok;
16081 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16082 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16083 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16084 ovl.fmt.RXF.r1); goto ok;
16085 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16086 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16087 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16088 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000016089 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16090 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16091 ovl.fmt.RXE.d2); goto ok;
16092 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16093 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16094 ovl.fmt.RXE.d2); goto ok;
16095 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16096 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16097 ovl.fmt.RXE.d2); goto ok;
16098 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16099 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16100 ovl.fmt.RXE.d2); goto ok;
16101 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16102 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16103 ovl.fmt.RXE.d2); goto ok;
16104 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16105 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16106 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016107 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16108 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16109 ovl.fmt.RXY.dl2,
16110 ovl.fmt.RXY.dh2); goto ok;
16111 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16112 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16113 ovl.fmt.RXY.dl2,
16114 ovl.fmt.RXY.dh2); goto ok;
16115 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16116 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16117 ovl.fmt.RXY.dl2,
16118 ovl.fmt.RXY.dh2); goto ok;
16119 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16120 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16121 ovl.fmt.RXY.dl2,
16122 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000016123 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16124 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16125 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16126 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016127 }
16128
16129 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16130 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16131 ovl.fmt.RIL.i2); goto ok;
16132 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16133 ovl.fmt.RIL.i2); goto ok;
16134 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16135 ovl.fmt.RIL.i2); goto ok;
16136 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16137 ovl.fmt.RIL.i2); goto ok;
16138 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16139 ovl.fmt.RIL.i2); goto ok;
16140 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16141 ovl.fmt.RIL.i2); goto ok;
16142 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16143 ovl.fmt.RIL.i2); goto ok;
16144 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16145 ovl.fmt.RIL.i2); goto ok;
16146 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16147 ovl.fmt.RIL.i2); goto ok;
16148 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16149 ovl.fmt.RIL.i2); goto ok;
16150 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16151 ovl.fmt.RIL.i2); goto ok;
16152 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16153 ovl.fmt.RIL.i2); goto ok;
16154 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16155 ovl.fmt.RIL.i2); goto ok;
16156 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16157 ovl.fmt.RIL.i2); goto ok;
16158 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16159 ovl.fmt.RIL.i2); goto ok;
16160 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16161 ovl.fmt.RIL.i2); goto ok;
16162 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16163 ovl.fmt.RIL.i2); goto ok;
16164 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16165 ovl.fmt.RIL.i2); goto ok;
16166 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16167 ovl.fmt.RIL.i2); goto ok;
16168 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16169 ovl.fmt.RIL.i2); goto ok;
16170 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16171 ovl.fmt.RIL.i2); goto ok;
16172 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16173 ovl.fmt.RIL.i2); goto ok;
16174 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16175 ovl.fmt.RIL.i2); goto ok;
16176 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16177 ovl.fmt.RIL.i2); goto ok;
16178 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16179 ovl.fmt.RIL.i2); goto ok;
16180 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16181 ovl.fmt.RIL.i2); goto ok;
16182 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16183 ovl.fmt.RIL.i2); goto ok;
16184 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16185 ovl.fmt.RIL.i2); goto ok;
16186 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16187 ovl.fmt.RIL.i2); goto ok;
16188 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16189 ovl.fmt.RIL.i2); goto ok;
16190 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16191 ovl.fmt.RIL.i2); goto ok;
16192 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16193 ovl.fmt.RIL.i2); goto ok;
16194 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16195 ovl.fmt.RIL.i2); goto ok;
16196 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16197 ovl.fmt.RIL.i2); goto ok;
16198 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16199 ovl.fmt.RIL.i2); goto ok;
16200 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16201 ovl.fmt.RIL.i2); goto ok;
16202 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16203 ovl.fmt.RIL.i2); goto ok;
16204 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16205 ovl.fmt.RIL.i2); goto ok;
16206 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16207 ovl.fmt.RIL.i2); goto ok;
16208 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16209 ovl.fmt.RIL.i2); goto ok;
16210 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16211 ovl.fmt.RIL.i2); goto ok;
16212 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16213 ovl.fmt.RIL.i2); goto ok;
16214 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16215 ovl.fmt.RIL.i2); goto ok;
16216 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16217 ovl.fmt.RIL.i2); goto ok;
16218 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16219 ovl.fmt.RIL.i2); goto ok;
16220 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16221 ovl.fmt.RIL.i2); goto ok;
16222 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16223 ovl.fmt.RIL.i2); goto ok;
16224 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16225 ovl.fmt.RIL.i2); goto ok;
16226 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16227 ovl.fmt.RIL.i2); goto ok;
16228 case 0xc800ULL: /* MVCOS */ goto unimplemented;
16229 case 0xc801ULL: /* ECTG */ goto unimplemented;
16230 case 0xc802ULL: /* CSST */ goto unimplemented;
16231 case 0xc804ULL: /* LPD */ goto unimplemented;
16232 case 0xc805ULL: /* LPDG */ goto unimplemented;
16233 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
16234 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16235 ovl.fmt.RIL.i2); goto ok;
16236 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16237 ovl.fmt.RIL.i2); goto ok;
16238 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16239 ovl.fmt.RIL.i2); goto ok;
16240 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16241 ovl.fmt.RIL.i2); goto ok;
16242 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16243 ovl.fmt.RIL.i2); goto ok;
16244 }
16245
16246 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000016247 case 0xc5ULL: /* BPRP */ goto unimplemented;
16248 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016249 case 0xd0ULL: /* TRTR */ goto unimplemented;
16250 case 0xd1ULL: /* MVN */ goto unimplemented;
16251 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16252 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16253 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16254 case 0xd3ULL: /* MVZ */ goto unimplemented;
16255 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16256 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16257 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16258 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16259 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16260 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16261 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16262 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16263 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000016264 case 0xd7ULL:
16265 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16266 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16267 else
16268 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16269 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16270 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16271 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016272 case 0xd9ULL: /* MVCK */ goto unimplemented;
16273 case 0xdaULL: /* MVCP */ goto unimplemented;
16274 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000016275 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16276 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16277 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016278 case 0xddULL: /* TRT */ goto unimplemented;
16279 case 0xdeULL: /* ED */ goto unimplemented;
16280 case 0xdfULL: /* EDMK */ goto unimplemented;
16281 case 0xe1ULL: /* PKU */ goto unimplemented;
16282 case 0xe2ULL: /* UNPKU */ goto unimplemented;
16283 case 0xe8ULL: /* MVCIN */ goto unimplemented;
16284 case 0xe9ULL: /* PKA */ goto unimplemented;
16285 case 0xeaULL: /* UNPKA */ goto unimplemented;
16286 case 0xeeULL: /* PLO */ goto unimplemented;
16287 case 0xefULL: /* LMD */ goto unimplemented;
16288 case 0xf0ULL: /* SRP */ goto unimplemented;
16289 case 0xf1ULL: /* MVO */ goto unimplemented;
16290 case 0xf2ULL: /* PACK */ goto unimplemented;
16291 case 0xf3ULL: /* UNPK */ goto unimplemented;
16292 case 0xf8ULL: /* ZAP */ goto unimplemented;
16293 case 0xf9ULL: /* CP */ goto unimplemented;
16294 case 0xfaULL: /* AP */ goto unimplemented;
16295 case 0xfbULL: /* SP */ goto unimplemented;
16296 case 0xfcULL: /* MP */ goto unimplemented;
16297 case 0xfdULL: /* DP */ goto unimplemented;
16298 }
16299
16300 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16301 case 0xe500ULL: /* LASP */ goto unimplemented;
16302 case 0xe501ULL: /* TPROT */ goto unimplemented;
16303 case 0xe502ULL: /* STRAG */ goto unimplemented;
16304 case 0xe50eULL: /* MVCSK */ goto unimplemented;
16305 case 0xe50fULL: /* MVCDK */ goto unimplemented;
16306 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16307 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16308 goto ok;
16309 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16310 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16311 goto ok;
16312 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16313 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16314 goto ok;
16315 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16316 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16317 goto ok;
16318 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16319 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16320 goto ok;
16321 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16322 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16323 goto ok;
16324 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16325 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16326 goto ok;
16327 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16328 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16329 goto ok;
16330 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16331 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16332 goto ok;
florian2289cd42012-12-05 04:23:42 +000016333 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16334 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016335 }
16336
16337 return S390_DECODE_UNKNOWN_INSN;
16338
16339ok:
16340 return S390_DECODE_OK;
16341
16342unimplemented:
16343 return S390_DECODE_UNIMPLEMENTED_INSN;
16344}
16345
16346/* Handle "special" instructions. */
16347static s390_decode_t
16348s390_decode_special_and_irgen(UChar *bytes)
16349{
16350 s390_decode_t status = S390_DECODE_OK;
16351
16352 /* Got a "Special" instruction preamble. Which one is it? */
16353 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16354 s390_irgen_client_request();
16355 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16356 s390_irgen_guest_NRADDR();
16357 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16358 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016359 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16360 vex_inject_ir(irsb, Iend_BE);
16361
16362 /* Invalidate the current insn. The reason is that the IRop we're
16363 injecting here can change. In which case the translation has to
16364 be redone. For ease of handling, we simply invalidate all the
16365 time. */
16366 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
16367 mkU64(guest_IA_curr_instr)));
16368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
16369 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16370 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16371 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16372
16373 put_IA(mkaddr_expr(guest_IA_next_instr));
16374 dis_res->whatNext = Dis_StopHere;
16375 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000016376 } else {
16377 /* We don't know what it is. */
16378 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16379 }
16380
16381 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16382
16383 return status;
16384}
16385
16386
16387/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016388static UInt
sewardj2019a972011-03-07 16:04:07 +000016389s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
16390{
16391 s390_decode_t status;
16392
16393 dis_res = dres;
16394
16395 /* Spot the 8-byte preamble: 18ff lr r15,r15
16396 1811 lr r1,r1
16397 1822 lr r2,r2
16398 1833 lr r3,r3 */
16399 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16400 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16401 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16402
16403 /* Handle special instruction that follows that preamble. */
16404 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016405
16406 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16407 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16408
16409 status =
16410 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016411 } else {
16412 /* Handle normal instructions. */
16413 switch (insn_length) {
16414 case 2:
16415 status = s390_decode_2byte_and_irgen(bytes);
16416 break;
16417
16418 case 4:
16419 status = s390_decode_4byte_and_irgen(bytes);
16420 break;
16421
16422 case 6:
16423 status = s390_decode_6byte_and_irgen(bytes);
16424 break;
16425
16426 default:
16427 status = S390_DECODE_ERROR;
16428 break;
16429 }
16430 }
florian5fcbba22011-07-27 20:40:22 +000016431 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016432 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16433 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016434 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016435 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016436 }
16437
16438 if (status == S390_DECODE_OK) return insn_length; /* OK */
16439
16440 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016441 if (sigill_diag) {
16442 vex_printf("vex s390->IR: ");
16443 switch (status) {
16444 case S390_DECODE_UNKNOWN_INSN:
16445 vex_printf("unknown insn: ");
16446 break;
sewardj2019a972011-03-07 16:04:07 +000016447
sewardj442e51a2012-12-06 18:08:04 +000016448 case S390_DECODE_UNIMPLEMENTED_INSN:
16449 vex_printf("unimplemented insn: ");
16450 break;
sewardj2019a972011-03-07 16:04:07 +000016451
sewardj442e51a2012-12-06 18:08:04 +000016452 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16453 vex_printf("unimplemented special insn: ");
16454 break;
sewardj2019a972011-03-07 16:04:07 +000016455
sewardj442e51a2012-12-06 18:08:04 +000016456 default:
16457 case S390_DECODE_ERROR:
16458 vex_printf("decoding error: ");
16459 break;
16460 }
16461
16462 vex_printf("%02x%02x", bytes[0], bytes[1]);
16463 if (insn_length > 2) {
16464 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16465 }
16466 if (insn_length > 4) {
16467 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16468 }
16469 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016470 }
16471
sewardj2019a972011-03-07 16:04:07 +000016472 return 0; /* Failed */
16473}
16474
16475
sewardj2019a972011-03-07 16:04:07 +000016476/* Disassemble a single instruction INSN into IR. */
16477static DisResult
florian420c5012011-07-22 02:12:28 +000016478disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016479{
16480 UChar byte;
16481 UInt insn_length;
16482 DisResult dres;
16483
16484 /* ---------------------------------------------------- */
16485 /* --- Compute instruction length -- */
16486 /* ---------------------------------------------------- */
16487
16488 /* Get the first byte of the insn. */
16489 byte = insn[0];
16490
16491 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16492 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16493 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16494
16495 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16496
16497 /* ---------------------------------------------------- */
16498 /* --- Initialise the DisResult data -- */
16499 /* ---------------------------------------------------- */
16500 dres.whatNext = Dis_Continue;
16501 dres.len = insn_length;
16502 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016503 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000016504
floriana99f20e2011-07-17 14:16:41 +000016505 /* fixs390: consider chasing of conditional jumps */
16506
sewardj2019a972011-03-07 16:04:07 +000016507 /* Normal and special instruction handling starts here. */
16508 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16509 /* All decode failures end up here. The decoder has already issued an
16510 error message.
16511 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016512 not been executed, and (is currently) the next to be executed.
16513 The insn address in the guest state needs to be set to
16514 guest_IA_curr_instr, otherwise the complaint will report an
16515 incorrect address. */
16516 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016517
florian8844a632012-04-13 04:04:06 +000016518 dres.whatNext = Dis_StopHere;
16519 dres.jk_StopHere = Ijk_NoDecode;
16520 dres.continueAt = 0;
16521 dres.len = 0;
16522 } else {
16523 /* Decode success */
16524 switch (dres.whatNext) {
16525 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016526 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016527 break;
16528 case Dis_ResteerU:
16529 case Dis_ResteerC:
16530 put_IA(mkaddr_expr(dres.continueAt));
16531 break;
16532 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016533 if (dres.jk_StopHere == Ijk_EmWarn ||
16534 dres.jk_StopHere == Ijk_EmFail) {
16535 /* We assume here, that emulation warnings are not given for
16536 insns that transfer control. There is no good way to
16537 do that. */
16538 put_IA(mkaddr_expr(guest_IA_next_instr));
16539 }
florian8844a632012-04-13 04:04:06 +000016540 break;
16541 default:
16542 vassert(0);
16543 }
sewardj2019a972011-03-07 16:04:07 +000016544 }
16545
16546 return dres;
16547}
16548
16549
16550/*------------------------------------------------------------*/
16551/*--- Top-level fn ---*/
16552/*------------------------------------------------------------*/
16553
16554/* Disassemble a single instruction into IR. The instruction
16555 is located in host memory at &guest_code[delta]. */
16556
16557DisResult
16558disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000016559 Bool (*resteerOkFn)(void *, Addr64),
16560 Bool resteerCisOk,
16561 void *callback_opaque,
16562 UChar *guest_code,
16563 Long delta,
16564 Addr64 guest_IP,
16565 VexArch guest_arch,
16566 VexArchInfo *archinfo,
16567 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000016568 Bool host_bigendian,
16569 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016570{
16571 vassert(guest_arch == VexArchS390X);
16572
16573 /* The instruction decoder requires a big-endian machine. */
16574 vassert(host_bigendian == True);
16575
16576 /* Set globals (see top of this file) */
16577 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016578 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016579 resteer_fn = resteerOkFn;
16580 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016581 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016582
florian420c5012011-07-22 02:12:28 +000016583 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016584}
16585
16586/*---------------------------------------------------------------*/
16587/*--- end guest_s390_toIR.c ---*/
16588/*---------------------------------------------------------------*/