blob: f33189790a5b6eb5b740bdb01717cc6554374fb0 [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
635 op = mkU64(opc);
636 dep1 = mkexpr(d1);
637 dep2 = mkU64(0);
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, dep1, dep2, ndep);
641}
642
643
644/* Write a floating point value and an integer into the flags thunk. The
645 integer value is zero-extended first. */
646static void
647s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
648{
649 IRExpr *op, *dep1, *dep2, *ndep;
650
651 op = mkU64(opc);
652 dep1 = mkexpr(d1);
653 dep2 = s390_cc_widen(d2, False);
654 ndep = mkU64(0);
655
656 s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a 128-bit floating point value into the flags thunk. This is
661 done by splitting the value into two 64-bits values. */
662static void
663s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
664{
665 IRExpr *op, *hi, *lo, *ndep;
666
667 op = mkU64(opc);
668 hi = unop(Iop_F128HItoF64, mkexpr(d1));
669 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, hi, lo, ndep);
673}
674
675
676/* Write a 128-bit floating point value and an integer into the flags thunk.
677 The integer value is zero-extended first. */
678static void
679s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
680{
681 IRExpr *op, *hi, *lo, *lox, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
686 ndep = s390_cc_widen(nd, False);
687
688 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
689
690 s390_cc_thunk_fill(op, hi, lox, ndep);
691}
692
693
floriane38f6412012-12-21 17:32:12 +0000694/* Write a 128-bit decimal floating point value into the flags thunk.
695 This is done by splitting the value into two 64-bits values. */
696static void
697s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
698{
699 IRExpr *op, *hi, *lo, *ndep;
700
701 op = mkU64(opc);
702 hi = unop(Iop_D128HItoD64, mkexpr(d1));
703 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
704 ndep = mkU64(0);
705
706 s390_cc_thunk_fill(op, hi, lo, ndep);
707}
708
709
floriance9e3db2012-12-27 20:14:03 +0000710/* Write a 128-bit decimal floating point value and an integer into the flags
711 thunk. The integer value is zero-extended first. */
712static void
713s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
714{
715 IRExpr *op, *hi, *lo, *lox, *ndep;
716
717 op = mkU64(opc);
718 hi = unop(Iop_D128HItoD64, mkexpr(d1));
719 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
720 ndep = s390_cc_widen(nd, False);
721
722 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
723
724 s390_cc_thunk_fill(op, hi, lox, ndep);
725}
726
727
sewardj2019a972011-03-07 16:04:07 +0000728static void
729s390_cc_set(UInt val)
730{
731 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
732 mkU64(val), mkU64(0), mkU64(0));
733}
734
735/* Build IR to calculate the condition code from flags thunk.
736 Returns an expression of type Ity_I32 */
737static IRExpr *
738s390_call_calculate_cc(void)
739{
740 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
741
florian428dfdd2012-03-27 03:09:49 +0000742 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
743 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
744 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
745 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000746
747 args = mkIRExprVec_4(op, dep1, dep2, ndep);
748 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
749 "s390_calculate_cc", &s390_calculate_cc, args);
750
751 /* Exclude OP and NDEP from definedness checking. We're only
752 interested in DEP1 and DEP2. */
753 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
754
755 return call;
756}
757
758/* Build IR to calculate the internal condition code for a "compare and branch"
759 insn. Returns an expression of type Ity_I32 */
760static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000761s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000762{
florianff9613f2012-05-12 15:26:44 +0000763 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000764
florianff9613f2012-05-12 15:26:44 +0000765 switch (opc) {
766 case S390_CC_OP_SIGNED_COMPARE:
767 dep1 = s390_cc_widen(op1, True);
768 dep2 = s390_cc_widen(op2, True);
769 break;
770
771 case S390_CC_OP_UNSIGNED_COMPARE:
772 dep1 = s390_cc_widen(op1, False);
773 dep2 = s390_cc_widen(op2, False);
774 break;
775
776 default:
777 vpanic("s390_call_calculate_icc");
778 }
779
780 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000781 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000782
florianff9613f2012-05-12 15:26:44 +0000783 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000784 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000785 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000786
florianff9613f2012-05-12 15:26:44 +0000787 /* Exclude the requested condition, OP and NDEP from definedness
788 checking. We're only interested in DEP1 and DEP2. */
789 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000790
791 return call;
792}
793
794/* Build IR to calculate the condition code from flags thunk.
795 Returns an expression of type Ity_I32 */
796static IRExpr *
797s390_call_calculate_cond(UInt m)
798{
799 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
800
801 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000802 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
803 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
804 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
805 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000806
807 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
808 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
809 "s390_calculate_cond", &s390_calculate_cond, args);
810
811 /* Exclude the requested condition, OP and NDEP from definedness
812 checking. We're only interested in DEP1 and DEP2. */
813 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
814
815 return call;
816}
817
818#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
819#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
820#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
821#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
822#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
823#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
824#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
825 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
826#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
827 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000828
829
sewardj2019a972011-03-07 16:04:07 +0000830
831
832/*------------------------------------------------------------*/
833/*--- Guest register access ---*/
834/*------------------------------------------------------------*/
835
836
837/*------------------------------------------------------------*/
838/*--- ar registers ---*/
839/*------------------------------------------------------------*/
840
841/* Return the guest state offset of a ar register. */
842static UInt
843ar_offset(UInt archreg)
844{
845 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000846 S390X_GUEST_OFFSET(guest_a0),
847 S390X_GUEST_OFFSET(guest_a1),
848 S390X_GUEST_OFFSET(guest_a2),
849 S390X_GUEST_OFFSET(guest_a3),
850 S390X_GUEST_OFFSET(guest_a4),
851 S390X_GUEST_OFFSET(guest_a5),
852 S390X_GUEST_OFFSET(guest_a6),
853 S390X_GUEST_OFFSET(guest_a7),
854 S390X_GUEST_OFFSET(guest_a8),
855 S390X_GUEST_OFFSET(guest_a9),
856 S390X_GUEST_OFFSET(guest_a10),
857 S390X_GUEST_OFFSET(guest_a11),
858 S390X_GUEST_OFFSET(guest_a12),
859 S390X_GUEST_OFFSET(guest_a13),
860 S390X_GUEST_OFFSET(guest_a14),
861 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000862 };
863
864 vassert(archreg < 16);
865
866 return offset[archreg];
867}
868
869
870/* Return the guest state offset of word #0 of a ar register. */
871static __inline__ UInt
872ar_w0_offset(UInt archreg)
873{
874 return ar_offset(archreg) + 0;
875}
876
877/* Write word #0 of a ar to the guest state. */
878static __inline__ void
879put_ar_w0(UInt archreg, IRExpr *expr)
880{
881 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
882
883 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
884}
885
886/* Read word #0 of a ar register. */
887static __inline__ IRExpr *
888get_ar_w0(UInt archreg)
889{
890 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
891}
892
893
894/*------------------------------------------------------------*/
895/*--- fpr registers ---*/
896/*------------------------------------------------------------*/
897
898/* Return the guest state offset of a fpr register. */
899static UInt
900fpr_offset(UInt archreg)
901{
902 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000903 S390X_GUEST_OFFSET(guest_f0),
904 S390X_GUEST_OFFSET(guest_f1),
905 S390X_GUEST_OFFSET(guest_f2),
906 S390X_GUEST_OFFSET(guest_f3),
907 S390X_GUEST_OFFSET(guest_f4),
908 S390X_GUEST_OFFSET(guest_f5),
909 S390X_GUEST_OFFSET(guest_f6),
910 S390X_GUEST_OFFSET(guest_f7),
911 S390X_GUEST_OFFSET(guest_f8),
912 S390X_GUEST_OFFSET(guest_f9),
913 S390X_GUEST_OFFSET(guest_f10),
914 S390X_GUEST_OFFSET(guest_f11),
915 S390X_GUEST_OFFSET(guest_f12),
916 S390X_GUEST_OFFSET(guest_f13),
917 S390X_GUEST_OFFSET(guest_f14),
918 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000919 };
920
921 vassert(archreg < 16);
922
923 return offset[archreg];
924}
925
926
927/* Return the guest state offset of word #0 of a fpr register. */
928static __inline__ UInt
929fpr_w0_offset(UInt archreg)
930{
931 return fpr_offset(archreg) + 0;
932}
933
934/* Write word #0 of a fpr to the guest state. */
935static __inline__ void
936put_fpr_w0(UInt archreg, IRExpr *expr)
937{
938 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
939
940 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
941}
942
943/* Read word #0 of a fpr register. */
944static __inline__ IRExpr *
945get_fpr_w0(UInt archreg)
946{
947 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
948}
949
950/* Return the guest state offset of double word #0 of a fpr register. */
951static __inline__ UInt
952fpr_dw0_offset(UInt archreg)
953{
954 return fpr_offset(archreg) + 0;
955}
956
957/* Write double word #0 of a fpr to the guest state. */
958static __inline__ void
959put_fpr_dw0(UInt archreg, IRExpr *expr)
960{
961 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
962
963 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
964}
965
966/* Read double word #0 of a fpr register. */
967static __inline__ IRExpr *
968get_fpr_dw0(UInt archreg)
969{
970 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
971}
972
floriane38f6412012-12-21 17:32:12 +0000973/* Write word #0 of a dpr to the guest state. */
974static __inline__ void
975put_dpr_w0(UInt archreg, IRExpr *expr)
976{
977 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
978
979 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
980}
981
982/* Read word #0 of a dpr register. */
983static __inline__ IRExpr *
984get_dpr_w0(UInt archreg)
985{
986 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
987}
988
florian12390202012-11-10 22:34:14 +0000989/* Write double word #0 of a fpr containg DFP value to the guest state. */
990static __inline__ void
991put_dpr_dw0(UInt archreg, IRExpr *expr)
992{
993 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
994
995 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
996}
997
998/* Read double word #0 of a fpr register containing DFP value. */
999static __inline__ IRExpr *
1000get_dpr_dw0(UInt archreg)
1001{
1002 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1003}
sewardj2019a972011-03-07 16:04:07 +00001004
1005/*------------------------------------------------------------*/
1006/*--- gpr registers ---*/
1007/*------------------------------------------------------------*/
1008
1009/* Return the guest state offset of a gpr register. */
1010static UInt
1011gpr_offset(UInt archreg)
1012{
1013 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001014 S390X_GUEST_OFFSET(guest_r0),
1015 S390X_GUEST_OFFSET(guest_r1),
1016 S390X_GUEST_OFFSET(guest_r2),
1017 S390X_GUEST_OFFSET(guest_r3),
1018 S390X_GUEST_OFFSET(guest_r4),
1019 S390X_GUEST_OFFSET(guest_r5),
1020 S390X_GUEST_OFFSET(guest_r6),
1021 S390X_GUEST_OFFSET(guest_r7),
1022 S390X_GUEST_OFFSET(guest_r8),
1023 S390X_GUEST_OFFSET(guest_r9),
1024 S390X_GUEST_OFFSET(guest_r10),
1025 S390X_GUEST_OFFSET(guest_r11),
1026 S390X_GUEST_OFFSET(guest_r12),
1027 S390X_GUEST_OFFSET(guest_r13),
1028 S390X_GUEST_OFFSET(guest_r14),
1029 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001030 };
1031
1032 vassert(archreg < 16);
1033
1034 return offset[archreg];
1035}
1036
1037
1038/* Return the guest state offset of word #0 of a gpr register. */
1039static __inline__ UInt
1040gpr_w0_offset(UInt archreg)
1041{
1042 return gpr_offset(archreg) + 0;
1043}
1044
1045/* Write word #0 of a gpr to the guest state. */
1046static __inline__ void
1047put_gpr_w0(UInt archreg, IRExpr *expr)
1048{
1049 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1050
1051 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1052}
1053
1054/* Read word #0 of a gpr register. */
1055static __inline__ IRExpr *
1056get_gpr_w0(UInt archreg)
1057{
1058 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1059}
1060
1061/* Return the guest state offset of double word #0 of a gpr register. */
1062static __inline__ UInt
1063gpr_dw0_offset(UInt archreg)
1064{
1065 return gpr_offset(archreg) + 0;
1066}
1067
1068/* Write double word #0 of a gpr to the guest state. */
1069static __inline__ void
1070put_gpr_dw0(UInt archreg, IRExpr *expr)
1071{
1072 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1073
1074 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1075}
1076
1077/* Read double word #0 of a gpr register. */
1078static __inline__ IRExpr *
1079get_gpr_dw0(UInt archreg)
1080{
1081 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1082}
1083
1084/* Return the guest state offset of half word #1 of a gpr register. */
1085static __inline__ UInt
1086gpr_hw1_offset(UInt archreg)
1087{
1088 return gpr_offset(archreg) + 2;
1089}
1090
1091/* Write half word #1 of a gpr to the guest state. */
1092static __inline__ void
1093put_gpr_hw1(UInt archreg, IRExpr *expr)
1094{
1095 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1096
1097 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1098}
1099
1100/* Read half word #1 of a gpr register. */
1101static __inline__ IRExpr *
1102get_gpr_hw1(UInt archreg)
1103{
1104 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1105}
1106
1107/* Return the guest state offset of byte #6 of a gpr register. */
1108static __inline__ UInt
1109gpr_b6_offset(UInt archreg)
1110{
1111 return gpr_offset(archreg) + 6;
1112}
1113
1114/* Write byte #6 of a gpr to the guest state. */
1115static __inline__ void
1116put_gpr_b6(UInt archreg, IRExpr *expr)
1117{
1118 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1119
1120 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1121}
1122
1123/* Read byte #6 of a gpr register. */
1124static __inline__ IRExpr *
1125get_gpr_b6(UInt archreg)
1126{
1127 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1128}
1129
1130/* Return the guest state offset of byte #3 of a gpr register. */
1131static __inline__ UInt
1132gpr_b3_offset(UInt archreg)
1133{
1134 return gpr_offset(archreg) + 3;
1135}
1136
1137/* Write byte #3 of a gpr to the guest state. */
1138static __inline__ void
1139put_gpr_b3(UInt archreg, IRExpr *expr)
1140{
1141 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1142
1143 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1144}
1145
1146/* Read byte #3 of a gpr register. */
1147static __inline__ IRExpr *
1148get_gpr_b3(UInt archreg)
1149{
1150 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1151}
1152
1153/* Return the guest state offset of byte #0 of a gpr register. */
1154static __inline__ UInt
1155gpr_b0_offset(UInt archreg)
1156{
1157 return gpr_offset(archreg) + 0;
1158}
1159
1160/* Write byte #0 of a gpr to the guest state. */
1161static __inline__ void
1162put_gpr_b0(UInt archreg, IRExpr *expr)
1163{
1164 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1165
1166 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1167}
1168
1169/* Read byte #0 of a gpr register. */
1170static __inline__ IRExpr *
1171get_gpr_b0(UInt archreg)
1172{
1173 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1174}
1175
1176/* Return the guest state offset of word #1 of a gpr register. */
1177static __inline__ UInt
1178gpr_w1_offset(UInt archreg)
1179{
1180 return gpr_offset(archreg) + 4;
1181}
1182
1183/* Write word #1 of a gpr to the guest state. */
1184static __inline__ void
1185put_gpr_w1(UInt archreg, IRExpr *expr)
1186{
1187 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1188
1189 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1190}
1191
1192/* Read word #1 of a gpr register. */
1193static __inline__ IRExpr *
1194get_gpr_w1(UInt archreg)
1195{
1196 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1197}
1198
1199/* Return the guest state offset of half word #3 of a gpr register. */
1200static __inline__ UInt
1201gpr_hw3_offset(UInt archreg)
1202{
1203 return gpr_offset(archreg) + 6;
1204}
1205
1206/* Write half word #3 of a gpr to the guest state. */
1207static __inline__ void
1208put_gpr_hw3(UInt archreg, IRExpr *expr)
1209{
1210 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1211
1212 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1213}
1214
1215/* Read half word #3 of a gpr register. */
1216static __inline__ IRExpr *
1217get_gpr_hw3(UInt archreg)
1218{
1219 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1220}
1221
1222/* Return the guest state offset of byte #7 of a gpr register. */
1223static __inline__ UInt
1224gpr_b7_offset(UInt archreg)
1225{
1226 return gpr_offset(archreg) + 7;
1227}
1228
1229/* Write byte #7 of a gpr to the guest state. */
1230static __inline__ void
1231put_gpr_b7(UInt archreg, IRExpr *expr)
1232{
1233 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1234
1235 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1236}
1237
1238/* Read byte #7 of a gpr register. */
1239static __inline__ IRExpr *
1240get_gpr_b7(UInt archreg)
1241{
1242 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1243}
1244
1245/* Return the guest state offset of half word #0 of a gpr register. */
1246static __inline__ UInt
1247gpr_hw0_offset(UInt archreg)
1248{
1249 return gpr_offset(archreg) + 0;
1250}
1251
1252/* Write half word #0 of a gpr to the guest state. */
1253static __inline__ void
1254put_gpr_hw0(UInt archreg, IRExpr *expr)
1255{
1256 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1257
1258 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1259}
1260
1261/* Read half word #0 of a gpr register. */
1262static __inline__ IRExpr *
1263get_gpr_hw0(UInt archreg)
1264{
1265 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1266}
1267
1268/* Return the guest state offset of byte #4 of a gpr register. */
1269static __inline__ UInt
1270gpr_b4_offset(UInt archreg)
1271{
1272 return gpr_offset(archreg) + 4;
1273}
1274
1275/* Write byte #4 of a gpr to the guest state. */
1276static __inline__ void
1277put_gpr_b4(UInt archreg, IRExpr *expr)
1278{
1279 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1280
1281 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1282}
1283
1284/* Read byte #4 of a gpr register. */
1285static __inline__ IRExpr *
1286get_gpr_b4(UInt archreg)
1287{
1288 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1289}
1290
1291/* Return the guest state offset of byte #1 of a gpr register. */
1292static __inline__ UInt
1293gpr_b1_offset(UInt archreg)
1294{
1295 return gpr_offset(archreg) + 1;
1296}
1297
1298/* Write byte #1 of a gpr to the guest state. */
1299static __inline__ void
1300put_gpr_b1(UInt archreg, IRExpr *expr)
1301{
1302 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1303
1304 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1305}
1306
1307/* Read byte #1 of a gpr register. */
1308static __inline__ IRExpr *
1309get_gpr_b1(UInt archreg)
1310{
1311 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1312}
1313
1314/* Return the guest state offset of half word #2 of a gpr register. */
1315static __inline__ UInt
1316gpr_hw2_offset(UInt archreg)
1317{
1318 return gpr_offset(archreg) + 4;
1319}
1320
1321/* Write half word #2 of a gpr to the guest state. */
1322static __inline__ void
1323put_gpr_hw2(UInt archreg, IRExpr *expr)
1324{
1325 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1326
1327 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1328}
1329
1330/* Read half word #2 of a gpr register. */
1331static __inline__ IRExpr *
1332get_gpr_hw2(UInt archreg)
1333{
1334 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1335}
1336
1337/* Return the guest state offset of byte #5 of a gpr register. */
1338static __inline__ UInt
1339gpr_b5_offset(UInt archreg)
1340{
1341 return gpr_offset(archreg) + 5;
1342}
1343
1344/* Write byte #5 of a gpr to the guest state. */
1345static __inline__ void
1346put_gpr_b5(UInt archreg, IRExpr *expr)
1347{
1348 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1349
1350 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1351}
1352
1353/* Read byte #5 of a gpr register. */
1354static __inline__ IRExpr *
1355get_gpr_b5(UInt archreg)
1356{
1357 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1358}
1359
1360/* Return the guest state offset of byte #2 of a gpr register. */
1361static __inline__ UInt
1362gpr_b2_offset(UInt archreg)
1363{
1364 return gpr_offset(archreg) + 2;
1365}
1366
1367/* Write byte #2 of a gpr to the guest state. */
1368static __inline__ void
1369put_gpr_b2(UInt archreg, IRExpr *expr)
1370{
1371 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1372
1373 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1374}
1375
1376/* Read byte #2 of a gpr register. */
1377static __inline__ IRExpr *
1378get_gpr_b2(UInt archreg)
1379{
1380 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1381}
1382
1383/* Return the guest state offset of the counter register. */
1384static UInt
1385counter_offset(void)
1386{
floriane88b3c92011-07-05 02:48:39 +00001387 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001388}
1389
1390/* Return the guest state offset of double word #0 of the counter register. */
1391static __inline__ UInt
1392counter_dw0_offset(void)
1393{
1394 return counter_offset() + 0;
1395}
1396
1397/* Write double word #0 of the counter to the guest state. */
1398static __inline__ void
1399put_counter_dw0(IRExpr *expr)
1400{
1401 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1402
1403 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1404}
1405
1406/* Read double word #0 of the counter register. */
1407static __inline__ IRExpr *
1408get_counter_dw0(void)
1409{
1410 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1411}
1412
1413/* Return the guest state offset of word #0 of the counter register. */
1414static __inline__ UInt
1415counter_w0_offset(void)
1416{
1417 return counter_offset() + 0;
1418}
1419
1420/* Return the guest state offset of word #1 of the counter register. */
1421static __inline__ UInt
1422counter_w1_offset(void)
1423{
1424 return counter_offset() + 4;
1425}
1426
1427/* Write word #0 of the counter to the guest state. */
1428static __inline__ void
1429put_counter_w0(IRExpr *expr)
1430{
1431 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1432
1433 stmt(IRStmt_Put(counter_w0_offset(), expr));
1434}
1435
1436/* Read word #0 of the counter register. */
1437static __inline__ IRExpr *
1438get_counter_w0(void)
1439{
1440 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1441}
1442
1443/* Write word #1 of the counter to the guest state. */
1444static __inline__ void
1445put_counter_w1(IRExpr *expr)
1446{
1447 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1448
1449 stmt(IRStmt_Put(counter_w1_offset(), expr));
1450}
1451
1452/* Read word #1 of the counter register. */
1453static __inline__ IRExpr *
1454get_counter_w1(void)
1455{
1456 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1457}
1458
1459/* Return the guest state offset of the fpc register. */
1460static UInt
1461fpc_offset(void)
1462{
floriane88b3c92011-07-05 02:48:39 +00001463 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001464}
1465
1466/* Return the guest state offset of word #0 of the fpc register. */
1467static __inline__ UInt
1468fpc_w0_offset(void)
1469{
1470 return fpc_offset() + 0;
1471}
1472
1473/* Write word #0 of the fpc to the guest state. */
1474static __inline__ void
1475put_fpc_w0(IRExpr *expr)
1476{
1477 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1478
1479 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1480}
1481
1482/* Read word #0 of the fpc register. */
1483static __inline__ IRExpr *
1484get_fpc_w0(void)
1485{
1486 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1487}
1488
1489
1490/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001491/*--- Rounding modes ---*/
1492/*------------------------------------------------------------*/
1493
florian125e20d2012-10-07 15:42:37 +00001494/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001495 IRRoundingMode:
1496
1497 rounding mode | s390 | IR
1498 -------------------------
1499 to nearest | 00 | 00
1500 to zero | 01 | 11
1501 to +infinity | 10 | 10
1502 to -infinity | 11 | 01
1503
1504 So: IR = (4 - s390) & 3
1505*/
1506static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001507get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001508{
1509 IRTemp fpc_bits = newTemp(Ity_I32);
1510
1511 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1512 Prior to that bits [30:31] contained the bfp rounding mode with
1513 bit 29 being unused and having a value of 0. So we can always
1514 extract the least significant 3 bits. */
1515 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1516
1517 /* fixs390:
1518
1519
1520 if (! s390_host_has_fpext && rounding_mode > 3) {
1521 emulation warning @ runtime and
1522 set fpc to round nearest
1523 }
1524 */
1525
1526 /* For now silently adjust an unsupported rounding mode to "nearest" */
1527 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1528 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001529 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001530
1531 // rm_IR = (4 - rm_s390) & 3;
1532 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1533}
1534
1535/* Encode the s390 rounding mode as it appears in the m3 field of certain
1536 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1537 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1538 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1539 considers the default rounding mode (4.3.3). */
1540static IRTemp
1541encode_bfp_rounding_mode(UChar mode)
1542{
1543 IRExpr *rm;
1544
1545 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001546 case S390_BFP_ROUND_PER_FPC:
1547 rm = get_bfp_rounding_mode_from_fpc();
1548 break;
1549 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1550 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1551 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1552 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1553 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1554 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001555 default:
1556 vpanic("encode_bfp_rounding_mode");
1557 }
1558
1559 return mktemp(Ity_I32, rm);
1560}
1561
florianc8e4f562012-10-27 16:19:31 +00001562/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1563 IRRoundingMode:
1564
1565 rounding mode | s390 | IR
1566 ------------------------------------------------
1567 to nearest, ties to even | 000 | 000
1568 to zero | 001 | 011
1569 to +infinity | 010 | 010
1570 to -infinity | 011 | 001
1571 to nearest, ties away from 0 | 100 | 100
1572 to nearest, ties toward 0 | 101 | 111
1573 to away from 0 | 110 | 110
1574 to prepare for shorter precision | 111 | 101
1575
1576 So: IR = (s390 ^ ((s390 << 1) & 2))
1577*/
florianc8e4f562012-10-27 16:19:31 +00001578static IRExpr *
1579get_dfp_rounding_mode_from_fpc(void)
1580{
1581 IRTemp fpc_bits = newTemp(Ity_I32);
1582
1583 /* The dfp rounding mode is stored in bits [25:27].
1584 extract the bits at 25:27 and right shift 4 times. */
1585 assign(fpc_bits, binop(Iop_Shr32,
1586 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1587 mkU8(4)));
1588
1589 IRExpr *rm_s390 = mkexpr(fpc_bits);
1590 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1591
1592 return binop(Iop_Xor32, rm_s390,
1593 binop( Iop_And32,
1594 binop(Iop_Shl32, rm_s390, mkU8(1)),
1595 mkU32(2)));
1596}
1597
1598/* Encode the s390 rounding mode as it appears in the m3 field of certain
1599 instructions to VEX's IRRoundingMode. */
1600static IRTemp
1601encode_dfp_rounding_mode(UChar mode)
1602{
1603 IRExpr *rm;
1604
1605 switch (mode) {
1606 case S390_DFP_ROUND_PER_FPC_0:
1607 case S390_DFP_ROUND_PER_FPC_2:
1608 rm = get_dfp_rounding_mode_from_fpc(); break;
1609 case S390_DFP_ROUND_NEAREST_EVEN_4:
1610 case S390_DFP_ROUND_NEAREST_EVEN_8:
1611 rm = mkU32(Irrm_DFP_NEAREST); break;
1612 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1613 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1614 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1615 case S390_DFP_ROUND_PREPARE_SHORT_3:
1616 case S390_DFP_ROUND_PREPARE_SHORT_15:
1617 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1618 case S390_DFP_ROUND_ZERO_5:
1619 case S390_DFP_ROUND_ZERO_9:
1620 rm = mkU32(Irrm_DFP_ZERO ); break;
1621 case S390_DFP_ROUND_POSINF_6:
1622 case S390_DFP_ROUND_POSINF_10:
1623 rm = mkU32(Irrm_DFP_PosINF); break;
1624 case S390_DFP_ROUND_NEGINF_7:
1625 case S390_DFP_ROUND_NEGINF_11:
1626 rm = mkU32(Irrm_DFP_NegINF); break;
1627 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1628 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1629 case S390_DFP_ROUND_AWAY_0:
1630 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1631 default:
1632 vpanic("encode_dfp_rounding_mode");
1633 }
1634
1635 return mktemp(Ity_I32, rm);
1636}
florian12390202012-11-10 22:34:14 +00001637
florianc8e4f562012-10-27 16:19:31 +00001638
florian2c74d242012-09-12 19:38:42 +00001639/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001640/*--- Condition code helpers ---*/
1641/*------------------------------------------------------------*/
1642
1643/* The result of a Iop_CmpFxx operation is a condition code. It is
1644 encoded using the values defined in type IRCmpFxxResult.
1645 Before we can store the condition code into the guest state (or do
1646 anything else with it for that matter) we need to convert it to
1647 the encoding that s390 uses. This is what this function does.
1648
1649 s390 VEX b6 b2 b0 cc.1 cc.0
1650 0 0x40 EQ 1 0 0 0 0
1651 1 0x01 LT 0 0 1 0 1
1652 2 0x00 GT 0 0 0 1 0
1653 3 0x45 Unordered 1 1 1 1 1
1654
1655 The following bits from the VEX encoding are interesting:
1656 b0, b2, b6 with b0 being the LSB. We observe:
1657
1658 cc.0 = b0;
1659 cc.1 = b2 | (~b0 & ~b6)
1660
1661 with cc being the s390 condition code.
1662*/
1663static IRExpr *
1664convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1665{
1666 IRTemp cc0 = newTemp(Ity_I32);
1667 IRTemp cc1 = newTemp(Ity_I32);
1668 IRTemp b0 = newTemp(Ity_I32);
1669 IRTemp b2 = newTemp(Ity_I32);
1670 IRTemp b6 = newTemp(Ity_I32);
1671
1672 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1673 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1674 mkU32(1)));
1675 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1676 mkU32(1)));
1677
1678 assign(cc0, mkexpr(b0));
1679 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1680 binop(Iop_And32,
1681 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1682 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1683 )));
1684
1685 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1686}
1687
1688
1689/* The result of a Iop_CmpDxx operation is a condition code. It is
1690 encoded using the values defined in type IRCmpDxxResult.
1691 Before we can store the condition code into the guest state (or do
1692 anything else with it for that matter) we need to convert it to
1693 the encoding that s390 uses. This is what this function does. */
1694static IRExpr *
1695convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1696{
1697 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1698 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001699 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001700}
1701
1702
1703/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001704/*--- Build IR for formats ---*/
1705/*------------------------------------------------------------*/
1706static void
florian55085f82012-11-21 00:36:55 +00001707s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001708 UChar i)
1709{
florian55085f82012-11-21 00:36:55 +00001710 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001711
sewardj7ee97522011-05-09 21:45:04 +00001712 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001713 s390_disasm(ENC2(MNM, UINT), mnm, i);
1714}
1715
1716static void
florian78d5ef72013-05-11 15:02:58 +00001717s390_format_E(const HChar *(*irgen)(void))
1718{
1719 const HChar *mnm = irgen();
1720
1721 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1722 s390_disasm(ENC1(MNM), mnm);
1723}
1724
1725static void
florian55085f82012-11-21 00:36:55 +00001726s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001727 UChar r1, UShort i2)
1728{
1729 irgen(r1, i2);
1730}
1731
1732static void
florian55085f82012-11-21 00:36:55 +00001733s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001734 UChar r1, UShort i2)
1735{
florian55085f82012-11-21 00:36:55 +00001736 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001737
sewardj7ee97522011-05-09 21:45:04 +00001738 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001739 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1740}
1741
1742static void
florian55085f82012-11-21 00:36:55 +00001743s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001744 UChar r1, UShort i2)
1745{
florian55085f82012-11-21 00:36:55 +00001746 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001747
sewardj7ee97522011-05-09 21:45:04 +00001748 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001749 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1750}
1751
1752static void
florian55085f82012-11-21 00:36:55 +00001753s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001754 UChar r1, UShort i2)
1755{
florian55085f82012-11-21 00:36:55 +00001756 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001757
sewardj7ee97522011-05-09 21:45:04 +00001758 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001759 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1760}
1761
1762static void
florian55085f82012-11-21 00:36:55 +00001763s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001764 UChar r1, UChar r3, UShort i2)
1765{
florian55085f82012-11-21 00:36:55 +00001766 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001767
sewardj7ee97522011-05-09 21:45:04 +00001768 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001769 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1770}
1771
1772static void
florian55085f82012-11-21 00:36:55 +00001773s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001774 UChar r1, UChar r3, UShort i2)
1775{
florian55085f82012-11-21 00:36:55 +00001776 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001777
sewardj7ee97522011-05-09 21:45:04 +00001778 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001779 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1780}
1781
1782static void
florian55085f82012-11-21 00:36:55 +00001783s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1784 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001785 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1786{
florian55085f82012-11-21 00:36:55 +00001787 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001788
sewardj7ee97522011-05-09 21:45:04 +00001789 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001790 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1791 i5);
1792}
1793
1794static void
florian55085f82012-11-21 00:36:55 +00001795s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1796 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001797 UChar r1, UChar r2, UShort i4, UChar m3)
1798{
florian55085f82012-11-21 00:36:55 +00001799 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001800
sewardj7ee97522011-05-09 21:45:04 +00001801 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001802 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1803 r2, m3, (Int)(Short)i4);
1804}
1805
1806static void
florian55085f82012-11-21 00:36:55 +00001807s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1808 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001809 UChar r1, UChar m3, UShort i4, UChar i2)
1810{
florian55085f82012-11-21 00:36:55 +00001811 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001812
sewardj7ee97522011-05-09 21:45:04 +00001813 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001814 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1815 r1, i2, m3, (Int)(Short)i4);
1816}
1817
1818static void
florian55085f82012-11-21 00:36:55 +00001819s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1820 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001821 UChar r1, UChar m3, UShort i4, UChar i2)
1822{
florian55085f82012-11-21 00:36:55 +00001823 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001824
sewardj7ee97522011-05-09 21:45:04 +00001825 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001826 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1827 (Int)(Char)i2, m3, (Int)(Short)i4);
1828}
1829
1830static void
florian55085f82012-11-21 00:36:55 +00001831s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001832 UChar r1, UInt i2)
1833{
1834 irgen(r1, i2);
1835}
1836
1837static void
florian55085f82012-11-21 00:36:55 +00001838s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001839 UChar r1, UInt i2)
1840{
florian55085f82012-11-21 00:36:55 +00001841 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001842
sewardj7ee97522011-05-09 21:45:04 +00001843 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001844 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1845}
1846
1847static void
florian55085f82012-11-21 00:36:55 +00001848s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001849 UChar r1, UInt i2)
1850{
florian55085f82012-11-21 00:36:55 +00001851 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001852
sewardj7ee97522011-05-09 21:45:04 +00001853 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001854 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1855}
1856
1857static void
florian55085f82012-11-21 00:36:55 +00001858s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001859 UChar r1, UInt i2)
1860{
florian55085f82012-11-21 00:36:55 +00001861 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001862
sewardj7ee97522011-05-09 21:45:04 +00001863 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001864 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1865}
1866
1867static void
florian55085f82012-11-21 00:36:55 +00001868s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001869 UChar r1, UInt i2)
1870{
florian55085f82012-11-21 00:36:55 +00001871 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001872
sewardj7ee97522011-05-09 21:45:04 +00001873 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001874 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1875}
1876
1877static void
florian55085f82012-11-21 00:36:55 +00001878s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001879 IRTemp op4addr),
1880 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1881{
florian55085f82012-11-21 00:36:55 +00001882 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001883 IRTemp op4addr = newTemp(Ity_I64);
1884
1885 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1886 mkU64(0)));
1887
1888 mnm = irgen(r1, m3, i2, op4addr);
1889
sewardj7ee97522011-05-09 21:45:04 +00001890 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001891 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1892 (Int)(Char)i2, m3, d4, 0, b4);
1893}
1894
1895static void
florian55085f82012-11-21 00:36:55 +00001896s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001897 IRTemp op4addr),
1898 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1899{
florian55085f82012-11-21 00:36:55 +00001900 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001901 IRTemp op4addr = newTemp(Ity_I64);
1902
1903 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1904 mkU64(0)));
1905
1906 mnm = irgen(r1, m3, i2, op4addr);
1907
sewardj7ee97522011-05-09 21:45:04 +00001908 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001909 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1910 i2, m3, d4, 0, b4);
1911}
1912
1913static void
florian55085f82012-11-21 00:36:55 +00001914s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001915 UChar r1, UChar r2)
1916{
1917 irgen(r1, r2);
1918}
1919
1920static void
florian55085f82012-11-21 00:36:55 +00001921s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001922 UChar r1, UChar r2)
1923{
florian55085f82012-11-21 00:36:55 +00001924 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001925
sewardj7ee97522011-05-09 21:45:04 +00001926 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001927 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1928}
1929
1930static void
florian55085f82012-11-21 00:36:55 +00001931s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001932 UChar r1, UChar r2)
1933{
florian55085f82012-11-21 00:36:55 +00001934 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001935
sewardj7ee97522011-05-09 21:45:04 +00001936 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001937 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1938}
1939
1940static void
florian55085f82012-11-21 00:36:55 +00001941s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001942 UChar r1, UChar r2)
1943{
1944 irgen(r1, r2);
1945}
1946
1947static void
florian55085f82012-11-21 00:36:55 +00001948s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001949 UChar r1, UChar r2)
1950{
florian55085f82012-11-21 00:36:55 +00001951 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001952
sewardj7ee97522011-05-09 21:45:04 +00001953 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001954 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1955}
1956
1957static void
florian55085f82012-11-21 00:36:55 +00001958s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001959 UChar r1, UChar r2)
1960{
florian55085f82012-11-21 00:36:55 +00001961 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001962
sewardj7ee97522011-05-09 21:45:04 +00001963 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001964 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1965}
1966
1967static void
florian55085f82012-11-21 00:36:55 +00001968s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001969 UChar r1, UChar r2)
1970{
florian55085f82012-11-21 00:36:55 +00001971 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001972
sewardj7ee97522011-05-09 21:45:04 +00001973 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001974 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1975}
1976
1977static void
florian55085f82012-11-21 00:36:55 +00001978s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001979 UChar r1, UChar r2)
1980{
florian55085f82012-11-21 00:36:55 +00001981 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001982
sewardj7ee97522011-05-09 21:45:04 +00001983 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001984 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1985}
1986
1987static void
florian55085f82012-11-21 00:36:55 +00001988s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001989 UChar r1)
1990{
florian55085f82012-11-21 00:36:55 +00001991 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001992
sewardj7ee97522011-05-09 21:45:04 +00001993 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001994 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1995}
1996
1997static void
florian55085f82012-11-21 00:36:55 +00001998s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001999 UChar r1)
2000{
florian55085f82012-11-21 00:36:55 +00002001 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002002
sewardj7ee97522011-05-09 21:45:04 +00002003 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002004 s390_disasm(ENC2(MNM, FPR), mnm, r1);
2005}
2006
2007static void
florian55085f82012-11-21 00:36:55 +00002008s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002009 UChar m3, UChar r1, UChar r2)
2010{
florian55085f82012-11-21 00:36:55 +00002011 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002012
2013 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002014 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002015}
2016
2017static void
florian55085f82012-11-21 00:36:55 +00002018s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002019 UChar r1, UChar r3, UChar r2)
2020{
florian55085f82012-11-21 00:36:55 +00002021 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002022
sewardj7ee97522011-05-09 21:45:04 +00002023 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002024 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2025}
2026
2027static void
florian5c539732013-02-14 14:27:12 +00002028s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2029 UChar r3, UChar r1, UChar r2)
2030{
2031 const HChar *mnm = irgen(r3, r1, r2);
2032
2033 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2034 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2035}
2036
2037static void
florian55085f82012-11-21 00:36:55 +00002038s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2039 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002040 UChar m3, UChar m4, UChar r1, UChar r2)
2041{
florian55085f82012-11-21 00:36:55 +00002042 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002043
2044 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2045 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2046}
2047
2048static void
floriane38f6412012-12-21 17:32:12 +00002049s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2050 UChar m4, UChar r1, UChar r2)
2051{
2052 const HChar *mnm = irgen(m4, r1, r2);
2053
2054 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2055 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2056}
2057
2058static void
florian55085f82012-11-21 00:36:55 +00002059s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2060 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002061 UChar m3, UChar m4, UChar r1, UChar r2)
2062{
florian55085f82012-11-21 00:36:55 +00002063 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002064
2065 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2066 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2067}
2068
2069static void
florian55085f82012-11-21 00:36:55 +00002070s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2071 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002072 UChar m3, UChar m4, UChar r1, UChar r2)
2073{
florian55085f82012-11-21 00:36:55 +00002074 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002075
2076 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2077 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2078}
2079
2080
2081static void
florian55085f82012-11-21 00:36:55 +00002082s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002083 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2084{
2085 irgen(m3, r1, r2);
2086
sewardj7ee97522011-05-09 21:45:04 +00002087 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002088 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2089}
2090
2091static void
florian55085f82012-11-21 00:36:55 +00002092s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002093 UChar r3, UChar r1, UChar r2)
2094{
florian55085f82012-11-21 00:36:55 +00002095 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002096
sewardj7ee97522011-05-09 21:45:04 +00002097 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002098 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2099}
2100
2101static void
florian5c539732013-02-14 14:27:12 +00002102s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2103 UChar r3, UChar m4, UChar r1, UChar r2)
2104{
2105 const HChar *mnm = irgen(r3, m4, r1, r2);
2106
2107 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2108 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2109}
2110
2111static void
2112s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2113 UChar r3, UChar m4, UChar r1, UChar r2)
2114{
2115 const HChar *mnm = irgen(r3, m4, r1, r2);
2116
2117 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2118 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2119}
2120
2121static void
florian55085f82012-11-21 00:36:55 +00002122s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002123 UChar r3, UChar m4, UChar r1, UChar r2)
2124{
florian55085f82012-11-21 00:36:55 +00002125 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002126
2127 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2128 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2129}
2130
2131static void
florian55085f82012-11-21 00:36:55 +00002132s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002133 UChar r3, UChar r1, UChar r2)
2134{
florian55085f82012-11-21 00:36:55 +00002135 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002136
sewardj7ee97522011-05-09 21:45:04 +00002137 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002138 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2139}
2140
2141static void
florian55085f82012-11-21 00:36:55 +00002142s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2143 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002144 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2145{
florian55085f82012-11-21 00:36:55 +00002146 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002147 IRTemp op4addr = newTemp(Ity_I64);
2148
2149 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2150 mkU64(0)));
2151
2152 mnm = irgen(r1, r2, m3, op4addr);
2153
sewardj7ee97522011-05-09 21:45:04 +00002154 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002155 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2156 r2, m3, d4, 0, b4);
2157}
2158
2159static void
florian55085f82012-11-21 00:36:55 +00002160s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002161 UChar r1, UChar b2, UShort d2)
2162{
florian55085f82012-11-21 00:36:55 +00002163 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002164 IRTemp op2addr = newTemp(Ity_I64);
2165
2166 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2167 mkU64(0)));
2168
2169 mnm = irgen(r1, op2addr);
2170
sewardj7ee97522011-05-09 21:45:04 +00002171 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002172 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2173}
2174
2175static void
florian55085f82012-11-21 00:36:55 +00002176s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002177 UChar r1, UChar r3, 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, r3, 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(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2189}
2190
2191static void
florian55085f82012-11-21 00:36:55 +00002192s390_format_RS_RURD(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, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2205}
2206
2207static void
florian55085f82012-11-21 00:36:55 +00002208s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
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, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2221}
2222
2223static void
florian55085f82012-11-21 00:36:55 +00002224s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002225 UChar r1, UChar r3, UShort i2)
2226{
florian55085f82012-11-21 00:36:55 +00002227 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002228
sewardj7ee97522011-05-09 21:45:04 +00002229 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002230 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2231}
2232
2233static void
florian55085f82012-11-21 00:36:55 +00002234s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002235 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2236{
florian55085f82012-11-21 00:36:55 +00002237 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002238 IRTemp op2addr = newTemp(Ity_I64);
2239 IRTemp d2 = newTemp(Ity_I64);
2240
2241 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2242 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2243 mkU64(0)));
2244
2245 mnm = irgen(r1, r3, op2addr);
2246
sewardj7ee97522011-05-09 21:45:04 +00002247 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002248 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2249}
2250
2251static void
florian55085f82012-11-21 00:36:55 +00002252s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002253 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2254{
florian55085f82012-11-21 00:36:55 +00002255 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002256 IRTemp op2addr = newTemp(Ity_I64);
2257 IRTemp d2 = newTemp(Ity_I64);
2258
2259 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2260 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2261 mkU64(0)));
2262
2263 mnm = irgen(r1, r3, op2addr);
2264
sewardj7ee97522011-05-09 21:45:04 +00002265 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002266 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2267}
2268
2269static void
florian55085f82012-11-21 00:36:55 +00002270s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002271 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2272{
florian55085f82012-11-21 00:36:55 +00002273 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002274 IRTemp op2addr = newTemp(Ity_I64);
2275 IRTemp d2 = newTemp(Ity_I64);
2276
2277 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2278 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2279 mkU64(0)));
2280
2281 mnm = irgen(r1, r3, op2addr);
2282
sewardj7ee97522011-05-09 21:45:04 +00002283 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002284 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2285}
2286
2287static void
florian55085f82012-11-21 00:36:55 +00002288s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002289 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2290 Int xmnm_kind)
2291{
2292 IRTemp op2addr = newTemp(Ity_I64);
2293 IRTemp d2 = newTemp(Ity_I64);
2294
florian6820ba52012-07-26 02:01:50 +00002295 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2296
sewardjd7bde722011-04-05 13:19:33 +00002297 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2298 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2299 mkU64(0)));
2300
2301 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002302
2303 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002304
sewardj7ee97522011-05-09 21:45:04 +00002305 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002306 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2307}
2308
2309static void
florian55085f82012-11-21 00:36:55 +00002310s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002311 IRTemp op2addr),
2312 UChar r1, UChar x2, UChar b2, UShort d2)
2313{
2314 IRTemp op2addr = newTemp(Ity_I64);
2315
2316 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2317 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2318 mkU64(0)));
2319
2320 irgen(r1, x2, b2, d2, op2addr);
2321}
2322
2323static void
florian55085f82012-11-21 00:36:55 +00002324s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002325 UChar r1, UChar x2, UChar b2, UShort d2)
2326{
florian55085f82012-11-21 00:36:55 +00002327 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002328 IRTemp op2addr = newTemp(Ity_I64);
2329
2330 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2331 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2332 mkU64(0)));
2333
2334 mnm = irgen(r1, op2addr);
2335
sewardj7ee97522011-05-09 21:45:04 +00002336 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002337 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2338}
2339
2340static void
florian55085f82012-11-21 00:36:55 +00002341s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002342 UChar r1, UChar x2, UChar b2, UShort d2)
2343{
florian55085f82012-11-21 00:36:55 +00002344 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002345 IRTemp op2addr = newTemp(Ity_I64);
2346
2347 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2348 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2349 mkU64(0)));
2350
2351 mnm = irgen(r1, op2addr);
2352
sewardj7ee97522011-05-09 21:45:04 +00002353 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002354 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2355}
2356
2357static void
florian55085f82012-11-21 00:36:55 +00002358s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002359 UChar r1, UChar x2, UChar b2, UShort d2)
2360{
florian55085f82012-11-21 00:36:55 +00002361 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002362 IRTemp op2addr = newTemp(Ity_I64);
2363
2364 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2365 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2366 mkU64(0)));
2367
2368 mnm = irgen(r1, op2addr);
2369
sewardj7ee97522011-05-09 21:45:04 +00002370 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002371 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2372}
2373
2374static void
florian55085f82012-11-21 00:36:55 +00002375s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002376 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2377{
florian55085f82012-11-21 00:36:55 +00002378 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002379 IRTemp op2addr = newTemp(Ity_I64);
2380
2381 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2382 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2383 mkU64(0)));
2384
2385 mnm = irgen(r3, op2addr, r1);
2386
sewardj7ee97522011-05-09 21:45:04 +00002387 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002388 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2389}
2390
2391static void
florian55085f82012-11-21 00:36:55 +00002392s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002393 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2394{
florian55085f82012-11-21 00:36:55 +00002395 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002396 IRTemp op2addr = newTemp(Ity_I64);
2397 IRTemp d2 = newTemp(Ity_I64);
2398
2399 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2400 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2401 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2402 mkU64(0)));
2403
2404 mnm = irgen(r1, op2addr);
2405
sewardj7ee97522011-05-09 21:45:04 +00002406 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002407 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2408}
2409
2410static void
florian55085f82012-11-21 00:36:55 +00002411s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002412 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2413{
florian55085f82012-11-21 00:36:55 +00002414 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002415 IRTemp op2addr = newTemp(Ity_I64);
2416 IRTemp d2 = newTemp(Ity_I64);
2417
2418 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2419 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2420 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2421 mkU64(0)));
2422
2423 mnm = irgen(r1, op2addr);
2424
sewardj7ee97522011-05-09 21:45:04 +00002425 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002426 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2427}
2428
2429static void
florian55085f82012-11-21 00:36:55 +00002430s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002431 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2432{
florian55085f82012-11-21 00:36:55 +00002433 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002434 IRTemp op2addr = newTemp(Ity_I64);
2435 IRTemp d2 = newTemp(Ity_I64);
2436
2437 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2438 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2439 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2440 mkU64(0)));
2441
2442 mnm = irgen();
2443
sewardj7ee97522011-05-09 21:45:04 +00002444 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002445 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2446}
2447
2448static void
florian55085f82012-11-21 00:36:55 +00002449s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002450 UChar b2, UShort d2)
2451{
florian55085f82012-11-21 00:36:55 +00002452 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002453 IRTemp op2addr = newTemp(Ity_I64);
2454
2455 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2456 mkU64(0)));
2457
2458 mnm = irgen(op2addr);
2459
sewardj7ee97522011-05-09 21:45:04 +00002460 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002461 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2462}
2463
2464static void
florian55085f82012-11-21 00:36:55 +00002465s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002466 UChar i2, UChar b1, UShort d1)
2467{
florian55085f82012-11-21 00:36:55 +00002468 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002469 IRTemp op1addr = newTemp(Ity_I64);
2470
2471 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2472 mkU64(0)));
2473
2474 mnm = irgen(i2, op1addr);
2475
sewardj7ee97522011-05-09 21:45:04 +00002476 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002477 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2478}
2479
2480static void
florian55085f82012-11-21 00:36:55 +00002481s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002482 UChar i2, UChar b1, UShort dl1, UChar dh1)
2483{
florian55085f82012-11-21 00:36:55 +00002484 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002485 IRTemp op1addr = newTemp(Ity_I64);
2486 IRTemp d1 = newTemp(Ity_I64);
2487
2488 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2489 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2490 mkU64(0)));
2491
2492 mnm = irgen(i2, op1addr);
2493
sewardj7ee97522011-05-09 21:45:04 +00002494 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002495 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2496}
2497
2498static void
florian55085f82012-11-21 00:36:55 +00002499s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002500 UChar i2, UChar b1, UShort dl1, UChar dh1)
2501{
florian55085f82012-11-21 00:36:55 +00002502 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002503 IRTemp op1addr = newTemp(Ity_I64);
2504 IRTemp d1 = newTemp(Ity_I64);
2505
2506 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2507 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2508 mkU64(0)));
2509
2510 mnm = irgen(i2, op1addr);
2511
sewardj7ee97522011-05-09 21:45:04 +00002512 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002513 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2514}
2515
2516static void
florian55085f82012-11-21 00:36:55 +00002517s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002518 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2519{
florian55085f82012-11-21 00:36:55 +00002520 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002521 IRTemp op1addr = newTemp(Ity_I64);
2522 IRTemp op2addr = newTemp(Ity_I64);
2523
2524 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2525 mkU64(0)));
2526 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2527 mkU64(0)));
2528
2529 mnm = irgen(l, op1addr, op2addr);
2530
sewardj7ee97522011-05-09 21:45:04 +00002531 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002532 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2533}
2534
2535static void
florian55085f82012-11-21 00:36:55 +00002536s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002537 UChar b1, UShort d1, UShort i2)
2538{
florian55085f82012-11-21 00:36:55 +00002539 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002540 IRTemp op1addr = newTemp(Ity_I64);
2541
2542 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2543 mkU64(0)));
2544
2545 mnm = irgen(i2, op1addr);
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, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2549}
2550
2551static void
florian55085f82012-11-21 00:36:55 +00002552s390_format_SIL_RDU(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, UINT), mnm, d1, 0, b1, i2);
2565}
2566
2567
2568
2569/*------------------------------------------------------------*/
2570/*--- Build IR for opcodes ---*/
2571/*------------------------------------------------------------*/
2572
florian55085f82012-11-21 00:36:55 +00002573static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002574s390_irgen_AR(UChar r1, UChar r2)
2575{
2576 IRTemp op1 = newTemp(Ity_I32);
2577 IRTemp op2 = newTemp(Ity_I32);
2578 IRTemp result = newTemp(Ity_I32);
2579
2580 assign(op1, get_gpr_w1(r1));
2581 assign(op2, get_gpr_w1(r2));
2582 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2583 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2584 put_gpr_w1(r1, mkexpr(result));
2585
2586 return "ar";
2587}
2588
florian55085f82012-11-21 00:36:55 +00002589static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002590s390_irgen_AGR(UChar r1, UChar r2)
2591{
2592 IRTemp op1 = newTemp(Ity_I64);
2593 IRTemp op2 = newTemp(Ity_I64);
2594 IRTemp result = newTemp(Ity_I64);
2595
2596 assign(op1, get_gpr_dw0(r1));
2597 assign(op2, get_gpr_dw0(r2));
2598 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2599 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2600 put_gpr_dw0(r1, mkexpr(result));
2601
2602 return "agr";
2603}
2604
florian55085f82012-11-21 00:36:55 +00002605static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002606s390_irgen_AGFR(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, unop(Iop_32Sto64, get_gpr_w1(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 "agfr";
2619}
2620
florian55085f82012-11-21 00:36:55 +00002621static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002622s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2623{
2624 IRTemp op2 = newTemp(Ity_I32);
2625 IRTemp op3 = newTemp(Ity_I32);
2626 IRTemp result = newTemp(Ity_I32);
2627
2628 assign(op2, get_gpr_w1(r2));
2629 assign(op3, get_gpr_w1(r3));
2630 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2631 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2632 put_gpr_w1(r1, mkexpr(result));
2633
2634 return "ark";
2635}
2636
florian55085f82012-11-21 00:36:55 +00002637static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002638s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2639{
2640 IRTemp op2 = newTemp(Ity_I64);
2641 IRTemp op3 = newTemp(Ity_I64);
2642 IRTemp result = newTemp(Ity_I64);
2643
2644 assign(op2, get_gpr_dw0(r2));
2645 assign(op3, get_gpr_dw0(r3));
2646 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2647 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2648 put_gpr_dw0(r1, mkexpr(result));
2649
2650 return "agrk";
2651}
2652
florian55085f82012-11-21 00:36:55 +00002653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002654s390_irgen_A(UChar r1, IRTemp op2addr)
2655{
2656 IRTemp op1 = newTemp(Ity_I32);
2657 IRTemp op2 = newTemp(Ity_I32);
2658 IRTemp result = newTemp(Ity_I32);
2659
2660 assign(op1, get_gpr_w1(r1));
2661 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2662 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2663 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2664 put_gpr_w1(r1, mkexpr(result));
2665
2666 return "a";
2667}
2668
florian55085f82012-11-21 00:36:55 +00002669static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002670s390_irgen_AY(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 "ay";
2683}
2684
florian55085f82012-11-21 00:36:55 +00002685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002686s390_irgen_AG(UChar r1, IRTemp op2addr)
2687{
2688 IRTemp op1 = newTemp(Ity_I64);
2689 IRTemp op2 = newTemp(Ity_I64);
2690 IRTemp result = newTemp(Ity_I64);
2691
2692 assign(op1, get_gpr_dw0(r1));
2693 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2694 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2695 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2696 put_gpr_dw0(r1, mkexpr(result));
2697
2698 return "ag";
2699}
2700
florian55085f82012-11-21 00:36:55 +00002701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002702s390_irgen_AGF(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, unop(Iop_32Sto64, load(Ity_I32, 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 "agf";
2715}
2716
florian55085f82012-11-21 00:36:55 +00002717static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002718s390_irgen_AFI(UChar r1, UInt i2)
2719{
2720 IRTemp op1 = newTemp(Ity_I32);
2721 Int op2;
2722 IRTemp result = newTemp(Ity_I32);
2723
2724 assign(op1, get_gpr_w1(r1));
2725 op2 = (Int)i2;
2726 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2727 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2728 mkU32((UInt)op2)));
2729 put_gpr_w1(r1, mkexpr(result));
2730
2731 return "afi";
2732}
2733
florian55085f82012-11-21 00:36:55 +00002734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002735s390_irgen_AGFI(UChar r1, UInt i2)
2736{
2737 IRTemp op1 = newTemp(Ity_I64);
2738 Long op2;
2739 IRTemp result = newTemp(Ity_I64);
2740
2741 assign(op1, get_gpr_dw0(r1));
2742 op2 = (Long)(Int)i2;
2743 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2744 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2745 mkU64((ULong)op2)));
2746 put_gpr_dw0(r1, mkexpr(result));
2747
2748 return "agfi";
2749}
2750
florian55085f82012-11-21 00:36:55 +00002751static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002752s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2753{
2754 Int op2;
2755 IRTemp op3 = newTemp(Ity_I32);
2756 IRTemp result = newTemp(Ity_I32);
2757
2758 op2 = (Int)(Short)i2;
2759 assign(op3, get_gpr_w1(r3));
2760 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2761 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2762 op2)), op3);
2763 put_gpr_w1(r1, mkexpr(result));
2764
2765 return "ahik";
2766}
2767
florian55085f82012-11-21 00:36:55 +00002768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002769s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2770{
2771 Long op2;
2772 IRTemp op3 = newTemp(Ity_I64);
2773 IRTemp result = newTemp(Ity_I64);
2774
2775 op2 = (Long)(Short)i2;
2776 assign(op3, get_gpr_dw0(r3));
2777 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2778 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2779 op2)), op3);
2780 put_gpr_dw0(r1, mkexpr(result));
2781
2782 return "aghik";
2783}
2784
florian55085f82012-11-21 00:36:55 +00002785static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002786s390_irgen_ASI(UChar i2, IRTemp op1addr)
2787{
2788 IRTemp op1 = newTemp(Ity_I32);
2789 Int op2;
2790 IRTemp result = newTemp(Ity_I32);
2791
2792 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2793 op2 = (Int)(Char)i2;
2794 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2795 store(mkexpr(op1addr), mkexpr(result));
2796 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2797 mkU32((UInt)op2)));
2798
2799 return "asi";
2800}
2801
florian55085f82012-11-21 00:36:55 +00002802static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002803s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2804{
2805 IRTemp op1 = newTemp(Ity_I64);
2806 Long op2;
2807 IRTemp result = newTemp(Ity_I64);
2808
2809 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2810 op2 = (Long)(Char)i2;
2811 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2812 store(mkexpr(op1addr), mkexpr(result));
2813 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2814 mkU64((ULong)op2)));
2815
2816 return "agsi";
2817}
2818
florian55085f82012-11-21 00:36:55 +00002819static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002820s390_irgen_AH(UChar r1, IRTemp op2addr)
2821{
2822 IRTemp op1 = newTemp(Ity_I32);
2823 IRTemp op2 = newTemp(Ity_I32);
2824 IRTemp result = newTemp(Ity_I32);
2825
2826 assign(op1, get_gpr_w1(r1));
2827 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2828 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2829 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2830 put_gpr_w1(r1, mkexpr(result));
2831
2832 return "ah";
2833}
2834
florian55085f82012-11-21 00:36:55 +00002835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002836s390_irgen_AHY(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 "ahy";
2849}
2850
florian55085f82012-11-21 00:36:55 +00002851static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002852s390_irgen_AHI(UChar r1, UShort i2)
2853{
2854 IRTemp op1 = newTemp(Ity_I32);
2855 Int op2;
2856 IRTemp result = newTemp(Ity_I32);
2857
2858 assign(op1, get_gpr_w1(r1));
2859 op2 = (Int)(Short)i2;
2860 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2861 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2862 mkU32((UInt)op2)));
2863 put_gpr_w1(r1, mkexpr(result));
2864
2865 return "ahi";
2866}
2867
florian55085f82012-11-21 00:36:55 +00002868static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002869s390_irgen_AGHI(UChar r1, UShort i2)
2870{
2871 IRTemp op1 = newTemp(Ity_I64);
2872 Long op2;
2873 IRTemp result = newTemp(Ity_I64);
2874
2875 assign(op1, get_gpr_dw0(r1));
2876 op2 = (Long)(Short)i2;
2877 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2878 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2879 mkU64((ULong)op2)));
2880 put_gpr_dw0(r1, mkexpr(result));
2881
2882 return "aghi";
2883}
2884
florian55085f82012-11-21 00:36:55 +00002885static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002886s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2887{
2888 IRTemp op2 = newTemp(Ity_I32);
2889 IRTemp op3 = newTemp(Ity_I32);
2890 IRTemp result = newTemp(Ity_I32);
2891
2892 assign(op2, get_gpr_w0(r2));
2893 assign(op3, get_gpr_w0(r3));
2894 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2895 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2896 put_gpr_w0(r1, mkexpr(result));
2897
2898 return "ahhhr";
2899}
2900
florian55085f82012-11-21 00:36:55 +00002901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002902s390_irgen_AHHLR(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_w1(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 "ahhlr";
2915}
2916
florian55085f82012-11-21 00:36:55 +00002917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002918s390_irgen_AIH(UChar r1, UInt i2)
2919{
2920 IRTemp op1 = newTemp(Ity_I32);
2921 Int op2;
2922 IRTemp result = newTemp(Ity_I32);
2923
2924 assign(op1, get_gpr_w0(r1));
2925 op2 = (Int)i2;
2926 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2927 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2928 mkU32((UInt)op2)));
2929 put_gpr_w0(r1, mkexpr(result));
2930
2931 return "aih";
2932}
2933
florian55085f82012-11-21 00:36:55 +00002934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002935s390_irgen_ALR(UChar r1, UChar r2)
2936{
2937 IRTemp op1 = newTemp(Ity_I32);
2938 IRTemp op2 = newTemp(Ity_I32);
2939 IRTemp result = newTemp(Ity_I32);
2940
2941 assign(op1, get_gpr_w1(r1));
2942 assign(op2, get_gpr_w1(r2));
2943 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2944 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2945 put_gpr_w1(r1, mkexpr(result));
2946
2947 return "alr";
2948}
2949
florian55085f82012-11-21 00:36:55 +00002950static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002951s390_irgen_ALGR(UChar r1, UChar r2)
2952{
2953 IRTemp op1 = newTemp(Ity_I64);
2954 IRTemp op2 = newTemp(Ity_I64);
2955 IRTemp result = newTemp(Ity_I64);
2956
2957 assign(op1, get_gpr_dw0(r1));
2958 assign(op2, get_gpr_dw0(r2));
2959 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2960 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2961 put_gpr_dw0(r1, mkexpr(result));
2962
2963 return "algr";
2964}
2965
florian55085f82012-11-21 00:36:55 +00002966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002967s390_irgen_ALGFR(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, unop(Iop_32Uto64, get_gpr_w1(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 "algfr";
2980}
2981
florian55085f82012-11-21 00:36:55 +00002982static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002983s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2984{
2985 IRTemp op2 = newTemp(Ity_I32);
2986 IRTemp op3 = newTemp(Ity_I32);
2987 IRTemp result = newTemp(Ity_I32);
2988
2989 assign(op2, get_gpr_w1(r2));
2990 assign(op3, get_gpr_w1(r3));
2991 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2992 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2993 put_gpr_w1(r1, mkexpr(result));
2994
2995 return "alrk";
2996}
2997
florian55085f82012-11-21 00:36:55 +00002998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002999s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
3000{
3001 IRTemp op2 = newTemp(Ity_I64);
3002 IRTemp op3 = newTemp(Ity_I64);
3003 IRTemp result = newTemp(Ity_I64);
3004
3005 assign(op2, get_gpr_dw0(r2));
3006 assign(op3, get_gpr_dw0(r3));
3007 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
3008 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3009 put_gpr_dw0(r1, mkexpr(result));
3010
3011 return "algrk";
3012}
3013
florian55085f82012-11-21 00:36:55 +00003014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003015s390_irgen_AL(UChar r1, IRTemp op2addr)
3016{
3017 IRTemp op1 = newTemp(Ity_I32);
3018 IRTemp op2 = newTemp(Ity_I32);
3019 IRTemp result = newTemp(Ity_I32);
3020
3021 assign(op1, get_gpr_w1(r1));
3022 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3023 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3024 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3025 put_gpr_w1(r1, mkexpr(result));
3026
3027 return "al";
3028}
3029
florian55085f82012-11-21 00:36:55 +00003030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003031s390_irgen_ALY(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 "aly";
3044}
3045
florian55085f82012-11-21 00:36:55 +00003046static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003047s390_irgen_ALG(UChar r1, IRTemp op2addr)
3048{
3049 IRTemp op1 = newTemp(Ity_I64);
3050 IRTemp op2 = newTemp(Ity_I64);
3051 IRTemp result = newTemp(Ity_I64);
3052
3053 assign(op1, get_gpr_dw0(r1));
3054 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3055 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3056 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3057 put_gpr_dw0(r1, mkexpr(result));
3058
3059 return "alg";
3060}
3061
florian55085f82012-11-21 00:36:55 +00003062static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003063s390_irgen_ALGF(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, unop(Iop_32Uto64, load(Ity_I32, 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 "algf";
3076}
3077
florian55085f82012-11-21 00:36:55 +00003078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003079s390_irgen_ALFI(UChar r1, UInt i2)
3080{
3081 IRTemp op1 = newTemp(Ity_I32);
3082 UInt op2;
3083 IRTemp result = newTemp(Ity_I32);
3084
3085 assign(op1, get_gpr_w1(r1));
3086 op2 = i2;
3087 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3088 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3089 mkU32(op2)));
3090 put_gpr_w1(r1, mkexpr(result));
3091
3092 return "alfi";
3093}
3094
florian55085f82012-11-21 00:36:55 +00003095static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003096s390_irgen_ALGFI(UChar r1, UInt i2)
3097{
3098 IRTemp op1 = newTemp(Ity_I64);
3099 ULong op2;
3100 IRTemp result = newTemp(Ity_I64);
3101
3102 assign(op1, get_gpr_dw0(r1));
3103 op2 = (ULong)i2;
3104 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3105 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3106 mkU64(op2)));
3107 put_gpr_dw0(r1, mkexpr(result));
3108
3109 return "algfi";
3110}
3111
florian55085f82012-11-21 00:36:55 +00003112static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003113s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3114{
3115 IRTemp op2 = newTemp(Ity_I32);
3116 IRTemp op3 = newTemp(Ity_I32);
3117 IRTemp result = newTemp(Ity_I32);
3118
3119 assign(op2, get_gpr_w0(r2));
3120 assign(op3, get_gpr_w0(r3));
3121 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3122 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3123 put_gpr_w0(r1, mkexpr(result));
3124
3125 return "alhhhr";
3126}
3127
florian55085f82012-11-21 00:36:55 +00003128static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003129s390_irgen_ALHHLR(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_w1(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 "alhhlr";
3142}
3143
florian55085f82012-11-21 00:36:55 +00003144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003145s390_irgen_ALCR(UChar r1, UChar r2)
3146{
3147 IRTemp op1 = newTemp(Ity_I32);
3148 IRTemp op2 = newTemp(Ity_I32);
3149 IRTemp result = newTemp(Ity_I32);
3150 IRTemp carry_in = newTemp(Ity_I32);
3151
3152 assign(op1, get_gpr_w1(r1));
3153 assign(op2, get_gpr_w1(r2));
3154 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3155 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3156 mkexpr(carry_in)));
3157 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3158 put_gpr_w1(r1, mkexpr(result));
3159
3160 return "alcr";
3161}
3162
florian55085f82012-11-21 00:36:55 +00003163static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003164s390_irgen_ALCGR(UChar r1, UChar r2)
3165{
3166 IRTemp op1 = newTemp(Ity_I64);
3167 IRTemp op2 = newTemp(Ity_I64);
3168 IRTemp result = newTemp(Ity_I64);
3169 IRTemp carry_in = newTemp(Ity_I64);
3170
3171 assign(op1, get_gpr_dw0(r1));
3172 assign(op2, get_gpr_dw0(r2));
3173 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3174 mkU8(1))));
3175 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3176 mkexpr(carry_in)));
3177 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3178 put_gpr_dw0(r1, mkexpr(result));
3179
3180 return "alcgr";
3181}
3182
florian55085f82012-11-21 00:36:55 +00003183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003184s390_irgen_ALC(UChar r1, IRTemp op2addr)
3185{
3186 IRTemp op1 = newTemp(Ity_I32);
3187 IRTemp op2 = newTemp(Ity_I32);
3188 IRTemp result = newTemp(Ity_I32);
3189 IRTemp carry_in = newTemp(Ity_I32);
3190
3191 assign(op1, get_gpr_w1(r1));
3192 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3193 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3194 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3195 mkexpr(carry_in)));
3196 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3197 put_gpr_w1(r1, mkexpr(result));
3198
3199 return "alc";
3200}
3201
florian55085f82012-11-21 00:36:55 +00003202static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003203s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3204{
3205 IRTemp op1 = newTemp(Ity_I64);
3206 IRTemp op2 = newTemp(Ity_I64);
3207 IRTemp result = newTemp(Ity_I64);
3208 IRTemp carry_in = newTemp(Ity_I64);
3209
3210 assign(op1, get_gpr_dw0(r1));
3211 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3212 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3213 mkU8(1))));
3214 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3215 mkexpr(carry_in)));
3216 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3217 put_gpr_dw0(r1, mkexpr(result));
3218
3219 return "alcg";
3220}
3221
florian55085f82012-11-21 00:36:55 +00003222static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003223s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3224{
3225 IRTemp op1 = newTemp(Ity_I32);
3226 UInt op2;
3227 IRTemp result = newTemp(Ity_I32);
3228
3229 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3230 op2 = (UInt)(Int)(Char)i2;
3231 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3232 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3233 mkU32(op2)));
3234 store(mkexpr(op1addr), mkexpr(result));
3235
3236 return "alsi";
3237}
3238
florian55085f82012-11-21 00:36:55 +00003239static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003240s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3241{
3242 IRTemp op1 = newTemp(Ity_I64);
3243 ULong op2;
3244 IRTemp result = newTemp(Ity_I64);
3245
3246 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3247 op2 = (ULong)(Long)(Char)i2;
3248 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3249 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3250 mkU64(op2)));
3251 store(mkexpr(op1addr), mkexpr(result));
3252
3253 return "algsi";
3254}
3255
florian55085f82012-11-21 00:36:55 +00003256static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003257s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3258{
3259 UInt op2;
3260 IRTemp op3 = newTemp(Ity_I32);
3261 IRTemp result = newTemp(Ity_I32);
3262
3263 op2 = (UInt)(Int)(Short)i2;
3264 assign(op3, get_gpr_w1(r3));
3265 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3266 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3267 op3);
3268 put_gpr_w1(r1, mkexpr(result));
3269
3270 return "alhsik";
3271}
3272
florian55085f82012-11-21 00:36:55 +00003273static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003274s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3275{
3276 ULong op2;
3277 IRTemp op3 = newTemp(Ity_I64);
3278 IRTemp result = newTemp(Ity_I64);
3279
3280 op2 = (ULong)(Long)(Short)i2;
3281 assign(op3, get_gpr_dw0(r3));
3282 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3283 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3284 op3);
3285 put_gpr_dw0(r1, mkexpr(result));
3286
3287 return "alghsik";
3288}
3289
florian55085f82012-11-21 00:36:55 +00003290static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003291s390_irgen_ALSIH(UChar r1, UInt i2)
3292{
3293 IRTemp op1 = newTemp(Ity_I32);
3294 UInt op2;
3295 IRTemp result = newTemp(Ity_I32);
3296
3297 assign(op1, get_gpr_w0(r1));
3298 op2 = i2;
3299 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3300 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3301 mkU32(op2)));
3302 put_gpr_w0(r1, mkexpr(result));
3303
3304 return "alsih";
3305}
3306
florian55085f82012-11-21 00:36:55 +00003307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003308s390_irgen_ALSIHN(UChar r1, UInt i2)
3309{
3310 IRTemp op1 = newTemp(Ity_I32);
3311 UInt op2;
3312 IRTemp result = newTemp(Ity_I32);
3313
3314 assign(op1, get_gpr_w0(r1));
3315 op2 = i2;
3316 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3317 put_gpr_w0(r1, mkexpr(result));
3318
3319 return "alsihn";
3320}
3321
florian55085f82012-11-21 00:36:55 +00003322static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003323s390_irgen_NR(UChar r1, UChar r2)
3324{
3325 IRTemp op1 = newTemp(Ity_I32);
3326 IRTemp op2 = newTemp(Ity_I32);
3327 IRTemp result = newTemp(Ity_I32);
3328
3329 assign(op1, get_gpr_w1(r1));
3330 assign(op2, get_gpr_w1(r2));
3331 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3332 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3333 put_gpr_w1(r1, mkexpr(result));
3334
3335 return "nr";
3336}
3337
florian55085f82012-11-21 00:36:55 +00003338static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003339s390_irgen_NGR(UChar r1, UChar r2)
3340{
3341 IRTemp op1 = newTemp(Ity_I64);
3342 IRTemp op2 = newTemp(Ity_I64);
3343 IRTemp result = newTemp(Ity_I64);
3344
3345 assign(op1, get_gpr_dw0(r1));
3346 assign(op2, get_gpr_dw0(r2));
3347 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3348 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3349 put_gpr_dw0(r1, mkexpr(result));
3350
3351 return "ngr";
3352}
3353
florian55085f82012-11-21 00:36:55 +00003354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003355s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3356{
3357 IRTemp op2 = newTemp(Ity_I32);
3358 IRTemp op3 = newTemp(Ity_I32);
3359 IRTemp result = newTemp(Ity_I32);
3360
3361 assign(op2, get_gpr_w1(r2));
3362 assign(op3, get_gpr_w1(r3));
3363 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3364 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3365 put_gpr_w1(r1, mkexpr(result));
3366
3367 return "nrk";
3368}
3369
florian55085f82012-11-21 00:36:55 +00003370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003371s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3372{
3373 IRTemp op2 = newTemp(Ity_I64);
3374 IRTemp op3 = newTemp(Ity_I64);
3375 IRTemp result = newTemp(Ity_I64);
3376
3377 assign(op2, get_gpr_dw0(r2));
3378 assign(op3, get_gpr_dw0(r3));
3379 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3380 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3381 put_gpr_dw0(r1, mkexpr(result));
3382
3383 return "ngrk";
3384}
3385
florian55085f82012-11-21 00:36:55 +00003386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003387s390_irgen_N(UChar r1, IRTemp op2addr)
3388{
3389 IRTemp op1 = newTemp(Ity_I32);
3390 IRTemp op2 = newTemp(Ity_I32);
3391 IRTemp result = newTemp(Ity_I32);
3392
3393 assign(op1, get_gpr_w1(r1));
3394 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3395 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3396 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3397 put_gpr_w1(r1, mkexpr(result));
3398
3399 return "n";
3400}
3401
florian55085f82012-11-21 00:36:55 +00003402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003403s390_irgen_NY(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 "ny";
3416}
3417
florian55085f82012-11-21 00:36:55 +00003418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003419s390_irgen_NG(UChar r1, IRTemp op2addr)
3420{
3421 IRTemp op1 = newTemp(Ity_I64);
3422 IRTemp op2 = newTemp(Ity_I64);
3423 IRTemp result = newTemp(Ity_I64);
3424
3425 assign(op1, get_gpr_dw0(r1));
3426 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3427 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3428 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3429 put_gpr_dw0(r1, mkexpr(result));
3430
3431 return "ng";
3432}
3433
florian55085f82012-11-21 00:36:55 +00003434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003435s390_irgen_NI(UChar i2, IRTemp op1addr)
3436{
3437 IRTemp op1 = newTemp(Ity_I8);
3438 UChar op2;
3439 IRTemp result = newTemp(Ity_I8);
3440
3441 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3442 op2 = i2;
3443 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3444 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3445 store(mkexpr(op1addr), mkexpr(result));
3446
3447 return "ni";
3448}
3449
florian55085f82012-11-21 00:36:55 +00003450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003451s390_irgen_NIY(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 "niy";
3464}
3465
florian55085f82012-11-21 00:36:55 +00003466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003467s390_irgen_NIHF(UChar r1, UInt i2)
3468{
3469 IRTemp op1 = newTemp(Ity_I32);
3470 UInt op2;
3471 IRTemp result = newTemp(Ity_I32);
3472
3473 assign(op1, get_gpr_w0(r1));
3474 op2 = i2;
3475 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3476 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3477 put_gpr_w0(r1, mkexpr(result));
3478
3479 return "nihf";
3480}
3481
florian55085f82012-11-21 00:36:55 +00003482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003483s390_irgen_NIHH(UChar r1, UShort i2)
3484{
3485 IRTemp op1 = newTemp(Ity_I16);
3486 UShort op2;
3487 IRTemp result = newTemp(Ity_I16);
3488
3489 assign(op1, get_gpr_hw0(r1));
3490 op2 = i2;
3491 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3492 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3493 put_gpr_hw0(r1, mkexpr(result));
3494
3495 return "nihh";
3496}
3497
florian55085f82012-11-21 00:36:55 +00003498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003499s390_irgen_NIHL(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_hw1(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_hw1(r1, mkexpr(result));
3510
3511 return "nihl";
3512}
3513
florian55085f82012-11-21 00:36:55 +00003514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003515s390_irgen_NILF(UChar r1, UInt i2)
3516{
3517 IRTemp op1 = newTemp(Ity_I32);
3518 UInt op2;
3519 IRTemp result = newTemp(Ity_I32);
3520
3521 assign(op1, get_gpr_w1(r1));
3522 op2 = i2;
3523 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3524 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3525 put_gpr_w1(r1, mkexpr(result));
3526
3527 return "nilf";
3528}
3529
florian55085f82012-11-21 00:36:55 +00003530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003531s390_irgen_NILH(UChar r1, UShort i2)
3532{
3533 IRTemp op1 = newTemp(Ity_I16);
3534 UShort op2;
3535 IRTemp result = newTemp(Ity_I16);
3536
3537 assign(op1, get_gpr_hw2(r1));
3538 op2 = i2;
3539 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3540 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3541 put_gpr_hw2(r1, mkexpr(result));
3542
3543 return "nilh";
3544}
3545
florian55085f82012-11-21 00:36:55 +00003546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003547s390_irgen_NILL(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_hw3(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_hw3(r1, mkexpr(result));
3558
3559 return "nill";
3560}
3561
florian55085f82012-11-21 00:36:55 +00003562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003563s390_irgen_BASR(UChar r1, UChar r2)
3564{
3565 IRTemp target = newTemp(Ity_I64);
3566
3567 if (r2 == 0) {
3568 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3569 } else {
3570 if (r1 != r2) {
3571 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3572 call_function(get_gpr_dw0(r2));
3573 } else {
3574 assign(target, get_gpr_dw0(r2));
3575 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3576 call_function(mkexpr(target));
3577 }
3578 }
3579
3580 return "basr";
3581}
3582
florian55085f82012-11-21 00:36:55 +00003583static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003584s390_irgen_BAS(UChar r1, IRTemp op2addr)
3585{
3586 IRTemp target = newTemp(Ity_I64);
3587
3588 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3589 assign(target, mkexpr(op2addr));
3590 call_function(mkexpr(target));
3591
3592 return "bas";
3593}
3594
florian55085f82012-11-21 00:36:55 +00003595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003596s390_irgen_BCR(UChar r1, UChar r2)
3597{
3598 IRTemp cond = newTemp(Ity_I32);
3599
sewardja52e37e2011-04-28 18:48:06 +00003600 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3601 stmt(IRStmt_MBE(Imbe_Fence));
3602 }
3603
sewardj2019a972011-03-07 16:04:07 +00003604 if ((r2 == 0) || (r1 == 0)) {
3605 } else {
3606 if (r1 == 15) {
3607 return_from_function(get_gpr_dw0(r2));
3608 } else {
3609 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003610 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3611 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003612 }
3613 }
sewardj7ee97522011-05-09 21:45:04 +00003614 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003615 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3616
3617 return "bcr";
3618}
3619
florian55085f82012-11-21 00:36:55 +00003620static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003621s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3622{
3623 IRTemp cond = newTemp(Ity_I32);
3624
3625 if (r1 == 0) {
3626 } else {
3627 if (r1 == 15) {
3628 always_goto(mkexpr(op2addr));
3629 } else {
3630 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003631 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3632 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003633 }
3634 }
sewardj7ee97522011-05-09 21:45:04 +00003635 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003636 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3637
3638 return "bc";
3639}
3640
florian55085f82012-11-21 00:36:55 +00003641static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003642s390_irgen_BCTR(UChar r1, UChar r2)
3643{
3644 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3645 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003646 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3647 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003648 }
3649
3650 return "bctr";
3651}
3652
florian55085f82012-11-21 00:36:55 +00003653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003654s390_irgen_BCTGR(UChar r1, UChar r2)
3655{
3656 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3657 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003658 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3659 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003660 }
3661
3662 return "bctgr";
3663}
3664
florian55085f82012-11-21 00:36:55 +00003665static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003666s390_irgen_BCT(UChar r1, IRTemp op2addr)
3667{
3668 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003669 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3670 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003671
3672 return "bct";
3673}
3674
florian55085f82012-11-21 00:36:55 +00003675static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003676s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3677{
3678 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003679 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3680 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003681
3682 return "bctg";
3683}
3684
florian55085f82012-11-21 00:36:55 +00003685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003686s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3687{
3688 IRTemp value = newTemp(Ity_I32);
3689
3690 assign(value, get_gpr_w1(r3 | 1));
3691 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003692 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3693 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003694
3695 return "bxh";
3696}
3697
florian55085f82012-11-21 00:36:55 +00003698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003699s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3700{
3701 IRTemp value = newTemp(Ity_I64);
3702
3703 assign(value, get_gpr_dw0(r3 | 1));
3704 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003705 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3706 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003707
3708 return "bxhg";
3709}
3710
florian55085f82012-11-21 00:36:55 +00003711static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003712s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3713{
3714 IRTemp value = newTemp(Ity_I32);
3715
3716 assign(value, get_gpr_w1(r3 | 1));
3717 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003718 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3719 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003720
3721 return "bxle";
3722}
3723
florian55085f82012-11-21 00:36:55 +00003724static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003725s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3726{
3727 IRTemp value = newTemp(Ity_I64);
3728
3729 assign(value, get_gpr_dw0(r3 | 1));
3730 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003731 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3732 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003733
3734 return "bxleg";
3735}
3736
florian55085f82012-11-21 00:36:55 +00003737static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003738s390_irgen_BRAS(UChar r1, UShort i2)
3739{
3740 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003741 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003742
3743 return "bras";
3744}
3745
florian55085f82012-11-21 00:36:55 +00003746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003747s390_irgen_BRASL(UChar r1, UInt i2)
3748{
3749 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003750 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003751
3752 return "brasl";
3753}
3754
florian55085f82012-11-21 00:36:55 +00003755static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003756s390_irgen_BRC(UChar r1, UShort i2)
3757{
3758 IRTemp cond = newTemp(Ity_I32);
3759
3760 if (r1 == 0) {
3761 } else {
3762 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003763 always_goto_and_chase(
3764 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003765 } else {
3766 assign(cond, s390_call_calculate_cond(r1));
3767 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3768 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3769
3770 }
3771 }
sewardj7ee97522011-05-09 21:45:04 +00003772 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003773 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3774
3775 return "brc";
3776}
3777
florian55085f82012-11-21 00:36:55 +00003778static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003779s390_irgen_BRCL(UChar r1, UInt i2)
3780{
3781 IRTemp cond = newTemp(Ity_I32);
3782
3783 if (r1 == 0) {
3784 } else {
3785 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003786 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003787 } else {
3788 assign(cond, s390_call_calculate_cond(r1));
3789 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3790 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3791 }
3792 }
sewardj7ee97522011-05-09 21:45:04 +00003793 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003794 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3795
3796 return "brcl";
3797}
3798
florian55085f82012-11-21 00:36:55 +00003799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003800s390_irgen_BRCT(UChar r1, UShort i2)
3801{
3802 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3803 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3804 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3805
3806 return "brct";
3807}
3808
florian55085f82012-11-21 00:36:55 +00003809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003810s390_irgen_BRCTG(UChar r1, UShort i2)
3811{
3812 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3813 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3814 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3815
3816 return "brctg";
3817}
3818
florian55085f82012-11-21 00:36:55 +00003819static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003820s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3821{
3822 IRTemp value = newTemp(Ity_I32);
3823
3824 assign(value, get_gpr_w1(r3 | 1));
3825 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3826 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3827 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3828
3829 return "brxh";
3830}
3831
florian55085f82012-11-21 00:36:55 +00003832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003833s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3834{
3835 IRTemp value = newTemp(Ity_I64);
3836
3837 assign(value, get_gpr_dw0(r3 | 1));
3838 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3839 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3840 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3841
3842 return "brxhg";
3843}
3844
florian55085f82012-11-21 00:36:55 +00003845static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003846s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3847{
3848 IRTemp value = newTemp(Ity_I32);
3849
3850 assign(value, get_gpr_w1(r3 | 1));
3851 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3852 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3853 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3854
3855 return "brxle";
3856}
3857
florian55085f82012-11-21 00:36:55 +00003858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003859s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3860{
3861 IRTemp value = newTemp(Ity_I64);
3862
3863 assign(value, get_gpr_dw0(r3 | 1));
3864 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3865 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3866 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3867
3868 return "brxlg";
3869}
3870
florian55085f82012-11-21 00:36:55 +00003871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003872s390_irgen_CR(UChar r1, UChar r2)
3873{
3874 IRTemp op1 = newTemp(Ity_I32);
3875 IRTemp op2 = newTemp(Ity_I32);
3876
3877 assign(op1, get_gpr_w1(r1));
3878 assign(op2, get_gpr_w1(r2));
3879 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3880
3881 return "cr";
3882}
3883
florian55085f82012-11-21 00:36:55 +00003884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003885s390_irgen_CGR(UChar r1, UChar r2)
3886{
3887 IRTemp op1 = newTemp(Ity_I64);
3888 IRTemp op2 = newTemp(Ity_I64);
3889
3890 assign(op1, get_gpr_dw0(r1));
3891 assign(op2, get_gpr_dw0(r2));
3892 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3893
3894 return "cgr";
3895}
3896
florian55085f82012-11-21 00:36:55 +00003897static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003898s390_irgen_CGFR(UChar r1, UChar r2)
3899{
3900 IRTemp op1 = newTemp(Ity_I64);
3901 IRTemp op2 = newTemp(Ity_I64);
3902
3903 assign(op1, get_gpr_dw0(r1));
3904 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3905 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3906
3907 return "cgfr";
3908}
3909
florian55085f82012-11-21 00:36:55 +00003910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003911s390_irgen_C(UChar r1, IRTemp op2addr)
3912{
3913 IRTemp op1 = newTemp(Ity_I32);
3914 IRTemp op2 = newTemp(Ity_I32);
3915
3916 assign(op1, get_gpr_w1(r1));
3917 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3918 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3919
3920 return "c";
3921}
3922
florian55085f82012-11-21 00:36:55 +00003923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003924s390_irgen_CY(UChar r1, IRTemp op2addr)
3925{
3926 IRTemp op1 = newTemp(Ity_I32);
3927 IRTemp op2 = newTemp(Ity_I32);
3928
3929 assign(op1, get_gpr_w1(r1));
3930 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3931 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3932
3933 return "cy";
3934}
3935
florian55085f82012-11-21 00:36:55 +00003936static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003937s390_irgen_CG(UChar r1, IRTemp op2addr)
3938{
3939 IRTemp op1 = newTemp(Ity_I64);
3940 IRTemp op2 = newTemp(Ity_I64);
3941
3942 assign(op1, get_gpr_dw0(r1));
3943 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3944 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3945
3946 return "cg";
3947}
3948
florian55085f82012-11-21 00:36:55 +00003949static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003950s390_irgen_CGF(UChar r1, IRTemp op2addr)
3951{
3952 IRTemp op1 = newTemp(Ity_I64);
3953 IRTemp op2 = newTemp(Ity_I64);
3954
3955 assign(op1, get_gpr_dw0(r1));
3956 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3957 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3958
3959 return "cgf";
3960}
3961
florian55085f82012-11-21 00:36:55 +00003962static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003963s390_irgen_CFI(UChar r1, UInt i2)
3964{
3965 IRTemp op1 = newTemp(Ity_I32);
3966 Int op2;
3967
3968 assign(op1, get_gpr_w1(r1));
3969 op2 = (Int)i2;
3970 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3971 mkU32((UInt)op2)));
3972
3973 return "cfi";
3974}
3975
florian55085f82012-11-21 00:36:55 +00003976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003977s390_irgen_CGFI(UChar r1, UInt i2)
3978{
3979 IRTemp op1 = newTemp(Ity_I64);
3980 Long op2;
3981
3982 assign(op1, get_gpr_dw0(r1));
3983 op2 = (Long)(Int)i2;
3984 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3985 mkU64((ULong)op2)));
3986
3987 return "cgfi";
3988}
3989
florian55085f82012-11-21 00:36:55 +00003990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003991s390_irgen_CRL(UChar r1, UInt i2)
3992{
3993 IRTemp op1 = newTemp(Ity_I32);
3994 IRTemp op2 = newTemp(Ity_I32);
3995
3996 assign(op1, get_gpr_w1(r1));
3997 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3998 i2 << 1))));
3999 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4000
4001 return "crl";
4002}
4003
florian55085f82012-11-21 00:36:55 +00004004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004005s390_irgen_CGRL(UChar r1, UInt i2)
4006{
4007 IRTemp op1 = newTemp(Ity_I64);
4008 IRTemp op2 = newTemp(Ity_I64);
4009
4010 assign(op1, get_gpr_dw0(r1));
4011 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4012 i2 << 1))));
4013 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4014
4015 return "cgrl";
4016}
4017
florian55085f82012-11-21 00:36:55 +00004018static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004019s390_irgen_CGFRL(UChar r1, UInt i2)
4020{
4021 IRTemp op1 = newTemp(Ity_I64);
4022 IRTemp op2 = newTemp(Ity_I64);
4023
4024 assign(op1, get_gpr_dw0(r1));
4025 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4026 ((ULong)(Long)(Int)i2 << 1)))));
4027 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4028
4029 return "cgfrl";
4030}
4031
florian55085f82012-11-21 00:36:55 +00004032static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004033s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4034{
4035 IRTemp op1 = newTemp(Ity_I32);
4036 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004037 IRTemp cond = newTemp(Ity_I32);
4038
4039 if (m3 == 0) {
4040 } else {
4041 if (m3 == 14) {
4042 always_goto(mkexpr(op4addr));
4043 } else {
4044 assign(op1, get_gpr_w1(r1));
4045 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004046 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4047 op1, op2));
florianf321da72012-07-21 20:32:57 +00004048 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4049 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004050 }
4051 }
4052
4053 return "crb";
4054}
4055
florian55085f82012-11-21 00:36:55 +00004056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004057s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4058{
4059 IRTemp op1 = newTemp(Ity_I64);
4060 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004061 IRTemp cond = newTemp(Ity_I32);
4062
4063 if (m3 == 0) {
4064 } else {
4065 if (m3 == 14) {
4066 always_goto(mkexpr(op4addr));
4067 } else {
4068 assign(op1, get_gpr_dw0(r1));
4069 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004070 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4071 op1, op2));
florianf321da72012-07-21 20:32:57 +00004072 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4073 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004074 }
4075 }
4076
4077 return "cgrb";
4078}
4079
florian55085f82012-11-21 00:36:55 +00004080static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004081s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4082{
4083 IRTemp op1 = newTemp(Ity_I32);
4084 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004085 IRTemp cond = newTemp(Ity_I32);
4086
4087 if (m3 == 0) {
4088 } else {
4089 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004090 always_goto_and_chase(
4091 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004092 } else {
4093 assign(op1, get_gpr_w1(r1));
4094 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004095 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4096 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004097 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4098 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4099
4100 }
4101 }
4102
4103 return "crj";
4104}
4105
florian55085f82012-11-21 00:36:55 +00004106static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004107s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4108{
4109 IRTemp op1 = newTemp(Ity_I64);
4110 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004111 IRTemp cond = newTemp(Ity_I32);
4112
4113 if (m3 == 0) {
4114 } else {
4115 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004116 always_goto_and_chase(
4117 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004118 } else {
4119 assign(op1, get_gpr_dw0(r1));
4120 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004121 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4122 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004123 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4124 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4125
4126 }
4127 }
4128
4129 return "cgrj";
4130}
4131
florian55085f82012-11-21 00:36:55 +00004132static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004133s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4134{
4135 IRTemp op1 = newTemp(Ity_I32);
4136 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004137 IRTemp cond = newTemp(Ity_I32);
4138
4139 if (m3 == 0) {
4140 } else {
4141 if (m3 == 14) {
4142 always_goto(mkexpr(op4addr));
4143 } else {
4144 assign(op1, get_gpr_w1(r1));
4145 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004146 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4147 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004148 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4149 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004150 }
4151 }
4152
4153 return "cib";
4154}
4155
florian55085f82012-11-21 00:36:55 +00004156static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004157s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4158{
4159 IRTemp op1 = newTemp(Ity_I64);
4160 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004161 IRTemp cond = newTemp(Ity_I32);
4162
4163 if (m3 == 0) {
4164 } else {
4165 if (m3 == 14) {
4166 always_goto(mkexpr(op4addr));
4167 } else {
4168 assign(op1, get_gpr_dw0(r1));
4169 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004170 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4171 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004172 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4173 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004174 }
4175 }
4176
4177 return "cgib";
4178}
4179
florian55085f82012-11-21 00:36:55 +00004180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004181s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4182{
4183 IRTemp op1 = newTemp(Ity_I32);
4184 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004185 IRTemp cond = newTemp(Ity_I32);
4186
4187 if (m3 == 0) {
4188 } else {
4189 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004190 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004191 } else {
4192 assign(op1, get_gpr_w1(r1));
4193 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004194 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4195 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004196 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4197 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4198
4199 }
4200 }
4201
4202 return "cij";
4203}
4204
florian55085f82012-11-21 00:36:55 +00004205static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004206s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4207{
4208 IRTemp op1 = newTemp(Ity_I64);
4209 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004210 IRTemp cond = newTemp(Ity_I32);
4211
4212 if (m3 == 0) {
4213 } else {
4214 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004215 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004216 } else {
4217 assign(op1, get_gpr_dw0(r1));
4218 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004219 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4220 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004221 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4222 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4223
4224 }
4225 }
4226
4227 return "cgij";
4228}
4229
florian55085f82012-11-21 00:36:55 +00004230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004231s390_irgen_CH(UChar r1, IRTemp op2addr)
4232{
4233 IRTemp op1 = newTemp(Ity_I32);
4234 IRTemp op2 = newTemp(Ity_I32);
4235
4236 assign(op1, get_gpr_w1(r1));
4237 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4238 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4239
4240 return "ch";
4241}
4242
florian55085f82012-11-21 00:36:55 +00004243static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004244s390_irgen_CHY(UChar r1, IRTemp op2addr)
4245{
4246 IRTemp op1 = newTemp(Ity_I32);
4247 IRTemp op2 = newTemp(Ity_I32);
4248
4249 assign(op1, get_gpr_w1(r1));
4250 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4251 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4252
4253 return "chy";
4254}
4255
florian55085f82012-11-21 00:36:55 +00004256static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004257s390_irgen_CGH(UChar r1, IRTemp op2addr)
4258{
4259 IRTemp op1 = newTemp(Ity_I64);
4260 IRTemp op2 = newTemp(Ity_I64);
4261
4262 assign(op1, get_gpr_dw0(r1));
4263 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4264 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4265
4266 return "cgh";
4267}
4268
florian55085f82012-11-21 00:36:55 +00004269static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004270s390_irgen_CHI(UChar r1, UShort i2)
4271{
4272 IRTemp op1 = newTemp(Ity_I32);
4273 Int op2;
4274
4275 assign(op1, get_gpr_w1(r1));
4276 op2 = (Int)(Short)i2;
4277 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4278 mkU32((UInt)op2)));
4279
4280 return "chi";
4281}
4282
florian55085f82012-11-21 00:36:55 +00004283static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004284s390_irgen_CGHI(UChar r1, UShort i2)
4285{
4286 IRTemp op1 = newTemp(Ity_I64);
4287 Long op2;
4288
4289 assign(op1, get_gpr_dw0(r1));
4290 op2 = (Long)(Short)i2;
4291 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4292 mkU64((ULong)op2)));
4293
4294 return "cghi";
4295}
4296
florian55085f82012-11-21 00:36:55 +00004297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004298s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4299{
4300 IRTemp op1 = newTemp(Ity_I16);
4301 Short op2;
4302
4303 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4304 op2 = (Short)i2;
4305 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4306 mkU16((UShort)op2)));
4307
4308 return "chhsi";
4309}
4310
florian55085f82012-11-21 00:36:55 +00004311static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004312s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4313{
4314 IRTemp op1 = newTemp(Ity_I32);
4315 Int op2;
4316
4317 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4318 op2 = (Int)(Short)i2;
4319 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4320 mkU32((UInt)op2)));
4321
4322 return "chsi";
4323}
4324
florian55085f82012-11-21 00:36:55 +00004325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004326s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4327{
4328 IRTemp op1 = newTemp(Ity_I64);
4329 Long op2;
4330
4331 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4332 op2 = (Long)(Short)i2;
4333 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4334 mkU64((ULong)op2)));
4335
4336 return "cghsi";
4337}
4338
florian55085f82012-11-21 00:36:55 +00004339static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004340s390_irgen_CHRL(UChar r1, UInt i2)
4341{
4342 IRTemp op1 = newTemp(Ity_I32);
4343 IRTemp op2 = newTemp(Ity_I32);
4344
4345 assign(op1, get_gpr_w1(r1));
4346 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4347 ((ULong)(Long)(Int)i2 << 1)))));
4348 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4349
4350 return "chrl";
4351}
4352
florian55085f82012-11-21 00:36:55 +00004353static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004354s390_irgen_CGHRL(UChar r1, UInt i2)
4355{
4356 IRTemp op1 = newTemp(Ity_I64);
4357 IRTemp op2 = newTemp(Ity_I64);
4358
4359 assign(op1, get_gpr_dw0(r1));
4360 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4361 ((ULong)(Long)(Int)i2 << 1)))));
4362 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4363
4364 return "cghrl";
4365}
4366
florian55085f82012-11-21 00:36:55 +00004367static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004368s390_irgen_CHHR(UChar r1, UChar r2)
4369{
4370 IRTemp op1 = newTemp(Ity_I32);
4371 IRTemp op2 = newTemp(Ity_I32);
4372
4373 assign(op1, get_gpr_w0(r1));
4374 assign(op2, get_gpr_w0(r2));
4375 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4376
4377 return "chhr";
4378}
4379
florian55085f82012-11-21 00:36:55 +00004380static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004381s390_irgen_CHLR(UChar r1, UChar r2)
4382{
4383 IRTemp op1 = newTemp(Ity_I32);
4384 IRTemp op2 = newTemp(Ity_I32);
4385
4386 assign(op1, get_gpr_w0(r1));
4387 assign(op2, get_gpr_w1(r2));
4388 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4389
4390 return "chlr";
4391}
4392
florian55085f82012-11-21 00:36:55 +00004393static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004394s390_irgen_CHF(UChar r1, IRTemp op2addr)
4395{
4396 IRTemp op1 = newTemp(Ity_I32);
4397 IRTemp op2 = newTemp(Ity_I32);
4398
4399 assign(op1, get_gpr_w0(r1));
4400 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4401 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4402
4403 return "chf";
4404}
4405
florian55085f82012-11-21 00:36:55 +00004406static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004407s390_irgen_CIH(UChar r1, UInt i2)
4408{
4409 IRTemp op1 = newTemp(Ity_I32);
4410 Int op2;
4411
4412 assign(op1, get_gpr_w0(r1));
4413 op2 = (Int)i2;
4414 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4415 mkU32((UInt)op2)));
4416
4417 return "cih";
4418}
4419
florian55085f82012-11-21 00:36:55 +00004420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004421s390_irgen_CLR(UChar r1, UChar r2)
4422{
4423 IRTemp op1 = newTemp(Ity_I32);
4424 IRTemp op2 = newTemp(Ity_I32);
4425
4426 assign(op1, get_gpr_w1(r1));
4427 assign(op2, get_gpr_w1(r2));
4428 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4429
4430 return "clr";
4431}
4432
florian55085f82012-11-21 00:36:55 +00004433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004434s390_irgen_CLGR(UChar r1, UChar r2)
4435{
4436 IRTemp op1 = newTemp(Ity_I64);
4437 IRTemp op2 = newTemp(Ity_I64);
4438
4439 assign(op1, get_gpr_dw0(r1));
4440 assign(op2, get_gpr_dw0(r2));
4441 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4442
4443 return "clgr";
4444}
4445
florian55085f82012-11-21 00:36:55 +00004446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004447s390_irgen_CLGFR(UChar r1, UChar r2)
4448{
4449 IRTemp op1 = newTemp(Ity_I64);
4450 IRTemp op2 = newTemp(Ity_I64);
4451
4452 assign(op1, get_gpr_dw0(r1));
4453 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4454 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4455
4456 return "clgfr";
4457}
4458
florian55085f82012-11-21 00:36:55 +00004459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004460s390_irgen_CL(UChar r1, IRTemp op2addr)
4461{
4462 IRTemp op1 = newTemp(Ity_I32);
4463 IRTemp op2 = newTemp(Ity_I32);
4464
4465 assign(op1, get_gpr_w1(r1));
4466 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4467 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4468
4469 return "cl";
4470}
4471
florian55085f82012-11-21 00:36:55 +00004472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004473s390_irgen_CLY(UChar r1, IRTemp op2addr)
4474{
4475 IRTemp op1 = newTemp(Ity_I32);
4476 IRTemp op2 = newTemp(Ity_I32);
4477
4478 assign(op1, get_gpr_w1(r1));
4479 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4480 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4481
4482 return "cly";
4483}
4484
florian55085f82012-11-21 00:36:55 +00004485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004486s390_irgen_CLG(UChar r1, IRTemp op2addr)
4487{
4488 IRTemp op1 = newTemp(Ity_I64);
4489 IRTemp op2 = newTemp(Ity_I64);
4490
4491 assign(op1, get_gpr_dw0(r1));
4492 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4493 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4494
4495 return "clg";
4496}
4497
florian55085f82012-11-21 00:36:55 +00004498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004499s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4500{
4501 IRTemp op1 = newTemp(Ity_I64);
4502 IRTemp op2 = newTemp(Ity_I64);
4503
4504 assign(op1, get_gpr_dw0(r1));
4505 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4506 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4507
4508 return "clgf";
4509}
4510
florian55085f82012-11-21 00:36:55 +00004511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004512s390_irgen_CLFI(UChar r1, UInt i2)
4513{
4514 IRTemp op1 = newTemp(Ity_I32);
4515 UInt op2;
4516
4517 assign(op1, get_gpr_w1(r1));
4518 op2 = i2;
4519 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4520 mkU32(op2)));
4521
4522 return "clfi";
4523}
4524
florian55085f82012-11-21 00:36:55 +00004525static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004526s390_irgen_CLGFI(UChar r1, UInt i2)
4527{
4528 IRTemp op1 = newTemp(Ity_I64);
4529 ULong op2;
4530
4531 assign(op1, get_gpr_dw0(r1));
4532 op2 = (ULong)i2;
4533 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4534 mkU64(op2)));
4535
4536 return "clgfi";
4537}
4538
florian55085f82012-11-21 00:36:55 +00004539static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004540s390_irgen_CLI(UChar i2, IRTemp op1addr)
4541{
4542 IRTemp op1 = newTemp(Ity_I8);
4543 UChar op2;
4544
4545 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4546 op2 = i2;
4547 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4548 mkU8(op2)));
4549
4550 return "cli";
4551}
4552
florian55085f82012-11-21 00:36:55 +00004553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004554s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4555{
4556 IRTemp op1 = newTemp(Ity_I8);
4557 UChar op2;
4558
4559 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4560 op2 = i2;
4561 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4562 mkU8(op2)));
4563
4564 return "cliy";
4565}
4566
florian55085f82012-11-21 00:36:55 +00004567static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004568s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4569{
4570 IRTemp op1 = newTemp(Ity_I32);
4571 UInt op2;
4572
4573 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4574 op2 = (UInt)i2;
4575 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4576 mkU32(op2)));
4577
4578 return "clfhsi";
4579}
4580
florian55085f82012-11-21 00:36:55 +00004581static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004582s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4583{
4584 IRTemp op1 = newTemp(Ity_I64);
4585 ULong op2;
4586
4587 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4588 op2 = (ULong)i2;
4589 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4590 mkU64(op2)));
4591
4592 return "clghsi";
4593}
4594
florian55085f82012-11-21 00:36:55 +00004595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004596s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4597{
4598 IRTemp op1 = newTemp(Ity_I16);
4599 UShort op2;
4600
4601 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4602 op2 = i2;
4603 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4604 mkU16(op2)));
4605
4606 return "clhhsi";
4607}
4608
florian55085f82012-11-21 00:36:55 +00004609static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004610s390_irgen_CLRL(UChar r1, UInt i2)
4611{
4612 IRTemp op1 = newTemp(Ity_I32);
4613 IRTemp op2 = newTemp(Ity_I32);
4614
4615 assign(op1, get_gpr_w1(r1));
4616 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4617 i2 << 1))));
4618 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4619
4620 return "clrl";
4621}
4622
florian55085f82012-11-21 00:36:55 +00004623static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004624s390_irgen_CLGRL(UChar r1, UInt i2)
4625{
4626 IRTemp op1 = newTemp(Ity_I64);
4627 IRTemp op2 = newTemp(Ity_I64);
4628
4629 assign(op1, get_gpr_dw0(r1));
4630 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4631 i2 << 1))));
4632 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4633
4634 return "clgrl";
4635}
4636
florian55085f82012-11-21 00:36:55 +00004637static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004638s390_irgen_CLGFRL(UChar r1, UInt i2)
4639{
4640 IRTemp op1 = newTemp(Ity_I64);
4641 IRTemp op2 = newTemp(Ity_I64);
4642
4643 assign(op1, get_gpr_dw0(r1));
4644 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4645 ((ULong)(Long)(Int)i2 << 1)))));
4646 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4647
4648 return "clgfrl";
4649}
4650
florian55085f82012-11-21 00:36:55 +00004651static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004652s390_irgen_CLHRL(UChar r1, UInt i2)
4653{
4654 IRTemp op1 = newTemp(Ity_I32);
4655 IRTemp op2 = newTemp(Ity_I32);
4656
4657 assign(op1, get_gpr_w1(r1));
4658 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4659 ((ULong)(Long)(Int)i2 << 1)))));
4660 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4661
4662 return "clhrl";
4663}
4664
florian55085f82012-11-21 00:36:55 +00004665static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004666s390_irgen_CLGHRL(UChar r1, UInt i2)
4667{
4668 IRTemp op1 = newTemp(Ity_I64);
4669 IRTemp op2 = newTemp(Ity_I64);
4670
4671 assign(op1, get_gpr_dw0(r1));
4672 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4673 ((ULong)(Long)(Int)i2 << 1)))));
4674 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4675
4676 return "clghrl";
4677}
4678
florian55085f82012-11-21 00:36:55 +00004679static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004680s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4681{
4682 IRTemp op1 = newTemp(Ity_I32);
4683 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004684 IRTemp cond = newTemp(Ity_I32);
4685
4686 if (m3 == 0) {
4687 } else {
4688 if (m3 == 14) {
4689 always_goto(mkexpr(op4addr));
4690 } else {
4691 assign(op1, get_gpr_w1(r1));
4692 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004693 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4694 op1, op2));
florianf321da72012-07-21 20:32:57 +00004695 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4696 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004697 }
4698 }
4699
4700 return "clrb";
4701}
4702
florian55085f82012-11-21 00:36:55 +00004703static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004704s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4705{
4706 IRTemp op1 = newTemp(Ity_I64);
4707 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004708 IRTemp cond = newTemp(Ity_I32);
4709
4710 if (m3 == 0) {
4711 } else {
4712 if (m3 == 14) {
4713 always_goto(mkexpr(op4addr));
4714 } else {
4715 assign(op1, get_gpr_dw0(r1));
4716 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004717 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4718 op1, op2));
florianf321da72012-07-21 20:32:57 +00004719 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4720 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004721 }
4722 }
4723
4724 return "clgrb";
4725}
4726
florian55085f82012-11-21 00:36:55 +00004727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004728s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4729{
4730 IRTemp op1 = newTemp(Ity_I32);
4731 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004732 IRTemp cond = newTemp(Ity_I32);
4733
4734 if (m3 == 0) {
4735 } else {
4736 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004737 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004738 } else {
4739 assign(op1, get_gpr_w1(r1));
4740 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004741 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4742 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004743 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4744 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4745
4746 }
4747 }
4748
4749 return "clrj";
4750}
4751
florian55085f82012-11-21 00:36:55 +00004752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004753s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4754{
4755 IRTemp op1 = newTemp(Ity_I64);
4756 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004757 IRTemp cond = newTemp(Ity_I32);
4758
4759 if (m3 == 0) {
4760 } else {
4761 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004762 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004763 } else {
4764 assign(op1, get_gpr_dw0(r1));
4765 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004766 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4767 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004768 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4769 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4770
4771 }
4772 }
4773
4774 return "clgrj";
4775}
4776
florian55085f82012-11-21 00:36:55 +00004777static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004778s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4779{
4780 IRTemp op1 = newTemp(Ity_I32);
4781 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004782 IRTemp cond = newTemp(Ity_I32);
4783
4784 if (m3 == 0) {
4785 } else {
4786 if (m3 == 14) {
4787 always_goto(mkexpr(op4addr));
4788 } else {
4789 assign(op1, get_gpr_w1(r1));
4790 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004791 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4792 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004793 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4794 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004795 }
4796 }
4797
4798 return "clib";
4799}
4800
florian55085f82012-11-21 00:36:55 +00004801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004802s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4803{
4804 IRTemp op1 = newTemp(Ity_I64);
4805 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004806 IRTemp cond = newTemp(Ity_I32);
4807
4808 if (m3 == 0) {
4809 } else {
4810 if (m3 == 14) {
4811 always_goto(mkexpr(op4addr));
4812 } else {
4813 assign(op1, get_gpr_dw0(r1));
4814 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004815 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4816 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004817 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4818 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004819 }
4820 }
4821
4822 return "clgib";
4823}
4824
florian55085f82012-11-21 00:36:55 +00004825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004826s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4827{
4828 IRTemp op1 = newTemp(Ity_I32);
4829 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004830 IRTemp cond = newTemp(Ity_I32);
4831
4832 if (m3 == 0) {
4833 } else {
4834 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004835 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004836 } else {
4837 assign(op1, get_gpr_w1(r1));
4838 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004839 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4840 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004841 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4842 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4843
4844 }
4845 }
4846
4847 return "clij";
4848}
4849
florian55085f82012-11-21 00:36:55 +00004850static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004851s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4852{
4853 IRTemp op1 = newTemp(Ity_I64);
4854 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004855 IRTemp cond = newTemp(Ity_I32);
4856
4857 if (m3 == 0) {
4858 } else {
4859 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004860 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004861 } else {
4862 assign(op1, get_gpr_dw0(r1));
4863 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004864 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4865 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004866 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4867 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4868
4869 }
4870 }
4871
4872 return "clgij";
4873}
4874
florian55085f82012-11-21 00:36:55 +00004875static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004876s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4877{
4878 IRTemp op1 = newTemp(Ity_I32);
4879 IRTemp op2 = newTemp(Ity_I32);
4880 IRTemp b0 = newTemp(Ity_I32);
4881 IRTemp b1 = newTemp(Ity_I32);
4882 IRTemp b2 = newTemp(Ity_I32);
4883 IRTemp b3 = newTemp(Ity_I32);
4884 IRTemp c0 = newTemp(Ity_I32);
4885 IRTemp c1 = newTemp(Ity_I32);
4886 IRTemp c2 = newTemp(Ity_I32);
4887 IRTemp c3 = newTemp(Ity_I32);
4888 UChar n;
4889
4890 n = 0;
4891 if ((r3 & 8) != 0) {
4892 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4893 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4894 n = n + 1;
4895 } else {
4896 assign(b0, mkU32(0));
4897 assign(c0, mkU32(0));
4898 }
4899 if ((r3 & 4) != 0) {
4900 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4901 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4902 mkU64(n)))));
4903 n = n + 1;
4904 } else {
4905 assign(b1, mkU32(0));
4906 assign(c1, mkU32(0));
4907 }
4908 if ((r3 & 2) != 0) {
4909 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4910 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4911 mkU64(n)))));
4912 n = n + 1;
4913 } else {
4914 assign(b2, mkU32(0));
4915 assign(c2, mkU32(0));
4916 }
4917 if ((r3 & 1) != 0) {
4918 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4919 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4920 mkU64(n)))));
4921 n = n + 1;
4922 } else {
4923 assign(b3, mkU32(0));
4924 assign(c3, mkU32(0));
4925 }
4926 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4927 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4928 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4929 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4930 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4931 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4932 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4933
4934 return "clm";
4935}
4936
florian55085f82012-11-21 00:36:55 +00004937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004938s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4939{
4940 IRTemp op1 = newTemp(Ity_I32);
4941 IRTemp op2 = newTemp(Ity_I32);
4942 IRTemp b0 = newTemp(Ity_I32);
4943 IRTemp b1 = newTemp(Ity_I32);
4944 IRTemp b2 = newTemp(Ity_I32);
4945 IRTemp b3 = newTemp(Ity_I32);
4946 IRTemp c0 = newTemp(Ity_I32);
4947 IRTemp c1 = newTemp(Ity_I32);
4948 IRTemp c2 = newTemp(Ity_I32);
4949 IRTemp c3 = newTemp(Ity_I32);
4950 UChar n;
4951
4952 n = 0;
4953 if ((r3 & 8) != 0) {
4954 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4955 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4956 n = n + 1;
4957 } else {
4958 assign(b0, mkU32(0));
4959 assign(c0, mkU32(0));
4960 }
4961 if ((r3 & 4) != 0) {
4962 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4963 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4964 mkU64(n)))));
4965 n = n + 1;
4966 } else {
4967 assign(b1, mkU32(0));
4968 assign(c1, mkU32(0));
4969 }
4970 if ((r3 & 2) != 0) {
4971 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4972 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4973 mkU64(n)))));
4974 n = n + 1;
4975 } else {
4976 assign(b2, mkU32(0));
4977 assign(c2, mkU32(0));
4978 }
4979 if ((r3 & 1) != 0) {
4980 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4981 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4982 mkU64(n)))));
4983 n = n + 1;
4984 } else {
4985 assign(b3, mkU32(0));
4986 assign(c3, mkU32(0));
4987 }
4988 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4989 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4990 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4991 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4992 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4993 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4994 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4995
4996 return "clmy";
4997}
4998
florian55085f82012-11-21 00:36:55 +00004999static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005000s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5001{
5002 IRTemp op1 = newTemp(Ity_I32);
5003 IRTemp op2 = newTemp(Ity_I32);
5004 IRTemp b0 = newTemp(Ity_I32);
5005 IRTemp b1 = newTemp(Ity_I32);
5006 IRTemp b2 = newTemp(Ity_I32);
5007 IRTemp b3 = newTemp(Ity_I32);
5008 IRTemp c0 = newTemp(Ity_I32);
5009 IRTemp c1 = newTemp(Ity_I32);
5010 IRTemp c2 = newTemp(Ity_I32);
5011 IRTemp c3 = newTemp(Ity_I32);
5012 UChar n;
5013
5014 n = 0;
5015 if ((r3 & 8) != 0) {
5016 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5017 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5018 n = n + 1;
5019 } else {
5020 assign(b0, mkU32(0));
5021 assign(c0, mkU32(0));
5022 }
5023 if ((r3 & 4) != 0) {
5024 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5025 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5026 mkU64(n)))));
5027 n = n + 1;
5028 } else {
5029 assign(b1, mkU32(0));
5030 assign(c1, mkU32(0));
5031 }
5032 if ((r3 & 2) != 0) {
5033 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5034 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5035 mkU64(n)))));
5036 n = n + 1;
5037 } else {
5038 assign(b2, mkU32(0));
5039 assign(c2, mkU32(0));
5040 }
5041 if ((r3 & 1) != 0) {
5042 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5043 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5044 mkU64(n)))));
5045 n = n + 1;
5046 } else {
5047 assign(b3, mkU32(0));
5048 assign(c3, mkU32(0));
5049 }
5050 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5051 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5052 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5053 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5054 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5055 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5056 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5057
5058 return "clmh";
5059}
5060
florian55085f82012-11-21 00:36:55 +00005061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005062s390_irgen_CLHHR(UChar r1, UChar r2)
5063{
5064 IRTemp op1 = newTemp(Ity_I32);
5065 IRTemp op2 = newTemp(Ity_I32);
5066
5067 assign(op1, get_gpr_w0(r1));
5068 assign(op2, get_gpr_w0(r2));
5069 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5070
5071 return "clhhr";
5072}
5073
florian55085f82012-11-21 00:36:55 +00005074static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005075s390_irgen_CLHLR(UChar r1, UChar r2)
5076{
5077 IRTemp op1 = newTemp(Ity_I32);
5078 IRTemp op2 = newTemp(Ity_I32);
5079
5080 assign(op1, get_gpr_w0(r1));
5081 assign(op2, get_gpr_w1(r2));
5082 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5083
5084 return "clhlr";
5085}
5086
florian55085f82012-11-21 00:36:55 +00005087static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005088s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5089{
5090 IRTemp op1 = newTemp(Ity_I32);
5091 IRTemp op2 = newTemp(Ity_I32);
5092
5093 assign(op1, get_gpr_w0(r1));
5094 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5095 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5096
5097 return "clhf";
5098}
5099
florian55085f82012-11-21 00:36:55 +00005100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005101s390_irgen_CLIH(UChar r1, UInt i2)
5102{
5103 IRTemp op1 = newTemp(Ity_I32);
5104 UInt op2;
5105
5106 assign(op1, get_gpr_w0(r1));
5107 op2 = i2;
5108 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5109 mkU32(op2)));
5110
5111 return "clih";
5112}
5113
florian55085f82012-11-21 00:36:55 +00005114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005115s390_irgen_CPYA(UChar r1, UChar r2)
5116{
5117 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005118 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005119 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5120
5121 return "cpya";
5122}
5123
florian55085f82012-11-21 00:36:55 +00005124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005125s390_irgen_XR(UChar r1, UChar r2)
5126{
5127 IRTemp op1 = newTemp(Ity_I32);
5128 IRTemp op2 = newTemp(Ity_I32);
5129 IRTemp result = newTemp(Ity_I32);
5130
5131 if (r1 == r2) {
5132 assign(result, mkU32(0));
5133 } else {
5134 assign(op1, get_gpr_w1(r1));
5135 assign(op2, get_gpr_w1(r2));
5136 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5137 }
5138 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5139 put_gpr_w1(r1, mkexpr(result));
5140
5141 return "xr";
5142}
5143
florian55085f82012-11-21 00:36:55 +00005144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005145s390_irgen_XGR(UChar r1, UChar r2)
5146{
5147 IRTemp op1 = newTemp(Ity_I64);
5148 IRTemp op2 = newTemp(Ity_I64);
5149 IRTemp result = newTemp(Ity_I64);
5150
5151 if (r1 == r2) {
5152 assign(result, mkU64(0));
5153 } else {
5154 assign(op1, get_gpr_dw0(r1));
5155 assign(op2, get_gpr_dw0(r2));
5156 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5157 }
5158 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5159 put_gpr_dw0(r1, mkexpr(result));
5160
5161 return "xgr";
5162}
5163
florian55085f82012-11-21 00:36:55 +00005164static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005165s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5166{
5167 IRTemp op2 = newTemp(Ity_I32);
5168 IRTemp op3 = newTemp(Ity_I32);
5169 IRTemp result = newTemp(Ity_I32);
5170
5171 assign(op2, get_gpr_w1(r2));
5172 assign(op3, get_gpr_w1(r3));
5173 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5174 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5175 put_gpr_w1(r1, mkexpr(result));
5176
5177 return "xrk";
5178}
5179
florian55085f82012-11-21 00:36:55 +00005180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005181s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5182{
5183 IRTemp op2 = newTemp(Ity_I64);
5184 IRTemp op3 = newTemp(Ity_I64);
5185 IRTemp result = newTemp(Ity_I64);
5186
5187 assign(op2, get_gpr_dw0(r2));
5188 assign(op3, get_gpr_dw0(r3));
5189 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5190 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5191 put_gpr_dw0(r1, mkexpr(result));
5192
5193 return "xgrk";
5194}
5195
florian55085f82012-11-21 00:36:55 +00005196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005197s390_irgen_X(UChar r1, IRTemp op2addr)
5198{
5199 IRTemp op1 = newTemp(Ity_I32);
5200 IRTemp op2 = newTemp(Ity_I32);
5201 IRTemp result = newTemp(Ity_I32);
5202
5203 assign(op1, get_gpr_w1(r1));
5204 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5205 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5206 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5207 put_gpr_w1(r1, mkexpr(result));
5208
5209 return "x";
5210}
5211
florian55085f82012-11-21 00:36:55 +00005212static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005213s390_irgen_XY(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 "xy";
5226}
5227
florian55085f82012-11-21 00:36:55 +00005228static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005229s390_irgen_XG(UChar r1, IRTemp op2addr)
5230{
5231 IRTemp op1 = newTemp(Ity_I64);
5232 IRTemp op2 = newTemp(Ity_I64);
5233 IRTemp result = newTemp(Ity_I64);
5234
5235 assign(op1, get_gpr_dw0(r1));
5236 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5237 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5238 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5239 put_gpr_dw0(r1, mkexpr(result));
5240
5241 return "xg";
5242}
5243
florian55085f82012-11-21 00:36:55 +00005244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005245s390_irgen_XI(UChar i2, IRTemp op1addr)
5246{
5247 IRTemp op1 = newTemp(Ity_I8);
5248 UChar op2;
5249 IRTemp result = newTemp(Ity_I8);
5250
5251 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5252 op2 = i2;
5253 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5254 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5255 store(mkexpr(op1addr), mkexpr(result));
5256
5257 return "xi";
5258}
5259
florian55085f82012-11-21 00:36:55 +00005260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005261s390_irgen_XIY(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 "xiy";
5274}
5275
florian55085f82012-11-21 00:36:55 +00005276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005277s390_irgen_XIHF(UChar r1, UInt i2)
5278{
5279 IRTemp op1 = newTemp(Ity_I32);
5280 UInt op2;
5281 IRTemp result = newTemp(Ity_I32);
5282
5283 assign(op1, get_gpr_w0(r1));
5284 op2 = i2;
5285 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5286 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5287 put_gpr_w0(r1, mkexpr(result));
5288
5289 return "xihf";
5290}
5291
florian55085f82012-11-21 00:36:55 +00005292static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005293s390_irgen_XILF(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_w1(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_w1(r1, mkexpr(result));
5304
5305 return "xilf";
5306}
5307
florian55085f82012-11-21 00:36:55 +00005308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005309s390_irgen_EAR(UChar r1, UChar r2)
5310{
5311 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005312 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005313 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5314
5315 return "ear";
5316}
5317
florian55085f82012-11-21 00:36:55 +00005318static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005319s390_irgen_IC(UChar r1, IRTemp op2addr)
5320{
5321 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5322
5323 return "ic";
5324}
5325
florian55085f82012-11-21 00:36:55 +00005326static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005327s390_irgen_ICY(UChar r1, IRTemp op2addr)
5328{
5329 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5330
5331 return "icy";
5332}
5333
florian55085f82012-11-21 00:36:55 +00005334static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005335s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5336{
5337 UChar n;
5338 IRTemp result = newTemp(Ity_I32);
5339 UInt mask;
5340
5341 n = 0;
5342 mask = (UInt)r3;
5343 if ((mask & 8) != 0) {
5344 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5345 n = n + 1;
5346 }
5347 if ((mask & 4) != 0) {
5348 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5349
5350 n = n + 1;
5351 }
5352 if ((mask & 2) != 0) {
5353 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5354
5355 n = n + 1;
5356 }
5357 if ((mask & 1) != 0) {
5358 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5359
5360 n = n + 1;
5361 }
5362 assign(result, get_gpr_w1(r1));
5363 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5364 mkU32(mask)));
5365
5366 return "icm";
5367}
5368
florian55085f82012-11-21 00:36:55 +00005369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005370s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5371{
5372 UChar n;
5373 IRTemp result = newTemp(Ity_I32);
5374 UInt mask;
5375
5376 n = 0;
5377 mask = (UInt)r3;
5378 if ((mask & 8) != 0) {
5379 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5380 n = n + 1;
5381 }
5382 if ((mask & 4) != 0) {
5383 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5384
5385 n = n + 1;
5386 }
5387 if ((mask & 2) != 0) {
5388 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5389
5390 n = n + 1;
5391 }
5392 if ((mask & 1) != 0) {
5393 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5394
5395 n = n + 1;
5396 }
5397 assign(result, get_gpr_w1(r1));
5398 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5399 mkU32(mask)));
5400
5401 return "icmy";
5402}
5403
florian55085f82012-11-21 00:36:55 +00005404static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005405s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5406{
5407 UChar n;
5408 IRTemp result = newTemp(Ity_I32);
5409 UInt mask;
5410
5411 n = 0;
5412 mask = (UInt)r3;
5413 if ((mask & 8) != 0) {
5414 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5415 n = n + 1;
5416 }
5417 if ((mask & 4) != 0) {
5418 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5419
5420 n = n + 1;
5421 }
5422 if ((mask & 2) != 0) {
5423 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5424
5425 n = n + 1;
5426 }
5427 if ((mask & 1) != 0) {
5428 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5429
5430 n = n + 1;
5431 }
5432 assign(result, get_gpr_w0(r1));
5433 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5434 mkU32(mask)));
5435
5436 return "icmh";
5437}
5438
florian55085f82012-11-21 00:36:55 +00005439static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005440s390_irgen_IIHF(UChar r1, UInt i2)
5441{
5442 put_gpr_w0(r1, mkU32(i2));
5443
5444 return "iihf";
5445}
5446
florian55085f82012-11-21 00:36:55 +00005447static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005448s390_irgen_IIHH(UChar r1, UShort i2)
5449{
5450 put_gpr_hw0(r1, mkU16(i2));
5451
5452 return "iihh";
5453}
5454
florian55085f82012-11-21 00:36:55 +00005455static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005456s390_irgen_IIHL(UChar r1, UShort i2)
5457{
5458 put_gpr_hw1(r1, mkU16(i2));
5459
5460 return "iihl";
5461}
5462
florian55085f82012-11-21 00:36:55 +00005463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005464s390_irgen_IILF(UChar r1, UInt i2)
5465{
5466 put_gpr_w1(r1, mkU32(i2));
5467
5468 return "iilf";
5469}
5470
florian55085f82012-11-21 00:36:55 +00005471static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005472s390_irgen_IILH(UChar r1, UShort i2)
5473{
5474 put_gpr_hw2(r1, mkU16(i2));
5475
5476 return "iilh";
5477}
5478
florian55085f82012-11-21 00:36:55 +00005479static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005480s390_irgen_IILL(UChar r1, UShort i2)
5481{
5482 put_gpr_hw3(r1, mkU16(i2));
5483
5484 return "iill";
5485}
5486
florian55085f82012-11-21 00:36:55 +00005487static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005488s390_irgen_LR(UChar r1, UChar r2)
5489{
5490 put_gpr_w1(r1, get_gpr_w1(r2));
5491
5492 return "lr";
5493}
5494
florian55085f82012-11-21 00:36:55 +00005495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005496s390_irgen_LGR(UChar r1, UChar r2)
5497{
5498 put_gpr_dw0(r1, get_gpr_dw0(r2));
5499
5500 return "lgr";
5501}
5502
florian55085f82012-11-21 00:36:55 +00005503static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005504s390_irgen_LGFR(UChar r1, UChar r2)
5505{
5506 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5507
5508 return "lgfr";
5509}
5510
florian55085f82012-11-21 00:36:55 +00005511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005512s390_irgen_L(UChar r1, IRTemp op2addr)
5513{
5514 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5515
5516 return "l";
5517}
5518
florian55085f82012-11-21 00:36:55 +00005519static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005520s390_irgen_LY(UChar r1, IRTemp op2addr)
5521{
5522 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5523
5524 return "ly";
5525}
5526
florian55085f82012-11-21 00:36:55 +00005527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005528s390_irgen_LG(UChar r1, IRTemp op2addr)
5529{
5530 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5531
5532 return "lg";
5533}
5534
florian55085f82012-11-21 00:36:55 +00005535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005536s390_irgen_LGF(UChar r1, IRTemp op2addr)
5537{
5538 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5539
5540 return "lgf";
5541}
5542
florian55085f82012-11-21 00:36:55 +00005543static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005544s390_irgen_LGFI(UChar r1, UInt i2)
5545{
5546 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5547
5548 return "lgfi";
5549}
5550
florian55085f82012-11-21 00:36:55 +00005551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005552s390_irgen_LRL(UChar r1, UInt i2)
5553{
5554 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5555 i2 << 1))));
5556
5557 return "lrl";
5558}
5559
florian55085f82012-11-21 00:36:55 +00005560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005561s390_irgen_LGRL(UChar r1, UInt i2)
5562{
5563 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5564 i2 << 1))));
5565
5566 return "lgrl";
5567}
5568
florian55085f82012-11-21 00:36:55 +00005569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005570s390_irgen_LGFRL(UChar r1, UInt i2)
5571{
5572 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5573 ((ULong)(Long)(Int)i2 << 1)))));
5574
5575 return "lgfrl";
5576}
5577
florian55085f82012-11-21 00:36:55 +00005578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005579s390_irgen_LA(UChar r1, IRTemp op2addr)
5580{
5581 put_gpr_dw0(r1, mkexpr(op2addr));
5582
5583 return "la";
5584}
5585
florian55085f82012-11-21 00:36:55 +00005586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005587s390_irgen_LAY(UChar r1, IRTemp op2addr)
5588{
5589 put_gpr_dw0(r1, mkexpr(op2addr));
5590
5591 return "lay";
5592}
5593
florian55085f82012-11-21 00:36:55 +00005594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005595s390_irgen_LAE(UChar r1, IRTemp op2addr)
5596{
5597 put_gpr_dw0(r1, mkexpr(op2addr));
5598
5599 return "lae";
5600}
5601
florian55085f82012-11-21 00:36:55 +00005602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005603s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5604{
5605 put_gpr_dw0(r1, mkexpr(op2addr));
5606
5607 return "laey";
5608}
5609
florian55085f82012-11-21 00:36:55 +00005610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005611s390_irgen_LARL(UChar r1, UInt i2)
5612{
5613 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5614
5615 return "larl";
5616}
5617
floriana265ee72012-12-02 20:58:17 +00005618/* The IR representation of LAA and friends is an approximation of what
5619 happens natively. Essentially a loop containing a compare-and-swap is
5620 constructed which will iterate until the CAS succeeds. As a consequence,
5621 instrumenters may see more memory accesses than happen natively. See also
5622 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005623static void
5624s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005625{
floriana265ee72012-12-02 20:58:17 +00005626 IRCAS *cas;
5627 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005628 IRTemp op2 = newTemp(Ity_I32);
5629 IRTemp op3 = newTemp(Ity_I32);
5630 IRTemp result = newTemp(Ity_I32);
5631
5632 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5633 assign(op3, get_gpr_w1(r3));
5634 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005635
5636 /* Place the addition of second operand and third operand at the
5637 second-operand location everytime */
5638 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5639 Iend_BE, mkexpr(op2addr),
5640 NULL, mkexpr(op2), /* expected value */
5641 NULL, mkexpr(result) /* new value */);
5642 stmt(IRStmt_CAS(cas));
5643
florianffc94012012-12-02 21:31:15 +00005644 /* Set CC according to 32-bit addition */
5645 if (is_signed) {
5646 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5647 } else {
5648 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5649 }
floriana265ee72012-12-02 20:58:17 +00005650
5651 /* If old_mem contains the expected value, then the CAS succeeded.
5652 Otherwise, it did not */
5653 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5654 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005655}
5656
5657static void
5658s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5659{
5660 IRCAS *cas;
5661 IRTemp old_mem = newTemp(Ity_I64);
5662 IRTemp op2 = newTemp(Ity_I64);
5663 IRTemp op3 = newTemp(Ity_I64);
5664 IRTemp result = newTemp(Ity_I64);
5665
5666 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5667 assign(op3, get_gpr_dw0(r3));
5668 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5669
5670 /* Place the addition of second operand and third operand at the
5671 second-operand location everytime */
5672 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5673 Iend_BE, mkexpr(op2addr),
5674 NULL, mkexpr(op2), /* expected value */
5675 NULL, mkexpr(result) /* new value */);
5676 stmt(IRStmt_CAS(cas));
5677
5678 /* Set CC according to 64-bit addition */
5679 if (is_signed) {
5680 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5681 } else {
5682 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5683 }
5684
5685 /* If old_mem contains the expected value, then the CAS succeeded.
5686 Otherwise, it did not */
5687 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5688 put_gpr_dw0(r1, mkexpr(old_mem));
5689}
5690
5691static void
5692s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5693{
5694 IRCAS *cas;
5695 IRTemp old_mem = newTemp(Ity_I32);
5696 IRTemp op2 = newTemp(Ity_I32);
5697 IRTemp op3 = newTemp(Ity_I32);
5698 IRTemp result = newTemp(Ity_I32);
5699
5700 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5701 assign(op3, get_gpr_w1(r3));
5702 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5703
5704 /* Place the addition of second operand and third operand at the
5705 second-operand location everytime */
5706 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5707 Iend_BE, mkexpr(op2addr),
5708 NULL, mkexpr(op2), /* expected value */
5709 NULL, mkexpr(result) /* new value */);
5710 stmt(IRStmt_CAS(cas));
5711
5712 /* Set CC according to bitwise operation */
5713 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5714
5715 /* If old_mem contains the expected value, then the CAS succeeded.
5716 Otherwise, it did not */
5717 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5718 put_gpr_w1(r1, mkexpr(old_mem));
5719}
5720
5721static void
5722s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5723{
5724 IRCAS *cas;
5725 IRTemp old_mem = newTemp(Ity_I64);
5726 IRTemp op2 = newTemp(Ity_I64);
5727 IRTemp op3 = newTemp(Ity_I64);
5728 IRTemp result = newTemp(Ity_I64);
5729
5730 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5731 assign(op3, get_gpr_dw0(r3));
5732 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5733
5734 /* Place the addition of second operand and third operand at the
5735 second-operand location everytime */
5736 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5737 Iend_BE, mkexpr(op2addr),
5738 NULL, mkexpr(op2), /* expected value */
5739 NULL, mkexpr(result) /* new value */);
5740 stmt(IRStmt_CAS(cas));
5741
5742 /* Set CC according to bitwise operation */
5743 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5744
5745 /* If old_mem contains the expected value, then the CAS succeeded.
5746 Otherwise, it did not */
5747 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5748 put_gpr_dw0(r1, mkexpr(old_mem));
5749}
5750
5751static const HChar *
5752s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5753{
5754 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005755
5756 return "laa";
5757}
5758
florian55085f82012-11-21 00:36:55 +00005759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005760s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5761{
florianffc94012012-12-02 21:31:15 +00005762 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005763
5764 return "laag";
5765}
5766
florian55085f82012-11-21 00:36:55 +00005767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005768s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5769{
florianffc94012012-12-02 21:31:15 +00005770 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005771
5772 return "laal";
5773}
5774
florian55085f82012-11-21 00:36:55 +00005775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005776s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5777{
florianffc94012012-12-02 21:31:15 +00005778 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005779
5780 return "laalg";
5781}
5782
florian55085f82012-11-21 00:36:55 +00005783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005784s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5785{
florianffc94012012-12-02 21:31:15 +00005786 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005787
5788 return "lan";
5789}
5790
florian55085f82012-11-21 00:36:55 +00005791static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005792s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5793{
florianffc94012012-12-02 21:31:15 +00005794 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005795
5796 return "lang";
5797}
5798
florian55085f82012-11-21 00:36:55 +00005799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005800s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5801{
florianffc94012012-12-02 21:31:15 +00005802 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005803
5804 return "lax";
5805}
5806
florian55085f82012-11-21 00:36:55 +00005807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005808s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5809{
florianffc94012012-12-02 21:31:15 +00005810 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005811
5812 return "laxg";
5813}
5814
florian55085f82012-11-21 00:36:55 +00005815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005816s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5817{
florianffc94012012-12-02 21:31:15 +00005818 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005819
5820 return "lao";
5821}
5822
florian55085f82012-11-21 00:36:55 +00005823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005824s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5825{
florianffc94012012-12-02 21:31:15 +00005826 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005827
5828 return "laog";
5829}
5830
florian55085f82012-11-21 00:36:55 +00005831static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005832s390_irgen_LTR(UChar r1, UChar r2)
5833{
5834 IRTemp op2 = newTemp(Ity_I32);
5835
5836 assign(op2, get_gpr_w1(r2));
5837 put_gpr_w1(r1, mkexpr(op2));
5838 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5839
5840 return "ltr";
5841}
5842
florian55085f82012-11-21 00:36:55 +00005843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005844s390_irgen_LTGR(UChar r1, UChar r2)
5845{
5846 IRTemp op2 = newTemp(Ity_I64);
5847
5848 assign(op2, get_gpr_dw0(r2));
5849 put_gpr_dw0(r1, mkexpr(op2));
5850 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5851
5852 return "ltgr";
5853}
5854
florian55085f82012-11-21 00:36:55 +00005855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005856s390_irgen_LTGFR(UChar r1, UChar r2)
5857{
5858 IRTemp op2 = newTemp(Ity_I64);
5859
5860 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5861 put_gpr_dw0(r1, mkexpr(op2));
5862 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5863
5864 return "ltgfr";
5865}
5866
florian55085f82012-11-21 00:36:55 +00005867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005868s390_irgen_LT(UChar r1, IRTemp op2addr)
5869{
5870 IRTemp op2 = newTemp(Ity_I32);
5871
5872 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5873 put_gpr_w1(r1, mkexpr(op2));
5874 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5875
5876 return "lt";
5877}
5878
florian55085f82012-11-21 00:36:55 +00005879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005880s390_irgen_LTG(UChar r1, IRTemp op2addr)
5881{
5882 IRTemp op2 = newTemp(Ity_I64);
5883
5884 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5885 put_gpr_dw0(r1, mkexpr(op2));
5886 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5887
5888 return "ltg";
5889}
5890
florian55085f82012-11-21 00:36:55 +00005891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005892s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5893{
5894 IRTemp op2 = newTemp(Ity_I64);
5895
5896 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5897 put_gpr_dw0(r1, mkexpr(op2));
5898 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5899
5900 return "ltgf";
5901}
5902
florian55085f82012-11-21 00:36:55 +00005903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005904s390_irgen_LBR(UChar r1, UChar r2)
5905{
5906 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5907
5908 return "lbr";
5909}
5910
florian55085f82012-11-21 00:36:55 +00005911static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005912s390_irgen_LGBR(UChar r1, UChar r2)
5913{
5914 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5915
5916 return "lgbr";
5917}
5918
florian55085f82012-11-21 00:36:55 +00005919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005920s390_irgen_LB(UChar r1, IRTemp op2addr)
5921{
5922 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5923
5924 return "lb";
5925}
5926
florian55085f82012-11-21 00:36:55 +00005927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005928s390_irgen_LGB(UChar r1, IRTemp op2addr)
5929{
5930 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5931
5932 return "lgb";
5933}
5934
florian55085f82012-11-21 00:36:55 +00005935static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005936s390_irgen_LBH(UChar r1, IRTemp op2addr)
5937{
5938 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5939
5940 return "lbh";
5941}
5942
florian55085f82012-11-21 00:36:55 +00005943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005944s390_irgen_LCR(UChar r1, UChar r2)
5945{
5946 Int op1;
5947 IRTemp op2 = newTemp(Ity_I32);
5948 IRTemp result = newTemp(Ity_I32);
5949
5950 op1 = 0;
5951 assign(op2, get_gpr_w1(r2));
5952 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5953 put_gpr_w1(r1, mkexpr(result));
5954 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5955 op1)), op2);
5956
5957 return "lcr";
5958}
5959
florian55085f82012-11-21 00:36:55 +00005960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005961s390_irgen_LCGR(UChar r1, UChar r2)
5962{
5963 Long op1;
5964 IRTemp op2 = newTemp(Ity_I64);
5965 IRTemp result = newTemp(Ity_I64);
5966
5967 op1 = 0ULL;
5968 assign(op2, get_gpr_dw0(r2));
5969 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5970 put_gpr_dw0(r1, mkexpr(result));
5971 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5972 op1)), op2);
5973
5974 return "lcgr";
5975}
5976
florian55085f82012-11-21 00:36:55 +00005977static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005978s390_irgen_LCGFR(UChar r1, UChar r2)
5979{
5980 Long op1;
5981 IRTemp op2 = newTemp(Ity_I64);
5982 IRTemp result = newTemp(Ity_I64);
5983
5984 op1 = 0ULL;
5985 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5986 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5987 put_gpr_dw0(r1, mkexpr(result));
5988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5989 op1)), op2);
5990
5991 return "lcgfr";
5992}
5993
florian55085f82012-11-21 00:36:55 +00005994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005995s390_irgen_LHR(UChar r1, UChar r2)
5996{
5997 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5998
5999 return "lhr";
6000}
6001
florian55085f82012-11-21 00:36:55 +00006002static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006003s390_irgen_LGHR(UChar r1, UChar r2)
6004{
6005 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6006
6007 return "lghr";
6008}
6009
florian55085f82012-11-21 00:36:55 +00006010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006011s390_irgen_LH(UChar r1, IRTemp op2addr)
6012{
6013 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6014
6015 return "lh";
6016}
6017
florian55085f82012-11-21 00:36:55 +00006018static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006019s390_irgen_LHY(UChar r1, IRTemp op2addr)
6020{
6021 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6022
6023 return "lhy";
6024}
6025
florian55085f82012-11-21 00:36:55 +00006026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006027s390_irgen_LGH(UChar r1, IRTemp op2addr)
6028{
6029 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6030
6031 return "lgh";
6032}
6033
florian55085f82012-11-21 00:36:55 +00006034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006035s390_irgen_LHI(UChar r1, UShort i2)
6036{
6037 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6038
6039 return "lhi";
6040}
6041
florian55085f82012-11-21 00:36:55 +00006042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006043s390_irgen_LGHI(UChar r1, UShort i2)
6044{
6045 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6046
6047 return "lghi";
6048}
6049
florian55085f82012-11-21 00:36:55 +00006050static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006051s390_irgen_LHRL(UChar r1, UInt i2)
6052{
6053 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6054 ((ULong)(Long)(Int)i2 << 1)))));
6055
6056 return "lhrl";
6057}
6058
florian55085f82012-11-21 00:36:55 +00006059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006060s390_irgen_LGHRL(UChar r1, UInt i2)
6061{
6062 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6063 ((ULong)(Long)(Int)i2 << 1)))));
6064
6065 return "lghrl";
6066}
6067
florian55085f82012-11-21 00:36:55 +00006068static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006069s390_irgen_LHH(UChar r1, IRTemp op2addr)
6070{
6071 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6072
6073 return "lhh";
6074}
6075
florian55085f82012-11-21 00:36:55 +00006076static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006077s390_irgen_LFH(UChar r1, IRTemp op2addr)
6078{
6079 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6080
6081 return "lfh";
6082}
6083
florian55085f82012-11-21 00:36:55 +00006084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006085s390_irgen_LLGFR(UChar r1, UChar r2)
6086{
6087 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6088
6089 return "llgfr";
6090}
6091
florian55085f82012-11-21 00:36:55 +00006092static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006093s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6094{
6095 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6096
6097 return "llgf";
6098}
6099
florian55085f82012-11-21 00:36:55 +00006100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006101s390_irgen_LLGFRL(UChar r1, UInt i2)
6102{
6103 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6104 ((ULong)(Long)(Int)i2 << 1)))));
6105
6106 return "llgfrl";
6107}
6108
florian55085f82012-11-21 00:36:55 +00006109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006110s390_irgen_LLCR(UChar r1, UChar r2)
6111{
6112 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6113
6114 return "llcr";
6115}
6116
florian55085f82012-11-21 00:36:55 +00006117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006118s390_irgen_LLGCR(UChar r1, UChar r2)
6119{
6120 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6121
6122 return "llgcr";
6123}
6124
florian55085f82012-11-21 00:36:55 +00006125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006126s390_irgen_LLC(UChar r1, IRTemp op2addr)
6127{
6128 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6129
6130 return "llc";
6131}
6132
florian55085f82012-11-21 00:36:55 +00006133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006134s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6135{
6136 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6137
6138 return "llgc";
6139}
6140
florian55085f82012-11-21 00:36:55 +00006141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006142s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6143{
6144 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6145
6146 return "llch";
6147}
6148
florian55085f82012-11-21 00:36:55 +00006149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006150s390_irgen_LLHR(UChar r1, UChar r2)
6151{
6152 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6153
6154 return "llhr";
6155}
6156
florian55085f82012-11-21 00:36:55 +00006157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006158s390_irgen_LLGHR(UChar r1, UChar r2)
6159{
6160 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6161
6162 return "llghr";
6163}
6164
florian55085f82012-11-21 00:36:55 +00006165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006166s390_irgen_LLH(UChar r1, IRTemp op2addr)
6167{
6168 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6169
6170 return "llh";
6171}
6172
florian55085f82012-11-21 00:36:55 +00006173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006174s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6175{
6176 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6177
6178 return "llgh";
6179}
6180
florian55085f82012-11-21 00:36:55 +00006181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006182s390_irgen_LLHRL(UChar r1, UInt i2)
6183{
6184 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6185 ((ULong)(Long)(Int)i2 << 1)))));
6186
6187 return "llhrl";
6188}
6189
florian55085f82012-11-21 00:36:55 +00006190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006191s390_irgen_LLGHRL(UChar r1, UInt i2)
6192{
6193 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6194 ((ULong)(Long)(Int)i2 << 1)))));
6195
6196 return "llghrl";
6197}
6198
florian55085f82012-11-21 00:36:55 +00006199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006200s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6201{
6202 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6203
6204 return "llhh";
6205}
6206
florian55085f82012-11-21 00:36:55 +00006207static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006208s390_irgen_LLIHF(UChar r1, UInt i2)
6209{
6210 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6211
6212 return "llihf";
6213}
6214
florian55085f82012-11-21 00:36:55 +00006215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006216s390_irgen_LLIHH(UChar r1, UShort i2)
6217{
6218 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6219
6220 return "llihh";
6221}
6222
florian55085f82012-11-21 00:36:55 +00006223static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006224s390_irgen_LLIHL(UChar r1, UShort i2)
6225{
6226 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6227
6228 return "llihl";
6229}
6230
florian55085f82012-11-21 00:36:55 +00006231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006232s390_irgen_LLILF(UChar r1, UInt i2)
6233{
6234 put_gpr_dw0(r1, mkU64(i2));
6235
6236 return "llilf";
6237}
6238
florian55085f82012-11-21 00:36:55 +00006239static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006240s390_irgen_LLILH(UChar r1, UShort i2)
6241{
6242 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6243
6244 return "llilh";
6245}
6246
florian55085f82012-11-21 00:36:55 +00006247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006248s390_irgen_LLILL(UChar r1, UShort i2)
6249{
6250 put_gpr_dw0(r1, mkU64(i2));
6251
6252 return "llill";
6253}
6254
florian55085f82012-11-21 00:36:55 +00006255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006256s390_irgen_LLGTR(UChar r1, UChar r2)
6257{
6258 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6259 mkU32(2147483647))));
6260
6261 return "llgtr";
6262}
6263
florian55085f82012-11-21 00:36:55 +00006264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006265s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6266{
6267 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6268 mkexpr(op2addr)), mkU32(2147483647))));
6269
6270 return "llgt";
6271}
6272
florian55085f82012-11-21 00:36:55 +00006273static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006274s390_irgen_LNR(UChar r1, UChar r2)
6275{
6276 IRTemp op2 = newTemp(Ity_I32);
6277 IRTemp result = newTemp(Ity_I32);
6278
6279 assign(op2, get_gpr_w1(r2));
6280 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6281 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6282 put_gpr_w1(r1, mkexpr(result));
6283 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6284
6285 return "lnr";
6286}
6287
florian55085f82012-11-21 00:36:55 +00006288static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006289s390_irgen_LNGR(UChar r1, UChar r2)
6290{
6291 IRTemp op2 = newTemp(Ity_I64);
6292 IRTemp result = newTemp(Ity_I64);
6293
6294 assign(op2, get_gpr_dw0(r2));
6295 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6296 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6297 put_gpr_dw0(r1, mkexpr(result));
6298 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6299
6300 return "lngr";
6301}
6302
florian55085f82012-11-21 00:36:55 +00006303static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006304s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6305{
6306 IRTemp op2 = newTemp(Ity_I64);
6307 IRTemp result = newTemp(Ity_I64);
6308
6309 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6310 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6311 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6312 put_gpr_dw0(r1, mkexpr(result));
6313 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6314
6315 return "lngfr";
6316}
6317
florian55085f82012-11-21 00:36:55 +00006318static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006319s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6320{
florian6820ba52012-07-26 02:01:50 +00006321 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006322 put_gpr_w1(r1, get_gpr_w1(r2));
6323
6324 return "locr";
6325}
6326
florian55085f82012-11-21 00:36:55 +00006327static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006328s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6329{
florian6820ba52012-07-26 02:01:50 +00006330 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006331 put_gpr_dw0(r1, get_gpr_dw0(r2));
6332
6333 return "locgr";
6334}
6335
florian55085f82012-11-21 00:36:55 +00006336static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006337s390_irgen_LOC(UChar r1, IRTemp op2addr)
6338{
6339 /* condition is checked in format handler */
6340 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6341
6342 return "loc";
6343}
6344
florian55085f82012-11-21 00:36:55 +00006345static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006346s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6347{
6348 /* condition is checked in format handler */
6349 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6350
6351 return "locg";
6352}
6353
florian55085f82012-11-21 00:36:55 +00006354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006355s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6356{
6357 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6358 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6359 ));
6360
6361 return "lpq";
6362}
6363
florian55085f82012-11-21 00:36:55 +00006364static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006365s390_irgen_LPR(UChar r1, UChar r2)
6366{
6367 IRTemp op2 = newTemp(Ity_I32);
6368 IRTemp result = newTemp(Ity_I32);
6369
6370 assign(op2, get_gpr_w1(r2));
6371 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6372 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6373 put_gpr_w1(r1, mkexpr(result));
6374 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6375
6376 return "lpr";
6377}
6378
florian55085f82012-11-21 00:36:55 +00006379static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006380s390_irgen_LPGR(UChar r1, UChar r2)
6381{
6382 IRTemp op2 = newTemp(Ity_I64);
6383 IRTemp result = newTemp(Ity_I64);
6384
6385 assign(op2, get_gpr_dw0(r2));
6386 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6387 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6388 put_gpr_dw0(r1, mkexpr(result));
6389 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6390
6391 return "lpgr";
6392}
6393
florian55085f82012-11-21 00:36:55 +00006394static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006395s390_irgen_LPGFR(UChar r1, UChar r2)
6396{
6397 IRTemp op2 = newTemp(Ity_I64);
6398 IRTemp result = newTemp(Ity_I64);
6399
6400 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6401 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6402 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6403 put_gpr_dw0(r1, mkexpr(result));
6404 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6405
6406 return "lpgfr";
6407}
6408
florian55085f82012-11-21 00:36:55 +00006409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006410s390_irgen_LRVR(UChar r1, UChar r2)
6411{
6412 IRTemp b0 = newTemp(Ity_I8);
6413 IRTemp b1 = newTemp(Ity_I8);
6414 IRTemp b2 = newTemp(Ity_I8);
6415 IRTemp b3 = newTemp(Ity_I8);
6416
6417 assign(b3, get_gpr_b7(r2));
6418 assign(b2, get_gpr_b6(r2));
6419 assign(b1, get_gpr_b5(r2));
6420 assign(b0, get_gpr_b4(r2));
6421 put_gpr_b4(r1, mkexpr(b3));
6422 put_gpr_b5(r1, mkexpr(b2));
6423 put_gpr_b6(r1, mkexpr(b1));
6424 put_gpr_b7(r1, mkexpr(b0));
6425
6426 return "lrvr";
6427}
6428
florian55085f82012-11-21 00:36:55 +00006429static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006430s390_irgen_LRVGR(UChar r1, UChar r2)
6431{
6432 IRTemp b0 = newTemp(Ity_I8);
6433 IRTemp b1 = newTemp(Ity_I8);
6434 IRTemp b2 = newTemp(Ity_I8);
6435 IRTemp b3 = newTemp(Ity_I8);
6436 IRTemp b4 = newTemp(Ity_I8);
6437 IRTemp b5 = newTemp(Ity_I8);
6438 IRTemp b6 = newTemp(Ity_I8);
6439 IRTemp b7 = newTemp(Ity_I8);
6440
6441 assign(b7, get_gpr_b7(r2));
6442 assign(b6, get_gpr_b6(r2));
6443 assign(b5, get_gpr_b5(r2));
6444 assign(b4, get_gpr_b4(r2));
6445 assign(b3, get_gpr_b3(r2));
6446 assign(b2, get_gpr_b2(r2));
6447 assign(b1, get_gpr_b1(r2));
6448 assign(b0, get_gpr_b0(r2));
6449 put_gpr_b0(r1, mkexpr(b7));
6450 put_gpr_b1(r1, mkexpr(b6));
6451 put_gpr_b2(r1, mkexpr(b5));
6452 put_gpr_b3(r1, mkexpr(b4));
6453 put_gpr_b4(r1, mkexpr(b3));
6454 put_gpr_b5(r1, mkexpr(b2));
6455 put_gpr_b6(r1, mkexpr(b1));
6456 put_gpr_b7(r1, mkexpr(b0));
6457
6458 return "lrvgr";
6459}
6460
florian55085f82012-11-21 00:36:55 +00006461static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006462s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6463{
6464 IRTemp op2 = newTemp(Ity_I16);
6465
6466 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6467 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6468 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6469
6470 return "lrvh";
6471}
6472
florian55085f82012-11-21 00:36:55 +00006473static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006474s390_irgen_LRV(UChar r1, IRTemp op2addr)
6475{
6476 IRTemp op2 = newTemp(Ity_I32);
6477
6478 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6479 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6480 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6481 mkU8(8)), mkU32(255))));
6482 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6483 mkU8(16)), mkU32(255))));
6484 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6485 mkU8(24)), mkU32(255))));
6486
6487 return "lrv";
6488}
6489
florian55085f82012-11-21 00:36:55 +00006490static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006491s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6492{
6493 IRTemp op2 = newTemp(Ity_I64);
6494
6495 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6496 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6497 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6498 mkU8(8)), mkU64(255))));
6499 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6500 mkU8(16)), mkU64(255))));
6501 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6502 mkU8(24)), mkU64(255))));
6503 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6504 mkU8(32)), mkU64(255))));
6505 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6506 mkU8(40)), mkU64(255))));
6507 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6508 mkU8(48)), mkU64(255))));
6509 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6510 mkU8(56)), mkU64(255))));
6511
6512 return "lrvg";
6513}
6514
florian55085f82012-11-21 00:36:55 +00006515static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006516s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6517{
6518 store(mkexpr(op1addr), mkU16(i2));
6519
6520 return "mvhhi";
6521}
6522
florian55085f82012-11-21 00:36:55 +00006523static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006524s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6525{
6526 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6527
6528 return "mvhi";
6529}
6530
florian55085f82012-11-21 00:36:55 +00006531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006532s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6533{
6534 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6535
6536 return "mvghi";
6537}
6538
florian55085f82012-11-21 00:36:55 +00006539static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006540s390_irgen_MVI(UChar i2, IRTemp op1addr)
6541{
6542 store(mkexpr(op1addr), mkU8(i2));
6543
6544 return "mvi";
6545}
6546
florian55085f82012-11-21 00:36:55 +00006547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006548s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6549{
6550 store(mkexpr(op1addr), mkU8(i2));
6551
6552 return "mviy";
6553}
6554
florian55085f82012-11-21 00:36:55 +00006555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006556s390_irgen_MR(UChar r1, UChar r2)
6557{
6558 IRTemp op1 = newTemp(Ity_I32);
6559 IRTemp op2 = newTemp(Ity_I32);
6560 IRTemp result = newTemp(Ity_I64);
6561
6562 assign(op1, get_gpr_w1(r1 + 1));
6563 assign(op2, get_gpr_w1(r2));
6564 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6565 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6566 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6567
6568 return "mr";
6569}
6570
florian55085f82012-11-21 00:36:55 +00006571static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006572s390_irgen_M(UChar r1, IRTemp op2addr)
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, load(Ity_I32, mkexpr(op2addr)));
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 "m";
6585}
6586
florian55085f82012-11-21 00:36:55 +00006587static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006588s390_irgen_MFY(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 "mfy";
6601}
6602
florian55085f82012-11-21 00:36:55 +00006603static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006604s390_irgen_MH(UChar r1, IRTemp op2addr)
6605{
6606 IRTemp op1 = newTemp(Ity_I32);
6607 IRTemp op2 = newTemp(Ity_I16);
6608 IRTemp result = newTemp(Ity_I64);
6609
6610 assign(op1, get_gpr_w1(r1));
6611 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6612 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6613 ));
6614 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6615
6616 return "mh";
6617}
6618
florian55085f82012-11-21 00:36:55 +00006619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006620s390_irgen_MHY(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 "mhy";
6633}
6634
florian55085f82012-11-21 00:36:55 +00006635static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006636s390_irgen_MHI(UChar r1, UShort i2)
6637{
6638 IRTemp op1 = newTemp(Ity_I32);
6639 Short op2;
6640 IRTemp result = newTemp(Ity_I64);
6641
6642 assign(op1, get_gpr_w1(r1));
6643 op2 = (Short)i2;
6644 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6645 mkU16((UShort)op2))));
6646 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6647
6648 return "mhi";
6649}
6650
florian55085f82012-11-21 00:36:55 +00006651static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006652s390_irgen_MGHI(UChar r1, UShort i2)
6653{
6654 IRTemp op1 = newTemp(Ity_I64);
6655 Short op2;
6656 IRTemp result = newTemp(Ity_I128);
6657
6658 assign(op1, get_gpr_dw0(r1));
6659 op2 = (Short)i2;
6660 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6661 mkU16((UShort)op2))));
6662 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6663
6664 return "mghi";
6665}
6666
florian55085f82012-11-21 00:36:55 +00006667static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006668s390_irgen_MLR(UChar r1, UChar r2)
6669{
6670 IRTemp op1 = newTemp(Ity_I32);
6671 IRTemp op2 = newTemp(Ity_I32);
6672 IRTemp result = newTemp(Ity_I64);
6673
6674 assign(op1, get_gpr_w1(r1 + 1));
6675 assign(op2, get_gpr_w1(r2));
6676 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6677 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6678 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6679
6680 return "mlr";
6681}
6682
florian55085f82012-11-21 00:36:55 +00006683static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006684s390_irgen_MLGR(UChar r1, UChar r2)
6685{
6686 IRTemp op1 = newTemp(Ity_I64);
6687 IRTemp op2 = newTemp(Ity_I64);
6688 IRTemp result = newTemp(Ity_I128);
6689
6690 assign(op1, get_gpr_dw0(r1 + 1));
6691 assign(op2, get_gpr_dw0(r2));
6692 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6693 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6694 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6695
6696 return "mlgr";
6697}
6698
florian55085f82012-11-21 00:36:55 +00006699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006700s390_irgen_ML(UChar r1, IRTemp op2addr)
6701{
6702 IRTemp op1 = newTemp(Ity_I32);
6703 IRTemp op2 = newTemp(Ity_I32);
6704 IRTemp result = newTemp(Ity_I64);
6705
6706 assign(op1, get_gpr_w1(r1 + 1));
6707 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6708 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6709 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6710 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6711
6712 return "ml";
6713}
6714
florian55085f82012-11-21 00:36:55 +00006715static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006716s390_irgen_MLG(UChar r1, IRTemp op2addr)
6717{
6718 IRTemp op1 = newTemp(Ity_I64);
6719 IRTemp op2 = newTemp(Ity_I64);
6720 IRTemp result = newTemp(Ity_I128);
6721
6722 assign(op1, get_gpr_dw0(r1 + 1));
6723 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6724 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6725 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6726 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6727
6728 return "mlg";
6729}
6730
florian55085f82012-11-21 00:36:55 +00006731static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006732s390_irgen_MSR(UChar r1, UChar r2)
6733{
6734 IRTemp op1 = newTemp(Ity_I32);
6735 IRTemp op2 = newTemp(Ity_I32);
6736 IRTemp result = newTemp(Ity_I64);
6737
6738 assign(op1, get_gpr_w1(r1));
6739 assign(op2, get_gpr_w1(r2));
6740 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6741 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6742
6743 return "msr";
6744}
6745
florian55085f82012-11-21 00:36:55 +00006746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006747s390_irgen_MSGR(UChar r1, UChar r2)
6748{
6749 IRTemp op1 = newTemp(Ity_I64);
6750 IRTemp op2 = newTemp(Ity_I64);
6751 IRTemp result = newTemp(Ity_I128);
6752
6753 assign(op1, get_gpr_dw0(r1));
6754 assign(op2, get_gpr_dw0(r2));
6755 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6756 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6757
6758 return "msgr";
6759}
6760
florian55085f82012-11-21 00:36:55 +00006761static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006762s390_irgen_MSGFR(UChar r1, UChar r2)
6763{
6764 IRTemp op1 = newTemp(Ity_I64);
6765 IRTemp op2 = newTemp(Ity_I32);
6766 IRTemp result = newTemp(Ity_I128);
6767
6768 assign(op1, get_gpr_dw0(r1));
6769 assign(op2, get_gpr_w1(r2));
6770 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6771 ));
6772 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6773
6774 return "msgfr";
6775}
6776
florian55085f82012-11-21 00:36:55 +00006777static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006778s390_irgen_MS(UChar r1, IRTemp op2addr)
6779{
6780 IRTemp op1 = newTemp(Ity_I32);
6781 IRTemp op2 = newTemp(Ity_I32);
6782 IRTemp result = newTemp(Ity_I64);
6783
6784 assign(op1, get_gpr_w1(r1));
6785 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6786 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6787 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6788
6789 return "ms";
6790}
6791
florian55085f82012-11-21 00:36:55 +00006792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006793s390_irgen_MSY(UChar r1, IRTemp op2addr)
6794{
6795 IRTemp op1 = newTemp(Ity_I32);
6796 IRTemp op2 = newTemp(Ity_I32);
6797 IRTemp result = newTemp(Ity_I64);
6798
6799 assign(op1, get_gpr_w1(r1));
6800 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6801 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6802 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6803
6804 return "msy";
6805}
6806
florian55085f82012-11-21 00:36:55 +00006807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006808s390_irgen_MSG(UChar r1, IRTemp op2addr)
6809{
6810 IRTemp op1 = newTemp(Ity_I64);
6811 IRTemp op2 = newTemp(Ity_I64);
6812 IRTemp result = newTemp(Ity_I128);
6813
6814 assign(op1, get_gpr_dw0(r1));
6815 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6816 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6817 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6818
6819 return "msg";
6820}
6821
florian55085f82012-11-21 00:36:55 +00006822static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006823s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6824{
6825 IRTemp op1 = newTemp(Ity_I64);
6826 IRTemp op2 = newTemp(Ity_I32);
6827 IRTemp result = newTemp(Ity_I128);
6828
6829 assign(op1, get_gpr_dw0(r1));
6830 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6831 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6832 ));
6833 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6834
6835 return "msgf";
6836}
6837
florian55085f82012-11-21 00:36:55 +00006838static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006839s390_irgen_MSFI(UChar r1, UInt i2)
6840{
6841 IRTemp op1 = newTemp(Ity_I32);
6842 Int op2;
6843 IRTemp result = newTemp(Ity_I64);
6844
6845 assign(op1, get_gpr_w1(r1));
6846 op2 = (Int)i2;
6847 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6848 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6849
6850 return "msfi";
6851}
6852
florian55085f82012-11-21 00:36:55 +00006853static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006854s390_irgen_MSGFI(UChar r1, UInt i2)
6855{
6856 IRTemp op1 = newTemp(Ity_I64);
6857 Int op2;
6858 IRTemp result = newTemp(Ity_I128);
6859
6860 assign(op1, get_gpr_dw0(r1));
6861 op2 = (Int)i2;
6862 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6863 op2))));
6864 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6865
6866 return "msgfi";
6867}
6868
florian55085f82012-11-21 00:36:55 +00006869static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006870s390_irgen_OR(UChar r1, UChar r2)
6871{
6872 IRTemp op1 = newTemp(Ity_I32);
6873 IRTemp op2 = newTemp(Ity_I32);
6874 IRTemp result = newTemp(Ity_I32);
6875
6876 assign(op1, get_gpr_w1(r1));
6877 assign(op2, get_gpr_w1(r2));
6878 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6879 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6880 put_gpr_w1(r1, mkexpr(result));
6881
6882 return "or";
6883}
6884
florian55085f82012-11-21 00:36:55 +00006885static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006886s390_irgen_OGR(UChar r1, UChar r2)
6887{
6888 IRTemp op1 = newTemp(Ity_I64);
6889 IRTemp op2 = newTemp(Ity_I64);
6890 IRTemp result = newTemp(Ity_I64);
6891
6892 assign(op1, get_gpr_dw0(r1));
6893 assign(op2, get_gpr_dw0(r2));
6894 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6895 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6896 put_gpr_dw0(r1, mkexpr(result));
6897
6898 return "ogr";
6899}
6900
florian55085f82012-11-21 00:36:55 +00006901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006902s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6903{
6904 IRTemp op2 = newTemp(Ity_I32);
6905 IRTemp op3 = newTemp(Ity_I32);
6906 IRTemp result = newTemp(Ity_I32);
6907
6908 assign(op2, get_gpr_w1(r2));
6909 assign(op3, get_gpr_w1(r3));
6910 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6911 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6912 put_gpr_w1(r1, mkexpr(result));
6913
6914 return "ork";
6915}
6916
florian55085f82012-11-21 00:36:55 +00006917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006918s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6919{
6920 IRTemp op2 = newTemp(Ity_I64);
6921 IRTemp op3 = newTemp(Ity_I64);
6922 IRTemp result = newTemp(Ity_I64);
6923
6924 assign(op2, get_gpr_dw0(r2));
6925 assign(op3, get_gpr_dw0(r3));
6926 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6927 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6928 put_gpr_dw0(r1, mkexpr(result));
6929
6930 return "ogrk";
6931}
6932
florian55085f82012-11-21 00:36:55 +00006933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006934s390_irgen_O(UChar r1, IRTemp op2addr)
6935{
6936 IRTemp op1 = newTemp(Ity_I32);
6937 IRTemp op2 = newTemp(Ity_I32);
6938 IRTemp result = newTemp(Ity_I32);
6939
6940 assign(op1, get_gpr_w1(r1));
6941 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6942 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6943 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6944 put_gpr_w1(r1, mkexpr(result));
6945
6946 return "o";
6947}
6948
florian55085f82012-11-21 00:36:55 +00006949static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006950s390_irgen_OY(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 "oy";
6963}
6964
florian55085f82012-11-21 00:36:55 +00006965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006966s390_irgen_OG(UChar r1, IRTemp op2addr)
6967{
6968 IRTemp op1 = newTemp(Ity_I64);
6969 IRTemp op2 = newTemp(Ity_I64);
6970 IRTemp result = newTemp(Ity_I64);
6971
6972 assign(op1, get_gpr_dw0(r1));
6973 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6974 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6975 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6976 put_gpr_dw0(r1, mkexpr(result));
6977
6978 return "og";
6979}
6980
florian55085f82012-11-21 00:36:55 +00006981static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006982s390_irgen_OI(UChar i2, IRTemp op1addr)
6983{
6984 IRTemp op1 = newTemp(Ity_I8);
6985 UChar op2;
6986 IRTemp result = newTemp(Ity_I8);
6987
6988 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6989 op2 = i2;
6990 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6991 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6992 store(mkexpr(op1addr), mkexpr(result));
6993
6994 return "oi";
6995}
6996
florian55085f82012-11-21 00:36:55 +00006997static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006998s390_irgen_OIY(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 "oiy";
7011}
7012
florian55085f82012-11-21 00:36:55 +00007013static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007014s390_irgen_OIHF(UChar r1, UInt i2)
7015{
7016 IRTemp op1 = newTemp(Ity_I32);
7017 UInt op2;
7018 IRTemp result = newTemp(Ity_I32);
7019
7020 assign(op1, get_gpr_w0(r1));
7021 op2 = i2;
7022 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7023 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7024 put_gpr_w0(r1, mkexpr(result));
7025
7026 return "oihf";
7027}
7028
florian55085f82012-11-21 00:36:55 +00007029static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007030s390_irgen_OIHH(UChar r1, UShort i2)
7031{
7032 IRTemp op1 = newTemp(Ity_I16);
7033 UShort op2;
7034 IRTemp result = newTemp(Ity_I16);
7035
7036 assign(op1, get_gpr_hw0(r1));
7037 op2 = i2;
7038 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7039 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7040 put_gpr_hw0(r1, mkexpr(result));
7041
7042 return "oihh";
7043}
7044
florian55085f82012-11-21 00:36:55 +00007045static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007046s390_irgen_OIHL(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_hw1(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_hw1(r1, mkexpr(result));
7057
7058 return "oihl";
7059}
7060
florian55085f82012-11-21 00:36:55 +00007061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007062s390_irgen_OILF(UChar r1, UInt i2)
7063{
7064 IRTemp op1 = newTemp(Ity_I32);
7065 UInt op2;
7066 IRTemp result = newTemp(Ity_I32);
7067
7068 assign(op1, get_gpr_w1(r1));
7069 op2 = i2;
7070 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7071 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7072 put_gpr_w1(r1, mkexpr(result));
7073
7074 return "oilf";
7075}
7076
florian55085f82012-11-21 00:36:55 +00007077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007078s390_irgen_OILH(UChar r1, UShort i2)
7079{
7080 IRTemp op1 = newTemp(Ity_I16);
7081 UShort op2;
7082 IRTemp result = newTemp(Ity_I16);
7083
7084 assign(op1, get_gpr_hw2(r1));
7085 op2 = i2;
7086 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7087 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7088 put_gpr_hw2(r1, mkexpr(result));
7089
7090 return "oilh";
7091}
7092
florian55085f82012-11-21 00:36:55 +00007093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007094s390_irgen_OILL(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_hw3(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_hw3(r1, mkexpr(result));
7105
7106 return "oill";
7107}
7108
florian55085f82012-11-21 00:36:55 +00007109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007110s390_irgen_PFD(void)
7111{
7112
7113 return "pfd";
7114}
7115
florian55085f82012-11-21 00:36:55 +00007116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007117s390_irgen_PFDRL(void)
7118{
7119
7120 return "pfdrl";
7121}
7122
florian78d5ef72013-05-11 15:02:58 +00007123static IRExpr *
7124get_rounding_mode_from_gr0(void)
7125{
7126 IRTemp rm_bits = newTemp(Ity_I32);
7127 IRExpr *s390rm;
7128 IRExpr *irrm;
7129
7130 vassert(s390_host_has_pfpo);
7131 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7132 when PFPO insn is called. So, extract the bits at [60:63] */
7133 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7134 s390rm = mkexpr(rm_bits);
7135 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7136 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7137 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7138 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7139 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7140 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7141 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7142 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7143 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7144 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7145 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7146 mkexpr(encode_dfp_rounding_mode(
7147 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7148 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7149 mkexpr(encode_dfp_rounding_mode(
7150 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7151 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7152 mkexpr(encode_dfp_rounding_mode(
7153 S390_DFP_ROUND_AWAY_0)),
7154 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7155 mkexpr(encode_dfp_rounding_mode(
7156 S390_DFP_ROUND_PREPARE_SHORT_15)),
7157 /* if rounding mode is 0 or invalid (2-7)
7158 set S390_DFP_ROUND_PER_FPC_0 */
7159 mkexpr(encode_dfp_rounding_mode(
7160 S390_DFP_ROUND_PER_FPC_0)))))))))));
7161
7162 return irrm;
7163}
7164
7165static IRExpr *
7166s390_call_pfpo_helper(IRExpr *gr0)
7167{
7168 IRExpr **args, *call;
7169
7170 args = mkIRExprVec_1(gr0);
7171 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7172 "s390_do_pfpo", &s390_do_pfpo, args);
7173 /* Nothing is excluded from definedness checking. */
7174 call->Iex.CCall.cee->mcx_mask = 0;
7175
7176 return call;
7177}
7178
7179static const HChar *
7180s390_irgen_PFPO(void)
7181{
7182 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
7183 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7184 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
7185 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
7186 IRTemp src1 = newTemp(Ity_F64);
7187 IRTemp dst1 = newTemp(Ity_D64);
7188 IRTemp src2 = newTemp(Ity_D64);
7189 IRTemp dst2 = newTemp(Ity_F64);
7190 IRTemp src3 = newTemp(Ity_F64);
7191 IRTemp dst3 = newTemp(Ity_D128);
7192 IRTemp src4 = newTemp(Ity_D128);
7193 IRTemp dst4 = newTemp(Ity_F64);
7194 IRTemp src5 = newTemp(Ity_F128);
7195 IRTemp dst5 = newTemp(Ity_D128);
7196 IRTemp src6 = newTemp(Ity_D128);
7197 IRTemp dst6 = newTemp(Ity_F128);
7198 IRExpr *irrm;
7199
7200 vassert(s390_host_has_pfpo);
7201
7202 assign(gr0, get_gpr_w1(0));
7203 /* get function code */
7204 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7205 mkU32(0x7fffff)));
7206 /* get validity test bit */
7207 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7208 mkU32(0x1)));
7209 irrm = get_rounding_mode_from_gr0();
7210
7211 /* test_bit is 1 */
7212 assign(src1, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7213 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7214
7215 /* Return code set in GR1 is usually 0. Non-zero value is set only
7216 when exceptions are raised. See Programming Notes point 5 in the
7217 instrcution description of pfpo in POP. Since valgrind does not
7218 model exception, it might be safe to just set 0 to GR 1. */
7219 put_gpr_w1(1, mkU32(0x0));
7220 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7221
7222 /* Check validity of function code in GR 0 */
7223 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
7224
7225 /* fixs390: Function emulation_failure can be used if it takes argument as
7226 IRExpr * instead of VexEmNote. */
7227 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkexpr(ef)));
7228 dis_res->whatNext = Dis_StopHere;
7229 dis_res->jk_StopHere = Ijk_EmFail;
7230
7231 stmt(
7232 IRStmt_Exit(
7233 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7234 Ijk_EmFail,
7235 IRConst_U64(guest_IA_next_instr),
7236 S390X_GUEST_OFFSET(guest_IA)
7237 )
7238 );
7239
7240 /* F64 -> D64 */
7241 /* get source from FPR 4,6 - already set in src1 */
7242 assign(dst1, binop(Iop_F64toD64, irrm, mkexpr(src1)));
7243 put_dpr_dw0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
7244 put_gpr_w1(1, mkU32(0x0));
7245 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7246 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7247
7248 /* D64 -> F64 */
7249 assign(src2, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7250 assign(dst2, binop(Iop_D64toF64, irrm, mkexpr(src2)));
7251 put_fpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
7252 put_gpr_w1(1, mkU32(0x0));
7253 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src2, gr0);
7254 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7255
7256 /* F64 -> D128 */
7257 assign(src3, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7258 assign(dst3, binop(Iop_F64toD128, irrm, mkexpr(src3)));
7259 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7260 put_gpr_w1(1, mkU32(0x0));
7261 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src3, gr0);
7262 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7263
7264 /* D128 -> F64 */
7265 assign(src4, get_dpr_pair(4)); /* get source from FPR 4,6 */
7266 assign(dst4, binop(Iop_D128toF64, irrm, mkexpr(src4)));
7267 put_fpr_dw0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7268 put_gpr_w1(1, mkU32(0x0));
7269 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src4, gr0);
7270 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7271
7272 /* F128 -> D128 */
7273 assign(src5, get_fpr_pair(4)); /* get source from FPR 4,6 */
7274 assign(dst5, binop(Iop_F128toD128, irrm, mkexpr(src5)));
7275 put_dpr_pair(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7276 put_gpr_w1(1, mkU32(0x0));
7277 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src5, gr0);
7278 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7279
7280 /* D128 -> F128 */
7281 assign(src6, get_dpr_pair(4)); /* get source from FPR 4,6 */
7282 assign(dst6, binop(Iop_D128toF128, irrm, mkexpr(src6)));
7283 put_fpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7284 put_gpr_w1(1, mkU32(0x0));
7285 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src6, gr0);
7286 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7287
7288 return "pfpo";
7289}
7290
florian55085f82012-11-21 00:36:55 +00007291static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007292s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7293{
7294 IRTemp amount = newTemp(Ity_I64);
7295 IRTemp op = newTemp(Ity_I32);
7296
7297 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7298 assign(op, get_gpr_w1(r3));
7299 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7300 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7301 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7302
7303 return "rll";
7304}
7305
florian55085f82012-11-21 00:36:55 +00007306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007307s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7308{
7309 IRTemp amount = newTemp(Ity_I64);
7310 IRTemp op = newTemp(Ity_I64);
7311
7312 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7313 assign(op, get_gpr_dw0(r3));
7314 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7315 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7316 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7317
7318 return "rllg";
7319}
7320
florian55085f82012-11-21 00:36:55 +00007321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007322s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7323{
7324 UChar from;
7325 UChar to;
7326 UChar rot;
7327 UChar t_bit;
7328 ULong mask;
7329 ULong maskc;
7330 IRTemp result = newTemp(Ity_I64);
7331 IRTemp op2 = newTemp(Ity_I64);
7332
7333 from = i3 & 63;
7334 to = i4 & 63;
7335 rot = i5 & 63;
7336 t_bit = i3 & 128;
7337 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7338 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7339 mkU8(64 - rot))));
7340 if (from <= to) {
7341 mask = ~0ULL;
7342 mask = (mask >> from) & (mask << (63 - to));
7343 maskc = ~mask;
7344 } else {
7345 maskc = ~0ULL;
7346 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7347 mask = ~maskc;
7348 }
7349 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7350 ), mkU64(mask)));
7351 if (t_bit == 0) {
7352 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7353 mkU64(maskc)), mkexpr(result)));
7354 }
7355 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7356
7357 return "rnsbg";
7358}
7359
florian55085f82012-11-21 00:36:55 +00007360static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007361s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7362{
7363 UChar from;
7364 UChar to;
7365 UChar rot;
7366 UChar t_bit;
7367 ULong mask;
7368 ULong maskc;
7369 IRTemp result = newTemp(Ity_I64);
7370 IRTemp op2 = newTemp(Ity_I64);
7371
7372 from = i3 & 63;
7373 to = i4 & 63;
7374 rot = i5 & 63;
7375 t_bit = i3 & 128;
7376 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7377 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7378 mkU8(64 - rot))));
7379 if (from <= to) {
7380 mask = ~0ULL;
7381 mask = (mask >> from) & (mask << (63 - to));
7382 maskc = ~mask;
7383 } else {
7384 maskc = ~0ULL;
7385 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7386 mask = ~maskc;
7387 }
7388 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7389 ), mkU64(mask)));
7390 if (t_bit == 0) {
7391 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7392 mkU64(maskc)), mkexpr(result)));
7393 }
7394 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7395
7396 return "rxsbg";
7397}
7398
florian55085f82012-11-21 00:36:55 +00007399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007400s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7401{
7402 UChar from;
7403 UChar to;
7404 UChar rot;
7405 UChar t_bit;
7406 ULong mask;
7407 ULong maskc;
7408 IRTemp result = newTemp(Ity_I64);
7409 IRTemp op2 = newTemp(Ity_I64);
7410
7411 from = i3 & 63;
7412 to = i4 & 63;
7413 rot = i5 & 63;
7414 t_bit = i3 & 128;
7415 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7416 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7417 mkU8(64 - rot))));
7418 if (from <= to) {
7419 mask = ~0ULL;
7420 mask = (mask >> from) & (mask << (63 - to));
7421 maskc = ~mask;
7422 } else {
7423 maskc = ~0ULL;
7424 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7425 mask = ~maskc;
7426 }
7427 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7428 ), mkU64(mask)));
7429 if (t_bit == 0) {
7430 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7431 mkU64(maskc)), mkexpr(result)));
7432 }
7433 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7434
7435 return "rosbg";
7436}
7437
florian55085f82012-11-21 00:36:55 +00007438static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007439s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7440{
7441 UChar from;
7442 UChar to;
7443 UChar rot;
7444 UChar z_bit;
7445 ULong mask;
7446 ULong maskc;
7447 IRTemp op2 = newTemp(Ity_I64);
7448 IRTemp result = newTemp(Ity_I64);
7449
7450 from = i3 & 63;
7451 to = i4 & 63;
7452 rot = i5 & 63;
7453 z_bit = i4 & 128;
7454 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7455 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7456 mkU8(64 - rot))));
7457 if (from <= to) {
7458 mask = ~0ULL;
7459 mask = (mask >> from) & (mask << (63 - to));
7460 maskc = ~mask;
7461 } else {
7462 maskc = ~0ULL;
7463 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7464 mask = ~maskc;
7465 }
7466 if (z_bit == 0) {
7467 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7468 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7469 } else {
7470 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7471 }
7472 assign(result, get_gpr_dw0(r1));
7473 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7474
7475 return "risbg";
7476}
7477
florian55085f82012-11-21 00:36:55 +00007478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007479s390_irgen_SAR(UChar r1, UChar r2)
7480{
7481 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007482 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007483 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7484
7485 return "sar";
7486}
7487
florian55085f82012-11-21 00:36:55 +00007488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007489s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7490{
7491 IRTemp p1 = newTemp(Ity_I64);
7492 IRTemp p2 = newTemp(Ity_I64);
7493 IRTemp op = newTemp(Ity_I64);
7494 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007495 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007496 IRTemp shift_amount = newTemp(Ity_I64);
7497
7498 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7499 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7500 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7501 ));
7502 sign_mask = 1ULL << 63;
7503 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7504 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007505 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7506 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007507 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7508 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7509 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7510
7511 return "slda";
7512}
7513
florian55085f82012-11-21 00:36:55 +00007514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007515s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7516{
7517 IRTemp p1 = newTemp(Ity_I64);
7518 IRTemp p2 = newTemp(Ity_I64);
7519 IRTemp result = newTemp(Ity_I64);
7520
7521 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7522 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7523 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7524 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7525 mkexpr(op2addr), mkU64(63)))));
7526 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7527 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7528
7529 return "sldl";
7530}
7531
florian55085f82012-11-21 00:36:55 +00007532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007533s390_irgen_SLA(UChar r1, IRTemp op2addr)
7534{
7535 IRTemp uop = newTemp(Ity_I32);
7536 IRTemp result = newTemp(Ity_I32);
7537 UInt sign_mask;
7538 IRTemp shift_amount = newTemp(Ity_I64);
7539 IRTemp op = newTemp(Ity_I32);
7540
7541 assign(op, get_gpr_w1(r1));
7542 assign(uop, get_gpr_w1(r1));
7543 sign_mask = 2147483648U;
7544 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7545 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7546 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7547 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7548 put_gpr_w1(r1, mkexpr(result));
7549 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7550
7551 return "sla";
7552}
7553
florian55085f82012-11-21 00:36:55 +00007554static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007555s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7556{
7557 IRTemp uop = newTemp(Ity_I32);
7558 IRTemp result = newTemp(Ity_I32);
7559 UInt sign_mask;
7560 IRTemp shift_amount = newTemp(Ity_I64);
7561 IRTemp op = newTemp(Ity_I32);
7562
7563 assign(op, get_gpr_w1(r3));
7564 assign(uop, get_gpr_w1(r3));
7565 sign_mask = 2147483648U;
7566 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7567 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7568 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7569 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7570 put_gpr_w1(r1, mkexpr(result));
7571 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7572
7573 return "slak";
7574}
7575
florian55085f82012-11-21 00:36:55 +00007576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007577s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7578{
7579 IRTemp uop = newTemp(Ity_I64);
7580 IRTemp result = newTemp(Ity_I64);
7581 ULong sign_mask;
7582 IRTemp shift_amount = newTemp(Ity_I64);
7583 IRTemp op = newTemp(Ity_I64);
7584
7585 assign(op, get_gpr_dw0(r3));
7586 assign(uop, get_gpr_dw0(r3));
7587 sign_mask = 9223372036854775808ULL;
7588 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7589 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7590 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7591 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7592 put_gpr_dw0(r1, mkexpr(result));
7593 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7594
7595 return "slag";
7596}
7597
florian55085f82012-11-21 00:36:55 +00007598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007599s390_irgen_SLL(UChar r1, IRTemp op2addr)
7600{
7601 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7602 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7603
7604 return "sll";
7605}
7606
florian55085f82012-11-21 00:36:55 +00007607static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007608s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7609{
7610 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7611 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7612
7613 return "sllk";
7614}
7615
florian55085f82012-11-21 00:36:55 +00007616static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007617s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7618{
7619 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7620 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7621
7622 return "sllg";
7623}
7624
florian55085f82012-11-21 00:36:55 +00007625static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007626s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7627{
7628 IRTemp p1 = newTemp(Ity_I64);
7629 IRTemp p2 = newTemp(Ity_I64);
7630 IRTemp result = newTemp(Ity_I64);
7631
7632 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7633 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7634 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7635 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7636 mkexpr(op2addr), mkU64(63)))));
7637 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7638 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7639 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7640
7641 return "srda";
7642}
7643
florian55085f82012-11-21 00:36:55 +00007644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007645s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7646{
7647 IRTemp p1 = newTemp(Ity_I64);
7648 IRTemp p2 = newTemp(Ity_I64);
7649 IRTemp result = newTemp(Ity_I64);
7650
7651 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7652 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7653 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7654 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7655 mkexpr(op2addr), mkU64(63)))));
7656 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7657 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7658
7659 return "srdl";
7660}
7661
florian55085f82012-11-21 00:36:55 +00007662static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007663s390_irgen_SRA(UChar r1, IRTemp op2addr)
7664{
7665 IRTemp result = newTemp(Ity_I32);
7666 IRTemp op = newTemp(Ity_I32);
7667
7668 assign(op, get_gpr_w1(r1));
7669 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7670 mkexpr(op2addr), mkU64(63)))));
7671 put_gpr_w1(r1, mkexpr(result));
7672 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7673
7674 return "sra";
7675}
7676
florian55085f82012-11-21 00:36:55 +00007677static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007678s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7679{
7680 IRTemp result = newTemp(Ity_I32);
7681 IRTemp op = newTemp(Ity_I32);
7682
7683 assign(op, get_gpr_w1(r3));
7684 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7685 mkexpr(op2addr), mkU64(63)))));
7686 put_gpr_w1(r1, mkexpr(result));
7687 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7688
7689 return "srak";
7690}
7691
florian55085f82012-11-21 00:36:55 +00007692static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007693s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7694{
7695 IRTemp result = newTemp(Ity_I64);
7696 IRTemp op = newTemp(Ity_I64);
7697
7698 assign(op, get_gpr_dw0(r3));
7699 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7700 mkexpr(op2addr), mkU64(63)))));
7701 put_gpr_dw0(r1, mkexpr(result));
7702 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7703
7704 return "srag";
7705}
7706
florian55085f82012-11-21 00:36:55 +00007707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007708s390_irgen_SRL(UChar r1, IRTemp op2addr)
7709{
7710 IRTemp op = newTemp(Ity_I32);
7711
7712 assign(op, get_gpr_w1(r1));
7713 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7714 mkexpr(op2addr), mkU64(63)))));
7715
7716 return "srl";
7717}
7718
florian55085f82012-11-21 00:36:55 +00007719static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007720s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7721{
7722 IRTemp op = newTemp(Ity_I32);
7723
7724 assign(op, get_gpr_w1(r3));
7725 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7726 mkexpr(op2addr), mkU64(63)))));
7727
7728 return "srlk";
7729}
7730
florian55085f82012-11-21 00:36:55 +00007731static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007732s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7733{
7734 IRTemp op = newTemp(Ity_I64);
7735
7736 assign(op, get_gpr_dw0(r3));
7737 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7738 mkexpr(op2addr), mkU64(63)))));
7739
7740 return "srlg";
7741}
7742
florian55085f82012-11-21 00:36:55 +00007743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007744s390_irgen_ST(UChar r1, IRTemp op2addr)
7745{
7746 store(mkexpr(op2addr), get_gpr_w1(r1));
7747
7748 return "st";
7749}
7750
florian55085f82012-11-21 00:36:55 +00007751static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007752s390_irgen_STY(UChar r1, IRTemp op2addr)
7753{
7754 store(mkexpr(op2addr), get_gpr_w1(r1));
7755
7756 return "sty";
7757}
7758
florian55085f82012-11-21 00:36:55 +00007759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007760s390_irgen_STG(UChar r1, IRTemp op2addr)
7761{
7762 store(mkexpr(op2addr), get_gpr_dw0(r1));
7763
7764 return "stg";
7765}
7766
florian55085f82012-11-21 00:36:55 +00007767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007768s390_irgen_STRL(UChar r1, UInt i2)
7769{
7770 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7771 get_gpr_w1(r1));
7772
7773 return "strl";
7774}
7775
florian55085f82012-11-21 00:36:55 +00007776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007777s390_irgen_STGRL(UChar r1, UInt i2)
7778{
7779 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7780 get_gpr_dw0(r1));
7781
7782 return "stgrl";
7783}
7784
florian55085f82012-11-21 00:36:55 +00007785static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007786s390_irgen_STC(UChar r1, IRTemp op2addr)
7787{
7788 store(mkexpr(op2addr), get_gpr_b7(r1));
7789
7790 return "stc";
7791}
7792
florian55085f82012-11-21 00:36:55 +00007793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007794s390_irgen_STCY(UChar r1, IRTemp op2addr)
7795{
7796 store(mkexpr(op2addr), get_gpr_b7(r1));
7797
7798 return "stcy";
7799}
7800
florian55085f82012-11-21 00:36:55 +00007801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007802s390_irgen_STCH(UChar r1, IRTemp op2addr)
7803{
7804 store(mkexpr(op2addr), get_gpr_b3(r1));
7805
7806 return "stch";
7807}
7808
florian55085f82012-11-21 00:36:55 +00007809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007810s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7811{
7812 UChar mask;
7813 UChar n;
7814
7815 mask = (UChar)r3;
7816 n = 0;
7817 if ((mask & 8) != 0) {
7818 store(mkexpr(op2addr), get_gpr_b4(r1));
7819 n = n + 1;
7820 }
7821 if ((mask & 4) != 0) {
7822 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7823 n = n + 1;
7824 }
7825 if ((mask & 2) != 0) {
7826 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7827 n = n + 1;
7828 }
7829 if ((mask & 1) != 0) {
7830 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7831 }
7832
7833 return "stcm";
7834}
7835
florian55085f82012-11-21 00:36:55 +00007836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007837s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7838{
7839 UChar mask;
7840 UChar n;
7841
7842 mask = (UChar)r3;
7843 n = 0;
7844 if ((mask & 8) != 0) {
7845 store(mkexpr(op2addr), get_gpr_b4(r1));
7846 n = n + 1;
7847 }
7848 if ((mask & 4) != 0) {
7849 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7850 n = n + 1;
7851 }
7852 if ((mask & 2) != 0) {
7853 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7854 n = n + 1;
7855 }
7856 if ((mask & 1) != 0) {
7857 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7858 }
7859
7860 return "stcmy";
7861}
7862
florian55085f82012-11-21 00:36:55 +00007863static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007864s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7865{
7866 UChar mask;
7867 UChar n;
7868
7869 mask = (UChar)r3;
7870 n = 0;
7871 if ((mask & 8) != 0) {
7872 store(mkexpr(op2addr), get_gpr_b0(r1));
7873 n = n + 1;
7874 }
7875 if ((mask & 4) != 0) {
7876 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7877 n = n + 1;
7878 }
7879 if ((mask & 2) != 0) {
7880 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7881 n = n + 1;
7882 }
7883 if ((mask & 1) != 0) {
7884 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7885 }
7886
7887 return "stcmh";
7888}
7889
florian55085f82012-11-21 00:36:55 +00007890static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007891s390_irgen_STH(UChar r1, IRTemp op2addr)
7892{
7893 store(mkexpr(op2addr), get_gpr_hw3(r1));
7894
7895 return "sth";
7896}
7897
florian55085f82012-11-21 00:36:55 +00007898static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007899s390_irgen_STHY(UChar r1, IRTemp op2addr)
7900{
7901 store(mkexpr(op2addr), get_gpr_hw3(r1));
7902
7903 return "sthy";
7904}
7905
florian55085f82012-11-21 00:36:55 +00007906static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007907s390_irgen_STHRL(UChar r1, UInt i2)
7908{
7909 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7910 get_gpr_hw3(r1));
7911
7912 return "sthrl";
7913}
7914
florian55085f82012-11-21 00:36:55 +00007915static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007916s390_irgen_STHH(UChar r1, IRTemp op2addr)
7917{
7918 store(mkexpr(op2addr), get_gpr_hw1(r1));
7919
7920 return "sthh";
7921}
7922
florian55085f82012-11-21 00:36:55 +00007923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007924s390_irgen_STFH(UChar r1, IRTemp op2addr)
7925{
7926 store(mkexpr(op2addr), get_gpr_w0(r1));
7927
7928 return "stfh";
7929}
7930
florian55085f82012-11-21 00:36:55 +00007931static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007932s390_irgen_STOC(UChar r1, IRTemp op2addr)
7933{
7934 /* condition is checked in format handler */
7935 store(mkexpr(op2addr), get_gpr_w1(r1));
7936
7937 return "stoc";
7938}
7939
florian55085f82012-11-21 00:36:55 +00007940static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007941s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7942{
7943 /* condition is checked in format handler */
7944 store(mkexpr(op2addr), get_gpr_dw0(r1));
7945
7946 return "stocg";
7947}
7948
florian55085f82012-11-21 00:36:55 +00007949static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007950s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7951{
7952 store(mkexpr(op2addr), get_gpr_dw0(r1));
7953 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7954
7955 return "stpq";
7956}
7957
florian55085f82012-11-21 00:36:55 +00007958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007959s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7960{
7961 store(mkexpr(op2addr), get_gpr_b7(r1));
7962 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7963
7964 return "strvh";
7965}
7966
florian55085f82012-11-21 00:36:55 +00007967static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007968s390_irgen_STRV(UChar r1, IRTemp op2addr)
7969{
7970 store(mkexpr(op2addr), get_gpr_b7(r1));
7971 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7972 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7973 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7974
7975 return "strv";
7976}
7977
florian55085f82012-11-21 00:36:55 +00007978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007979s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7980{
7981 store(mkexpr(op2addr), get_gpr_b7(r1));
7982 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7983 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7984 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7985 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7986 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7987 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7988 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7989
7990 return "strvg";
7991}
7992
florian55085f82012-11-21 00:36:55 +00007993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007994s390_irgen_SR(UChar r1, UChar r2)
7995{
7996 IRTemp op1 = newTemp(Ity_I32);
7997 IRTemp op2 = newTemp(Ity_I32);
7998 IRTemp result = newTemp(Ity_I32);
7999
8000 assign(op1, get_gpr_w1(r1));
8001 assign(op2, get_gpr_w1(r2));
8002 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8003 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8004 put_gpr_w1(r1, mkexpr(result));
8005
8006 return "sr";
8007}
8008
florian55085f82012-11-21 00:36:55 +00008009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008010s390_irgen_SGR(UChar r1, UChar r2)
8011{
8012 IRTemp op1 = newTemp(Ity_I64);
8013 IRTemp op2 = newTemp(Ity_I64);
8014 IRTemp result = newTemp(Ity_I64);
8015
8016 assign(op1, get_gpr_dw0(r1));
8017 assign(op2, get_gpr_dw0(r2));
8018 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8019 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8020 put_gpr_dw0(r1, mkexpr(result));
8021
8022 return "sgr";
8023}
8024
florian55085f82012-11-21 00:36:55 +00008025static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008026s390_irgen_SGFR(UChar r1, UChar r2)
8027{
8028 IRTemp op1 = newTemp(Ity_I64);
8029 IRTemp op2 = newTemp(Ity_I64);
8030 IRTemp result = newTemp(Ity_I64);
8031
8032 assign(op1, get_gpr_dw0(r1));
8033 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8034 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8035 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8036 put_gpr_dw0(r1, mkexpr(result));
8037
8038 return "sgfr";
8039}
8040
florian55085f82012-11-21 00:36:55 +00008041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008042s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8043{
8044 IRTemp op2 = newTemp(Ity_I32);
8045 IRTemp op3 = newTemp(Ity_I32);
8046 IRTemp result = newTemp(Ity_I32);
8047
8048 assign(op2, get_gpr_w1(r2));
8049 assign(op3, get_gpr_w1(r3));
8050 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8051 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8052 put_gpr_w1(r1, mkexpr(result));
8053
8054 return "srk";
8055}
8056
florian55085f82012-11-21 00:36:55 +00008057static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008058s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8059{
8060 IRTemp op2 = newTemp(Ity_I64);
8061 IRTemp op3 = newTemp(Ity_I64);
8062 IRTemp result = newTemp(Ity_I64);
8063
8064 assign(op2, get_gpr_dw0(r2));
8065 assign(op3, get_gpr_dw0(r3));
8066 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8067 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8068 put_gpr_dw0(r1, mkexpr(result));
8069
8070 return "sgrk";
8071}
8072
florian55085f82012-11-21 00:36:55 +00008073static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008074s390_irgen_S(UChar r1, IRTemp op2addr)
8075{
8076 IRTemp op1 = newTemp(Ity_I32);
8077 IRTemp op2 = newTemp(Ity_I32);
8078 IRTemp result = newTemp(Ity_I32);
8079
8080 assign(op1, get_gpr_w1(r1));
8081 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8082 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8083 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8084 put_gpr_w1(r1, mkexpr(result));
8085
8086 return "s";
8087}
8088
florian55085f82012-11-21 00:36:55 +00008089static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008090s390_irgen_SY(UChar r1, IRTemp op2addr)
8091{
8092 IRTemp op1 = newTemp(Ity_I32);
8093 IRTemp op2 = newTemp(Ity_I32);
8094 IRTemp result = newTemp(Ity_I32);
8095
8096 assign(op1, get_gpr_w1(r1));
8097 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8098 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8099 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8100 put_gpr_w1(r1, mkexpr(result));
8101
8102 return "sy";
8103}
8104
florian55085f82012-11-21 00:36:55 +00008105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008106s390_irgen_SG(UChar r1, IRTemp op2addr)
8107{
8108 IRTemp op1 = newTemp(Ity_I64);
8109 IRTemp op2 = newTemp(Ity_I64);
8110 IRTemp result = newTemp(Ity_I64);
8111
8112 assign(op1, get_gpr_dw0(r1));
8113 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8114 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8115 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8116 put_gpr_dw0(r1, mkexpr(result));
8117
8118 return "sg";
8119}
8120
florian55085f82012-11-21 00:36:55 +00008121static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008122s390_irgen_SGF(UChar r1, IRTemp op2addr)
8123{
8124 IRTemp op1 = newTemp(Ity_I64);
8125 IRTemp op2 = newTemp(Ity_I64);
8126 IRTemp result = newTemp(Ity_I64);
8127
8128 assign(op1, get_gpr_dw0(r1));
8129 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8130 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8131 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8132 put_gpr_dw0(r1, mkexpr(result));
8133
8134 return "sgf";
8135}
8136
florian55085f82012-11-21 00:36:55 +00008137static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008138s390_irgen_SH(UChar r1, IRTemp op2addr)
8139{
8140 IRTemp op1 = newTemp(Ity_I32);
8141 IRTemp op2 = newTemp(Ity_I32);
8142 IRTemp result = newTemp(Ity_I32);
8143
8144 assign(op1, get_gpr_w1(r1));
8145 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8146 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8147 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8148 put_gpr_w1(r1, mkexpr(result));
8149
8150 return "sh";
8151}
8152
florian55085f82012-11-21 00:36:55 +00008153static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008154s390_irgen_SHY(UChar r1, IRTemp op2addr)
8155{
8156 IRTemp op1 = newTemp(Ity_I32);
8157 IRTemp op2 = newTemp(Ity_I32);
8158 IRTemp result = newTemp(Ity_I32);
8159
8160 assign(op1, get_gpr_w1(r1));
8161 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8162 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8163 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8164 put_gpr_w1(r1, mkexpr(result));
8165
8166 return "shy";
8167}
8168
florian55085f82012-11-21 00:36:55 +00008169static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008170s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8171{
8172 IRTemp op2 = newTemp(Ity_I32);
8173 IRTemp op3 = newTemp(Ity_I32);
8174 IRTemp result = newTemp(Ity_I32);
8175
8176 assign(op2, get_gpr_w0(r1));
8177 assign(op3, get_gpr_w0(r2));
8178 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8179 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8180 put_gpr_w0(r1, mkexpr(result));
8181
8182 return "shhhr";
8183}
8184
florian55085f82012-11-21 00:36:55 +00008185static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008186s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8187{
8188 IRTemp op2 = newTemp(Ity_I32);
8189 IRTemp op3 = newTemp(Ity_I32);
8190 IRTemp result = newTemp(Ity_I32);
8191
8192 assign(op2, get_gpr_w0(r1));
8193 assign(op3, get_gpr_w1(r2));
8194 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8195 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8196 put_gpr_w0(r1, mkexpr(result));
8197
8198 return "shhlr";
8199}
8200
florian55085f82012-11-21 00:36:55 +00008201static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008202s390_irgen_SLR(UChar r1, UChar r2)
8203{
8204 IRTemp op1 = newTemp(Ity_I32);
8205 IRTemp op2 = newTemp(Ity_I32);
8206 IRTemp result = newTemp(Ity_I32);
8207
8208 assign(op1, get_gpr_w1(r1));
8209 assign(op2, get_gpr_w1(r2));
8210 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8211 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8212 put_gpr_w1(r1, mkexpr(result));
8213
8214 return "slr";
8215}
8216
florian55085f82012-11-21 00:36:55 +00008217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008218s390_irgen_SLGR(UChar r1, UChar r2)
8219{
8220 IRTemp op1 = newTemp(Ity_I64);
8221 IRTemp op2 = newTemp(Ity_I64);
8222 IRTemp result = newTemp(Ity_I64);
8223
8224 assign(op1, get_gpr_dw0(r1));
8225 assign(op2, get_gpr_dw0(r2));
8226 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8227 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8228 put_gpr_dw0(r1, mkexpr(result));
8229
8230 return "slgr";
8231}
8232
florian55085f82012-11-21 00:36:55 +00008233static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008234s390_irgen_SLGFR(UChar r1, UChar r2)
8235{
8236 IRTemp op1 = newTemp(Ity_I64);
8237 IRTemp op2 = newTemp(Ity_I64);
8238 IRTemp result = newTemp(Ity_I64);
8239
8240 assign(op1, get_gpr_dw0(r1));
8241 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8242 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8243 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8244 put_gpr_dw0(r1, mkexpr(result));
8245
8246 return "slgfr";
8247}
8248
florian55085f82012-11-21 00:36:55 +00008249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008250s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8251{
8252 IRTemp op2 = newTemp(Ity_I32);
8253 IRTemp op3 = newTemp(Ity_I32);
8254 IRTemp result = newTemp(Ity_I32);
8255
8256 assign(op2, get_gpr_w1(r2));
8257 assign(op3, get_gpr_w1(r3));
8258 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8259 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8260 put_gpr_w1(r1, mkexpr(result));
8261
8262 return "slrk";
8263}
8264
florian55085f82012-11-21 00:36:55 +00008265static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008266s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8267{
8268 IRTemp op2 = newTemp(Ity_I64);
8269 IRTemp op3 = newTemp(Ity_I64);
8270 IRTemp result = newTemp(Ity_I64);
8271
8272 assign(op2, get_gpr_dw0(r2));
8273 assign(op3, get_gpr_dw0(r3));
8274 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8275 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8276 put_gpr_dw0(r1, mkexpr(result));
8277
8278 return "slgrk";
8279}
8280
florian55085f82012-11-21 00:36:55 +00008281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008282s390_irgen_SL(UChar r1, IRTemp op2addr)
8283{
8284 IRTemp op1 = newTemp(Ity_I32);
8285 IRTemp op2 = newTemp(Ity_I32);
8286 IRTemp result = newTemp(Ity_I32);
8287
8288 assign(op1, get_gpr_w1(r1));
8289 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8290 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8291 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8292 put_gpr_w1(r1, mkexpr(result));
8293
8294 return "sl";
8295}
8296
florian55085f82012-11-21 00:36:55 +00008297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008298s390_irgen_SLY(UChar r1, IRTemp op2addr)
8299{
8300 IRTemp op1 = newTemp(Ity_I32);
8301 IRTemp op2 = newTemp(Ity_I32);
8302 IRTemp result = newTemp(Ity_I32);
8303
8304 assign(op1, get_gpr_w1(r1));
8305 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8306 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8307 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8308 put_gpr_w1(r1, mkexpr(result));
8309
8310 return "sly";
8311}
8312
florian55085f82012-11-21 00:36:55 +00008313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008314s390_irgen_SLG(UChar r1, IRTemp op2addr)
8315{
8316 IRTemp op1 = newTemp(Ity_I64);
8317 IRTemp op2 = newTemp(Ity_I64);
8318 IRTemp result = newTemp(Ity_I64);
8319
8320 assign(op1, get_gpr_dw0(r1));
8321 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8322 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8323 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8324 put_gpr_dw0(r1, mkexpr(result));
8325
8326 return "slg";
8327}
8328
florian55085f82012-11-21 00:36:55 +00008329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008330s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8331{
8332 IRTemp op1 = newTemp(Ity_I64);
8333 IRTemp op2 = newTemp(Ity_I64);
8334 IRTemp result = newTemp(Ity_I64);
8335
8336 assign(op1, get_gpr_dw0(r1));
8337 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8338 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8339 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8340 put_gpr_dw0(r1, mkexpr(result));
8341
8342 return "slgf";
8343}
8344
florian55085f82012-11-21 00:36:55 +00008345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008346s390_irgen_SLFI(UChar r1, UInt i2)
8347{
8348 IRTemp op1 = newTemp(Ity_I32);
8349 UInt op2;
8350 IRTemp result = newTemp(Ity_I32);
8351
8352 assign(op1, get_gpr_w1(r1));
8353 op2 = i2;
8354 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8355 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8356 mkU32(op2)));
8357 put_gpr_w1(r1, mkexpr(result));
8358
8359 return "slfi";
8360}
8361
florian55085f82012-11-21 00:36:55 +00008362static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008363s390_irgen_SLGFI(UChar r1, UInt i2)
8364{
8365 IRTemp op1 = newTemp(Ity_I64);
8366 ULong op2;
8367 IRTemp result = newTemp(Ity_I64);
8368
8369 assign(op1, get_gpr_dw0(r1));
8370 op2 = (ULong)i2;
8371 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8372 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8373 mkU64(op2)));
8374 put_gpr_dw0(r1, mkexpr(result));
8375
8376 return "slgfi";
8377}
8378
florian55085f82012-11-21 00:36:55 +00008379static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008380s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8381{
8382 IRTemp op2 = newTemp(Ity_I32);
8383 IRTemp op3 = newTemp(Ity_I32);
8384 IRTemp result = newTemp(Ity_I32);
8385
8386 assign(op2, get_gpr_w0(r1));
8387 assign(op3, get_gpr_w0(r2));
8388 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8389 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8390 put_gpr_w0(r1, mkexpr(result));
8391
8392 return "slhhhr";
8393}
8394
florian55085f82012-11-21 00:36:55 +00008395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008396s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8397{
8398 IRTemp op2 = newTemp(Ity_I32);
8399 IRTemp op3 = newTemp(Ity_I32);
8400 IRTemp result = newTemp(Ity_I32);
8401
8402 assign(op2, get_gpr_w0(r1));
8403 assign(op3, get_gpr_w1(r2));
8404 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8405 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8406 put_gpr_w0(r1, mkexpr(result));
8407
8408 return "slhhlr";
8409}
8410
florian55085f82012-11-21 00:36:55 +00008411static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008412s390_irgen_SLBR(UChar r1, UChar r2)
8413{
8414 IRTemp op1 = newTemp(Ity_I32);
8415 IRTemp op2 = newTemp(Ity_I32);
8416 IRTemp result = newTemp(Ity_I32);
8417 IRTemp borrow_in = newTemp(Ity_I32);
8418
8419 assign(op1, get_gpr_w1(r1));
8420 assign(op2, get_gpr_w1(r2));
8421 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8422 s390_call_calculate_cc(), mkU8(1))));
8423 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8424 mkexpr(borrow_in)));
8425 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8426 put_gpr_w1(r1, mkexpr(result));
8427
8428 return "slbr";
8429}
8430
florian55085f82012-11-21 00:36:55 +00008431static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008432s390_irgen_SLBGR(UChar r1, UChar r2)
8433{
8434 IRTemp op1 = newTemp(Ity_I64);
8435 IRTemp op2 = newTemp(Ity_I64);
8436 IRTemp result = newTemp(Ity_I64);
8437 IRTemp borrow_in = newTemp(Ity_I64);
8438
8439 assign(op1, get_gpr_dw0(r1));
8440 assign(op2, get_gpr_dw0(r2));
8441 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8442 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8443 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8444 mkexpr(borrow_in)));
8445 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8446 put_gpr_dw0(r1, mkexpr(result));
8447
8448 return "slbgr";
8449}
8450
florian55085f82012-11-21 00:36:55 +00008451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008452s390_irgen_SLB(UChar r1, IRTemp op2addr)
8453{
8454 IRTemp op1 = newTemp(Ity_I32);
8455 IRTemp op2 = newTemp(Ity_I32);
8456 IRTemp result = newTemp(Ity_I32);
8457 IRTemp borrow_in = newTemp(Ity_I32);
8458
8459 assign(op1, get_gpr_w1(r1));
8460 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8461 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8462 s390_call_calculate_cc(), mkU8(1))));
8463 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8464 mkexpr(borrow_in)));
8465 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8466 put_gpr_w1(r1, mkexpr(result));
8467
8468 return "slb";
8469}
8470
florian55085f82012-11-21 00:36:55 +00008471static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008472s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8473{
8474 IRTemp op1 = newTemp(Ity_I64);
8475 IRTemp op2 = newTemp(Ity_I64);
8476 IRTemp result = newTemp(Ity_I64);
8477 IRTemp borrow_in = newTemp(Ity_I64);
8478
8479 assign(op1, get_gpr_dw0(r1));
8480 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8481 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8482 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8483 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8484 mkexpr(borrow_in)));
8485 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8486 put_gpr_dw0(r1, mkexpr(result));
8487
8488 return "slbg";
8489}
8490
florian55085f82012-11-21 00:36:55 +00008491static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008492s390_irgen_SVC(UChar i)
8493{
8494 IRTemp sysno = newTemp(Ity_I64);
8495
8496 if (i != 0) {
8497 assign(sysno, mkU64(i));
8498 } else {
8499 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8500 }
8501 system_call(mkexpr(sysno));
8502
8503 return "svc";
8504}
8505
florian55085f82012-11-21 00:36:55 +00008506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008507s390_irgen_TM(UChar i2, IRTemp op1addr)
8508{
8509 UChar mask;
8510 IRTemp value = newTemp(Ity_I8);
8511
8512 mask = i2;
8513 assign(value, load(Ity_I8, mkexpr(op1addr)));
8514 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8515 mkU8(mask)));
8516
8517 return "tm";
8518}
8519
florian55085f82012-11-21 00:36:55 +00008520static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008521s390_irgen_TMY(UChar i2, IRTemp op1addr)
8522{
8523 UChar mask;
8524 IRTemp value = newTemp(Ity_I8);
8525
8526 mask = i2;
8527 assign(value, load(Ity_I8, mkexpr(op1addr)));
8528 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8529 mkU8(mask)));
8530
8531 return "tmy";
8532}
8533
florian55085f82012-11-21 00:36:55 +00008534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008535s390_irgen_TMHH(UChar r1, UShort i2)
8536{
8537 UShort mask;
8538 IRTemp value = newTemp(Ity_I16);
8539
8540 mask = i2;
8541 assign(value, get_gpr_hw0(r1));
8542 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8543 mkU16(mask)));
8544
8545 return "tmhh";
8546}
8547
florian55085f82012-11-21 00:36:55 +00008548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008549s390_irgen_TMHL(UChar r1, UShort i2)
8550{
8551 UShort mask;
8552 IRTemp value = newTemp(Ity_I16);
8553
8554 mask = i2;
8555 assign(value, get_gpr_hw1(r1));
8556 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8557 mkU16(mask)));
8558
8559 return "tmhl";
8560}
8561
florian55085f82012-11-21 00:36:55 +00008562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008563s390_irgen_TMLH(UChar r1, UShort i2)
8564{
8565 UShort mask;
8566 IRTemp value = newTemp(Ity_I16);
8567
8568 mask = i2;
8569 assign(value, get_gpr_hw2(r1));
8570 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8571 mkU16(mask)));
8572
8573 return "tmlh";
8574}
8575
florian55085f82012-11-21 00:36:55 +00008576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008577s390_irgen_TMLL(UChar r1, UShort i2)
8578{
8579 UShort mask;
8580 IRTemp value = newTemp(Ity_I16);
8581
8582 mask = i2;
8583 assign(value, get_gpr_hw3(r1));
8584 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8585 mkU16(mask)));
8586
8587 return "tmll";
8588}
8589
florian55085f82012-11-21 00:36:55 +00008590static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008591s390_irgen_EFPC(UChar r1)
8592{
8593 put_gpr_w1(r1, get_fpc_w0());
8594
8595 return "efpc";
8596}
8597
florian55085f82012-11-21 00:36:55 +00008598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008599s390_irgen_LER(UChar r1, UChar r2)
8600{
8601 put_fpr_w0(r1, get_fpr_w0(r2));
8602
8603 return "ler";
8604}
8605
florian55085f82012-11-21 00:36:55 +00008606static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008607s390_irgen_LDR(UChar r1, UChar r2)
8608{
8609 put_fpr_dw0(r1, get_fpr_dw0(r2));
8610
8611 return "ldr";
8612}
8613
florian55085f82012-11-21 00:36:55 +00008614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008615s390_irgen_LXR(UChar r1, UChar r2)
8616{
8617 put_fpr_dw0(r1, get_fpr_dw0(r2));
8618 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8619
8620 return "lxr";
8621}
8622
florian55085f82012-11-21 00:36:55 +00008623static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008624s390_irgen_LE(UChar r1, IRTemp op2addr)
8625{
8626 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8627
8628 return "le";
8629}
8630
florian55085f82012-11-21 00:36:55 +00008631static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008632s390_irgen_LD(UChar r1, IRTemp op2addr)
8633{
8634 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8635
8636 return "ld";
8637}
8638
florian55085f82012-11-21 00:36:55 +00008639static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008640s390_irgen_LEY(UChar r1, IRTemp op2addr)
8641{
8642 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8643
8644 return "ley";
8645}
8646
florian55085f82012-11-21 00:36:55 +00008647static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008648s390_irgen_LDY(UChar r1, IRTemp op2addr)
8649{
8650 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8651
8652 return "ldy";
8653}
8654
florian55085f82012-11-21 00:36:55 +00008655static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008656s390_irgen_LFPC(IRTemp op2addr)
8657{
8658 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8659
8660 return "lfpc";
8661}
8662
florian55085f82012-11-21 00:36:55 +00008663static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008664s390_irgen_LZER(UChar r1)
8665{
8666 put_fpr_w0(r1, mkF32i(0x0));
8667
8668 return "lzer";
8669}
8670
florian55085f82012-11-21 00:36:55 +00008671static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008672s390_irgen_LZDR(UChar r1)
8673{
8674 put_fpr_dw0(r1, mkF64i(0x0));
8675
8676 return "lzdr";
8677}
8678
florian55085f82012-11-21 00:36:55 +00008679static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008680s390_irgen_LZXR(UChar r1)
8681{
8682 put_fpr_dw0(r1, mkF64i(0x0));
8683 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8684
8685 return "lzxr";
8686}
8687
florian55085f82012-11-21 00:36:55 +00008688static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008689s390_irgen_SRNM(IRTemp op2addr)
8690{
florianf0fa1be2012-09-18 20:24:38 +00008691 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008692
florianf0fa1be2012-09-18 20:24:38 +00008693 input_mask = 3;
8694 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008695
florianf0fa1be2012-09-18 20:24:38 +00008696 put_fpc_w0(binop(Iop_Or32,
8697 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8698 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8699 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008700 return "srnm";
8701}
8702
florian55085f82012-11-21 00:36:55 +00008703static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008704s390_irgen_SRNMB(IRTemp op2addr)
8705{
8706 UInt input_mask, fpc_mask;
8707
8708 input_mask = 7;
8709 fpc_mask = 7;
8710
8711 put_fpc_w0(binop(Iop_Or32,
8712 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8713 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8714 mkU32(input_mask))));
8715 return "srnmb";
8716}
8717
florian81a4bfe2012-09-20 01:25:28 +00008718static void
florianf0fa1be2012-09-18 20:24:38 +00008719s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8720{
8721 if (b2 == 0) { /* This is the typical case */
8722 if (d2 > 3) {
8723 if (s390_host_has_fpext && d2 == 7) {
8724 /* ok */
8725 } else {
8726 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008727 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008728 }
8729 }
8730 }
8731
8732 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8733}
8734
florian82cdba62013-03-12 01:31:24 +00008735/* Wrapper to validate the parameter as in SRNMB is not required, as all
8736 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8737static const HChar *
8738s390_irgen_SRNMT(IRTemp op2addr)
8739{
8740 UInt input_mask, fpc_mask;
8741
8742 input_mask = 7;
8743 fpc_mask = 0x70;
8744
8745 /* fpc[25:27] <- op2addr[61:63]
8746 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8747 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8748 binop(Iop_Shl32, binop(Iop_And32,
8749 unop(Iop_64to32, mkexpr(op2addr)),
8750 mkU32(input_mask)), mkU8(4))));
8751 return "srnmt";
8752}
8753
florianf0fa1be2012-09-18 20:24:38 +00008754
florian55085f82012-11-21 00:36:55 +00008755static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008756s390_irgen_SFPC(UChar r1)
8757{
8758 put_fpc_w0(get_gpr_w1(r1));
8759
8760 return "sfpc";
8761}
8762
florian55085f82012-11-21 00:36:55 +00008763static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008764s390_irgen_STE(UChar r1, IRTemp op2addr)
8765{
8766 store(mkexpr(op2addr), get_fpr_w0(r1));
8767
8768 return "ste";
8769}
8770
florian55085f82012-11-21 00:36:55 +00008771static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008772s390_irgen_STD(UChar r1, IRTemp op2addr)
8773{
8774 store(mkexpr(op2addr), get_fpr_dw0(r1));
8775
8776 return "std";
8777}
8778
florian55085f82012-11-21 00:36:55 +00008779static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008780s390_irgen_STEY(UChar r1, IRTemp op2addr)
8781{
8782 store(mkexpr(op2addr), get_fpr_w0(r1));
8783
8784 return "stey";
8785}
8786
florian55085f82012-11-21 00:36:55 +00008787static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008788s390_irgen_STDY(UChar r1, IRTemp op2addr)
8789{
8790 store(mkexpr(op2addr), get_fpr_dw0(r1));
8791
8792 return "stdy";
8793}
8794
florian55085f82012-11-21 00:36:55 +00008795static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008796s390_irgen_STFPC(IRTemp op2addr)
8797{
8798 store(mkexpr(op2addr), get_fpc_w0());
8799
8800 return "stfpc";
8801}
8802
florian55085f82012-11-21 00:36:55 +00008803static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008804s390_irgen_AEBR(UChar r1, UChar r2)
8805{
8806 IRTemp op1 = newTemp(Ity_F32);
8807 IRTemp op2 = newTemp(Ity_F32);
8808 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008809 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008810
8811 assign(op1, get_fpr_w0(r1));
8812 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008813 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008814 mkexpr(op2)));
8815 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8816 put_fpr_w0(r1, mkexpr(result));
8817
8818 return "aebr";
8819}
8820
florian55085f82012-11-21 00:36:55 +00008821static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008822s390_irgen_ADBR(UChar r1, UChar r2)
8823{
8824 IRTemp op1 = newTemp(Ity_F64);
8825 IRTemp op2 = newTemp(Ity_F64);
8826 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008827 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008828
8829 assign(op1, get_fpr_dw0(r1));
8830 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008831 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008832 mkexpr(op2)));
8833 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8834 put_fpr_dw0(r1, mkexpr(result));
8835
8836 return "adbr";
8837}
8838
florian55085f82012-11-21 00:36:55 +00008839static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008840s390_irgen_AEB(UChar r1, IRTemp op2addr)
8841{
8842 IRTemp op1 = newTemp(Ity_F32);
8843 IRTemp op2 = newTemp(Ity_F32);
8844 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008845 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008846
8847 assign(op1, get_fpr_w0(r1));
8848 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008849 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008850 mkexpr(op2)));
8851 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8852 put_fpr_w0(r1, mkexpr(result));
8853
8854 return "aeb";
8855}
8856
florian55085f82012-11-21 00:36:55 +00008857static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008858s390_irgen_ADB(UChar r1, IRTemp op2addr)
8859{
8860 IRTemp op1 = newTemp(Ity_F64);
8861 IRTemp op2 = newTemp(Ity_F64);
8862 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008863 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008864
8865 assign(op1, get_fpr_dw0(r1));
8866 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008867 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008868 mkexpr(op2)));
8869 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8870 put_fpr_dw0(r1, mkexpr(result));
8871
8872 return "adb";
8873}
8874
florian55085f82012-11-21 00:36:55 +00008875static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008876s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8877 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008878{
florian125e20d2012-10-07 15:42:37 +00008879 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008880 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008881 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008882 }
sewardj2019a972011-03-07 16:04:07 +00008883 IRTemp op2 = newTemp(Ity_I32);
8884
8885 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008886 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008887 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008888
8889 return "cefbr";
8890}
8891
florian55085f82012-11-21 00:36:55 +00008892static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008893s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8894 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008895{
8896 IRTemp op2 = newTemp(Ity_I32);
8897
8898 assign(op2, get_gpr_w1(r2));
8899 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8900
8901 return "cdfbr";
8902}
8903
florian55085f82012-11-21 00:36:55 +00008904static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008905s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8906 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008907{
florian125e20d2012-10-07 15:42:37 +00008908 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008909 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008910 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008911 }
sewardj2019a972011-03-07 16:04:07 +00008912 IRTemp op2 = newTemp(Ity_I64);
8913
8914 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008915 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008916 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008917
8918 return "cegbr";
8919}
8920
florian55085f82012-11-21 00:36:55 +00008921static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008922s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8923 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008924{
florian125e20d2012-10-07 15:42:37 +00008925 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008926 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008927 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008928 }
sewardj2019a972011-03-07 16:04:07 +00008929 IRTemp op2 = newTemp(Ity_I64);
8930
8931 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008932 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008933 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008934
8935 return "cdgbr";
8936}
8937
florian55085f82012-11-21 00:36:55 +00008938static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008939s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8940 UChar r1, UChar r2)
8941{
floriane75dafa2012-09-01 17:54:09 +00008942 if (! s390_host_has_fpext) {
8943 emulation_failure(EmFail_S390X_fpext);
8944 } else {
8945 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008946
floriane75dafa2012-09-01 17:54:09 +00008947 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008948 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008949 mkexpr(op2)));
8950 }
florian1c8f7ff2012-09-01 00:12:11 +00008951 return "celfbr";
8952}
8953
florian55085f82012-11-21 00:36:55 +00008954static const HChar *
floriand2129202012-09-01 20:01:39 +00008955s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8956 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008957{
floriane75dafa2012-09-01 17:54:09 +00008958 if (! s390_host_has_fpext) {
8959 emulation_failure(EmFail_S390X_fpext);
8960 } else {
8961 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008962
floriane75dafa2012-09-01 17:54:09 +00008963 assign(op2, get_gpr_w1(r2));
8964 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8965 }
florian1c8f7ff2012-09-01 00:12:11 +00008966 return "cdlfbr";
8967}
8968
florian55085f82012-11-21 00:36:55 +00008969static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008970s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8971 UChar r1, UChar r2)
8972{
floriane75dafa2012-09-01 17:54:09 +00008973 if (! s390_host_has_fpext) {
8974 emulation_failure(EmFail_S390X_fpext);
8975 } else {
8976 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008977
floriane75dafa2012-09-01 17:54:09 +00008978 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008979 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008980 mkexpr(op2)));
8981 }
florian1c8f7ff2012-09-01 00:12:11 +00008982 return "celgbr";
8983}
8984
florian55085f82012-11-21 00:36:55 +00008985static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008986s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8987 UChar r1, UChar r2)
8988{
floriane75dafa2012-09-01 17:54:09 +00008989 if (! s390_host_has_fpext) {
8990 emulation_failure(EmFail_S390X_fpext);
8991 } else {
8992 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008993
floriane75dafa2012-09-01 17:54:09 +00008994 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008995 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8996 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008997 mkexpr(op2)));
8998 }
florian1c8f7ff2012-09-01 00:12:11 +00008999 return "cdlgbr";
9000}
9001
florian55085f82012-11-21 00:36:55 +00009002static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009003s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9004 UChar r1, UChar r2)
9005{
floriane75dafa2012-09-01 17:54:09 +00009006 if (! s390_host_has_fpext) {
9007 emulation_failure(EmFail_S390X_fpext);
9008 } else {
9009 IRTemp op = newTemp(Ity_F32);
9010 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009011 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009012
floriane75dafa2012-09-01 17:54:09 +00009013 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009014 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009015 mkexpr(op)));
9016 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009017 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009018 }
florian1c8f7ff2012-09-01 00:12:11 +00009019 return "clfebr";
9020}
9021
florian55085f82012-11-21 00:36:55 +00009022static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009023s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9024 UChar r1, UChar r2)
9025{
floriane75dafa2012-09-01 17:54:09 +00009026 if (! s390_host_has_fpext) {
9027 emulation_failure(EmFail_S390X_fpext);
9028 } else {
9029 IRTemp op = newTemp(Ity_F64);
9030 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009031 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009032
floriane75dafa2012-09-01 17:54:09 +00009033 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009034 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009035 mkexpr(op)));
9036 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009037 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009038 }
florian1c8f7ff2012-09-01 00:12:11 +00009039 return "clfdbr";
9040}
9041
florian55085f82012-11-21 00:36:55 +00009042static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009043s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9044 UChar r1, UChar r2)
9045{
floriane75dafa2012-09-01 17:54:09 +00009046 if (! s390_host_has_fpext) {
9047 emulation_failure(EmFail_S390X_fpext);
9048 } else {
9049 IRTemp op = newTemp(Ity_F32);
9050 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009051 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009052
floriane75dafa2012-09-01 17:54:09 +00009053 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009054 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009055 mkexpr(op)));
9056 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009057 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009058 }
florian1c8f7ff2012-09-01 00:12:11 +00009059 return "clgebr";
9060}
9061
florian55085f82012-11-21 00:36:55 +00009062static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009063s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9064 UChar r1, UChar r2)
9065{
floriane75dafa2012-09-01 17:54:09 +00009066 if (! s390_host_has_fpext) {
9067 emulation_failure(EmFail_S390X_fpext);
9068 } else {
9069 IRTemp op = newTemp(Ity_F64);
9070 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009071 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009072
floriane75dafa2012-09-01 17:54:09 +00009073 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009074 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009075 mkexpr(op)));
9076 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009077 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009078 }
florian1c8f7ff2012-09-01 00:12:11 +00009079 return "clgdbr";
9080}
9081
florian55085f82012-11-21 00:36:55 +00009082static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009083s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9084 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009085{
9086 IRTemp op = newTemp(Ity_F32);
9087 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009088 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009089
9090 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009091 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009092 mkexpr(op)));
9093 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009094 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009095
9096 return "cfebr";
9097}
9098
florian55085f82012-11-21 00:36:55 +00009099static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009100s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9101 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009102{
9103 IRTemp op = newTemp(Ity_F64);
9104 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009105 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009106
9107 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009108 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009109 mkexpr(op)));
9110 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009111 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009112
9113 return "cfdbr";
9114}
9115
florian55085f82012-11-21 00:36:55 +00009116static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009117s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9118 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009119{
9120 IRTemp op = newTemp(Ity_F32);
9121 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009122 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009123
9124 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009125 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009126 mkexpr(op)));
9127 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009128 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009129
9130 return "cgebr";
9131}
9132
florian55085f82012-11-21 00:36:55 +00009133static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009134s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9135 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009136{
9137 IRTemp op = newTemp(Ity_F64);
9138 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009139 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009140
9141 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009142 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009143 mkexpr(op)));
9144 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009145 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009146
9147 return "cgdbr";
9148}
9149
florian55085f82012-11-21 00:36:55 +00009150static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009151s390_irgen_DEBR(UChar r1, UChar r2)
9152{
9153 IRTemp op1 = newTemp(Ity_F32);
9154 IRTemp op2 = newTemp(Ity_F32);
9155 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009156 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009157
9158 assign(op1, get_fpr_w0(r1));
9159 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009160 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009161 mkexpr(op2)));
9162 put_fpr_w0(r1, mkexpr(result));
9163
9164 return "debr";
9165}
9166
florian55085f82012-11-21 00:36:55 +00009167static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009168s390_irgen_DDBR(UChar r1, UChar r2)
9169{
9170 IRTemp op1 = newTemp(Ity_F64);
9171 IRTemp op2 = newTemp(Ity_F64);
9172 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009173 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009174
9175 assign(op1, get_fpr_dw0(r1));
9176 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009177 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009178 mkexpr(op2)));
9179 put_fpr_dw0(r1, mkexpr(result));
9180
9181 return "ddbr";
9182}
9183
florian55085f82012-11-21 00:36:55 +00009184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009185s390_irgen_DEB(UChar r1, IRTemp op2addr)
9186{
9187 IRTemp op1 = newTemp(Ity_F32);
9188 IRTemp op2 = newTemp(Ity_F32);
9189 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009190 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009191
9192 assign(op1, get_fpr_w0(r1));
9193 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009194 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009195 mkexpr(op2)));
9196 put_fpr_w0(r1, mkexpr(result));
9197
9198 return "deb";
9199}
9200
florian55085f82012-11-21 00:36:55 +00009201static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009202s390_irgen_DDB(UChar r1, IRTemp op2addr)
9203{
9204 IRTemp op1 = newTemp(Ity_F64);
9205 IRTemp op2 = newTemp(Ity_F64);
9206 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009207 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009208
9209 assign(op1, get_fpr_dw0(r1));
9210 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009211 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009212 mkexpr(op2)));
9213 put_fpr_dw0(r1, mkexpr(result));
9214
9215 return "ddb";
9216}
9217
florian55085f82012-11-21 00:36:55 +00009218static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009219s390_irgen_LTEBR(UChar r1, UChar r2)
9220{
9221 IRTemp result = newTemp(Ity_F32);
9222
9223 assign(result, get_fpr_w0(r2));
9224 put_fpr_w0(r1, mkexpr(result));
9225 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9226
9227 return "ltebr";
9228}
9229
florian55085f82012-11-21 00:36:55 +00009230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009231s390_irgen_LTDBR(UChar r1, UChar r2)
9232{
9233 IRTemp result = newTemp(Ity_F64);
9234
9235 assign(result, get_fpr_dw0(r2));
9236 put_fpr_dw0(r1, mkexpr(result));
9237 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9238
9239 return "ltdbr";
9240}
9241
florian55085f82012-11-21 00:36:55 +00009242static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009243s390_irgen_LCEBR(UChar r1, UChar r2)
9244{
9245 IRTemp result = newTemp(Ity_F32);
9246
9247 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9248 put_fpr_w0(r1, mkexpr(result));
9249 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9250
9251 return "lcebr";
9252}
9253
florian55085f82012-11-21 00:36:55 +00009254static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009255s390_irgen_LCDBR(UChar r1, UChar r2)
9256{
9257 IRTemp result = newTemp(Ity_F64);
9258
9259 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9260 put_fpr_dw0(r1, mkexpr(result));
9261 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9262
9263 return "lcdbr";
9264}
9265
florian55085f82012-11-21 00:36:55 +00009266static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009267s390_irgen_LDEBR(UChar r1, UChar r2)
9268{
9269 IRTemp op = newTemp(Ity_F32);
9270
9271 assign(op, get_fpr_w0(r2));
9272 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9273
9274 return "ldebr";
9275}
9276
florian55085f82012-11-21 00:36:55 +00009277static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009278s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9279{
9280 IRTemp op = newTemp(Ity_F32);
9281
9282 assign(op, load(Ity_F32, mkexpr(op2addr)));
9283 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9284
9285 return "ldeb";
9286}
9287
florian55085f82012-11-21 00:36:55 +00009288static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009289s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9290 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009291{
florian125e20d2012-10-07 15:42:37 +00009292 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009293 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009294 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009295 }
sewardj2019a972011-03-07 16:04:07 +00009296 IRTemp op = newTemp(Ity_F64);
9297
9298 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009299 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009300 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009301
9302 return "ledbr";
9303}
9304
florian55085f82012-11-21 00:36:55 +00009305static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009306s390_irgen_MEEBR(UChar r1, UChar r2)
9307{
9308 IRTemp op1 = newTemp(Ity_F32);
9309 IRTemp op2 = newTemp(Ity_F32);
9310 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009311 IRRoundingMode rounding_mode =
9312 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009313
9314 assign(op1, get_fpr_w0(r1));
9315 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009316 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009317 mkexpr(op2)));
9318 put_fpr_w0(r1, mkexpr(result));
9319
9320 return "meebr";
9321}
9322
florian55085f82012-11-21 00:36:55 +00009323static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009324s390_irgen_MDBR(UChar r1, UChar r2)
9325{
9326 IRTemp op1 = newTemp(Ity_F64);
9327 IRTemp op2 = newTemp(Ity_F64);
9328 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009329 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009330
9331 assign(op1, get_fpr_dw0(r1));
9332 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009333 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009334 mkexpr(op2)));
9335 put_fpr_dw0(r1, mkexpr(result));
9336
9337 return "mdbr";
9338}
9339
florian55085f82012-11-21 00:36:55 +00009340static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009341s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9342{
9343 IRTemp op1 = newTemp(Ity_F32);
9344 IRTemp op2 = newTemp(Ity_F32);
9345 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009346 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009347
9348 assign(op1, get_fpr_w0(r1));
9349 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009350 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009351 mkexpr(op2)));
9352 put_fpr_w0(r1, mkexpr(result));
9353
9354 return "meeb";
9355}
9356
florian55085f82012-11-21 00:36:55 +00009357static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009358s390_irgen_MDB(UChar r1, IRTemp op2addr)
9359{
9360 IRTemp op1 = newTemp(Ity_F64);
9361 IRTemp op2 = newTemp(Ity_F64);
9362 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009363 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009364
9365 assign(op1, get_fpr_dw0(r1));
9366 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009367 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009368 mkexpr(op2)));
9369 put_fpr_dw0(r1, mkexpr(result));
9370
9371 return "mdb";
9372}
9373
florian55085f82012-11-21 00:36:55 +00009374static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009375s390_irgen_SEBR(UChar r1, UChar r2)
9376{
9377 IRTemp op1 = newTemp(Ity_F32);
9378 IRTemp op2 = newTemp(Ity_F32);
9379 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009380 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009381
9382 assign(op1, get_fpr_w0(r1));
9383 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009384 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009385 mkexpr(op2)));
9386 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9387 put_fpr_w0(r1, mkexpr(result));
9388
9389 return "sebr";
9390}
9391
florian55085f82012-11-21 00:36:55 +00009392static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009393s390_irgen_SDBR(UChar r1, UChar r2)
9394{
9395 IRTemp op1 = newTemp(Ity_F64);
9396 IRTemp op2 = newTemp(Ity_F64);
9397 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009398 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009399
9400 assign(op1, get_fpr_dw0(r1));
9401 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009402 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009403 mkexpr(op2)));
9404 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9405 put_fpr_dw0(r1, mkexpr(result));
9406
9407 return "sdbr";
9408}
9409
florian55085f82012-11-21 00:36:55 +00009410static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009411s390_irgen_SEB(UChar r1, IRTemp op2addr)
9412{
9413 IRTemp op1 = newTemp(Ity_F32);
9414 IRTemp op2 = newTemp(Ity_F32);
9415 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009416 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009417
9418 assign(op1, get_fpr_w0(r1));
9419 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009420 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009421 mkexpr(op2)));
9422 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9423 put_fpr_w0(r1, mkexpr(result));
9424
9425 return "seb";
9426}
9427
florian55085f82012-11-21 00:36:55 +00009428static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009429s390_irgen_SDB(UChar r1, IRTemp op2addr)
9430{
9431 IRTemp op1 = newTemp(Ity_F64);
9432 IRTemp op2 = newTemp(Ity_F64);
9433 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009434 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009435
9436 assign(op1, get_fpr_dw0(r1));
9437 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009438 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009439 mkexpr(op2)));
9440 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9441 put_fpr_dw0(r1, mkexpr(result));
9442
9443 return "sdb";
9444}
9445
florian55085f82012-11-21 00:36:55 +00009446static const HChar *
florian12390202012-11-10 22:34:14 +00009447s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9448{
9449 IRTemp op1 = newTemp(Ity_D64);
9450 IRTemp op2 = newTemp(Ity_D64);
9451 IRTemp result = newTemp(Ity_D64);
9452 IRTemp rounding_mode;
9453
9454 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009455
9456 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9457 emulation_warning(EmWarn_S390X_fpext_rounding);
9458 m4 = S390_DFP_ROUND_PER_FPC_0;
9459 }
9460
florian12390202012-11-10 22:34:14 +00009461 rounding_mode = encode_dfp_rounding_mode(m4);
9462 assign(op1, get_dpr_dw0(r2));
9463 assign(op2, get_dpr_dw0(r3));
9464 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9465 mkexpr(op2)));
9466 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9467 put_dpr_dw0(r1, mkexpr(result));
9468
9469 return (m4 == 0) ? "adtr" : "adtra";
9470}
9471
florian55085f82012-11-21 00:36:55 +00009472static const HChar *
floriane38f6412012-12-21 17:32:12 +00009473s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9474{
9475 IRTemp op1 = newTemp(Ity_D128);
9476 IRTemp op2 = newTemp(Ity_D128);
9477 IRTemp result = newTemp(Ity_D128);
9478 IRTemp rounding_mode;
9479
9480 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009481
9482 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9483 emulation_warning(EmWarn_S390X_fpext_rounding);
9484 m4 = S390_DFP_ROUND_PER_FPC_0;
9485 }
9486
floriane38f6412012-12-21 17:32:12 +00009487 rounding_mode = encode_dfp_rounding_mode(m4);
9488 assign(op1, get_dpr_pair(r2));
9489 assign(op2, get_dpr_pair(r3));
9490 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9491 mkexpr(op2)));
9492 put_dpr_pair(r1, mkexpr(result));
9493
9494 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9495
9496 return (m4 == 0) ? "axtr" : "axtra";
9497}
9498
9499static const HChar *
9500s390_irgen_CDTR(UChar r1, UChar r2)
9501{
9502 IRTemp op1 = newTemp(Ity_D64);
9503 IRTemp op2 = newTemp(Ity_D64);
9504 IRTemp cc_vex = newTemp(Ity_I32);
9505 IRTemp cc_s390 = newTemp(Ity_I32);
9506
9507 assign(op1, get_dpr_dw0(r1));
9508 assign(op2, get_dpr_dw0(r2));
9509 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9510
florian2d3d87f2012-12-21 21:05:17 +00009511 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009512 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9513
9514 return "cdtr";
9515}
9516
9517static const HChar *
9518s390_irgen_CXTR(UChar r1, UChar r2)
9519{
9520 IRTemp op1 = newTemp(Ity_D128);
9521 IRTemp op2 = newTemp(Ity_D128);
9522 IRTemp cc_vex = newTemp(Ity_I32);
9523 IRTemp cc_s390 = newTemp(Ity_I32);
9524
9525 assign(op1, get_dpr_pair(r1));
9526 assign(op2, get_dpr_pair(r2));
9527 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9528
florian2d3d87f2012-12-21 21:05:17 +00009529 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009530 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9531
9532 return "cxtr";
9533}
9534
9535static const HChar *
florian5f034622013-01-13 02:29:05 +00009536s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9537 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9538{
9539 vassert(s390_host_has_dfp);
9540
9541 if (! s390_host_has_fpext) {
9542 emulation_failure(EmFail_S390X_fpext);
9543 } else {
9544 IRTemp op2 = newTemp(Ity_I32);
9545
9546 assign(op2, get_gpr_w1(r2));
9547 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9548 }
9549 return "cdftr";
9550}
9551
9552static const HChar *
9553s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9554 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9555{
9556 vassert(s390_host_has_dfp);
9557
9558 if (! s390_host_has_fpext) {
9559 emulation_failure(EmFail_S390X_fpext);
9560 } else {
9561 IRTemp op2 = newTemp(Ity_I32);
9562
9563 assign(op2, get_gpr_w1(r2));
9564 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9565 }
9566 return "cxftr";
9567}
9568
9569static const HChar *
floriana887acd2013-02-08 23:32:54 +00009570s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9571 UChar r1, UChar r2)
9572{
9573 IRTemp op2 = newTemp(Ity_I64);
9574
9575 vassert(s390_host_has_dfp);
9576 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9577 emulation_warning(EmWarn_S390X_fpext_rounding);
9578 m3 = S390_DFP_ROUND_PER_FPC_0;
9579 }
9580
9581 assign(op2, get_gpr_dw0(r2));
9582 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9583 mkexpr(op2)));
9584
9585 return (m3 == 0) ? "cdgtr" : "cdgtra";
9586}
9587
9588static const HChar *
9589s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9590 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9591{
9592 IRTemp op2 = newTemp(Ity_I64);
9593
9594 vassert(s390_host_has_dfp);
9595
florian1bb7f6f2013-02-11 00:03:27 +00009596 /* No emulation warning here about an non-zero m3 on hosts without
9597 floating point extension facility. No rounding is performed */
9598
floriana887acd2013-02-08 23:32:54 +00009599 assign(op2, get_gpr_dw0(r2));
9600 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9601
9602 return "cxgtr";
9603}
9604
9605static const HChar *
florian5f034622013-01-13 02:29:05 +00009606s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9607 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9608{
9609 vassert(s390_host_has_dfp);
9610
9611 if (! s390_host_has_fpext) {
9612 emulation_failure(EmFail_S390X_fpext);
9613 } else {
9614 IRTemp op2 = newTemp(Ity_I32);
9615
9616 assign(op2, get_gpr_w1(r2));
9617 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9618 }
9619 return "cdlftr";
9620}
9621
9622static const HChar *
9623s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9624 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9625{
9626 vassert(s390_host_has_dfp);
9627
9628 if (! s390_host_has_fpext) {
9629 emulation_failure(EmFail_S390X_fpext);
9630 } else {
9631 IRTemp op2 = newTemp(Ity_I32);
9632
9633 assign(op2, get_gpr_w1(r2));
9634 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9635 }
9636 return "cxlftr";
9637}
9638
9639static const HChar *
9640s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9641 UChar r1, UChar r2)
9642{
9643 vassert(s390_host_has_dfp);
9644
9645 if (! s390_host_has_fpext) {
9646 emulation_failure(EmFail_S390X_fpext);
9647 } else {
9648 IRTemp op2 = newTemp(Ity_I64);
9649
9650 assign(op2, get_gpr_dw0(r2));
9651 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9652 mkexpr(encode_dfp_rounding_mode(m3)),
9653 mkexpr(op2)));
9654 }
9655 return "cdlgtr";
9656}
9657
9658static const HChar *
9659s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9660 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9661{
9662 vassert(s390_host_has_dfp);
9663
9664 if (! s390_host_has_fpext) {
9665 emulation_failure(EmFail_S390X_fpext);
9666 } else {
9667 IRTemp op2 = newTemp(Ity_I64);
9668
9669 assign(op2, get_gpr_dw0(r2));
9670 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9671 }
9672 return "cxlgtr";
9673}
9674
9675static const HChar *
9676s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9677 UChar r1, UChar r2)
9678{
9679 vassert(s390_host_has_dfp);
9680
9681 if (! s390_host_has_fpext) {
9682 emulation_failure(EmFail_S390X_fpext);
9683 } else {
9684 IRTemp op = newTemp(Ity_D64);
9685 IRTemp result = newTemp(Ity_I32);
9686 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9687
9688 assign(op, get_dpr_dw0(r2));
9689 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9690 mkexpr(op)));
9691 put_gpr_w1(r1, mkexpr(result));
9692 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9693 }
9694 return "cfdtr";
9695}
9696
9697static const HChar *
9698s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9699 UChar r1, UChar r2)
9700{
9701 vassert(s390_host_has_dfp);
9702
9703 if (! s390_host_has_fpext) {
9704 emulation_failure(EmFail_S390X_fpext);
9705 } else {
9706 IRTemp op = newTemp(Ity_D128);
9707 IRTemp result = newTemp(Ity_I32);
9708 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9709
9710 assign(op, get_dpr_pair(r2));
9711 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9712 mkexpr(op)));
9713 put_gpr_w1(r1, mkexpr(result));
9714 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9715 }
9716 return "cfxtr";
9717}
9718
9719static const HChar *
floriana887acd2013-02-08 23:32:54 +00009720s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9721 UChar r1, UChar r2)
9722{
9723 IRTemp op = newTemp(Ity_D64);
9724 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9725
9726 vassert(s390_host_has_dfp);
9727
9728 /* If fpext is not installed and m3 is in 1:7,
9729 rounding mode performed is unpredictable */
9730 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9731 emulation_warning(EmWarn_S390X_fpext_rounding);
9732 m3 = S390_DFP_ROUND_PER_FPC_0;
9733 }
9734
9735 assign(op, get_dpr_dw0(r2));
9736 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9737 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9738
9739 return "cgdtr";
9740}
9741
9742static const HChar *
9743s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9744 UChar r1, UChar r2)
9745{
9746 IRTemp op = newTemp(Ity_D128);
9747 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9748
9749 vassert(s390_host_has_dfp);
9750
9751 /* If fpext is not installed and m3 is in 1:7,
9752 rounding mode performed is unpredictable */
9753 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9754 emulation_warning(EmWarn_S390X_fpext_rounding);
9755 m3 = S390_DFP_ROUND_PER_FPC_0;
9756 }
9757 assign(op, get_dpr_pair(r2));
9758 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9759 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9760
9761 return "cgxtr";
9762}
9763
9764static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009765s390_irgen_CEDTR(UChar r1, UChar r2)
9766{
9767 IRTemp op1 = newTemp(Ity_D64);
9768 IRTemp op2 = newTemp(Ity_D64);
9769 IRTemp cc_vex = newTemp(Ity_I32);
9770 IRTemp cc_s390 = newTemp(Ity_I32);
9771
9772 vassert(s390_host_has_dfp);
9773 assign(op1, get_dpr_dw0(r1));
9774 assign(op2, get_dpr_dw0(r2));
9775 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9776
9777 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9778 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9779
9780 return "cedtr";
9781}
9782
9783static const HChar *
9784s390_irgen_CEXTR(UChar r1, UChar r2)
9785{
9786 IRTemp op1 = newTemp(Ity_D128);
9787 IRTemp op2 = newTemp(Ity_D128);
9788 IRTemp cc_vex = newTemp(Ity_I32);
9789 IRTemp cc_s390 = newTemp(Ity_I32);
9790
9791 vassert(s390_host_has_dfp);
9792 assign(op1, get_dpr_pair(r1));
9793 assign(op2, get_dpr_pair(r2));
9794 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9795
9796 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9797 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9798
9799 return "cextr";
9800}
9801
9802static const HChar *
florian5f034622013-01-13 02:29:05 +00009803s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9804 UChar r1, UChar r2)
9805{
9806 vassert(s390_host_has_dfp);
9807
9808 if (! s390_host_has_fpext) {
9809 emulation_failure(EmFail_S390X_fpext);
9810 } else {
9811 IRTemp op = newTemp(Ity_D64);
9812 IRTemp result = newTemp(Ity_I32);
9813 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9814
9815 assign(op, get_dpr_dw0(r2));
9816 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9817 mkexpr(op)));
9818 put_gpr_w1(r1, mkexpr(result));
9819 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9820 }
9821 return "clfdtr";
9822}
9823
9824static const HChar *
9825s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9826 UChar r1, UChar r2)
9827{
9828 vassert(s390_host_has_dfp);
9829
9830 if (! s390_host_has_fpext) {
9831 emulation_failure(EmFail_S390X_fpext);
9832 } else {
9833 IRTemp op = newTemp(Ity_D128);
9834 IRTemp result = newTemp(Ity_I32);
9835 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9836
9837 assign(op, get_dpr_pair(r2));
9838 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9839 mkexpr(op)));
9840 put_gpr_w1(r1, mkexpr(result));
9841 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9842 }
9843 return "clfxtr";
9844}
9845
9846static const HChar *
9847s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9848 UChar r1, UChar r2)
9849{
9850 vassert(s390_host_has_dfp);
9851
9852 if (! s390_host_has_fpext) {
9853 emulation_failure(EmFail_S390X_fpext);
9854 } else {
9855 IRTemp op = newTemp(Ity_D64);
9856 IRTemp result = newTemp(Ity_I64);
9857 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9858
9859 assign(op, get_dpr_dw0(r2));
9860 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
9861 mkexpr(op)));
9862 put_gpr_dw0(r1, mkexpr(result));
9863 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
9864 }
9865 return "clgdtr";
9866}
9867
9868static const HChar *
9869s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
9870 UChar r1, UChar r2)
9871{
9872 vassert(s390_host_has_dfp);
9873
9874 if (! s390_host_has_fpext) {
9875 emulation_failure(EmFail_S390X_fpext);
9876 } else {
9877 IRTemp op = newTemp(Ity_D128);
9878 IRTemp result = newTemp(Ity_I64);
9879 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9880
9881 assign(op, get_dpr_pair(r2));
9882 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
9883 mkexpr(op)));
9884 put_gpr_dw0(r1, mkexpr(result));
9885 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
9886 rounding_mode);
9887 }
9888 return "clgxtr";
9889}
9890
9891static const HChar *
florian12390202012-11-10 22:34:14 +00009892s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9893{
9894 IRTemp op1 = newTemp(Ity_D64);
9895 IRTemp op2 = newTemp(Ity_D64);
9896 IRTemp result = newTemp(Ity_D64);
9897 IRTemp rounding_mode;
9898
9899 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009900
9901 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9902 emulation_warning(EmWarn_S390X_fpext_rounding);
9903 m4 = S390_DFP_ROUND_PER_FPC_0;
9904 }
9905
florian12390202012-11-10 22:34:14 +00009906 rounding_mode = encode_dfp_rounding_mode(m4);
9907 assign(op1, get_dpr_dw0(r2));
9908 assign(op2, get_dpr_dw0(r3));
9909 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9910 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009911 put_dpr_dw0(r1, mkexpr(result));
9912
9913 return (m4 == 0) ? "ddtr" : "ddtra";
9914}
9915
florian55085f82012-11-21 00:36:55 +00009916static const HChar *
floriane38f6412012-12-21 17:32:12 +00009917s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9918{
9919 IRTemp op1 = newTemp(Ity_D128);
9920 IRTemp op2 = newTemp(Ity_D128);
9921 IRTemp result = newTemp(Ity_D128);
9922 IRTemp rounding_mode;
9923
9924 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009925
9926 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9927 emulation_warning(EmWarn_S390X_fpext_rounding);
9928 m4 = S390_DFP_ROUND_PER_FPC_0;
9929 }
9930
floriane38f6412012-12-21 17:32:12 +00009931 rounding_mode = encode_dfp_rounding_mode(m4);
9932 assign(op1, get_dpr_pair(r2));
9933 assign(op2, get_dpr_pair(r3));
9934 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9935 mkexpr(op2)));
9936 put_dpr_pair(r1, mkexpr(result));
9937
9938 return (m4 == 0) ? "dxtr" : "dxtra";
9939}
9940
9941static const HChar *
florian5c539732013-02-14 14:27:12 +00009942s390_irgen_EEDTR(UChar r1, UChar r2)
9943{
9944 vassert(s390_host_has_dfp);
9945
9946 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
9947 return "eedtr";
9948}
9949
9950static const HChar *
9951s390_irgen_EEXTR(UChar r1, UChar r2)
9952{
9953 vassert(s390_host_has_dfp);
9954
9955 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
9956 return "eextr";
9957}
9958
9959static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009960s390_irgen_ESDTR(UChar r1, UChar r2)
9961{
9962 vassert(s390_host_has_dfp);
9963 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
9964 return "esdtr";
9965}
9966
9967static const HChar *
9968s390_irgen_ESXTR(UChar r1, UChar r2)
9969{
9970 vassert(s390_host_has_dfp);
9971 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
9972 return "esxtr";
9973}
9974
9975static const HChar *
florian5c539732013-02-14 14:27:12 +00009976s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
9977{
9978 IRTemp op1 = newTemp(Ity_I64);
9979 IRTemp op2 = newTemp(Ity_D64);
9980 IRTemp result = newTemp(Ity_D64);
9981
9982 vassert(s390_host_has_dfp);
9983
9984 assign(op1, get_gpr_dw0(r2));
9985 assign(op2, get_dpr_dw0(r3));
9986 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
9987 put_dpr_dw0(r1, mkexpr(result));
9988
9989 return "iedtr";
9990}
9991
9992static const HChar *
9993s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
9994{
9995 IRTemp op1 = newTemp(Ity_I64);
9996 IRTemp op2 = newTemp(Ity_D128);
9997 IRTemp result = newTemp(Ity_D128);
9998
9999 vassert(s390_host_has_dfp);
10000
10001 assign(op1, get_gpr_dw0(r2));
10002 assign(op2, get_dpr_pair(r3));
10003 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10004 put_dpr_pair(r1, mkexpr(result));
10005
10006 return "iextr";
10007}
10008
10009static const HChar *
floriane38f6412012-12-21 17:32:12 +000010010s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10011{
10012 IRTemp op = newTemp(Ity_D32);
10013
10014 vassert(s390_host_has_dfp);
10015
10016 assign(op, get_dpr_w0(r2));
10017 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10018
10019 return "ldetr";
10020}
10021
10022static const HChar *
10023s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10024{
10025 IRTemp op = newTemp(Ity_D64);
10026
10027 assign(op, get_dpr_dw0(r2));
10028 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10029
10030 return "lxdtr";
10031}
10032
10033static const HChar *
10034s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10035 UChar r1, UChar r2)
10036{
10037 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010038
10039 /* If fpext is not installed and m3 is in 1:7,
10040 rounding mode performed is unpredictable */
10041 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010042 emulation_warning(EmWarn_S390X_fpext_rounding);
10043 m3 = S390_DFP_ROUND_PER_FPC_0;
10044 }
10045 IRTemp result = newTemp(Ity_D64);
10046
10047 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10048 get_dpr_pair(r2)));
10049 put_dpr_dw0(r1, mkexpr(result));
10050
10051 return "ldxtr";
10052}
10053
10054static const HChar *
10055s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10056 UChar r1, UChar r2)
10057{
10058 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010059
10060 /* If fpext is not installed and m3 is in 1:7,
10061 rounding mode performed is unpredictable */
10062 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010063 emulation_warning(EmWarn_S390X_fpext_rounding);
10064 m3 = S390_DFP_ROUND_PER_FPC_0;
10065 }
10066 IRTemp op = newTemp(Ity_D64);
10067
10068 assign(op, get_dpr_dw0(r2));
10069 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10070 mkexpr(op)));
10071
10072 return "ledtr";
10073}
10074
10075static const HChar *
10076s390_irgen_LTDTR(UChar r1, UChar r2)
10077{
10078 IRTemp result = newTemp(Ity_D64);
10079
10080 assign(result, get_dpr_dw0(r2));
10081 put_dpr_dw0(r1, mkexpr(result));
10082 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10083
10084 return "ltdtr";
10085}
10086
10087static const HChar *
10088s390_irgen_LTXTR(UChar r1, UChar r2)
10089{
10090 IRTemp result = newTemp(Ity_D128);
10091
10092 assign(result, get_dpr_pair(r2));
10093 put_dpr_pair(r1, mkexpr(result));
10094 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10095
10096 return "ltxtr";
10097}
10098
10099static const HChar *
florian12390202012-11-10 22:34:14 +000010100s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10101{
10102 IRTemp op1 = newTemp(Ity_D64);
10103 IRTemp op2 = newTemp(Ity_D64);
10104 IRTemp result = newTemp(Ity_D64);
10105 IRTemp rounding_mode;
10106
10107 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010108
10109 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10110 emulation_warning(EmWarn_S390X_fpext_rounding);
10111 m4 = S390_DFP_ROUND_PER_FPC_0;
10112 }
10113
florian12390202012-11-10 22:34:14 +000010114 rounding_mode = encode_dfp_rounding_mode(m4);
10115 assign(op1, get_dpr_dw0(r2));
10116 assign(op2, get_dpr_dw0(r3));
10117 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10118 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010119 put_dpr_dw0(r1, mkexpr(result));
10120
10121 return (m4 == 0) ? "mdtr" : "mdtra";
10122}
10123
florian55085f82012-11-21 00:36:55 +000010124static const HChar *
floriane38f6412012-12-21 17:32:12 +000010125s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10126{
10127 IRTemp op1 = newTemp(Ity_D128);
10128 IRTemp op2 = newTemp(Ity_D128);
10129 IRTemp result = newTemp(Ity_D128);
10130 IRTemp rounding_mode;
10131
10132 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010133
10134 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10135 emulation_warning(EmWarn_S390X_fpext_rounding);
10136 m4 = S390_DFP_ROUND_PER_FPC_0;
10137 }
10138
floriane38f6412012-12-21 17:32:12 +000010139 rounding_mode = encode_dfp_rounding_mode(m4);
10140 assign(op1, get_dpr_pair(r2));
10141 assign(op2, get_dpr_pair(r3));
10142 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10143 mkexpr(op2)));
10144 put_dpr_pair(r1, mkexpr(result));
10145
10146 return (m4 == 0) ? "mxtr" : "mxtra";
10147}
10148
10149static const HChar *
florian5c539732013-02-14 14:27:12 +000010150s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10151{
10152 IRTemp op1 = newTemp(Ity_D64);
10153 IRTemp op2 = newTemp(Ity_D64);
10154 IRTemp result = newTemp(Ity_D64);
10155 IRTemp rounding_mode;
10156
10157 vassert(s390_host_has_dfp);
10158 /* If fpext is not installed and m4 is in 1:7,
10159 rounding mode performed is unpredictable */
10160 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10161 emulation_warning(EmWarn_S390X_fpext_rounding);
10162 m4 = S390_DFP_ROUND_PER_FPC_0;
10163 }
10164
10165 rounding_mode = encode_dfp_rounding_mode(m4);
10166 assign(op1, get_dpr_dw0(r2));
10167 assign(op2, get_dpr_dw0(r3));
10168 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10169 mkexpr(op2)));
10170 put_dpr_dw0(r1, mkexpr(result));
10171
10172 return "qadtr";
10173}
10174
10175static const HChar *
10176s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10177{
10178 IRTemp op1 = newTemp(Ity_D128);
10179 IRTemp op2 = newTemp(Ity_D128);
10180 IRTemp result = newTemp(Ity_D128);
10181 IRTemp rounding_mode;
10182
10183 vassert(s390_host_has_dfp);
10184 /* If fpext is not installed and m4 is in 1:7,
10185 rounding mode performed is unpredictable */
10186 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10187 emulation_warning(EmWarn_S390X_fpext_rounding);
10188 m4 = S390_DFP_ROUND_PER_FPC_0;
10189 }
10190
10191 rounding_mode = encode_dfp_rounding_mode(m4);
10192 assign(op1, get_dpr_pair(r2));
10193 assign(op2, get_dpr_pair(r3));
10194 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10195 mkexpr(op2)));
10196 put_dpr_pair(r1, mkexpr(result));
10197
10198 return "qaxtr";
10199}
10200
10201static const HChar *
10202s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10203{
10204 IRTemp op1 = newTemp(Ity_I8);
10205 IRTemp op2 = newTemp(Ity_D64);
10206 IRTemp result = newTemp(Ity_D64);
10207 IRTemp rounding_mode;
10208
10209 vassert(s390_host_has_dfp);
10210 /* If fpext is not installed and m4 is in 1:7,
10211 rounding mode performed is unpredictable */
10212 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10213 emulation_warning(EmWarn_S390X_fpext_rounding);
10214 m4 = S390_DFP_ROUND_PER_FPC_0;
10215 }
10216
10217 rounding_mode = encode_dfp_rounding_mode(m4);
10218 assign(op1, get_gpr_b7(r2));
10219 assign(op2, get_dpr_dw0(r3));
10220 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10221 mkexpr(op1), mkexpr(op2)));
10222 put_dpr_dw0(r1, mkexpr(result));
10223
10224 return "rrdtr";
10225}
10226
10227static const HChar *
10228s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10229{
10230 IRTemp op1 = newTemp(Ity_I8);
10231 IRTemp op2 = newTemp(Ity_D128);
10232 IRTemp result = newTemp(Ity_D128);
10233 IRTemp rounding_mode;
10234
10235 vassert(s390_host_has_dfp);
10236 /* If fpext is not installed and m4 is in 1:7,
10237 rounding mode performed is unpredictable */
10238 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10239 emulation_warning(EmWarn_S390X_fpext_rounding);
10240 m4 = S390_DFP_ROUND_PER_FPC_0;
10241 }
10242
10243 rounding_mode = encode_dfp_rounding_mode(m4);
10244 assign(op1, get_gpr_b7(r2));
10245 assign(op2, get_dpr_pair(r3));
10246 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10247 mkexpr(op1), mkexpr(op2)));
10248 put_dpr_pair(r1, mkexpr(result));
10249
10250 return "rrxtr";
10251}
10252
10253static const HChar *
florian12390202012-11-10 22:34:14 +000010254s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10255{
10256 IRTemp op1 = newTemp(Ity_D64);
10257 IRTemp op2 = newTemp(Ity_D64);
10258 IRTemp result = newTemp(Ity_D64);
10259 IRTemp rounding_mode;
10260
10261 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010262
10263 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10264 emulation_warning(EmWarn_S390X_fpext_rounding);
10265 m4 = S390_DFP_ROUND_PER_FPC_0;
10266 }
10267
florian12390202012-11-10 22:34:14 +000010268 rounding_mode = encode_dfp_rounding_mode(m4);
10269 assign(op1, get_dpr_dw0(r2));
10270 assign(op2, get_dpr_dw0(r3));
10271 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10272 mkexpr(op2)));
10273 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10274 put_dpr_dw0(r1, mkexpr(result));
10275
10276 return (m4 == 0) ? "sdtr" : "sdtra";
10277}
10278
floriane38f6412012-12-21 17:32:12 +000010279static const HChar *
10280s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10281{
10282 IRTemp op1 = newTemp(Ity_D128);
10283 IRTemp op2 = newTemp(Ity_D128);
10284 IRTemp result = newTemp(Ity_D128);
10285 IRTemp rounding_mode;
10286
10287 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010288
10289 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10290 emulation_warning(EmWarn_S390X_fpext_rounding);
10291 m4 = S390_DFP_ROUND_PER_FPC_0;
10292 }
10293
floriane38f6412012-12-21 17:32:12 +000010294 rounding_mode = encode_dfp_rounding_mode(m4);
10295 assign(op1, get_dpr_pair(r2));
10296 assign(op2, get_dpr_pair(r3));
10297 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10298 mkexpr(op2)));
10299 put_dpr_pair(r1, mkexpr(result));
10300
10301 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10302
10303 return (m4 == 0) ? "sxtr" : "sxtra";
10304}
sewardj2019a972011-03-07 16:04:07 +000010305
florian55085f82012-11-21 00:36:55 +000010306static const HChar *
florian1b901d42013-01-01 22:19:24 +000010307s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10308{
10309 IRTemp op = newTemp(Ity_D64);
10310
10311 vassert(s390_host_has_dfp);
10312
10313 assign(op, get_dpr_dw0(r3));
10314 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
10315 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10316
10317 return "sldt";
10318}
10319
10320static const HChar *
10321s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10322{
10323 IRTemp op = newTemp(Ity_D128);
10324
10325 vassert(s390_host_has_dfp);
10326
10327 assign(op, get_dpr_pair(r3));
10328 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
10329 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10330
10331 return "slxt";
10332}
10333
10334static const HChar *
10335s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10336{
10337 IRTemp op = newTemp(Ity_D64);
10338
10339 vassert(s390_host_has_dfp);
10340
10341 assign(op, get_dpr_dw0(r3));
10342 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
10343 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10344
10345 return "srdt";
10346}
10347
10348static const HChar *
10349s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10350{
10351 IRTemp op = newTemp(Ity_D128);
10352
10353 vassert(s390_host_has_dfp);
10354
10355 assign(op, get_dpr_pair(r3));
10356 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
10357 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10358
10359 return "srxt";
10360}
10361
10362static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010363s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10364{
10365 IRTemp value = newTemp(Ity_D32);
10366
10367 vassert(s390_host_has_dfp);
10368 assign(value, get_dpr_w0(r1));
10369
10370 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10371
10372 return "tdcet";
10373}
10374
10375static const HChar *
10376s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10377{
10378 IRTemp value = newTemp(Ity_D64);
10379
10380 vassert(s390_host_has_dfp);
10381 assign(value, get_dpr_dw0(r1));
10382
10383 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10384
10385 return "tdcdt";
10386}
10387
10388static const HChar *
10389s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10390{
10391 IRTemp value = newTemp(Ity_D128);
10392
10393 vassert(s390_host_has_dfp);
10394 assign(value, get_dpr_pair(r1));
10395
10396 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10397
10398 return "tdcxt";
10399}
10400
10401static const HChar *
10402s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10403{
10404 IRTemp value = newTemp(Ity_D32);
10405
10406 vassert(s390_host_has_dfp);
10407 assign(value, get_dpr_w0(r1));
10408
10409 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10410
10411 return "tdget";
10412}
10413
10414static const HChar *
10415s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10416{
10417 IRTemp value = newTemp(Ity_D64);
10418
10419 vassert(s390_host_has_dfp);
10420 assign(value, get_dpr_dw0(r1));
10421
10422 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10423
10424 return "tdgdt";
10425}
10426
10427static const HChar *
10428s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10429{
10430 IRTemp value = newTemp(Ity_D128);
10431
10432 vassert(s390_host_has_dfp);
10433 assign(value, get_dpr_pair(r1));
10434
10435 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10436
10437 return "tdgxt";
10438}
10439
10440static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010441s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10442{
florian79e839e2012-05-05 02:20:30 +000010443 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010444
florian79e839e2012-05-05 02:20:30 +000010445 assign(len, mkU64(length));
10446 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010447
10448 return "clc";
10449}
10450
florian55085f82012-11-21 00:36:55 +000010451static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010452s390_irgen_CLCL(UChar r1, UChar r2)
10453{
10454 IRTemp addr1 = newTemp(Ity_I64);
10455 IRTemp addr2 = newTemp(Ity_I64);
10456 IRTemp addr1_load = newTemp(Ity_I64);
10457 IRTemp addr2_load = newTemp(Ity_I64);
10458 IRTemp len1 = newTemp(Ity_I32);
10459 IRTemp len2 = newTemp(Ity_I32);
10460 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10461 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10462 IRTemp single1 = newTemp(Ity_I8);
10463 IRTemp single2 = newTemp(Ity_I8);
10464 IRTemp pad = newTemp(Ity_I8);
10465
10466 assign(addr1, get_gpr_dw0(r1));
10467 assign(r1p1, get_gpr_w1(r1 + 1));
10468 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10469 assign(addr2, get_gpr_dw0(r2));
10470 assign(r2p1, get_gpr_w1(r2 + 1));
10471 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10472 assign(pad, get_gpr_b4(r2 + 1));
10473
10474 /* len1 == 0 and len2 == 0? Exit */
10475 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010476 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10477 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010478
10479 /* Because mkite evaluates both the then-clause and the else-clause
10480 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10481 may be NULL and loading from there would segfault. So we provide a
10482 valid dummy address in that case. Loading from there does no harm and
10483 the value will be discarded at runtime. */
10484 assign(addr1_load,
10485 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10486 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10487 assign(single1,
10488 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10489 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10490
10491 assign(addr2_load,
10492 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10493 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10494 assign(single2,
10495 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10496 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10497
10498 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10499 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010500 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010501
10502 /* Update len1 and addr1, unless len1 == 0. */
10503 put_gpr_dw0(r1,
10504 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10505 mkexpr(addr1),
10506 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10507
10508 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10509 put_gpr_w1(r1 + 1,
10510 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10511 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10512 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10513
10514 /* Update len2 and addr2, unless len2 == 0. */
10515 put_gpr_dw0(r2,
10516 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10517 mkexpr(addr2),
10518 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10519
10520 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10521 put_gpr_w1(r2 + 1,
10522 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10523 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10524 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10525
florian6820ba52012-07-26 02:01:50 +000010526 iterate();
florianb0c9a132011-09-08 15:37:39 +000010527
10528 return "clcl";
10529}
10530
florian55085f82012-11-21 00:36:55 +000010531static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010532s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10533{
10534 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10535
10536 addr1 = newTemp(Ity_I64);
10537 addr3 = newTemp(Ity_I64);
10538 addr1_load = newTemp(Ity_I64);
10539 addr3_load = newTemp(Ity_I64);
10540 len1 = newTemp(Ity_I64);
10541 len3 = newTemp(Ity_I64);
10542 single1 = newTemp(Ity_I8);
10543 single3 = newTemp(Ity_I8);
10544
10545 assign(addr1, get_gpr_dw0(r1));
10546 assign(len1, get_gpr_dw0(r1 + 1));
10547 assign(addr3, get_gpr_dw0(r3));
10548 assign(len3, get_gpr_dw0(r3 + 1));
10549
10550 /* len1 == 0 and len3 == 0? Exit */
10551 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010552 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10553 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010554
10555 /* A mux requires both ways to be possible. This is a way to prevent clcle
10556 from reading from addr1 if it should read from the pad. Since the pad
10557 has no address, just read from the instruction, we discard that anyway */
10558 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010559 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10560 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010561
10562 /* same for addr3 */
10563 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010564 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10565 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010566
10567 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010568 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10569 unop(Iop_64to8, mkexpr(pad2)),
10570 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010571
10572 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010573 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10574 unop(Iop_64to8, mkexpr(pad2)),
10575 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010576
10577 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10578 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010579 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010580
10581 /* If a length in 0 we must not change this length and the address */
10582 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010583 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10584 mkexpr(addr1),
10585 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010586
10587 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010588 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10589 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010590
10591 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010592 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10593 mkexpr(addr3),
10594 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010595
10596 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010597 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10598 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010599
florian6820ba52012-07-26 02:01:50 +000010600 iterate();
sewardj2019a972011-03-07 16:04:07 +000010601
10602 return "clcle";
10603}
floriana64c2432011-07-16 02:11:50 +000010604
florianb0bf6602012-05-05 00:01:16 +000010605
sewardj2019a972011-03-07 16:04:07 +000010606static void
10607s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10608{
florianb0bf6602012-05-05 00:01:16 +000010609 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10610}
sewardj2019a972011-03-07 16:04:07 +000010611
sewardj2019a972011-03-07 16:04:07 +000010612
florianb0bf6602012-05-05 00:01:16 +000010613static void
10614s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10615{
10616 s390_irgen_xonc(Iop_And8, length, start1, start2);
10617}
sewardj2019a972011-03-07 16:04:07 +000010618
sewardj2019a972011-03-07 16:04:07 +000010619
florianb0bf6602012-05-05 00:01:16 +000010620static void
10621s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10622{
10623 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010624}
10625
10626
10627static void
10628s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10629{
10630 IRTemp current1 = newTemp(Ity_I8);
10631 IRTemp current2 = newTemp(Ity_I8);
10632 IRTemp counter = newTemp(Ity_I64);
10633
10634 assign(counter, get_counter_dw0());
10635 put_counter_dw0(mkU64(0));
10636
10637 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10638 mkexpr(counter))));
10639 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10640 mkexpr(counter))));
10641 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10642 False);
10643
10644 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010645 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010646
10647 /* Check for end of field */
10648 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010649 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010650 put_counter_dw0(mkU64(0));
10651}
10652
10653static void
10654s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10655{
10656 IRTemp counter = newTemp(Ity_I64);
10657
10658 assign(counter, get_counter_dw0());
10659
10660 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10661 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10662
10663 /* Check for end of field */
10664 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010665 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010666 put_counter_dw0(mkU64(0));
10667}
10668
florianf87d4fb2012-05-05 02:55:24 +000010669static void
10670s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10671{
10672 IRTemp op = newTemp(Ity_I8);
10673 IRTemp op1 = newTemp(Ity_I8);
10674 IRTemp result = newTemp(Ity_I64);
10675 IRTemp counter = newTemp(Ity_I64);
10676
10677 assign(counter, get_counter_dw0());
10678
10679 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10680
10681 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10682
10683 assign(op1, load(Ity_I8, mkexpr(result)));
10684 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10685
10686 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010687 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010688 put_counter_dw0(mkU64(0));
10689}
sewardj2019a972011-03-07 16:04:07 +000010690
10691
10692static void
10693s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010694 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010695 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010696{
10697 struct SS {
10698 unsigned int op : 8;
10699 unsigned int l : 8;
10700 unsigned int b1 : 4;
10701 unsigned int d1 : 12;
10702 unsigned int b2 : 4;
10703 unsigned int d2 : 12;
10704 };
10705 union {
10706 struct SS dec;
10707 unsigned long bytes;
10708 } ss;
10709 IRTemp cond;
10710 IRDirty *d;
10711 IRTemp torun;
10712
10713 IRTemp start1 = newTemp(Ity_I64);
10714 IRTemp start2 = newTemp(Ity_I64);
10715 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10716 cond = newTemp(Ity_I1);
10717 torun = newTemp(Ity_I64);
10718
10719 assign(torun, load(Ity_I64, mkexpr(addr2)));
10720 /* Start with a check that the saved code is still correct */
10721 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10722 /* If not, save the new value */
10723 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10724 mkIRExprVec_1(mkexpr(torun)));
10725 d->guard = mkexpr(cond);
10726 stmt(IRStmt_Dirty(d));
10727
10728 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010729 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10730 mkU64(guest_IA_curr_instr)));
10731 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010732 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010733
10734 ss.bytes = last_execute_target;
10735 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10736 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10737 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10738 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10739 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10740 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10741 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010742
sewardj2019a972011-03-07 16:04:07 +000010743 last_execute_target = 0;
10744}
10745
florian55085f82012-11-21 00:36:55 +000010746static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010747s390_irgen_EX(UChar r1, IRTemp addr2)
10748{
10749 switch(last_execute_target & 0xff00000000000000ULL) {
10750 case 0:
10751 {
10752 /* no code information yet */
10753 IRDirty *d;
10754
10755 /* so safe the code... */
10756 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10757 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10758 stmt(IRStmt_Dirty(d));
10759 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010760 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10761 mkU64(guest_IA_curr_instr)));
10762 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010763 restart_if(IRExpr_Const(IRConst_U1(True)));
10764
sewardj2019a972011-03-07 16:04:07 +000010765 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010766 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010767 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000010768 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000010769 break;
10770 }
10771
10772 case 0xd200000000000000ULL:
10773 /* special case MVC */
10774 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010775 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010776
10777 case 0xd500000000000000ULL:
10778 /* special case CLC */
10779 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010780 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010781
10782 case 0xd700000000000000ULL:
10783 /* special case XC */
10784 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010785 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010786
florianb0bf6602012-05-05 00:01:16 +000010787 case 0xd600000000000000ULL:
10788 /* special case OC */
10789 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010790 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010791
10792 case 0xd400000000000000ULL:
10793 /* special case NC */
10794 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010795 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010796
florianf87d4fb2012-05-05 02:55:24 +000010797 case 0xdc00000000000000ULL:
10798 /* special case TR */
10799 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010800 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010801
sewardj2019a972011-03-07 16:04:07 +000010802 default:
10803 {
10804 /* everything else will get a self checking prefix that also checks the
10805 register content */
10806 IRDirty *d;
10807 UChar *bytes;
10808 IRTemp cond;
10809 IRTemp orperand;
10810 IRTemp torun;
10811
10812 cond = newTemp(Ity_I1);
10813 orperand = newTemp(Ity_I64);
10814 torun = newTemp(Ity_I64);
10815
10816 if (r1 == 0)
10817 assign(orperand, mkU64(0));
10818 else
10819 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10820 /* This code is going to be translated */
10821 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10822 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10823
10824 /* Start with a check that saved code is still correct */
10825 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10826 mkU64(last_execute_target)));
10827 /* If not, save the new value */
10828 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10829 mkIRExprVec_1(mkexpr(torun)));
10830 d->guard = mkexpr(cond);
10831 stmt(IRStmt_Dirty(d));
10832
10833 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010834 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10835 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010836 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010837
10838 /* Now comes the actual translation */
10839 bytes = (UChar *) &last_execute_target;
10840 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10841 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010842 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010843 vex_printf(" which was executed by\n");
10844 /* dont make useless translations in the next execute */
10845 last_execute_target = 0;
10846 }
10847 }
10848 return "ex";
10849}
10850
florian55085f82012-11-21 00:36:55 +000010851static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010852s390_irgen_EXRL(UChar r1, UInt offset)
10853{
10854 IRTemp addr = newTemp(Ity_I64);
10855 /* we might save one round trip because we know the target */
10856 if (!last_execute_target)
10857 last_execute_target = *(ULong *)(HWord)
10858 (guest_IA_curr_instr + offset * 2UL);
10859 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10860 s390_irgen_EX(r1, addr);
10861 return "exrl";
10862}
10863
florian55085f82012-11-21 00:36:55 +000010864static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010865s390_irgen_IPM(UChar r1)
10866{
10867 // As long as we dont support SPM, lets just assume 0 as program mask
10868 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
10869 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
10870
10871 return "ipm";
10872}
10873
10874
florian55085f82012-11-21 00:36:55 +000010875static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010876s390_irgen_SRST(UChar r1, UChar r2)
10877{
10878 IRTemp address = newTemp(Ity_I64);
10879 IRTemp next = newTemp(Ity_I64);
10880 IRTemp delim = newTemp(Ity_I8);
10881 IRTemp counter = newTemp(Ity_I64);
10882 IRTemp byte = newTemp(Ity_I8);
10883
10884 assign(address, get_gpr_dw0(r2));
10885 assign(next, get_gpr_dw0(r1));
10886
10887 assign(counter, get_counter_dw0());
10888 put_counter_dw0(mkU64(0));
10889
10890 // start = next? CC=2 and out r1 and r2 unchanged
10891 s390_cc_set(2);
10892 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010893 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000010894
10895 assign(byte, load(Ity_I8, mkexpr(address)));
10896 assign(delim, get_gpr_b7(0));
10897
10898 // byte = delim? CC=1, R1=address
10899 s390_cc_set(1);
10900 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000010901 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010902
10903 // else: all equal, no end yet, loop
10904 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10905 put_gpr_dw0(r1, mkexpr(next));
10906 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010907
florian6820ba52012-07-26 02:01:50 +000010908 iterate();
sewardj2019a972011-03-07 16:04:07 +000010909
10910 return "srst";
10911}
10912
florian55085f82012-11-21 00:36:55 +000010913static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010914s390_irgen_CLST(UChar r1, UChar r2)
10915{
10916 IRTemp address1 = newTemp(Ity_I64);
10917 IRTemp address2 = newTemp(Ity_I64);
10918 IRTemp end = newTemp(Ity_I8);
10919 IRTemp counter = newTemp(Ity_I64);
10920 IRTemp byte1 = newTemp(Ity_I8);
10921 IRTemp byte2 = newTemp(Ity_I8);
10922
10923 assign(address1, get_gpr_dw0(r1));
10924 assign(address2, get_gpr_dw0(r2));
10925 assign(end, get_gpr_b7(0));
10926 assign(counter, get_counter_dw0());
10927 put_counter_dw0(mkU64(0));
10928 assign(byte1, load(Ity_I8, mkexpr(address1)));
10929 assign(byte2, load(Ity_I8, mkexpr(address2)));
10930
10931 // end in both? all equal, reset r1 and r2 to start values
10932 s390_cc_set(0);
10933 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
10934 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010935 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10936 binop(Iop_Or8,
10937 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10938 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010939
10940 put_gpr_dw0(r1, mkexpr(address1));
10941 put_gpr_dw0(r2, mkexpr(address2));
10942
10943 // End found in string1
10944 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010945 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010946
10947 // End found in string2
10948 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010949 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010950
10951 // string1 < string2
10952 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010953 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10954 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010955
10956 // string2 < string1
10957 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010958 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10959 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010960
10961 // else: all equal, no end yet, loop
10962 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10963 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10964 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010965
florian6820ba52012-07-26 02:01:50 +000010966 iterate();
sewardj2019a972011-03-07 16:04:07 +000010967
10968 return "clst";
10969}
10970
10971static void
10972s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10973{
10974 UChar reg;
10975 IRTemp addr = newTemp(Ity_I64);
10976
10977 assign(addr, mkexpr(op2addr));
10978 reg = r1;
10979 do {
10980 IRTemp old = addr;
10981
10982 reg %= 16;
10983 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10984 addr = newTemp(Ity_I64);
10985 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10986 reg++;
10987 } while (reg != (r3 + 1));
10988}
10989
florian55085f82012-11-21 00:36:55 +000010990static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010991s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10992{
10993 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10994
10995 return "lm";
10996}
10997
florian55085f82012-11-21 00:36:55 +000010998static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010999s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11000{
11001 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11002
11003 return "lmy";
11004}
11005
florian55085f82012-11-21 00:36:55 +000011006static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011007s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11008{
11009 UChar reg;
11010 IRTemp addr = newTemp(Ity_I64);
11011
11012 assign(addr, mkexpr(op2addr));
11013 reg = r1;
11014 do {
11015 IRTemp old = addr;
11016
11017 reg %= 16;
11018 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11019 addr = newTemp(Ity_I64);
11020 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11021 reg++;
11022 } while (reg != (r3 + 1));
11023
11024 return "lmh";
11025}
11026
florian55085f82012-11-21 00:36:55 +000011027static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011028s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11029{
11030 UChar reg;
11031 IRTemp addr = newTemp(Ity_I64);
11032
11033 assign(addr, mkexpr(op2addr));
11034 reg = r1;
11035 do {
11036 IRTemp old = addr;
11037
11038 reg %= 16;
11039 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11040 addr = newTemp(Ity_I64);
11041 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11042 reg++;
11043 } while (reg != (r3 + 1));
11044
11045 return "lmg";
11046}
11047
11048static void
11049s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11050{
11051 UChar reg;
11052 IRTemp addr = newTemp(Ity_I64);
11053
11054 assign(addr, mkexpr(op2addr));
11055 reg = r1;
11056 do {
11057 IRTemp old = addr;
11058
11059 reg %= 16;
11060 store(mkexpr(addr), get_gpr_w1(reg));
11061 addr = newTemp(Ity_I64);
11062 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11063 reg++;
11064 } while( reg != (r3 + 1));
11065}
11066
florian55085f82012-11-21 00:36:55 +000011067static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011068s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11069{
11070 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11071
11072 return "stm";
11073}
11074
florian55085f82012-11-21 00:36:55 +000011075static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011076s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11077{
11078 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11079
11080 return "stmy";
11081}
11082
florian55085f82012-11-21 00:36:55 +000011083static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011084s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11085{
11086 UChar reg;
11087 IRTemp addr = newTemp(Ity_I64);
11088
11089 assign(addr, mkexpr(op2addr));
11090 reg = r1;
11091 do {
11092 IRTemp old = addr;
11093
11094 reg %= 16;
11095 store(mkexpr(addr), get_gpr_w0(reg));
11096 addr = newTemp(Ity_I64);
11097 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11098 reg++;
11099 } while( reg != (r3 + 1));
11100
11101 return "stmh";
11102}
11103
florian55085f82012-11-21 00:36:55 +000011104static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011105s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11106{
11107 UChar reg;
11108 IRTemp addr = newTemp(Ity_I64);
11109
11110 assign(addr, mkexpr(op2addr));
11111 reg = r1;
11112 do {
11113 IRTemp old = addr;
11114
11115 reg %= 16;
11116 store(mkexpr(addr), get_gpr_dw0(reg));
11117 addr = newTemp(Ity_I64);
11118 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11119 reg++;
11120 } while( reg != (r3 + 1));
11121
11122 return "stmg";
11123}
11124
11125static void
florianb0bf6602012-05-05 00:01:16 +000011126s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000011127{
11128 IRTemp old1 = newTemp(Ity_I8);
11129 IRTemp old2 = newTemp(Ity_I8);
11130 IRTemp new1 = newTemp(Ity_I8);
11131 IRTemp counter = newTemp(Ity_I32);
11132 IRTemp addr1 = newTemp(Ity_I64);
11133
11134 assign(counter, get_counter_w0());
11135
11136 assign(addr1, binop(Iop_Add64, mkexpr(start1),
11137 unop(Iop_32Uto64, mkexpr(counter))));
11138
11139 assign(old1, load(Ity_I8, mkexpr(addr1)));
11140 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11141 unop(Iop_32Uto64,mkexpr(counter)))));
11142 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11143
11144 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000011145 if (op == Iop_Xor8) {
11146 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000011147 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11148 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000011149 } else
11150 store(mkexpr(addr1), mkexpr(new1));
11151 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11152 get_counter_w1()));
11153
11154 /* Check for end of field */
11155 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011156 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000011157 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11158 False);
11159 put_counter_dw0(mkU64(0));
11160}
11161
florian55085f82012-11-21 00:36:55 +000011162static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011163s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11164{
florianb0bf6602012-05-05 00:01:16 +000011165 IRTemp len = newTemp(Ity_I32);
11166
11167 assign(len, mkU32(length));
11168 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011169
11170 return "xc";
11171}
11172
sewardjb63967e2011-03-24 08:50:04 +000011173static void
11174s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11175{
11176 IRTemp counter = newTemp(Ity_I32);
11177 IRTemp start = newTemp(Ity_I64);
11178 IRTemp addr = newTemp(Ity_I64);
11179
11180 assign(start,
11181 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11182
11183 if (length < 8) {
11184 UInt i;
11185
11186 for (i = 0; i <= length; ++i) {
11187 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11188 }
11189 } else {
11190 assign(counter, get_counter_w0());
11191
11192 assign(addr, binop(Iop_Add64, mkexpr(start),
11193 unop(Iop_32Uto64, mkexpr(counter))));
11194
11195 store(mkexpr(addr), mkU8(0));
11196
11197 /* Check for end of field */
11198 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011199 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011200
11201 /* Reset counter */
11202 put_counter_dw0(mkU64(0));
11203 }
11204
11205 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11206
sewardj7ee97522011-05-09 21:45:04 +000011207 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011208 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11209}
11210
florian55085f82012-11-21 00:36:55 +000011211static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011212s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11213{
florianb0bf6602012-05-05 00:01:16 +000011214 IRTemp len = newTemp(Ity_I32);
11215
11216 assign(len, mkU32(length));
11217 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011218
11219 return "nc";
11220}
11221
florian55085f82012-11-21 00:36:55 +000011222static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011223s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11224{
florianb0bf6602012-05-05 00:01:16 +000011225 IRTemp len = newTemp(Ity_I32);
11226
11227 assign(len, mkU32(length));
11228 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011229
11230 return "oc";
11231}
11232
11233
florian55085f82012-11-21 00:36:55 +000011234static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011235s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11236{
florian79e839e2012-05-05 02:20:30 +000011237 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011238
florian79e839e2012-05-05 02:20:30 +000011239 assign(len, mkU64(length));
11240 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011241
11242 return "mvc";
11243}
11244
florian55085f82012-11-21 00:36:55 +000011245static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011246s390_irgen_MVCL(UChar r1, UChar r2)
11247{
11248 IRTemp addr1 = newTemp(Ity_I64);
11249 IRTemp addr2 = newTemp(Ity_I64);
11250 IRTemp addr2_load = newTemp(Ity_I64);
11251 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11252 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11253 IRTemp len1 = newTemp(Ity_I32);
11254 IRTemp len2 = newTemp(Ity_I32);
11255 IRTemp pad = newTemp(Ity_I8);
11256 IRTemp single = newTemp(Ity_I8);
11257
11258 assign(addr1, get_gpr_dw0(r1));
11259 assign(r1p1, get_gpr_w1(r1 + 1));
11260 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11261 assign(addr2, get_gpr_dw0(r2));
11262 assign(r2p1, get_gpr_w1(r2 + 1));
11263 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11264 assign(pad, get_gpr_b4(r2 + 1));
11265
11266 /* len1 == 0 ? */
11267 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011268 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011269
11270 /* Check for destructive overlap:
11271 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11272 s390_cc_set(3);
11273 IRTemp cond1 = newTemp(Ity_I32);
11274 assign(cond1, unop(Iop_1Uto32,
11275 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11276 IRTemp cond2 = newTemp(Ity_I32);
11277 assign(cond2, unop(Iop_1Uto32,
11278 binop(Iop_CmpLT64U, mkexpr(addr1),
11279 binop(Iop_Add64, mkexpr(addr2),
11280 unop(Iop_32Uto64, mkexpr(len1))))));
11281 IRTemp cond3 = newTemp(Ity_I32);
11282 assign(cond3, unop(Iop_1Uto32,
11283 binop(Iop_CmpLT64U,
11284 mkexpr(addr1),
11285 binop(Iop_Add64, mkexpr(addr2),
11286 unop(Iop_32Uto64, mkexpr(len2))))));
11287
florian6820ba52012-07-26 02:01:50 +000011288 next_insn_if(binop(Iop_CmpEQ32,
11289 binop(Iop_And32,
11290 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11291 mkexpr(cond3)),
11292 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011293
11294 /* See s390_irgen_CLCL for explanation why we cannot load directly
11295 and need two steps. */
11296 assign(addr2_load,
11297 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11298 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11299 assign(single,
11300 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11301 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11302
11303 store(mkexpr(addr1), mkexpr(single));
11304
11305 /* Update addr1 and len1 */
11306 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11307 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11308
11309 /* Update addr2 and len2 */
11310 put_gpr_dw0(r2,
11311 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11312 mkexpr(addr2),
11313 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11314
11315 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11316 put_gpr_w1(r2 + 1,
11317 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11318 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11319 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11320
11321 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011322 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011323
11324 return "mvcl";
11325}
11326
11327
florian55085f82012-11-21 00:36:55 +000011328static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011329s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11330{
11331 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11332
11333 addr1 = newTemp(Ity_I64);
11334 addr3 = newTemp(Ity_I64);
11335 addr3_load = newTemp(Ity_I64);
11336 len1 = newTemp(Ity_I64);
11337 len3 = newTemp(Ity_I64);
11338 single = newTemp(Ity_I8);
11339
11340 assign(addr1, get_gpr_dw0(r1));
11341 assign(len1, get_gpr_dw0(r1 + 1));
11342 assign(addr3, get_gpr_dw0(r3));
11343 assign(len3, get_gpr_dw0(r3 + 1));
11344
11345 // len1 == 0 ?
11346 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011347 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011348
11349 /* This is a hack to prevent mvcle from reading from addr3 if it
11350 should read from the pad. Since the pad has no address, just
11351 read from the instruction, we discard that anyway */
11352 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011353 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11354 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011355
11356 assign(single,
florian6ad49522011-09-09 02:38:55 +000011357 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11358 unop(Iop_64to8, mkexpr(pad2)),
11359 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011360 store(mkexpr(addr1), mkexpr(single));
11361
11362 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11363
11364 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11365
11366 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011367 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11368 mkexpr(addr3),
11369 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011370
11371 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011372 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11373 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011374
sewardj2019a972011-03-07 16:04:07 +000011375 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011376 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011377
11378 return "mvcle";
11379}
11380
florian55085f82012-11-21 00:36:55 +000011381static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011382s390_irgen_MVST(UChar r1, UChar r2)
11383{
11384 IRTemp addr1 = newTemp(Ity_I64);
11385 IRTemp addr2 = newTemp(Ity_I64);
11386 IRTemp end = newTemp(Ity_I8);
11387 IRTemp byte = newTemp(Ity_I8);
11388 IRTemp counter = newTemp(Ity_I64);
11389
11390 assign(addr1, get_gpr_dw0(r1));
11391 assign(addr2, get_gpr_dw0(r2));
11392 assign(counter, get_counter_dw0());
11393 assign(end, get_gpr_b7(0));
11394 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11395 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11396
11397 // We use unlimited as cpu-determined number
11398 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011399 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011400
11401 // and always set cc=1 at the end + update r1
11402 s390_cc_set(1);
11403 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11404 put_counter_dw0(mkU64(0));
11405
11406 return "mvst";
11407}
11408
11409static void
11410s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11411{
11412 IRTemp op1 = newTemp(Ity_I64);
11413 IRTemp result = newTemp(Ity_I64);
11414
11415 assign(op1, binop(Iop_32HLto64,
11416 get_gpr_w1(r1), // high 32 bits
11417 get_gpr_w1(r1 + 1))); // low 32 bits
11418 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11419 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11420 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11421}
11422
11423static void
11424s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11425{
11426 IRTemp op1 = newTemp(Ity_I128);
11427 IRTemp result = newTemp(Ity_I128);
11428
11429 assign(op1, binop(Iop_64HLto128,
11430 get_gpr_dw0(r1), // high 64 bits
11431 get_gpr_dw0(r1 + 1))); // low 64 bits
11432 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11433 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11434 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11435}
11436
11437static void
11438s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11439{
11440 IRTemp op1 = newTemp(Ity_I64);
11441 IRTemp result = newTemp(Ity_I128);
11442
11443 assign(op1, get_gpr_dw0(r1 + 1));
11444 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11445 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11446 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11447}
11448
florian55085f82012-11-21 00:36:55 +000011449static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011450s390_irgen_DR(UChar r1, UChar r2)
11451{
11452 IRTemp op2 = newTemp(Ity_I32);
11453
11454 assign(op2, get_gpr_w1(r2));
11455
11456 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11457
11458 return "dr";
11459}
11460
florian55085f82012-11-21 00:36:55 +000011461static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011462s390_irgen_D(UChar r1, IRTemp op2addr)
11463{
11464 IRTemp op2 = newTemp(Ity_I32);
11465
11466 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11467
11468 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11469
11470 return "d";
11471}
11472
florian55085f82012-11-21 00:36:55 +000011473static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011474s390_irgen_DLR(UChar r1, UChar r2)
11475{
11476 IRTemp op2 = newTemp(Ity_I32);
11477
11478 assign(op2, get_gpr_w1(r2));
11479
11480 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11481
florian7cd1cde2012-08-16 23:57:43 +000011482 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011483}
11484
florian55085f82012-11-21 00:36:55 +000011485static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011486s390_irgen_DL(UChar r1, IRTemp op2addr)
11487{
11488 IRTemp op2 = newTemp(Ity_I32);
11489
11490 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11491
11492 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11493
11494 return "dl";
11495}
11496
florian55085f82012-11-21 00:36:55 +000011497static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011498s390_irgen_DLG(UChar r1, IRTemp op2addr)
11499{
11500 IRTemp op2 = newTemp(Ity_I64);
11501
11502 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11503
11504 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11505
11506 return "dlg";
11507}
11508
florian55085f82012-11-21 00:36:55 +000011509static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011510s390_irgen_DLGR(UChar r1, UChar r2)
11511{
11512 IRTemp op2 = newTemp(Ity_I64);
11513
11514 assign(op2, get_gpr_dw0(r2));
11515
11516 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11517
11518 return "dlgr";
11519}
11520
florian55085f82012-11-21 00:36:55 +000011521static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011522s390_irgen_DSGR(UChar r1, UChar r2)
11523{
11524 IRTemp op2 = newTemp(Ity_I64);
11525
11526 assign(op2, get_gpr_dw0(r2));
11527
11528 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11529
11530 return "dsgr";
11531}
11532
florian55085f82012-11-21 00:36:55 +000011533static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011534s390_irgen_DSG(UChar r1, IRTemp op2addr)
11535{
11536 IRTemp op2 = newTemp(Ity_I64);
11537
11538 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11539
11540 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11541
11542 return "dsg";
11543}
11544
florian55085f82012-11-21 00:36:55 +000011545static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011546s390_irgen_DSGFR(UChar r1, UChar r2)
11547{
11548 IRTemp op2 = newTemp(Ity_I64);
11549
11550 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11551
11552 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11553
11554 return "dsgfr";
11555}
11556
florian55085f82012-11-21 00:36:55 +000011557static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011558s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11559{
11560 IRTemp op2 = newTemp(Ity_I64);
11561
11562 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11563
11564 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11565
11566 return "dsgf";
11567}
11568
11569static void
11570s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11571{
11572 UChar reg;
11573 IRTemp addr = newTemp(Ity_I64);
11574
11575 assign(addr, mkexpr(op2addr));
11576 reg = r1;
11577 do {
11578 IRTemp old = addr;
11579
11580 reg %= 16;
11581 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11582 addr = newTemp(Ity_I64);
11583 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11584 reg++;
11585 } while (reg != (r3 + 1));
11586}
11587
florian55085f82012-11-21 00:36:55 +000011588static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011589s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11590{
11591 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11592
11593 return "lam";
11594}
11595
florian55085f82012-11-21 00:36:55 +000011596static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011597s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11598{
11599 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11600
11601 return "lamy";
11602}
11603
11604static void
11605s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11606{
11607 UChar reg;
11608 IRTemp addr = newTemp(Ity_I64);
11609
11610 assign(addr, mkexpr(op2addr));
11611 reg = r1;
11612 do {
11613 IRTemp old = addr;
11614
11615 reg %= 16;
11616 store(mkexpr(addr), get_ar_w0(reg));
11617 addr = newTemp(Ity_I64);
11618 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11619 reg++;
11620 } while (reg != (r3 + 1));
11621}
11622
florian55085f82012-11-21 00:36:55 +000011623static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011624s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11625{
11626 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11627
11628 return "stam";
11629}
11630
florian55085f82012-11-21 00:36:55 +000011631static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011632s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11633{
11634 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11635
11636 return "stamy";
11637}
11638
11639
11640/* Implementation for 32-bit compare-and-swap */
11641static void
11642s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11643{
11644 IRCAS *cas;
11645 IRTemp op1 = newTemp(Ity_I32);
11646 IRTemp old_mem = newTemp(Ity_I32);
11647 IRTemp op3 = newTemp(Ity_I32);
11648 IRTemp result = newTemp(Ity_I32);
11649 IRTemp nequal = newTemp(Ity_I1);
11650
11651 assign(op1, get_gpr_w1(r1));
11652 assign(op3, get_gpr_w1(r3));
11653
11654 /* The first and second operands are compared. If they are equal,
11655 the third operand is stored at the second- operand location. */
11656 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11657 Iend_BE, mkexpr(op2addr),
11658 NULL, mkexpr(op1), /* expected value */
11659 NULL, mkexpr(op3) /* new value */);
11660 stmt(IRStmt_CAS(cas));
11661
11662 /* Set CC. Operands compared equal -> 0, else 1. */
11663 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11664 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11665
11666 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11667 Otherwise, store the old_value from memory in r1 and yield. */
11668 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11669 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011670 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011671}
11672
florian55085f82012-11-21 00:36:55 +000011673static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011674s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11675{
11676 s390_irgen_cas_32(r1, r3, op2addr);
11677
11678 return "cs";
11679}
11680
florian55085f82012-11-21 00:36:55 +000011681static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011682s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11683{
11684 s390_irgen_cas_32(r1, r3, op2addr);
11685
11686 return "csy";
11687}
11688
florian55085f82012-11-21 00:36:55 +000011689static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011690s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11691{
11692 IRCAS *cas;
11693 IRTemp op1 = newTemp(Ity_I64);
11694 IRTemp old_mem = newTemp(Ity_I64);
11695 IRTemp op3 = newTemp(Ity_I64);
11696 IRTemp result = newTemp(Ity_I64);
11697 IRTemp nequal = newTemp(Ity_I1);
11698
11699 assign(op1, get_gpr_dw0(r1));
11700 assign(op3, get_gpr_dw0(r3));
11701
11702 /* The first and second operands are compared. If they are equal,
11703 the third operand is stored at the second- operand location. */
11704 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11705 Iend_BE, mkexpr(op2addr),
11706 NULL, mkexpr(op1), /* expected value */
11707 NULL, mkexpr(op3) /* new value */);
11708 stmt(IRStmt_CAS(cas));
11709
11710 /* Set CC. Operands compared equal -> 0, else 1. */
11711 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11712 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11713
11714 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11715 Otherwise, store the old_value from memory in r1 and yield. */
11716 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11717 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011718 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011719
11720 return "csg";
11721}
11722
florian448cbba2012-06-06 02:26:01 +000011723/* Implementation for 32-bit compare-double-and-swap */
11724static void
11725s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11726{
11727 IRCAS *cas;
11728 IRTemp op1_high = newTemp(Ity_I32);
11729 IRTemp op1_low = newTemp(Ity_I32);
11730 IRTemp old_mem_high = newTemp(Ity_I32);
11731 IRTemp old_mem_low = newTemp(Ity_I32);
11732 IRTemp op3_high = newTemp(Ity_I32);
11733 IRTemp op3_low = newTemp(Ity_I32);
11734 IRTemp result = newTemp(Ity_I32);
11735 IRTemp nequal = newTemp(Ity_I1);
11736
11737 assign(op1_high, get_gpr_w1(r1));
11738 assign(op1_low, get_gpr_w1(r1+1));
11739 assign(op3_high, get_gpr_w1(r3));
11740 assign(op3_low, get_gpr_w1(r3+1));
11741
11742 /* The first and second operands are compared. If they are equal,
11743 the third operand is stored at the second-operand location. */
11744 cas = mkIRCAS(old_mem_high, old_mem_low,
11745 Iend_BE, mkexpr(op2addr),
11746 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11747 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11748 stmt(IRStmt_CAS(cas));
11749
11750 /* Set CC. Operands compared equal -> 0, else 1. */
11751 assign(result, unop(Iop_1Uto32,
11752 binop(Iop_CmpNE32,
11753 binop(Iop_Or32,
11754 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11755 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11756 mkU32(0))));
11757
11758 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11759
11760 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11761 Otherwise, store the old_value from memory in r1 and yield. */
11762 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11763 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11764 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011765 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011766}
11767
florian55085f82012-11-21 00:36:55 +000011768static const HChar *
florian448cbba2012-06-06 02:26:01 +000011769s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11770{
11771 s390_irgen_cdas_32(r1, r3, op2addr);
11772
11773 return "cds";
11774}
11775
florian55085f82012-11-21 00:36:55 +000011776static const HChar *
florian448cbba2012-06-06 02:26:01 +000011777s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11778{
11779 s390_irgen_cdas_32(r1, r3, op2addr);
11780
11781 return "cdsy";
11782}
11783
florian55085f82012-11-21 00:36:55 +000011784static const HChar *
florian448cbba2012-06-06 02:26:01 +000011785s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11786{
11787 IRCAS *cas;
11788 IRTemp op1_high = newTemp(Ity_I64);
11789 IRTemp op1_low = newTemp(Ity_I64);
11790 IRTemp old_mem_high = newTemp(Ity_I64);
11791 IRTemp old_mem_low = newTemp(Ity_I64);
11792 IRTemp op3_high = newTemp(Ity_I64);
11793 IRTemp op3_low = newTemp(Ity_I64);
11794 IRTemp result = newTemp(Ity_I64);
11795 IRTemp nequal = newTemp(Ity_I1);
11796
11797 assign(op1_high, get_gpr_dw0(r1));
11798 assign(op1_low, get_gpr_dw0(r1+1));
11799 assign(op3_high, get_gpr_dw0(r3));
11800 assign(op3_low, get_gpr_dw0(r3+1));
11801
11802 /* The first and second operands are compared. If they are equal,
11803 the third operand is stored at the second-operand location. */
11804 cas = mkIRCAS(old_mem_high, old_mem_low,
11805 Iend_BE, mkexpr(op2addr),
11806 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11807 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11808 stmt(IRStmt_CAS(cas));
11809
11810 /* Set CC. Operands compared equal -> 0, else 1. */
11811 assign(result, unop(Iop_1Uto64,
11812 binop(Iop_CmpNE64,
11813 binop(Iop_Or64,
11814 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11815 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11816 mkU64(0))));
11817
11818 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11819
11820 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11821 Otherwise, store the old_value from memory in r1 and yield. */
11822 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11823 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11824 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011825 yield_if(mkexpr(nequal));
11826
florian448cbba2012-06-06 02:26:01 +000011827 return "cdsg";
11828}
11829
sewardj2019a972011-03-07 16:04:07 +000011830
11831/* Binary floating point */
11832
florian55085f82012-11-21 00:36:55 +000011833static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011834s390_irgen_AXBR(UChar r1, UChar r2)
11835{
11836 IRTemp op1 = newTemp(Ity_F128);
11837 IRTemp op2 = newTemp(Ity_F128);
11838 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011839 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011840
11841 assign(op1, get_fpr_pair(r1));
11842 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011843 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011844 mkexpr(op2)));
11845 put_fpr_pair(r1, mkexpr(result));
11846
11847 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11848
11849 return "axbr";
11850}
11851
florian55085f82012-11-21 00:36:55 +000011852static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011853s390_irgen_CEBR(UChar r1, UChar r2)
11854{
11855 IRTemp op1 = newTemp(Ity_F32);
11856 IRTemp op2 = newTemp(Ity_F32);
11857 IRTemp cc_vex = newTemp(Ity_I32);
11858 IRTemp cc_s390 = newTemp(Ity_I32);
11859
11860 assign(op1, get_fpr_w0(r1));
11861 assign(op2, get_fpr_w0(r2));
11862 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11863
florian2d3d87f2012-12-21 21:05:17 +000011864 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011865 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11866
11867 return "cebr";
11868}
11869
florian55085f82012-11-21 00:36:55 +000011870static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011871s390_irgen_CDBR(UChar r1, UChar r2)
11872{
11873 IRTemp op1 = newTemp(Ity_F64);
11874 IRTemp op2 = newTemp(Ity_F64);
11875 IRTemp cc_vex = newTemp(Ity_I32);
11876 IRTemp cc_s390 = newTemp(Ity_I32);
11877
11878 assign(op1, get_fpr_dw0(r1));
11879 assign(op2, get_fpr_dw0(r2));
11880 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11881
florian2d3d87f2012-12-21 21:05:17 +000011882 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011883 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11884
11885 return "cdbr";
11886}
11887
florian55085f82012-11-21 00:36:55 +000011888static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011889s390_irgen_CXBR(UChar r1, UChar r2)
11890{
11891 IRTemp op1 = newTemp(Ity_F128);
11892 IRTemp op2 = newTemp(Ity_F128);
11893 IRTemp cc_vex = newTemp(Ity_I32);
11894 IRTemp cc_s390 = newTemp(Ity_I32);
11895
11896 assign(op1, get_fpr_pair(r1));
11897 assign(op2, get_fpr_pair(r2));
11898 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
11899
florian2d3d87f2012-12-21 21:05:17 +000011900 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011901 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11902
11903 return "cxbr";
11904}
11905
florian55085f82012-11-21 00:36:55 +000011906static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011907s390_irgen_CEB(UChar r1, IRTemp op2addr)
11908{
11909 IRTemp op1 = newTemp(Ity_F32);
11910 IRTemp op2 = newTemp(Ity_F32);
11911 IRTemp cc_vex = newTemp(Ity_I32);
11912 IRTemp cc_s390 = newTemp(Ity_I32);
11913
11914 assign(op1, get_fpr_w0(r1));
11915 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11916 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11917
florian2d3d87f2012-12-21 21:05:17 +000011918 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011919 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11920
11921 return "ceb";
11922}
11923
florian55085f82012-11-21 00:36:55 +000011924static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011925s390_irgen_CDB(UChar r1, IRTemp op2addr)
11926{
11927 IRTemp op1 = newTemp(Ity_F64);
11928 IRTemp op2 = newTemp(Ity_F64);
11929 IRTemp cc_vex = newTemp(Ity_I32);
11930 IRTemp cc_s390 = newTemp(Ity_I32);
11931
11932 assign(op1, get_fpr_dw0(r1));
11933 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11934 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11935
florian2d3d87f2012-12-21 21:05:17 +000011936 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011937 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11938
11939 return "cdb";
11940}
11941
florian55085f82012-11-21 00:36:55 +000011942static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011943s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11944 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011945{
11946 IRTemp op2 = newTemp(Ity_I32);
11947
11948 assign(op2, get_gpr_w1(r2));
11949 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11950
11951 return "cxfbr";
11952}
11953
florian55085f82012-11-21 00:36:55 +000011954static const HChar *
floriand2129202012-09-01 20:01:39 +000011955s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11956 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011957{
floriane75dafa2012-09-01 17:54:09 +000011958 if (! s390_host_has_fpext) {
11959 emulation_failure(EmFail_S390X_fpext);
11960 } else {
11961 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011962
floriane75dafa2012-09-01 17:54:09 +000011963 assign(op2, get_gpr_w1(r2));
11964 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11965 }
florian1c8f7ff2012-09-01 00:12:11 +000011966 return "cxlfbr";
11967}
11968
11969
florian55085f82012-11-21 00:36:55 +000011970static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011971s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11972 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011973{
11974 IRTemp op2 = newTemp(Ity_I64);
11975
11976 assign(op2, get_gpr_dw0(r2));
11977 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11978
11979 return "cxgbr";
11980}
11981
florian55085f82012-11-21 00:36:55 +000011982static const HChar *
floriand2129202012-09-01 20:01:39 +000011983s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11984 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011985{
floriane75dafa2012-09-01 17:54:09 +000011986 if (! s390_host_has_fpext) {
11987 emulation_failure(EmFail_S390X_fpext);
11988 } else {
11989 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011990
floriane75dafa2012-09-01 17:54:09 +000011991 assign(op2, get_gpr_dw0(r2));
11992 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11993 }
florian1c8f7ff2012-09-01 00:12:11 +000011994 return "cxlgbr";
11995}
11996
florian55085f82012-11-21 00:36:55 +000011997static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011998s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11999 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012000{
12001 IRTemp op = newTemp(Ity_F128);
12002 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012003 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012004
12005 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012006 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012007 mkexpr(op)));
12008 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012009 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012010
12011 return "cfxbr";
12012}
12013
florian55085f82012-11-21 00:36:55 +000012014static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012015s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12016 UChar r1, UChar r2)
12017{
floriane75dafa2012-09-01 17:54:09 +000012018 if (! s390_host_has_fpext) {
12019 emulation_failure(EmFail_S390X_fpext);
12020 } else {
12021 IRTemp op = newTemp(Ity_F128);
12022 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012023 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012024
floriane75dafa2012-09-01 17:54:09 +000012025 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012026 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012027 mkexpr(op)));
12028 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012029 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012030 }
florian1c8f7ff2012-09-01 00:12:11 +000012031 return "clfxbr";
12032}
12033
12034
florian55085f82012-11-21 00:36:55 +000012035static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012036s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12037 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012038{
12039 IRTemp op = newTemp(Ity_F128);
12040 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012041 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012042
12043 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012044 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012045 mkexpr(op)));
12046 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012047 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012048
12049 return "cgxbr";
12050}
12051
florian55085f82012-11-21 00:36:55 +000012052static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012053s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12054 UChar r1, UChar r2)
12055{
floriane75dafa2012-09-01 17:54:09 +000012056 if (! s390_host_has_fpext) {
12057 emulation_failure(EmFail_S390X_fpext);
12058 } else {
12059 IRTemp op = newTemp(Ity_F128);
12060 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012061 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012062
floriane75dafa2012-09-01 17:54:09 +000012063 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012064 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012065 mkexpr(op)));
12066 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012067 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12068 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012069 }
florian1c8f7ff2012-09-01 00:12:11 +000012070 return "clgxbr";
12071}
12072
florian55085f82012-11-21 00:36:55 +000012073static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012074s390_irgen_DXBR(UChar r1, UChar r2)
12075{
12076 IRTemp op1 = newTemp(Ity_F128);
12077 IRTemp op2 = newTemp(Ity_F128);
12078 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012079 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012080
12081 assign(op1, get_fpr_pair(r1));
12082 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012083 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012084 mkexpr(op2)));
12085 put_fpr_pair(r1, mkexpr(result));
12086
12087 return "dxbr";
12088}
12089
florian55085f82012-11-21 00:36:55 +000012090static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012091s390_irgen_LTXBR(UChar r1, UChar r2)
12092{
12093 IRTemp result = newTemp(Ity_F128);
12094
12095 assign(result, get_fpr_pair(r2));
12096 put_fpr_pair(r1, mkexpr(result));
12097 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12098
12099 return "ltxbr";
12100}
12101
florian55085f82012-11-21 00:36:55 +000012102static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012103s390_irgen_LCXBR(UChar r1, UChar r2)
12104{
12105 IRTemp result = newTemp(Ity_F128);
12106
12107 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12108 put_fpr_pair(r1, mkexpr(result));
12109 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12110
12111 return "lcxbr";
12112}
12113
florian55085f82012-11-21 00:36:55 +000012114static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012115s390_irgen_LXDBR(UChar r1, UChar r2)
12116{
12117 IRTemp op = newTemp(Ity_F64);
12118
12119 assign(op, get_fpr_dw0(r2));
12120 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12121
12122 return "lxdbr";
12123}
12124
florian55085f82012-11-21 00:36:55 +000012125static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012126s390_irgen_LXEBR(UChar r1, UChar r2)
12127{
12128 IRTemp op = newTemp(Ity_F32);
12129
12130 assign(op, get_fpr_w0(r2));
12131 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12132
12133 return "lxebr";
12134}
12135
florian55085f82012-11-21 00:36:55 +000012136static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012137s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12138{
12139 IRTemp op = newTemp(Ity_F64);
12140
12141 assign(op, load(Ity_F64, mkexpr(op2addr)));
12142 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12143
12144 return "lxdb";
12145}
12146
florian55085f82012-11-21 00:36:55 +000012147static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012148s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12149{
12150 IRTemp op = newTemp(Ity_F32);
12151
12152 assign(op, load(Ity_F32, mkexpr(op2addr)));
12153 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12154
12155 return "lxeb";
12156}
12157
florian55085f82012-11-21 00:36:55 +000012158static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012159s390_irgen_LNEBR(UChar r1, UChar r2)
12160{
12161 IRTemp result = newTemp(Ity_F32);
12162
12163 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12164 put_fpr_w0(r1, mkexpr(result));
12165 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12166
12167 return "lnebr";
12168}
12169
florian55085f82012-11-21 00:36:55 +000012170static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012171s390_irgen_LNDBR(UChar r1, UChar r2)
12172{
12173 IRTemp result = newTemp(Ity_F64);
12174
12175 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12176 put_fpr_dw0(r1, mkexpr(result));
12177 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12178
12179 return "lndbr";
12180}
12181
florian55085f82012-11-21 00:36:55 +000012182static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012183s390_irgen_LNXBR(UChar r1, UChar r2)
12184{
12185 IRTemp result = newTemp(Ity_F128);
12186
12187 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12188 put_fpr_pair(r1, mkexpr(result));
12189 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12190
12191 return "lnxbr";
12192}
12193
florian55085f82012-11-21 00:36:55 +000012194static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012195s390_irgen_LPEBR(UChar r1, UChar r2)
12196{
12197 IRTemp result = newTemp(Ity_F32);
12198
12199 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12200 put_fpr_w0(r1, mkexpr(result));
12201 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12202
12203 return "lpebr";
12204}
12205
florian55085f82012-11-21 00:36:55 +000012206static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012207s390_irgen_LPDBR(UChar r1, UChar r2)
12208{
12209 IRTemp result = newTemp(Ity_F64);
12210
12211 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12212 put_fpr_dw0(r1, mkexpr(result));
12213 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12214
12215 return "lpdbr";
12216}
12217
florian55085f82012-11-21 00:36:55 +000012218static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012219s390_irgen_LPXBR(UChar r1, UChar r2)
12220{
12221 IRTemp result = newTemp(Ity_F128);
12222
12223 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12224 put_fpr_pair(r1, mkexpr(result));
12225 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12226
12227 return "lpxbr";
12228}
12229
florian55085f82012-11-21 00:36:55 +000012230static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012231s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12232 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012233{
florian125e20d2012-10-07 15:42:37 +000012234 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012235 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012236 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012237 }
sewardj2019a972011-03-07 16:04:07 +000012238 IRTemp result = newTemp(Ity_F64);
12239
floriandb4fcaa2012-09-05 19:54:08 +000012240 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012241 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012242 put_fpr_dw0(r1, mkexpr(result));
12243
12244 return "ldxbr";
12245}
12246
florian55085f82012-11-21 00:36:55 +000012247static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012248s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12249 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012250{
florian125e20d2012-10-07 15:42:37 +000012251 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012252 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012253 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012254 }
sewardj2019a972011-03-07 16:04:07 +000012255 IRTemp result = newTemp(Ity_F32);
12256
floriandb4fcaa2012-09-05 19:54:08 +000012257 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012258 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012259 put_fpr_w0(r1, mkexpr(result));
12260
12261 return "lexbr";
12262}
12263
florian55085f82012-11-21 00:36:55 +000012264static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012265s390_irgen_MXBR(UChar r1, UChar r2)
12266{
12267 IRTemp op1 = newTemp(Ity_F128);
12268 IRTemp op2 = newTemp(Ity_F128);
12269 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012270 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012271
12272 assign(op1, get_fpr_pair(r1));
12273 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012274 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012275 mkexpr(op2)));
12276 put_fpr_pair(r1, mkexpr(result));
12277
12278 return "mxbr";
12279}
12280
florian55085f82012-11-21 00:36:55 +000012281static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012282s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12283{
florian125e20d2012-10-07 15:42:37 +000012284 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012285
floriandb4fcaa2012-09-05 19:54:08 +000012286 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012287 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012288
12289 return "maebr";
12290}
12291
florian55085f82012-11-21 00:36:55 +000012292static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012293s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12294{
florian125e20d2012-10-07 15:42:37 +000012295 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012296
floriandb4fcaa2012-09-05 19:54:08 +000012297 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012298 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012299
12300 return "madbr";
12301}
12302
florian55085f82012-11-21 00:36:55 +000012303static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012304s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12305{
12306 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012307 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012308
floriandb4fcaa2012-09-05 19:54:08 +000012309 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012310 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012311
12312 return "maeb";
12313}
12314
florian55085f82012-11-21 00:36:55 +000012315static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012316s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12317{
12318 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012319 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012320
floriandb4fcaa2012-09-05 19:54:08 +000012321 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012322 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012323
12324 return "madb";
12325}
12326
florian55085f82012-11-21 00:36:55 +000012327static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012328s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12329{
florian125e20d2012-10-07 15:42:37 +000012330 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012331
floriandb4fcaa2012-09-05 19:54:08 +000012332 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012333 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012334
12335 return "msebr";
12336}
12337
florian55085f82012-11-21 00:36:55 +000012338static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012339s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12340{
florian125e20d2012-10-07 15:42:37 +000012341 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012342
floriandb4fcaa2012-09-05 19:54:08 +000012343 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012344 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012345
12346 return "msdbr";
12347}
12348
florian55085f82012-11-21 00:36:55 +000012349static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012350s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12351{
12352 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012353 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012354
floriandb4fcaa2012-09-05 19:54:08 +000012355 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012356 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012357
12358 return "mseb";
12359}
12360
florian55085f82012-11-21 00:36:55 +000012361static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012362s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12363{
12364 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012365 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012366
floriandb4fcaa2012-09-05 19:54:08 +000012367 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012368 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012369
12370 return "msdb";
12371}
12372
florian55085f82012-11-21 00:36:55 +000012373static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012374s390_irgen_SQEBR(UChar r1, UChar r2)
12375{
12376 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012377 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012378
floriandb4fcaa2012-09-05 19:54:08 +000012379 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012380 put_fpr_w0(r1, mkexpr(result));
12381
12382 return "sqebr";
12383}
12384
florian55085f82012-11-21 00:36:55 +000012385static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012386s390_irgen_SQDBR(UChar r1, UChar r2)
12387{
12388 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012389 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012390
floriandb4fcaa2012-09-05 19:54:08 +000012391 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012392 put_fpr_dw0(r1, mkexpr(result));
12393
12394 return "sqdbr";
12395}
12396
florian55085f82012-11-21 00:36:55 +000012397static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012398s390_irgen_SQXBR(UChar r1, UChar r2)
12399{
12400 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012401 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012402
floriandb4fcaa2012-09-05 19:54:08 +000012403 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12404 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012405 put_fpr_pair(r1, mkexpr(result));
12406
12407 return "sqxbr";
12408}
12409
florian55085f82012-11-21 00:36:55 +000012410static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012411s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12412{
12413 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012414 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012415
12416 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012417 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012418
12419 return "sqeb";
12420}
12421
florian55085f82012-11-21 00:36:55 +000012422static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012423s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12424{
12425 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012426 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012427
12428 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012429 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012430
12431 return "sqdb";
12432}
12433
florian55085f82012-11-21 00:36:55 +000012434static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012435s390_irgen_SXBR(UChar r1, UChar r2)
12436{
12437 IRTemp op1 = newTemp(Ity_F128);
12438 IRTemp op2 = newTemp(Ity_F128);
12439 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012440 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012441
12442 assign(op1, get_fpr_pair(r1));
12443 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012444 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012445 mkexpr(op2)));
12446 put_fpr_pair(r1, mkexpr(result));
12447 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12448
12449 return "sxbr";
12450}
12451
florian55085f82012-11-21 00:36:55 +000012452static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012453s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12454{
12455 IRTemp value = newTemp(Ity_F32);
12456
12457 assign(value, get_fpr_w0(r1));
12458
12459 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12460
12461 return "tceb";
12462}
12463
florian55085f82012-11-21 00:36:55 +000012464static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012465s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12466{
12467 IRTemp value = newTemp(Ity_F64);
12468
12469 assign(value, get_fpr_dw0(r1));
12470
12471 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12472
12473 return "tcdb";
12474}
12475
florian55085f82012-11-21 00:36:55 +000012476static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012477s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12478{
12479 IRTemp value = newTemp(Ity_F128);
12480
12481 assign(value, get_fpr_pair(r1));
12482
12483 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12484
12485 return "tcxb";
12486}
12487
florian55085f82012-11-21 00:36:55 +000012488static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012489s390_irgen_LCDFR(UChar r1, UChar r2)
12490{
12491 IRTemp result = newTemp(Ity_F64);
12492
12493 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12494 put_fpr_dw0(r1, mkexpr(result));
12495
12496 return "lcdfr";
12497}
12498
florian55085f82012-11-21 00:36:55 +000012499static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012500s390_irgen_LNDFR(UChar r1, UChar r2)
12501{
12502 IRTemp result = newTemp(Ity_F64);
12503
12504 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12505 put_fpr_dw0(r1, mkexpr(result));
12506
12507 return "lndfr";
12508}
12509
florian55085f82012-11-21 00:36:55 +000012510static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012511s390_irgen_LPDFR(UChar r1, UChar r2)
12512{
12513 IRTemp result = newTemp(Ity_F64);
12514
12515 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12516 put_fpr_dw0(r1, mkexpr(result));
12517
12518 return "lpdfr";
12519}
12520
florian55085f82012-11-21 00:36:55 +000012521static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012522s390_irgen_LDGR(UChar r1, UChar r2)
12523{
12524 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12525
12526 return "ldgr";
12527}
12528
florian55085f82012-11-21 00:36:55 +000012529static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012530s390_irgen_LGDR(UChar r1, UChar r2)
12531{
12532 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12533
12534 return "lgdr";
12535}
12536
12537
florian55085f82012-11-21 00:36:55 +000012538static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012539s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12540{
12541 IRTemp sign = newTemp(Ity_I64);
12542 IRTemp value = newTemp(Ity_I64);
12543
12544 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12545 mkU64(1ULL << 63)));
12546 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12547 mkU64((1ULL << 63) - 1)));
12548 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12549 mkexpr(sign))));
12550
12551 return "cpsdr";
12552}
12553
12554
sewardj2019a972011-03-07 16:04:07 +000012555static IRExpr *
12556s390_call_cvb(IRExpr *in)
12557{
12558 IRExpr **args, *call;
12559
12560 args = mkIRExprVec_1(in);
12561 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12562 "s390_do_cvb", &s390_do_cvb, args);
12563
12564 /* Nothing is excluded from definedness checking. */
12565 call->Iex.CCall.cee->mcx_mask = 0;
12566
12567 return call;
12568}
12569
florian55085f82012-11-21 00:36:55 +000012570static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012571s390_irgen_CVB(UChar r1, IRTemp op2addr)
12572{
12573 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12574
12575 return "cvb";
12576}
12577
florian55085f82012-11-21 00:36:55 +000012578static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012579s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12580{
12581 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12582
12583 return "cvby";
12584}
12585
12586
sewardj2019a972011-03-07 16:04:07 +000012587static IRExpr *
12588s390_call_cvd(IRExpr *in)
12589{
12590 IRExpr **args, *call;
12591
12592 args = mkIRExprVec_1(in);
12593 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12594 "s390_do_cvd", &s390_do_cvd, args);
12595
12596 /* Nothing is excluded from definedness checking. */
12597 call->Iex.CCall.cee->mcx_mask = 0;
12598
12599 return call;
12600}
12601
florian55085f82012-11-21 00:36:55 +000012602static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012603s390_irgen_CVD(UChar r1, IRTemp op2addr)
12604{
florian11b8ee82012-08-06 13:35:33 +000012605 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012606
12607 return "cvd";
12608}
12609
florian55085f82012-11-21 00:36:55 +000012610static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012611s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12612{
12613 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12614
12615 return "cvdy";
12616}
12617
florian55085f82012-11-21 00:36:55 +000012618static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012619s390_irgen_FLOGR(UChar r1, UChar r2)
12620{
12621 IRTemp input = newTemp(Ity_I64);
12622 IRTemp not_zero = newTemp(Ity_I64);
12623 IRTemp tmpnum = newTemp(Ity_I64);
12624 IRTemp num = newTemp(Ity_I64);
12625 IRTemp shift_amount = newTemp(Ity_I8);
12626
12627 /* We use the "count leading zeroes" operator because the number of
12628 leading zeroes is identical with the bit position of the first '1' bit.
12629 However, that operator does not work when the input value is zero.
12630 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12631 the modified value. If input == 0, then the result is 64. Otherwise,
12632 the result of Clz64 is what we want. */
12633
12634 assign(input, get_gpr_dw0(r2));
12635 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12636 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12637
12638 /* num = (input == 0) ? 64 : tmpnum */
12639 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12640 /* == 0 */ mkU64(64),
12641 /* != 0 */ mkexpr(tmpnum)));
12642
12643 put_gpr_dw0(r1, mkexpr(num));
12644
12645 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12646 is to first shift the input value by NUM + 1 bits to the left which
12647 causes the leftmost '1' bit to disappear. Then we shift logically to
12648 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12649 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12650 the width of the value-to-be-shifted, we need to special case
12651 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12652 For both such INPUT values the result will be 0. */
12653
12654 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12655 mkU64(1))));
12656
12657 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012658 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12659 /* == 0 || == 1*/ mkU64(0),
12660 /* otherwise */
12661 binop(Iop_Shr64,
12662 binop(Iop_Shl64, mkexpr(input),
12663 mkexpr(shift_amount)),
12664 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012665
12666 /* Compare the original value as an unsigned integer with 0. */
12667 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12668 mktemp(Ity_I64, mkU64(0)), False);
12669
12670 return "flogr";
12671}
12672
florian55085f82012-11-21 00:36:55 +000012673static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012674s390_irgen_STCK(IRTemp op2addr)
12675{
12676 IRDirty *d;
12677 IRTemp cc = newTemp(Ity_I64);
12678
12679 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12680 &s390x_dirtyhelper_STCK,
12681 mkIRExprVec_1(mkexpr(op2addr)));
12682 d->mFx = Ifx_Write;
12683 d->mAddr = mkexpr(op2addr);
12684 d->mSize = 8;
12685 stmt(IRStmt_Dirty(d));
12686 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12687 mkexpr(cc), mkU64(0), mkU64(0));
12688 return "stck";
12689}
12690
florian55085f82012-11-21 00:36:55 +000012691static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012692s390_irgen_STCKF(IRTemp op2addr)
12693{
florianc5c669b2012-08-26 14:32:28 +000012694 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012695 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012696 } else {
12697 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012698
florianc5c669b2012-08-26 14:32:28 +000012699 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12700 &s390x_dirtyhelper_STCKF,
12701 mkIRExprVec_1(mkexpr(op2addr)));
12702 d->mFx = Ifx_Write;
12703 d->mAddr = mkexpr(op2addr);
12704 d->mSize = 8;
12705 stmt(IRStmt_Dirty(d));
12706 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12707 mkexpr(cc), mkU64(0), mkU64(0));
12708 }
sewardj1e5fea62011-05-17 16:18:36 +000012709 return "stckf";
12710}
12711
florian55085f82012-11-21 00:36:55 +000012712static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012713s390_irgen_STCKE(IRTemp op2addr)
12714{
12715 IRDirty *d;
12716 IRTemp cc = newTemp(Ity_I64);
12717
12718 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12719 &s390x_dirtyhelper_STCKE,
12720 mkIRExprVec_1(mkexpr(op2addr)));
12721 d->mFx = Ifx_Write;
12722 d->mAddr = mkexpr(op2addr);
12723 d->mSize = 16;
12724 stmt(IRStmt_Dirty(d));
12725 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12726 mkexpr(cc), mkU64(0), mkU64(0));
12727 return "stcke";
12728}
12729
florian55085f82012-11-21 00:36:55 +000012730static const HChar *
florian933065d2011-07-11 01:48:02 +000012731s390_irgen_STFLE(IRTemp op2addr)
12732{
florian4e0083e2012-08-26 03:41:56 +000012733 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012734 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012735 return "stfle";
12736 }
12737
florian933065d2011-07-11 01:48:02 +000012738 IRDirty *d;
12739 IRTemp cc = newTemp(Ity_I64);
12740
12741 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12742 &s390x_dirtyhelper_STFLE,
12743 mkIRExprVec_1(mkexpr(op2addr)));
12744
12745 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
12746
sewardjc9069f22012-06-01 16:09:50 +000012747 d->nFxState = 1;
12748 vex_bzero(&d->fxState, sizeof(d->fxState));
12749
florian933065d2011-07-11 01:48:02 +000012750 d->fxState[0].fx = Ifx_Modify; /* read then write */
12751 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12752 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012753
12754 d->mAddr = mkexpr(op2addr);
12755 /* Pretend all double words are written */
12756 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12757 d->mFx = Ifx_Write;
12758
12759 stmt(IRStmt_Dirty(d));
12760
12761 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12762
12763 return "stfle";
12764}
12765
florian55085f82012-11-21 00:36:55 +000012766static const HChar *
floriana4384a32011-08-11 16:58:45 +000012767s390_irgen_CKSM(UChar r1,UChar r2)
12768{
12769 IRTemp addr = newTemp(Ity_I64);
12770 IRTemp op = newTemp(Ity_I32);
12771 IRTemp len = newTemp(Ity_I64);
12772 IRTemp oldval = newTemp(Ity_I32);
12773 IRTemp mask = newTemp(Ity_I32);
12774 IRTemp newop = newTemp(Ity_I32);
12775 IRTemp result = newTemp(Ity_I32);
12776 IRTemp result1 = newTemp(Ity_I32);
12777 IRTemp inc = newTemp(Ity_I64);
12778
12779 assign(oldval, get_gpr_w1(r1));
12780 assign(addr, get_gpr_dw0(r2));
12781 assign(len, get_gpr_dw0(r2+1));
12782
12783 /* Condition code is always zero. */
12784 s390_cc_set(0);
12785
12786 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012787 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012788
12789 /* Assiging the increment variable to adjust address and length
12790 later on. */
12791 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12792 mkexpr(len), mkU64(4)));
12793
12794 /* If length < 4 the final 4-byte 2nd operand value is computed by
12795 appending the remaining bytes to the right with 0. This is done
12796 by AND'ing the 4 bytes loaded from memory with an appropriate
12797 mask. If length >= 4, that mask is simply 0xffffffff. */
12798
12799 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12800 /* Mask computation when len < 4:
12801 0xffffffff << (32 - (len % 4)*8) */
12802 binop(Iop_Shl32, mkU32(0xffffffff),
12803 unop(Iop_32to8,
12804 binop(Iop_Sub32, mkU32(32),
12805 binop(Iop_Shl32,
12806 unop(Iop_64to32,
12807 binop(Iop_And64,
12808 mkexpr(len), mkU64(3))),
12809 mkU8(3))))),
12810 mkU32(0xffffffff)));
12811
12812 assign(op, load(Ity_I32, mkexpr(addr)));
12813 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12814 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12815
12816 /* Checking for carry */
12817 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12818 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12819 mkexpr(result)));
12820
12821 put_gpr_w1(r1, mkexpr(result1));
12822 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12823 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12824
florian6820ba52012-07-26 02:01:50 +000012825 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012826
12827 return "cksm";
12828}
12829
florian55085f82012-11-21 00:36:55 +000012830static const HChar *
florian9af37692012-01-15 21:01:16 +000012831s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12832{
12833 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12834 src_addr = newTemp(Ity_I64);
12835 des_addr = newTemp(Ity_I64);
12836 tab_addr = newTemp(Ity_I64);
12837 test_byte = newTemp(Ity_I8);
12838 src_len = newTemp(Ity_I64);
12839
12840 assign(src_addr, get_gpr_dw0(r2));
12841 assign(des_addr, get_gpr_dw0(r1));
12842 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012843 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012844 assign(test_byte, get_gpr_b7(0));
12845
12846 IRTemp op = newTemp(Ity_I8);
12847 IRTemp op1 = newTemp(Ity_I8);
12848 IRTemp result = newTemp(Ity_I64);
12849
12850 /* End of source string? We're done; proceed to next insn */
12851 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012852 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012853
12854 /* Load character from source string, index translation table and
12855 store translated character in op1. */
12856 assign(op, load(Ity_I8, mkexpr(src_addr)));
12857
12858 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12859 mkexpr(tab_addr)));
12860 assign(op1, load(Ity_I8, mkexpr(result)));
12861
12862 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12863 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012864 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000012865 }
12866 store(get_gpr_dw0(r1), mkexpr(op1));
12867
12868 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12869 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12870 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12871
florian6820ba52012-07-26 02:01:50 +000012872 iterate();
florian9af37692012-01-15 21:01:16 +000012873
12874 return "troo";
12875}
12876
florian55085f82012-11-21 00:36:55 +000012877static const HChar *
florian730448f2012-02-04 17:07:07 +000012878s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
12879{
12880 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12881 src_addr = newTemp(Ity_I64);
12882 des_addr = newTemp(Ity_I64);
12883 tab_addr = newTemp(Ity_I64);
12884 test_byte = newTemp(Ity_I8);
12885 src_len = newTemp(Ity_I64);
12886
12887 assign(src_addr, get_gpr_dw0(r2));
12888 assign(des_addr, get_gpr_dw0(r1));
12889 assign(tab_addr, get_gpr_dw0(1));
12890 assign(src_len, get_gpr_dw0(r1+1));
12891 assign(test_byte, get_gpr_b7(0));
12892
12893 IRTemp op = newTemp(Ity_I16);
12894 IRTemp op1 = newTemp(Ity_I8);
12895 IRTemp result = newTemp(Ity_I64);
12896
12897 /* End of source string? We're done; proceed to next insn */
12898 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012899 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012900
12901 /* Load character from source string, index translation table and
12902 store translated character in op1. */
12903 assign(op, load(Ity_I16, mkexpr(src_addr)));
12904
12905 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12906 mkexpr(tab_addr)));
12907
12908 assign(op1, load(Ity_I8, mkexpr(result)));
12909
12910 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12911 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012912 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012913 }
12914 store(get_gpr_dw0(r1), mkexpr(op1));
12915
12916 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12917 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12918 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12919
florian6820ba52012-07-26 02:01:50 +000012920 iterate();
florian730448f2012-02-04 17:07:07 +000012921
12922 return "trto";
12923}
12924
florian55085f82012-11-21 00:36:55 +000012925static const HChar *
florian730448f2012-02-04 17:07:07 +000012926s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
12927{
12928 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12929 src_addr = newTemp(Ity_I64);
12930 des_addr = newTemp(Ity_I64);
12931 tab_addr = newTemp(Ity_I64);
12932 test_byte = newTemp(Ity_I16);
12933 src_len = newTemp(Ity_I64);
12934
12935 assign(src_addr, get_gpr_dw0(r2));
12936 assign(des_addr, get_gpr_dw0(r1));
12937 assign(tab_addr, get_gpr_dw0(1));
12938 assign(src_len, get_gpr_dw0(r1+1));
12939 assign(test_byte, get_gpr_hw3(0));
12940
12941 IRTemp op = newTemp(Ity_I8);
12942 IRTemp op1 = newTemp(Ity_I16);
12943 IRTemp result = newTemp(Ity_I64);
12944
12945 /* End of source string? We're done; proceed to next insn */
12946 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012947 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012948
12949 /* Load character from source string, index translation table and
12950 store translated character in op1. */
12951 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12952
12953 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12954 mkexpr(tab_addr)));
12955 assign(op1, load(Ity_I16, mkexpr(result)));
12956
12957 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12958 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012959 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012960 }
12961 store(get_gpr_dw0(r1), mkexpr(op1));
12962
12963 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12964 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12965 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12966
florian6820ba52012-07-26 02:01:50 +000012967 iterate();
florian730448f2012-02-04 17:07:07 +000012968
12969 return "trot";
12970}
12971
florian55085f82012-11-21 00:36:55 +000012972static const HChar *
florian730448f2012-02-04 17:07:07 +000012973s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12974{
12975 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12976 src_addr = newTemp(Ity_I64);
12977 des_addr = newTemp(Ity_I64);
12978 tab_addr = newTemp(Ity_I64);
12979 test_byte = newTemp(Ity_I16);
12980 src_len = newTemp(Ity_I64);
12981
12982 assign(src_addr, get_gpr_dw0(r2));
12983 assign(des_addr, get_gpr_dw0(r1));
12984 assign(tab_addr, get_gpr_dw0(1));
12985 assign(src_len, get_gpr_dw0(r1+1));
12986 assign(test_byte, get_gpr_hw3(0));
12987
12988 IRTemp op = newTemp(Ity_I16);
12989 IRTemp op1 = newTemp(Ity_I16);
12990 IRTemp result = newTemp(Ity_I64);
12991
12992 /* End of source string? We're done; proceed to next insn */
12993 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012994 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012995
12996 /* Load character from source string, index translation table and
12997 store translated character in op1. */
12998 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12999
13000 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13001 mkexpr(tab_addr)));
13002 assign(op1, load(Ity_I16, mkexpr(result)));
13003
13004 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13005 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013006 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013007 }
13008
13009 store(get_gpr_dw0(r1), mkexpr(op1));
13010
13011 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13012 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13013 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13014
florian6820ba52012-07-26 02:01:50 +000013015 iterate();
florian730448f2012-02-04 17:07:07 +000013016
13017 return "trtt";
13018}
13019
florian55085f82012-11-21 00:36:55 +000013020static const HChar *
florian730448f2012-02-04 17:07:07 +000013021s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13022{
florianf87d4fb2012-05-05 02:55:24 +000013023 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000013024
florianf87d4fb2012-05-05 02:55:24 +000013025 assign(len, mkU64(length));
13026 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000013027
13028 return "tr";
13029}
13030
florian55085f82012-11-21 00:36:55 +000013031static const HChar *
florian730448f2012-02-04 17:07:07 +000013032s390_irgen_TRE(UChar r1,UChar r2)
13033{
13034 IRTemp src_addr, tab_addr, src_len, test_byte;
13035 src_addr = newTemp(Ity_I64);
13036 tab_addr = newTemp(Ity_I64);
13037 src_len = newTemp(Ity_I64);
13038 test_byte = newTemp(Ity_I8);
13039
13040 assign(src_addr, get_gpr_dw0(r1));
13041 assign(src_len, get_gpr_dw0(r1+1));
13042 assign(tab_addr, get_gpr_dw0(r2));
13043 assign(test_byte, get_gpr_b7(0));
13044
13045 IRTemp op = newTemp(Ity_I8);
13046 IRTemp op1 = newTemp(Ity_I8);
13047 IRTemp result = newTemp(Ity_I64);
13048
13049 /* End of source string? We're done; proceed to next insn */
13050 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013051 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013052
13053 /* Load character from source string and compare with test byte */
13054 assign(op, load(Ity_I8, mkexpr(src_addr)));
13055
13056 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013057 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013058
13059 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13060 mkexpr(tab_addr)));
13061
13062 assign(op1, load(Ity_I8, mkexpr(result)));
13063
13064 store(get_gpr_dw0(r1), mkexpr(op1));
13065 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13066 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13067
florian6820ba52012-07-26 02:01:50 +000013068 iterate();
florian730448f2012-02-04 17:07:07 +000013069
13070 return "tre";
13071}
13072
floriana0100c92012-07-20 00:06:35 +000013073static IRExpr *
13074s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13075{
13076 IRExpr **args, *call;
13077 args = mkIRExprVec_2(srcval, low_surrogate);
13078 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13079 "s390_do_cu21", &s390_do_cu21, args);
13080
13081 /* Nothing is excluded from definedness checking. */
13082 call->Iex.CCall.cee->mcx_mask = 0;
13083
13084 return call;
13085}
13086
florian55085f82012-11-21 00:36:55 +000013087static const HChar *
floriana0100c92012-07-20 00:06:35 +000013088s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13089{
13090 IRTemp addr1 = newTemp(Ity_I64);
13091 IRTemp addr2 = newTemp(Ity_I64);
13092 IRTemp len1 = newTemp(Ity_I64);
13093 IRTemp len2 = newTemp(Ity_I64);
13094
13095 assign(addr1, get_gpr_dw0(r1));
13096 assign(addr2, get_gpr_dw0(r2));
13097 assign(len1, get_gpr_dw0(r1 + 1));
13098 assign(len2, get_gpr_dw0(r2 + 1));
13099
13100 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13101 there are less than 2 bytes left, then the 2nd operand is exhausted
13102 and we're done here. cc = 0 */
13103 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013104 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000013105
13106 /* There are at least two bytes there. Read them. */
13107 IRTemp srcval = newTemp(Ity_I32);
13108 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13109
13110 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13111 inside the interval [0xd800 - 0xdbff] */
13112 IRTemp is_high_surrogate = newTemp(Ity_I32);
13113 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13114 mkU32(1), mkU32(0));
13115 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13116 mkU32(1), mkU32(0));
13117 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13118
13119 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13120 then the 2nd operand is exhausted and we're done here. cc = 0 */
13121 IRExpr *not_enough_bytes =
13122 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13123
florian6820ba52012-07-26 02:01:50 +000013124 next_insn_if(binop(Iop_CmpEQ32,
13125 binop(Iop_And32, mkexpr(is_high_surrogate),
13126 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000013127
13128 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13129 surrogate, read the next two bytes (low surrogate). */
13130 IRTemp low_surrogate = newTemp(Ity_I32);
13131 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13132
13133 assign(low_surrogate,
13134 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13135 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13136 mkU32(0))); // any value is fine; it will not be used
13137
13138 /* Call the helper */
13139 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013140 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13141 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000013142
13143 /* Before we can test whether the 1st operand is exhausted we need to
13144 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13145 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13146 IRExpr *invalid_low_surrogate =
13147 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13148
13149 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013150 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000013151 }
13152
13153 /* Now test whether the 1st operand is exhausted */
13154 IRTemp num_bytes = newTemp(Ity_I64);
13155 assign(num_bytes, binop(Iop_And64,
13156 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13157 mkU64(0xff)));
13158 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013159 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000013160
13161 /* Extract the bytes to be stored at addr1 */
13162 IRTemp data = newTemp(Ity_I64);
13163 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13164
13165 /* To store the bytes construct 4 dirty helper calls. The helper calls
13166 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13167 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013168 UInt i;
floriana0100c92012-07-20 00:06:35 +000013169 for (i = 1; i <= 4; ++i) {
13170 IRDirty *d;
13171
13172 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13173 &s390x_dirtyhelper_CUxy,
13174 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13175 mkexpr(num_bytes)));
13176 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13177 d->mFx = Ifx_Write;
13178 d->mAddr = mkexpr(addr1);
13179 d->mSize = i;
13180 stmt(IRStmt_Dirty(d));
13181 }
13182
13183 /* Update source address and length */
13184 IRTemp num_src_bytes = newTemp(Ity_I64);
13185 assign(num_src_bytes,
13186 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13187 mkU64(4), mkU64(2)));
13188 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13189 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13190
13191 /* Update destination address and length */
13192 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13193 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13194
florian6820ba52012-07-26 02:01:50 +000013195 iterate();
floriana0100c92012-07-20 00:06:35 +000013196
13197 return "cu21";
13198}
13199
florian2a415a12012-07-21 17:41:36 +000013200static IRExpr *
13201s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13202{
13203 IRExpr **args, *call;
13204 args = mkIRExprVec_2(srcval, low_surrogate);
13205 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13206 "s390_do_cu24", &s390_do_cu24, args);
13207
13208 /* Nothing is excluded from definedness checking. */
13209 call->Iex.CCall.cee->mcx_mask = 0;
13210
13211 return call;
13212}
13213
florian55085f82012-11-21 00:36:55 +000013214static const HChar *
florian2a415a12012-07-21 17:41:36 +000013215s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13216{
13217 IRTemp addr1 = newTemp(Ity_I64);
13218 IRTemp addr2 = newTemp(Ity_I64);
13219 IRTemp len1 = newTemp(Ity_I64);
13220 IRTemp len2 = newTemp(Ity_I64);
13221
13222 assign(addr1, get_gpr_dw0(r1));
13223 assign(addr2, get_gpr_dw0(r2));
13224 assign(len1, get_gpr_dw0(r1 + 1));
13225 assign(len2, get_gpr_dw0(r2 + 1));
13226
13227 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13228 there are less than 2 bytes left, then the 2nd operand is exhausted
13229 and we're done here. cc = 0 */
13230 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013231 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013232
13233 /* There are at least two bytes there. Read them. */
13234 IRTemp srcval = newTemp(Ity_I32);
13235 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13236
13237 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13238 inside the interval [0xd800 - 0xdbff] */
13239 IRTemp is_high_surrogate = newTemp(Ity_I32);
13240 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13241 mkU32(1), mkU32(0));
13242 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13243 mkU32(1), mkU32(0));
13244 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13245
13246 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13247 then the 2nd operand is exhausted and we're done here. cc = 0 */
13248 IRExpr *not_enough_bytes =
13249 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13250
florian6820ba52012-07-26 02:01:50 +000013251 next_insn_if(binop(Iop_CmpEQ32,
13252 binop(Iop_And32, mkexpr(is_high_surrogate),
13253 not_enough_bytes),
13254 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013255
13256 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13257 surrogate, read the next two bytes (low surrogate). */
13258 IRTemp low_surrogate = newTemp(Ity_I32);
13259 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13260
13261 assign(low_surrogate,
13262 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13263 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13264 mkU32(0))); // any value is fine; it will not be used
13265
13266 /* Call the helper */
13267 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013268 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13269 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013270
13271 /* Before we can test whether the 1st operand is exhausted we need to
13272 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13273 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13274 IRExpr *invalid_low_surrogate =
13275 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13276
13277 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013278 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013279 }
13280
13281 /* Now test whether the 1st operand is exhausted */
13282 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013283 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013284
13285 /* Extract the bytes to be stored at addr1 */
13286 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13287
13288 store(mkexpr(addr1), data);
13289
13290 /* Update source address and length */
13291 IRTemp num_src_bytes = newTemp(Ity_I64);
13292 assign(num_src_bytes,
13293 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13294 mkU64(4), mkU64(2)));
13295 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13296 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13297
13298 /* Update destination address and length */
13299 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13300 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13301
florian6820ba52012-07-26 02:01:50 +000013302 iterate();
florian2a415a12012-07-21 17:41:36 +000013303
13304 return "cu24";
13305}
floriana4384a32011-08-11 16:58:45 +000013306
florian956194b2012-07-28 22:18:32 +000013307static IRExpr *
13308s390_call_cu42(IRExpr *srcval)
13309{
13310 IRExpr **args, *call;
13311 args = mkIRExprVec_1(srcval);
13312 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13313 "s390_do_cu42", &s390_do_cu42, args);
13314
13315 /* Nothing is excluded from definedness checking. */
13316 call->Iex.CCall.cee->mcx_mask = 0;
13317
13318 return call;
13319}
13320
florian55085f82012-11-21 00:36:55 +000013321static const HChar *
florian956194b2012-07-28 22:18:32 +000013322s390_irgen_CU42(UChar r1, UChar r2)
13323{
13324 IRTemp addr1 = newTemp(Ity_I64);
13325 IRTemp addr2 = newTemp(Ity_I64);
13326 IRTemp len1 = newTemp(Ity_I64);
13327 IRTemp len2 = newTemp(Ity_I64);
13328
13329 assign(addr1, get_gpr_dw0(r1));
13330 assign(addr2, get_gpr_dw0(r2));
13331 assign(len1, get_gpr_dw0(r1 + 1));
13332 assign(len2, get_gpr_dw0(r2 + 1));
13333
13334 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13335 there are less than 4 bytes left, then the 2nd operand is exhausted
13336 and we're done here. cc = 0 */
13337 s390_cc_set(0);
13338 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13339
13340 /* Read the 2nd operand. */
13341 IRTemp srcval = newTemp(Ity_I32);
13342 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13343
13344 /* Call the helper */
13345 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013346 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013347
13348 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13349 cc=2 outranks cc=1 (1st operand exhausted) */
13350 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13351
13352 s390_cc_set(2);
13353 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13354
13355 /* Now test whether the 1st operand is exhausted */
13356 IRTemp num_bytes = newTemp(Ity_I64);
13357 assign(num_bytes, binop(Iop_And64,
13358 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13359 mkU64(0xff)));
13360 s390_cc_set(1);
13361 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13362
13363 /* Extract the bytes to be stored at addr1 */
13364 IRTemp data = newTemp(Ity_I64);
13365 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13366
13367 /* To store the bytes construct 2 dirty helper calls. The helper calls
13368 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13369 that only one of them will be called at runtime. */
13370
13371 Int i;
13372 for (i = 2; i <= 4; ++i) {
13373 IRDirty *d;
13374
13375 if (i == 3) continue; // skip this one
13376
13377 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13378 &s390x_dirtyhelper_CUxy,
13379 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13380 mkexpr(num_bytes)));
13381 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13382 d->mFx = Ifx_Write;
13383 d->mAddr = mkexpr(addr1);
13384 d->mSize = i;
13385 stmt(IRStmt_Dirty(d));
13386 }
13387
13388 /* Update source address and length */
13389 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13390 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13391
13392 /* Update destination address and length */
13393 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13394 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13395
13396 iterate();
13397
13398 return "cu42";
13399}
13400
florian6d9b9b22012-08-03 18:35:39 +000013401static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013402s390_call_cu41(IRExpr *srcval)
13403{
13404 IRExpr **args, *call;
13405 args = mkIRExprVec_1(srcval);
13406 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13407 "s390_do_cu41", &s390_do_cu41, args);
13408
13409 /* Nothing is excluded from definedness checking. */
13410 call->Iex.CCall.cee->mcx_mask = 0;
13411
13412 return call;
13413}
13414
florian55085f82012-11-21 00:36:55 +000013415static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013416s390_irgen_CU41(UChar r1, UChar r2)
13417{
13418 IRTemp addr1 = newTemp(Ity_I64);
13419 IRTemp addr2 = newTemp(Ity_I64);
13420 IRTemp len1 = newTemp(Ity_I64);
13421 IRTemp len2 = newTemp(Ity_I64);
13422
13423 assign(addr1, get_gpr_dw0(r1));
13424 assign(addr2, get_gpr_dw0(r2));
13425 assign(len1, get_gpr_dw0(r1 + 1));
13426 assign(len2, get_gpr_dw0(r2 + 1));
13427
13428 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13429 there are less than 4 bytes left, then the 2nd operand is exhausted
13430 and we're done here. cc = 0 */
13431 s390_cc_set(0);
13432 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13433
13434 /* Read the 2nd operand. */
13435 IRTemp srcval = newTemp(Ity_I32);
13436 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13437
13438 /* Call the helper */
13439 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013440 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013441
13442 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13443 cc=2 outranks cc=1 (1st operand exhausted) */
13444 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13445
13446 s390_cc_set(2);
13447 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13448
13449 /* Now test whether the 1st operand is exhausted */
13450 IRTemp num_bytes = newTemp(Ity_I64);
13451 assign(num_bytes, binop(Iop_And64,
13452 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13453 mkU64(0xff)));
13454 s390_cc_set(1);
13455 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13456
13457 /* Extract the bytes to be stored at addr1 */
13458 IRTemp data = newTemp(Ity_I64);
13459 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13460
13461 /* To store the bytes construct 4 dirty helper calls. The helper calls
13462 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13463 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013464 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013465 for (i = 1; i <= 4; ++i) {
13466 IRDirty *d;
13467
13468 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13469 &s390x_dirtyhelper_CUxy,
13470 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13471 mkexpr(num_bytes)));
13472 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13473 d->mFx = Ifx_Write;
13474 d->mAddr = mkexpr(addr1);
13475 d->mSize = i;
13476 stmt(IRStmt_Dirty(d));
13477 }
13478
13479 /* Update source address and length */
13480 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13481 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13482
13483 /* Update destination address and length */
13484 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13485 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13486
13487 iterate();
13488
13489 return "cu41";
13490}
13491
13492static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013493s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013494{
13495 IRExpr **args, *call;
13496 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013497 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13498 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013499
13500 /* Nothing is excluded from definedness checking. */
13501 call->Iex.CCall.cee->mcx_mask = 0;
13502
13503 return call;
13504}
13505
13506static IRExpr *
13507s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13508 IRExpr *byte4, IRExpr *stuff)
13509{
13510 IRExpr **args, *call;
13511 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13512 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13513 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13514
13515 /* Nothing is excluded from definedness checking. */
13516 call->Iex.CCall.cee->mcx_mask = 0;
13517
13518 return call;
13519}
13520
florian3f8a96a2012-08-05 02:59:55 +000013521static IRExpr *
13522s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13523 IRExpr *byte4, IRExpr *stuff)
13524{
13525 IRExpr **args, *call;
13526 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13527 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13528 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13529
13530 /* Nothing is excluded from definedness checking. */
13531 call->Iex.CCall.cee->mcx_mask = 0;
13532
13533 return call;
13534}
13535
13536static void
13537s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013538{
13539 IRTemp addr1 = newTemp(Ity_I64);
13540 IRTemp addr2 = newTemp(Ity_I64);
13541 IRTemp len1 = newTemp(Ity_I64);
13542 IRTemp len2 = newTemp(Ity_I64);
13543
13544 assign(addr1, get_gpr_dw0(r1));
13545 assign(addr2, get_gpr_dw0(r2));
13546 assign(len1, get_gpr_dw0(r1 + 1));
13547 assign(len2, get_gpr_dw0(r2 + 1));
13548
13549 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13550
13551 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13552 there is less than 1 byte left, then the 2nd operand is exhausted
13553 and we're done here. cc = 0 */
13554 s390_cc_set(0);
13555 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13556
13557 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013558 IRTemp byte1 = newTemp(Ity_I64);
13559 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013560
13561 /* Call the helper to get number of bytes and invalid byte indicator */
13562 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013563 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013564 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013565
13566 /* Check for invalid 1st byte */
13567 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13568 s390_cc_set(2);
13569 next_insn_if(is_invalid);
13570
13571 /* How many bytes do we have to read? */
13572 IRTemp num_src_bytes = newTemp(Ity_I64);
13573 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13574
13575 /* Now test whether the 2nd operand is exhausted */
13576 s390_cc_set(0);
13577 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13578
13579 /* Read the remaining bytes */
13580 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13581
13582 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13583 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013584 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013585 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13586 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013587 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013588 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13589 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013590 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013591
13592 /* Call the helper to get the converted value and invalid byte indicator.
13593 We can pass at most 5 arguments; therefore some encoding is needed
13594 here */
13595 IRExpr *stuff = binop(Iop_Or64,
13596 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13597 mkU64(extended_checking));
13598 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013599
13600 if (is_cu12) {
13601 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13602 byte4, stuff));
13603 } else {
13604 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13605 byte4, stuff));
13606 }
florian6d9b9b22012-08-03 18:35:39 +000013607
13608 /* Check for invalid character */
13609 s390_cc_set(2);
13610 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13611 next_insn_if(is_invalid);
13612
13613 /* Now test whether the 1st operand is exhausted */
13614 IRTemp num_bytes = newTemp(Ity_I64);
13615 assign(num_bytes, binop(Iop_And64,
13616 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13617 mkU64(0xff)));
13618 s390_cc_set(1);
13619 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13620
13621 /* Extract the bytes to be stored at addr1 */
13622 IRTemp data = newTemp(Ity_I64);
13623 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13624
florian3f8a96a2012-08-05 02:59:55 +000013625 if (is_cu12) {
13626 /* To store the bytes construct 2 dirty helper calls. The helper calls
13627 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13628 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013629
florian3f8a96a2012-08-05 02:59:55 +000013630 Int i;
13631 for (i = 2; i <= 4; ++i) {
13632 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013633
florian3f8a96a2012-08-05 02:59:55 +000013634 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013635
florian3f8a96a2012-08-05 02:59:55 +000013636 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13637 &s390x_dirtyhelper_CUxy,
13638 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13639 mkexpr(num_bytes)));
13640 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13641 d->mFx = Ifx_Write;
13642 d->mAddr = mkexpr(addr1);
13643 d->mSize = i;
13644 stmt(IRStmt_Dirty(d));
13645 }
13646 } else {
13647 // cu14
13648 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013649 }
13650
13651 /* Update source address and length */
13652 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13653 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13654
13655 /* Update destination address and length */
13656 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13657 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13658
13659 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013660}
13661
florian55085f82012-11-21 00:36:55 +000013662static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013663s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13664{
13665 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013666
13667 return "cu12";
13668}
13669
florian55085f82012-11-21 00:36:55 +000013670static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013671s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13672{
13673 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13674
13675 return "cu14";
13676}
13677
florian8c88cb62012-08-26 18:58:13 +000013678static IRExpr *
13679s390_call_ecag(IRExpr *op2addr)
13680{
13681 IRExpr **args, *call;
13682
13683 args = mkIRExprVec_1(op2addr);
13684 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13685 "s390_do_ecag", &s390_do_ecag, args);
13686
13687 /* Nothing is excluded from definedness checking. */
13688 call->Iex.CCall.cee->mcx_mask = 0;
13689
13690 return call;
13691}
13692
florian55085f82012-11-21 00:36:55 +000013693static const HChar *
floriand2129202012-09-01 20:01:39 +000013694s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013695{
13696 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013697 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013698 } else {
13699 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13700 }
13701
13702 return "ecag";
13703}
13704
13705
florianb7def222012-12-04 04:45:32 +000013706/* New insns are added here.
13707 If an insn is contingent on a facility being installed also
13708 check whether the list of supported facilities in function
13709 s390x_dirtyhelper_STFLE needs updating */
13710
sewardj2019a972011-03-07 16:04:07 +000013711/*------------------------------------------------------------*/
13712/*--- Build IR for special instructions ---*/
13713/*------------------------------------------------------------*/
13714
florianb4df7682011-07-05 02:09:01 +000013715static void
sewardj2019a972011-03-07 16:04:07 +000013716s390_irgen_client_request(void)
13717{
13718 if (0)
13719 vex_printf("%%R3 = client_request ( %%R2 )\n");
13720
florianf9e1ed72012-04-17 02:41:56 +000013721 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13722 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013723
florianf9e1ed72012-04-17 02:41:56 +000013724 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013725 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013726
13727 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013728}
13729
florianb4df7682011-07-05 02:09:01 +000013730static void
sewardj2019a972011-03-07 16:04:07 +000013731s390_irgen_guest_NRADDR(void)
13732{
13733 if (0)
13734 vex_printf("%%R3 = guest_NRADDR\n");
13735
floriane88b3c92011-07-05 02:48:39 +000013736 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013737}
13738
florianb4df7682011-07-05 02:09:01 +000013739static void
sewardj2019a972011-03-07 16:04:07 +000013740s390_irgen_call_noredir(void)
13741{
florianf9e1ed72012-04-17 02:41:56 +000013742 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13743 + S390_SPECIAL_OP_SIZE;
13744
sewardj2019a972011-03-07 16:04:07 +000013745 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013746 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013747
13748 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013749 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013750
13751 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013752 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013753}
13754
13755/* Force proper alignment for the structures below. */
13756#pragma pack(1)
13757
13758
13759static s390_decode_t
13760s390_decode_2byte_and_irgen(UChar *bytes)
13761{
13762 typedef union {
13763 struct {
13764 unsigned int op : 16;
13765 } E;
13766 struct {
13767 unsigned int op : 8;
13768 unsigned int i : 8;
13769 } I;
13770 struct {
13771 unsigned int op : 8;
13772 unsigned int r1 : 4;
13773 unsigned int r2 : 4;
13774 } RR;
13775 } formats;
13776 union {
13777 formats fmt;
13778 UShort value;
13779 } ovl;
13780
13781 vassert(sizeof(formats) == 2);
13782
florianffbd84d2012-12-09 02:06:29 +000013783 ((UChar *)(&ovl.value))[0] = bytes[0];
13784 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013785
13786 switch (ovl.value & 0xffff) {
13787 case 0x0101: /* PR */ goto unimplemented;
13788 case 0x0102: /* UPT */ goto unimplemented;
13789 case 0x0104: /* PTFF */ goto unimplemented;
13790 case 0x0107: /* SCKPF */ goto unimplemented;
florian78d5ef72013-05-11 15:02:58 +000013791 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013792 case 0x010b: /* TAM */ goto unimplemented;
13793 case 0x010c: /* SAM24 */ goto unimplemented;
13794 case 0x010d: /* SAM31 */ goto unimplemented;
13795 case 0x010e: /* SAM64 */ goto unimplemented;
13796 case 0x01ff: /* TRAP2 */ goto unimplemented;
13797 }
13798
13799 switch ((ovl.value & 0xff00) >> 8) {
13800 case 0x04: /* SPM */ goto unimplemented;
13801 case 0x05: /* BALR */ goto unimplemented;
13802 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13803 goto ok;
13804 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13805 goto ok;
13806 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13807 case 0x0b: /* BSM */ goto unimplemented;
13808 case 0x0c: /* BASSM */ goto unimplemented;
13809 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13810 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013811 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13812 goto ok;
13813 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13814 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013815 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13816 goto ok;
13817 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13818 goto ok;
13819 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13820 goto ok;
13821 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13822 goto ok;
13823 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13824 goto ok;
13825 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13826 goto ok;
13827 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13828 goto ok;
13829 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13830 goto ok;
13831 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13832 goto ok;
13833 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13834 goto ok;
13835 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13836 goto ok;
13837 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13838 goto ok;
13839 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13840 goto ok;
13841 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13842 goto ok;
13843 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13844 goto ok;
13845 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13846 goto ok;
13847 case 0x20: /* LPDR */ goto unimplemented;
13848 case 0x21: /* LNDR */ goto unimplemented;
13849 case 0x22: /* LTDR */ goto unimplemented;
13850 case 0x23: /* LCDR */ goto unimplemented;
13851 case 0x24: /* HDR */ goto unimplemented;
13852 case 0x25: /* LDXR */ goto unimplemented;
13853 case 0x26: /* MXR */ goto unimplemented;
13854 case 0x27: /* MXDR */ goto unimplemented;
13855 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13856 goto ok;
13857 case 0x29: /* CDR */ goto unimplemented;
13858 case 0x2a: /* ADR */ goto unimplemented;
13859 case 0x2b: /* SDR */ goto unimplemented;
13860 case 0x2c: /* MDR */ goto unimplemented;
13861 case 0x2d: /* DDR */ goto unimplemented;
13862 case 0x2e: /* AWR */ goto unimplemented;
13863 case 0x2f: /* SWR */ goto unimplemented;
13864 case 0x30: /* LPER */ goto unimplemented;
13865 case 0x31: /* LNER */ goto unimplemented;
13866 case 0x32: /* LTER */ goto unimplemented;
13867 case 0x33: /* LCER */ goto unimplemented;
13868 case 0x34: /* HER */ goto unimplemented;
13869 case 0x35: /* LEDR */ goto unimplemented;
13870 case 0x36: /* AXR */ goto unimplemented;
13871 case 0x37: /* SXR */ goto unimplemented;
13872 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13873 goto ok;
13874 case 0x39: /* CER */ goto unimplemented;
13875 case 0x3a: /* AER */ goto unimplemented;
13876 case 0x3b: /* SER */ goto unimplemented;
13877 case 0x3c: /* MDER */ goto unimplemented;
13878 case 0x3d: /* DER */ goto unimplemented;
13879 case 0x3e: /* AUR */ goto unimplemented;
13880 case 0x3f: /* SUR */ goto unimplemented;
13881 }
13882
13883 return S390_DECODE_UNKNOWN_INSN;
13884
13885ok:
13886 return S390_DECODE_OK;
13887
13888unimplemented:
13889 return S390_DECODE_UNIMPLEMENTED_INSN;
13890}
13891
13892static s390_decode_t
13893s390_decode_4byte_and_irgen(UChar *bytes)
13894{
13895 typedef union {
13896 struct {
13897 unsigned int op1 : 8;
13898 unsigned int r1 : 4;
13899 unsigned int op2 : 4;
13900 unsigned int i2 : 16;
13901 } RI;
13902 struct {
13903 unsigned int op : 16;
13904 unsigned int : 8;
13905 unsigned int r1 : 4;
13906 unsigned int r2 : 4;
13907 } RRE;
13908 struct {
13909 unsigned int op : 16;
13910 unsigned int r1 : 4;
13911 unsigned int : 4;
13912 unsigned int r3 : 4;
13913 unsigned int r2 : 4;
13914 } RRF;
13915 struct {
13916 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000013917 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000013918 unsigned int m4 : 4;
13919 unsigned int r1 : 4;
13920 unsigned int r2 : 4;
13921 } RRF2;
13922 struct {
13923 unsigned int op : 16;
13924 unsigned int r3 : 4;
13925 unsigned int : 4;
13926 unsigned int r1 : 4;
13927 unsigned int r2 : 4;
13928 } RRF3;
13929 struct {
13930 unsigned int op : 16;
13931 unsigned int r3 : 4;
13932 unsigned int : 4;
13933 unsigned int r1 : 4;
13934 unsigned int r2 : 4;
13935 } RRR;
13936 struct {
13937 unsigned int op : 16;
13938 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013939 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013940 unsigned int r1 : 4;
13941 unsigned int r2 : 4;
13942 } RRF4;
13943 struct {
floriane38f6412012-12-21 17:32:12 +000013944 unsigned int op : 16;
13945 unsigned int : 4;
13946 unsigned int m4 : 4;
13947 unsigned int r1 : 4;
13948 unsigned int r2 : 4;
13949 } RRF5;
13950 struct {
sewardj2019a972011-03-07 16:04:07 +000013951 unsigned int op : 8;
13952 unsigned int r1 : 4;
13953 unsigned int r3 : 4;
13954 unsigned int b2 : 4;
13955 unsigned int d2 : 12;
13956 } RS;
13957 struct {
13958 unsigned int op : 8;
13959 unsigned int r1 : 4;
13960 unsigned int r3 : 4;
13961 unsigned int i2 : 16;
13962 } RSI;
13963 struct {
13964 unsigned int op : 8;
13965 unsigned int r1 : 4;
13966 unsigned int x2 : 4;
13967 unsigned int b2 : 4;
13968 unsigned int d2 : 12;
13969 } RX;
13970 struct {
13971 unsigned int op : 16;
13972 unsigned int b2 : 4;
13973 unsigned int d2 : 12;
13974 } S;
13975 struct {
13976 unsigned int op : 8;
13977 unsigned int i2 : 8;
13978 unsigned int b1 : 4;
13979 unsigned int d1 : 12;
13980 } SI;
13981 } formats;
13982 union {
13983 formats fmt;
13984 UInt value;
13985 } ovl;
13986
13987 vassert(sizeof(formats) == 4);
13988
florianffbd84d2012-12-09 02:06:29 +000013989 ((UChar *)(&ovl.value))[0] = bytes[0];
13990 ((UChar *)(&ovl.value))[1] = bytes[1];
13991 ((UChar *)(&ovl.value))[2] = bytes[2];
13992 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013993
13994 switch ((ovl.value & 0xff0f0000) >> 16) {
13995 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13996 ovl.fmt.RI.i2); goto ok;
13997 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13998 ovl.fmt.RI.i2); goto ok;
13999 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14000 ovl.fmt.RI.i2); goto ok;
14001 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14002 ovl.fmt.RI.i2); goto ok;
14003 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14004 ovl.fmt.RI.i2); goto ok;
14005 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14006 ovl.fmt.RI.i2); goto ok;
14007 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14008 ovl.fmt.RI.i2); goto ok;
14009 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14010 ovl.fmt.RI.i2); goto ok;
14011 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14012 ovl.fmt.RI.i2); goto ok;
14013 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14014 ovl.fmt.RI.i2); goto ok;
14015 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14016 ovl.fmt.RI.i2); goto ok;
14017 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14018 ovl.fmt.RI.i2); goto ok;
14019 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14020 ovl.fmt.RI.i2); goto ok;
14021 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14022 ovl.fmt.RI.i2); goto ok;
14023 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14024 ovl.fmt.RI.i2); goto ok;
14025 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14026 ovl.fmt.RI.i2); goto ok;
14027 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14028 ovl.fmt.RI.i2); goto ok;
14029 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14030 ovl.fmt.RI.i2); goto ok;
14031 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14032 ovl.fmt.RI.i2); goto ok;
14033 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14034 ovl.fmt.RI.i2); goto ok;
14035 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14036 goto ok;
14037 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14038 ovl.fmt.RI.i2); goto ok;
14039 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14040 ovl.fmt.RI.i2); goto ok;
14041 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14042 ovl.fmt.RI.i2); goto ok;
14043 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14044 goto ok;
14045 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14046 ovl.fmt.RI.i2); goto ok;
14047 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14048 goto ok;
14049 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14050 ovl.fmt.RI.i2); goto ok;
14051 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14052 goto ok;
14053 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14054 ovl.fmt.RI.i2); goto ok;
14055 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14056 goto ok;
14057 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14058 ovl.fmt.RI.i2); goto ok;
14059 }
14060
14061 switch ((ovl.value & 0xffff0000) >> 16) {
14062 case 0x8000: /* SSM */ goto unimplemented;
14063 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014064 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014065 case 0xb202: /* STIDP */ goto unimplemented;
14066 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014067 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14068 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014069 case 0xb206: /* SCKC */ goto unimplemented;
14070 case 0xb207: /* STCKC */ goto unimplemented;
14071 case 0xb208: /* SPT */ goto unimplemented;
14072 case 0xb209: /* STPT */ goto unimplemented;
14073 case 0xb20a: /* SPKA */ goto unimplemented;
14074 case 0xb20b: /* IPK */ goto unimplemented;
14075 case 0xb20d: /* PTLB */ goto unimplemented;
14076 case 0xb210: /* SPX */ goto unimplemented;
14077 case 0xb211: /* STPX */ goto unimplemented;
14078 case 0xb212: /* STAP */ goto unimplemented;
14079 case 0xb214: /* SIE */ goto unimplemented;
14080 case 0xb218: /* PC */ goto unimplemented;
14081 case 0xb219: /* SAC */ goto unimplemented;
14082 case 0xb21a: /* CFC */ goto unimplemented;
14083 case 0xb221: /* IPTE */ goto unimplemented;
14084 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
14085 case 0xb223: /* IVSK */ goto unimplemented;
14086 case 0xb224: /* IAC */ goto unimplemented;
14087 case 0xb225: /* SSAR */ goto unimplemented;
14088 case 0xb226: /* EPAR */ goto unimplemented;
14089 case 0xb227: /* ESAR */ goto unimplemented;
14090 case 0xb228: /* PT */ goto unimplemented;
14091 case 0xb229: /* ISKE */ goto unimplemented;
14092 case 0xb22a: /* RRBE */ goto unimplemented;
14093 case 0xb22b: /* SSKE */ goto unimplemented;
14094 case 0xb22c: /* TB */ goto unimplemented;
14095 case 0xb22d: /* DXR */ goto unimplemented;
14096 case 0xb22e: /* PGIN */ goto unimplemented;
14097 case 0xb22f: /* PGOUT */ goto unimplemented;
14098 case 0xb230: /* CSCH */ goto unimplemented;
14099 case 0xb231: /* HSCH */ goto unimplemented;
14100 case 0xb232: /* MSCH */ goto unimplemented;
14101 case 0xb233: /* SSCH */ goto unimplemented;
14102 case 0xb234: /* STSCH */ goto unimplemented;
14103 case 0xb235: /* TSCH */ goto unimplemented;
14104 case 0xb236: /* TPI */ goto unimplemented;
14105 case 0xb237: /* SAL */ goto unimplemented;
14106 case 0xb238: /* RSCH */ goto unimplemented;
14107 case 0xb239: /* STCRW */ goto unimplemented;
14108 case 0xb23a: /* STCPS */ goto unimplemented;
14109 case 0xb23b: /* RCHP */ goto unimplemented;
14110 case 0xb23c: /* SCHM */ goto unimplemented;
14111 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000014112 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14113 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014114 case 0xb244: /* SQDR */ goto unimplemented;
14115 case 0xb245: /* SQER */ goto unimplemented;
14116 case 0xb246: /* STURA */ goto unimplemented;
14117 case 0xb247: /* MSTA */ goto unimplemented;
14118 case 0xb248: /* PALB */ goto unimplemented;
14119 case 0xb249: /* EREG */ goto unimplemented;
14120 case 0xb24a: /* ESTA */ goto unimplemented;
14121 case 0xb24b: /* LURA */ goto unimplemented;
14122 case 0xb24c: /* TAR */ goto unimplemented;
14123 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14124 ovl.fmt.RRE.r2); goto ok;
14125 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14126 goto ok;
14127 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14128 goto ok;
14129 case 0xb250: /* CSP */ goto unimplemented;
14130 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14131 ovl.fmt.RRE.r2); goto ok;
14132 case 0xb254: /* MVPG */ goto unimplemented;
14133 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14134 ovl.fmt.RRE.r2); goto ok;
14135 case 0xb257: /* CUSE */ goto unimplemented;
14136 case 0xb258: /* BSG */ goto unimplemented;
14137 case 0xb25a: /* BSA */ goto unimplemented;
14138 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14139 ovl.fmt.RRE.r2); goto ok;
14140 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14141 ovl.fmt.RRE.r2); goto ok;
14142 case 0xb263: /* CMPSC */ goto unimplemented;
14143 case 0xb274: /* SIGA */ goto unimplemented;
14144 case 0xb276: /* XSCH */ goto unimplemented;
14145 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014146 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 +000014147 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014148 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 +000014149 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014150 case 0xb280: /* LPP */ goto unimplemented;
14151 case 0xb284: /* LCCTL */ goto unimplemented;
14152 case 0xb285: /* LPCTL */ goto unimplemented;
14153 case 0xb286: /* QSI */ goto unimplemented;
14154 case 0xb287: /* LSCTL */ goto unimplemented;
14155 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014156 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14157 goto ok;
14158 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14159 goto ok;
14160 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14161 goto ok;
florian730448f2012-02-04 17:07:07 +000014162 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 +000014163 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14164 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14165 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000014166 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14167 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14168 goto ok;
florian933065d2011-07-11 01:48:02 +000014169 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14170 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014171 case 0xb2b1: /* STFL */ goto unimplemented;
14172 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000014173 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14174 goto ok;
florian82cdba62013-03-12 01:31:24 +000014175 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14176 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014177 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014178 case 0xb2e0: /* SCCTR */ goto unimplemented;
14179 case 0xb2e1: /* SPCTR */ goto unimplemented;
14180 case 0xb2e4: /* ECCTR */ goto unimplemented;
14181 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014182 case 0xb2e8: /* PPA */ goto unimplemented;
14183 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014184 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014185 case 0xb2f8: /* TEND */ goto unimplemented;
14186 case 0xb2fa: /* NIAI */ goto unimplemented;
14187 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014188 case 0xb2ff: /* TRAP4 */ goto unimplemented;
14189 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14190 ovl.fmt.RRE.r2); goto ok;
14191 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14192 ovl.fmt.RRE.r2); goto ok;
14193 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14194 ovl.fmt.RRE.r2); goto ok;
14195 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14196 ovl.fmt.RRE.r2); goto ok;
14197 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14198 ovl.fmt.RRE.r2); goto ok;
14199 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14200 ovl.fmt.RRE.r2); goto ok;
14201 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14202 ovl.fmt.RRE.r2); goto ok;
14203 case 0xb307: /* MXDBR */ goto unimplemented;
14204 case 0xb308: /* KEBR */ goto unimplemented;
14205 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14206 ovl.fmt.RRE.r2); goto ok;
14207 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14208 ovl.fmt.RRE.r2); goto ok;
14209 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14210 ovl.fmt.RRE.r2); goto ok;
14211 case 0xb30c: /* MDEBR */ goto unimplemented;
14212 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14213 ovl.fmt.RRE.r2); goto ok;
14214 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14215 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14216 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14217 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14218 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14219 ovl.fmt.RRE.r2); goto ok;
14220 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14221 ovl.fmt.RRE.r2); goto ok;
14222 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14223 ovl.fmt.RRE.r2); goto ok;
14224 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14225 ovl.fmt.RRE.r2); goto ok;
14226 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14227 ovl.fmt.RRE.r2); goto ok;
14228 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14229 ovl.fmt.RRE.r2); goto ok;
14230 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14231 ovl.fmt.RRE.r2); goto ok;
14232 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14233 ovl.fmt.RRE.r2); goto ok;
14234 case 0xb318: /* KDBR */ goto unimplemented;
14235 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14236 ovl.fmt.RRE.r2); goto ok;
14237 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14238 ovl.fmt.RRE.r2); goto ok;
14239 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14240 ovl.fmt.RRE.r2); goto ok;
14241 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14242 ovl.fmt.RRE.r2); goto ok;
14243 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14244 ovl.fmt.RRE.r2); goto ok;
14245 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14246 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14247 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14248 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14249 case 0xb324: /* LDER */ goto unimplemented;
14250 case 0xb325: /* LXDR */ goto unimplemented;
14251 case 0xb326: /* LXER */ goto unimplemented;
14252 case 0xb32e: /* MAER */ goto unimplemented;
14253 case 0xb32f: /* MSER */ goto unimplemented;
14254 case 0xb336: /* SQXR */ goto unimplemented;
14255 case 0xb337: /* MEER */ goto unimplemented;
14256 case 0xb338: /* MAYLR */ goto unimplemented;
14257 case 0xb339: /* MYLR */ goto unimplemented;
14258 case 0xb33a: /* MAYR */ goto unimplemented;
14259 case 0xb33b: /* MYR */ goto unimplemented;
14260 case 0xb33c: /* MAYHR */ goto unimplemented;
14261 case 0xb33d: /* MYHR */ goto unimplemented;
14262 case 0xb33e: /* MADR */ goto unimplemented;
14263 case 0xb33f: /* MSDR */ goto unimplemented;
14264 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14265 ovl.fmt.RRE.r2); goto ok;
14266 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14267 ovl.fmt.RRE.r2); goto ok;
14268 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14269 ovl.fmt.RRE.r2); goto ok;
14270 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14271 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014272 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14273 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14274 ovl.fmt.RRF2.r2); goto ok;
14275 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14276 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14277 ovl.fmt.RRF2.r2); goto ok;
14278 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14279 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14280 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014281 case 0xb347: /* FIXBR */ goto unimplemented;
14282 case 0xb348: /* KXBR */ goto unimplemented;
14283 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14284 ovl.fmt.RRE.r2); goto ok;
14285 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14286 ovl.fmt.RRE.r2); goto ok;
14287 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14288 ovl.fmt.RRE.r2); goto ok;
14289 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14290 ovl.fmt.RRE.r2); goto ok;
14291 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14292 ovl.fmt.RRE.r2); goto ok;
14293 case 0xb350: /* TBEDR */ goto unimplemented;
14294 case 0xb351: /* TBDR */ goto unimplemented;
14295 case 0xb353: /* DIEBR */ goto unimplemented;
14296 case 0xb357: /* FIEBR */ goto unimplemented;
14297 case 0xb358: /* THDER */ goto unimplemented;
14298 case 0xb359: /* THDR */ goto unimplemented;
14299 case 0xb35b: /* DIDBR */ goto unimplemented;
14300 case 0xb35f: /* FIDBR */ goto unimplemented;
14301 case 0xb360: /* LPXR */ goto unimplemented;
14302 case 0xb361: /* LNXR */ goto unimplemented;
14303 case 0xb362: /* LTXR */ goto unimplemented;
14304 case 0xb363: /* LCXR */ goto unimplemented;
14305 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14306 ovl.fmt.RRE.r2); goto ok;
14307 case 0xb366: /* LEXR */ goto unimplemented;
14308 case 0xb367: /* FIXR */ goto unimplemented;
14309 case 0xb369: /* CXR */ goto unimplemented;
14310 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14311 ovl.fmt.RRE.r2); goto ok;
14312 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14313 ovl.fmt.RRE.r2); goto ok;
14314 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14315 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14316 goto ok;
14317 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14318 ovl.fmt.RRE.r2); goto ok;
14319 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14320 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14321 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14322 case 0xb377: /* FIER */ goto unimplemented;
14323 case 0xb37f: /* FIDR */ goto unimplemented;
14324 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14325 case 0xb385: /* SFASR */ goto unimplemented;
14326 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014327 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14328 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14329 ovl.fmt.RRF2.r2); goto ok;
14330 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14331 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14332 ovl.fmt.RRF2.r2); goto ok;
14333 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14334 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14335 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014336 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14337 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14338 ovl.fmt.RRF2.r2); goto ok;
14339 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14340 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14341 ovl.fmt.RRF2.r2); goto ok;
14342 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14343 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14344 ovl.fmt.RRF2.r2); goto ok;
14345 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14346 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14347 ovl.fmt.RRF2.r2); goto ok;
14348 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14349 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14350 ovl.fmt.RRF2.r2); goto ok;
14351 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14352 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14353 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014354 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14355 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14356 ovl.fmt.RRF2.r2); goto ok;
14357 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14358 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14359 ovl.fmt.RRF2.r2); goto ok;
14360 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14361 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14362 ovl.fmt.RRF2.r2); goto ok;
14363 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14364 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14365 ovl.fmt.RRF2.r2); goto ok;
14366 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14367 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14368 ovl.fmt.RRF2.r2); goto ok;
14369 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14370 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14371 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014372 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14373 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14374 ovl.fmt.RRF2.r2); goto ok;
14375 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14376 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14377 ovl.fmt.RRF2.r2); goto ok;
14378 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14379 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14380 ovl.fmt.RRF2.r2); goto ok;
14381 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14382 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14383 ovl.fmt.RRF2.r2); goto ok;
14384 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14385 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14386 ovl.fmt.RRF2.r2); goto ok;
14387 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14388 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14389 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014390 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14391 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14392 ovl.fmt.RRF2.r2); goto ok;
14393 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14394 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14395 ovl.fmt.RRF2.r2); goto ok;
14396 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14397 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14398 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014399 case 0xb3b4: /* CEFR */ goto unimplemented;
14400 case 0xb3b5: /* CDFR */ goto unimplemented;
14401 case 0xb3b6: /* CXFR */ goto unimplemented;
14402 case 0xb3b8: /* CFER */ goto unimplemented;
14403 case 0xb3b9: /* CFDR */ goto unimplemented;
14404 case 0xb3ba: /* CFXR */ goto unimplemented;
14405 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14406 ovl.fmt.RRE.r2); goto ok;
14407 case 0xb3c4: /* CEGR */ goto unimplemented;
14408 case 0xb3c5: /* CDGR */ goto unimplemented;
14409 case 0xb3c6: /* CXGR */ goto unimplemented;
14410 case 0xb3c8: /* CGER */ goto unimplemented;
14411 case 0xb3c9: /* CGDR */ goto unimplemented;
14412 case 0xb3ca: /* CGXR */ goto unimplemented;
14413 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14414 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014415 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14416 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14417 ovl.fmt.RRF4.r2); goto ok;
14418 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14419 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14420 ovl.fmt.RRF4.r2); goto ok;
14421 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14422 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14423 ovl.fmt.RRF4.r2); goto ok;
14424 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14425 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14426 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014427 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14428 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14429 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14430 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14431 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014432 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14433 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014434 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014435 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14436 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14437 ovl.fmt.RRF4.r2); goto ok;
14438 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14439 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14440 ovl.fmt.RRF4.r2); goto ok;
14441 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14442 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14443 ovl.fmt.RRF4.r2); goto ok;
14444 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14445 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14446 ovl.fmt.RRF4.r2); goto ok;
14447 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14448 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14449 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14450 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14451 ovl.fmt.RRF2.r2); goto ok;
14452 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14453 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014454 case 0xb3df: /* FIXTR */ goto unimplemented;
14455 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014456 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14457 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14458 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014459 case 0xb3e2: /* CUDTR */ goto unimplemented;
14460 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014461 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14462 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014463 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14464 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014465 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14466 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014467 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014468 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14469 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14470 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014471 case 0xb3ea: /* CUXTR */ goto unimplemented;
14472 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014473 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14474 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014475 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14476 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014477 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14478 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014479 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14480 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14481 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014482 case 0xb3f2: /* CDUTR */ goto unimplemented;
14483 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014484 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14485 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014486 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14487 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14488 ovl.fmt.RRF4.r2); goto ok;
14489 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14490 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14491 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14492 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14493 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014494 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14495 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14496 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014497 case 0xb3fa: /* CXUTR */ goto unimplemented;
14498 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014499 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14500 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014501 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14502 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14503 ovl.fmt.RRF4.r2); goto ok;
14504 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14505 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14506 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14507 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14508 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014509 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14510 ovl.fmt.RRE.r2); goto ok;
14511 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14512 ovl.fmt.RRE.r2); goto ok;
14513 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14514 ovl.fmt.RRE.r2); goto ok;
14515 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14516 ovl.fmt.RRE.r2); goto ok;
14517 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14518 ovl.fmt.RRE.r2); goto ok;
14519 case 0xb905: /* LURAG */ goto unimplemented;
14520 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14521 ovl.fmt.RRE.r2); goto ok;
14522 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14523 ovl.fmt.RRE.r2); goto ok;
14524 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14525 ovl.fmt.RRE.r2); goto ok;
14526 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14527 ovl.fmt.RRE.r2); goto ok;
14528 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14529 ovl.fmt.RRE.r2); goto ok;
14530 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14531 ovl.fmt.RRE.r2); goto ok;
14532 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14533 ovl.fmt.RRE.r2); goto ok;
14534 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14535 ovl.fmt.RRE.r2); goto ok;
14536 case 0xb90e: /* EREGG */ goto unimplemented;
14537 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14538 ovl.fmt.RRE.r2); goto ok;
14539 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14540 ovl.fmt.RRE.r2); goto ok;
14541 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14542 ovl.fmt.RRE.r2); goto ok;
14543 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14544 ovl.fmt.RRE.r2); goto ok;
14545 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14546 ovl.fmt.RRE.r2); goto ok;
14547 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14548 ovl.fmt.RRE.r2); goto ok;
14549 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14550 ovl.fmt.RRE.r2); goto ok;
14551 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14552 ovl.fmt.RRE.r2); goto ok;
14553 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14554 ovl.fmt.RRE.r2); goto ok;
14555 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14556 ovl.fmt.RRE.r2); goto ok;
14557 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14558 ovl.fmt.RRE.r2); goto ok;
14559 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14560 ovl.fmt.RRE.r2); goto ok;
14561 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14562 ovl.fmt.RRE.r2); goto ok;
14563 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14564 ovl.fmt.RRE.r2); goto ok;
14565 case 0xb91e: /* KMAC */ goto unimplemented;
14566 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14567 ovl.fmt.RRE.r2); goto ok;
14568 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14569 ovl.fmt.RRE.r2); goto ok;
14570 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14571 ovl.fmt.RRE.r2); goto ok;
14572 case 0xb925: /* STURG */ goto unimplemented;
14573 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14574 ovl.fmt.RRE.r2); goto ok;
14575 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14576 ovl.fmt.RRE.r2); goto ok;
14577 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014578 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014579 case 0xb92b: /* KMO */ goto unimplemented;
14580 case 0xb92c: /* PCC */ goto unimplemented;
14581 case 0xb92d: /* KMCTR */ goto unimplemented;
14582 case 0xb92e: /* KM */ goto unimplemented;
14583 case 0xb92f: /* KMC */ goto unimplemented;
14584 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14585 ovl.fmt.RRE.r2); goto ok;
14586 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14587 ovl.fmt.RRE.r2); goto ok;
14588 case 0xb93e: /* KIMD */ goto unimplemented;
14589 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014590 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14591 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14592 ovl.fmt.RRF2.r2); goto ok;
14593 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14594 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14595 ovl.fmt.RRF2.r2); goto ok;
14596 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14597 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14598 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014599 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14600 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014601 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14602 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14603 ovl.fmt.RRF2.r2); goto ok;
14604 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14605 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14606 ovl.fmt.RRF2.r2); goto ok;
14607 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14608 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14609 ovl.fmt.RRF2.r2); goto ok;
14610 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14611 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14612 ovl.fmt.RRF2.r2); goto ok;
14613 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14614 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14615 ovl.fmt.RRF2.r2); goto ok;
14616 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14617 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14618 ovl.fmt.RRF2.r2); goto ok;
14619 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14620 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14621 ovl.fmt.RRF2.r2); goto ok;
14622 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14623 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14624 ovl.fmt.RRF2.r2); goto ok;
14625 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14626 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14627 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014628 case 0xb960: /* CGRT */ goto unimplemented;
14629 case 0xb961: /* CLGRT */ goto unimplemented;
14630 case 0xb972: /* CRT */ goto unimplemented;
14631 case 0xb973: /* CLRT */ goto unimplemented;
14632 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14633 ovl.fmt.RRE.r2); goto ok;
14634 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14635 ovl.fmt.RRE.r2); goto ok;
14636 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14637 ovl.fmt.RRE.r2); goto ok;
14638 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14639 ovl.fmt.RRE.r2); goto ok;
14640 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14641 ovl.fmt.RRE.r2); goto ok;
14642 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14643 ovl.fmt.RRE.r2); goto ok;
14644 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14645 ovl.fmt.RRE.r2); goto ok;
14646 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14647 ovl.fmt.RRE.r2); goto ok;
14648 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14649 ovl.fmt.RRE.r2); goto ok;
14650 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14651 ovl.fmt.RRE.r2); goto ok;
14652 case 0xb98a: /* CSPG */ goto unimplemented;
14653 case 0xb98d: /* EPSW */ goto unimplemented;
14654 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014655 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014656 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14657 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14658 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14659 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14660 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14661 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014662 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14663 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014664 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14665 ovl.fmt.RRE.r2); goto ok;
14666 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14667 ovl.fmt.RRE.r2); goto ok;
14668 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14669 ovl.fmt.RRE.r2); goto ok;
14670 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14671 ovl.fmt.RRE.r2); goto ok;
14672 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14673 ovl.fmt.RRE.r2); goto ok;
14674 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14675 ovl.fmt.RRE.r2); goto ok;
14676 case 0xb99a: /* EPAIR */ goto unimplemented;
14677 case 0xb99b: /* ESAIR */ goto unimplemented;
14678 case 0xb99d: /* ESEA */ goto unimplemented;
14679 case 0xb99e: /* PTI */ goto unimplemented;
14680 case 0xb99f: /* SSAIR */ goto unimplemented;
14681 case 0xb9a2: /* PTF */ goto unimplemented;
14682 case 0xb9aa: /* LPTEA */ goto unimplemented;
14683 case 0xb9ae: /* RRBM */ goto unimplemented;
14684 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014685 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14686 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14687 goto ok;
florian2a415a12012-07-21 17:41:36 +000014688 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14689 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14690 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014691 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14692 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014693 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14694 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014695 case 0xb9bd: /* TRTRE */ goto unimplemented;
14696 case 0xb9be: /* SRSTU */ goto unimplemented;
14697 case 0xb9bf: /* TRTE */ goto unimplemented;
14698 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14699 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14700 goto ok;
14701 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14702 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14703 goto ok;
14704 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14705 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14706 goto ok;
14707 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14708 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14709 goto ok;
14710 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14711 ovl.fmt.RRE.r2); goto ok;
14712 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14713 ovl.fmt.RRE.r2); goto ok;
14714 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14715 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14716 goto ok;
14717 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14718 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14719 goto ok;
14720 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14721 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14722 goto ok;
14723 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14724 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14725 goto ok;
14726 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14727 ovl.fmt.RRE.r2); goto ok;
14728 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14729 ovl.fmt.RRE.r2); goto ok;
14730 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014731 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14732 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14733 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014734 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14735 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14736 goto ok;
14737 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14738 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14739 goto ok;
14740 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14741 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14742 goto ok;
14743 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14744 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14745 goto ok;
14746 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14747 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14748 goto ok;
14749 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14750 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14751 goto ok;
14752 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14753 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14754 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014755 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14756 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14757 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014758 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14759 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14760 goto ok;
14761 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14762 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14763 goto ok;
14764 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14765 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14766 goto ok;
14767 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14768 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14769 goto ok;
14770 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14771 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14772 goto ok;
14773 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14774 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14775 goto ok;
14776 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14777 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14778 goto ok;
14779 }
14780
14781 switch ((ovl.value & 0xff000000) >> 24) {
14782 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14783 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14784 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14785 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14786 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14787 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14788 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14789 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14790 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14791 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14792 case 0x45: /* BAL */ goto unimplemented;
14793 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14794 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14795 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14796 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14797 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14798 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14799 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14800 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14801 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14802 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14803 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14804 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14805 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14806 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14807 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14808 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14809 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14810 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14811 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14812 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14813 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14814 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14815 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14816 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14817 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14818 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14819 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14820 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14821 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14822 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14823 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14824 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14825 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14826 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14827 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14828 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14829 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14830 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14831 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14832 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14833 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14834 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14835 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14836 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14837 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14838 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14839 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14840 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14841 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14842 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14843 case 0x67: /* MXD */ goto unimplemented;
14844 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14845 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14846 case 0x69: /* CD */ goto unimplemented;
14847 case 0x6a: /* AD */ goto unimplemented;
14848 case 0x6b: /* SD */ goto unimplemented;
14849 case 0x6c: /* MD */ goto unimplemented;
14850 case 0x6d: /* DD */ goto unimplemented;
14851 case 0x6e: /* AW */ goto unimplemented;
14852 case 0x6f: /* SW */ goto unimplemented;
14853 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14854 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14855 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14856 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14857 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14858 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14859 case 0x79: /* CE */ goto unimplemented;
14860 case 0x7a: /* AE */ goto unimplemented;
14861 case 0x7b: /* SE */ goto unimplemented;
14862 case 0x7c: /* MDE */ goto unimplemented;
14863 case 0x7d: /* DE */ goto unimplemented;
14864 case 0x7e: /* AU */ goto unimplemented;
14865 case 0x7f: /* SU */ goto unimplemented;
14866 case 0x83: /* DIAG */ goto unimplemented;
14867 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
14868 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14869 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
14870 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14871 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14872 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14873 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14874 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14875 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14876 ovl.fmt.RS.d2); goto ok;
14877 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14878 ovl.fmt.RS.d2); goto ok;
14879 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14880 ovl.fmt.RS.d2); goto ok;
14881 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14882 ovl.fmt.RS.d2); goto ok;
14883 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14884 ovl.fmt.RS.d2); goto ok;
14885 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14886 ovl.fmt.RS.d2); goto ok;
14887 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14888 ovl.fmt.RS.d2); goto ok;
14889 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14890 ovl.fmt.RS.d2); goto ok;
14891 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14892 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14893 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14894 ovl.fmt.SI.d1); goto ok;
14895 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14896 ovl.fmt.SI.d1); goto ok;
14897 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14898 ovl.fmt.SI.d1); goto ok;
14899 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14900 ovl.fmt.SI.d1); goto ok;
14901 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14902 ovl.fmt.SI.d1); goto ok;
14903 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14904 ovl.fmt.SI.d1); goto ok;
14905 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14906 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14907 case 0x99: /* TRACE */ goto unimplemented;
14908 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14909 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14910 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14911 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14912 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
14913 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14914 goto ok;
14915 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
14916 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14917 goto ok;
14918 case 0xac: /* STNSM */ goto unimplemented;
14919 case 0xad: /* STOSM */ goto unimplemented;
14920 case 0xae: /* SIGP */ goto unimplemented;
14921 case 0xaf: /* MC */ goto unimplemented;
14922 case 0xb1: /* LRA */ goto unimplemented;
14923 case 0xb6: /* STCTL */ goto unimplemented;
14924 case 0xb7: /* LCTL */ goto unimplemented;
14925 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14926 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014927 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14928 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014929 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14930 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14931 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14932 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14933 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14934 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14935 }
14936
14937 return S390_DECODE_UNKNOWN_INSN;
14938
14939ok:
14940 return S390_DECODE_OK;
14941
14942unimplemented:
14943 return S390_DECODE_UNIMPLEMENTED_INSN;
14944}
14945
14946static s390_decode_t
14947s390_decode_6byte_and_irgen(UChar *bytes)
14948{
14949 typedef union {
14950 struct {
14951 unsigned int op1 : 8;
14952 unsigned int r1 : 4;
14953 unsigned int r3 : 4;
14954 unsigned int i2 : 16;
14955 unsigned int : 8;
14956 unsigned int op2 : 8;
14957 } RIE;
14958 struct {
14959 unsigned int op1 : 8;
14960 unsigned int r1 : 4;
14961 unsigned int r2 : 4;
14962 unsigned int i3 : 8;
14963 unsigned int i4 : 8;
14964 unsigned int i5 : 8;
14965 unsigned int op2 : 8;
14966 } RIE_RRUUU;
14967 struct {
14968 unsigned int op1 : 8;
14969 unsigned int r1 : 4;
14970 unsigned int : 4;
14971 unsigned int i2 : 16;
14972 unsigned int m3 : 4;
14973 unsigned int : 4;
14974 unsigned int op2 : 8;
14975 } RIEv1;
14976 struct {
14977 unsigned int op1 : 8;
14978 unsigned int r1 : 4;
14979 unsigned int r2 : 4;
14980 unsigned int i4 : 16;
14981 unsigned int m3 : 4;
14982 unsigned int : 4;
14983 unsigned int op2 : 8;
14984 } RIE_RRPU;
14985 struct {
14986 unsigned int op1 : 8;
14987 unsigned int r1 : 4;
14988 unsigned int m3 : 4;
14989 unsigned int i4 : 16;
14990 unsigned int i2 : 8;
14991 unsigned int op2 : 8;
14992 } RIEv3;
14993 struct {
14994 unsigned int op1 : 8;
14995 unsigned int r1 : 4;
14996 unsigned int op2 : 4;
14997 unsigned int i2 : 32;
14998 } RIL;
14999 struct {
15000 unsigned int op1 : 8;
15001 unsigned int r1 : 4;
15002 unsigned int m3 : 4;
15003 unsigned int b4 : 4;
15004 unsigned int d4 : 12;
15005 unsigned int i2 : 8;
15006 unsigned int op2 : 8;
15007 } RIS;
15008 struct {
15009 unsigned int op1 : 8;
15010 unsigned int r1 : 4;
15011 unsigned int r2 : 4;
15012 unsigned int b4 : 4;
15013 unsigned int d4 : 12;
15014 unsigned int m3 : 4;
15015 unsigned int : 4;
15016 unsigned int op2 : 8;
15017 } RRS;
15018 struct {
15019 unsigned int op1 : 8;
15020 unsigned int l1 : 4;
15021 unsigned int : 4;
15022 unsigned int b1 : 4;
15023 unsigned int d1 : 12;
15024 unsigned int : 8;
15025 unsigned int op2 : 8;
15026 } RSL;
15027 struct {
15028 unsigned int op1 : 8;
15029 unsigned int r1 : 4;
15030 unsigned int r3 : 4;
15031 unsigned int b2 : 4;
15032 unsigned int dl2 : 12;
15033 unsigned int dh2 : 8;
15034 unsigned int op2 : 8;
15035 } RSY;
15036 struct {
15037 unsigned int op1 : 8;
15038 unsigned int r1 : 4;
15039 unsigned int x2 : 4;
15040 unsigned int b2 : 4;
15041 unsigned int d2 : 12;
15042 unsigned int : 8;
15043 unsigned int op2 : 8;
15044 } RXE;
15045 struct {
15046 unsigned int op1 : 8;
15047 unsigned int r3 : 4;
15048 unsigned int x2 : 4;
15049 unsigned int b2 : 4;
15050 unsigned int d2 : 12;
15051 unsigned int r1 : 4;
15052 unsigned int : 4;
15053 unsigned int op2 : 8;
15054 } RXF;
15055 struct {
15056 unsigned int op1 : 8;
15057 unsigned int r1 : 4;
15058 unsigned int x2 : 4;
15059 unsigned int b2 : 4;
15060 unsigned int dl2 : 12;
15061 unsigned int dh2 : 8;
15062 unsigned int op2 : 8;
15063 } RXY;
15064 struct {
15065 unsigned int op1 : 8;
15066 unsigned int i2 : 8;
15067 unsigned int b1 : 4;
15068 unsigned int dl1 : 12;
15069 unsigned int dh1 : 8;
15070 unsigned int op2 : 8;
15071 } SIY;
15072 struct {
15073 unsigned int op : 8;
15074 unsigned int l : 8;
15075 unsigned int b1 : 4;
15076 unsigned int d1 : 12;
15077 unsigned int b2 : 4;
15078 unsigned int d2 : 12;
15079 } SS;
15080 struct {
15081 unsigned int op : 8;
15082 unsigned int l1 : 4;
15083 unsigned int l2 : 4;
15084 unsigned int b1 : 4;
15085 unsigned int d1 : 12;
15086 unsigned int b2 : 4;
15087 unsigned int d2 : 12;
15088 } SS_LLRDRD;
15089 struct {
15090 unsigned int op : 8;
15091 unsigned int r1 : 4;
15092 unsigned int r3 : 4;
15093 unsigned int b2 : 4;
15094 unsigned int d2 : 12;
15095 unsigned int b4 : 4;
15096 unsigned int d4 : 12;
15097 } SS_RRRDRD2;
15098 struct {
15099 unsigned int op : 16;
15100 unsigned int b1 : 4;
15101 unsigned int d1 : 12;
15102 unsigned int b2 : 4;
15103 unsigned int d2 : 12;
15104 } SSE;
15105 struct {
15106 unsigned int op1 : 8;
15107 unsigned int r3 : 4;
15108 unsigned int op2 : 4;
15109 unsigned int b1 : 4;
15110 unsigned int d1 : 12;
15111 unsigned int b2 : 4;
15112 unsigned int d2 : 12;
15113 } SSF;
15114 struct {
15115 unsigned int op : 16;
15116 unsigned int b1 : 4;
15117 unsigned int d1 : 12;
15118 unsigned int i2 : 16;
15119 } SIL;
15120 } formats;
15121 union {
15122 formats fmt;
15123 ULong value;
15124 } ovl;
15125
15126 vassert(sizeof(formats) == 6);
15127
florianffbd84d2012-12-09 02:06:29 +000015128 ((UChar *)(&ovl.value))[0] = bytes[0];
15129 ((UChar *)(&ovl.value))[1] = bytes[1];
15130 ((UChar *)(&ovl.value))[2] = bytes[2];
15131 ((UChar *)(&ovl.value))[3] = bytes[3];
15132 ((UChar *)(&ovl.value))[4] = bytes[4];
15133 ((UChar *)(&ovl.value))[5] = bytes[5];
15134 ((UChar *)(&ovl.value))[6] = 0x0;
15135 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000015136
15137 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15138 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15139 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15140 ovl.fmt.RXY.dl2,
15141 ovl.fmt.RXY.dh2); goto ok;
15142 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15143 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15144 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15145 ovl.fmt.RXY.dl2,
15146 ovl.fmt.RXY.dh2); goto ok;
15147 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15148 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15149 ovl.fmt.RXY.dl2,
15150 ovl.fmt.RXY.dh2); goto ok;
15151 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15152 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15153 ovl.fmt.RXY.dl2,
15154 ovl.fmt.RXY.dh2); goto ok;
15155 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15156 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15157 ovl.fmt.RXY.dl2,
15158 ovl.fmt.RXY.dh2); goto ok;
15159 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15160 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15161 ovl.fmt.RXY.dl2,
15162 ovl.fmt.RXY.dh2); goto ok;
15163 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15164 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15165 ovl.fmt.RXY.dl2,
15166 ovl.fmt.RXY.dh2); goto ok;
15167 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15168 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15169 ovl.fmt.RXY.dl2,
15170 ovl.fmt.RXY.dh2); goto ok;
15171 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15172 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15173 ovl.fmt.RXY.dl2,
15174 ovl.fmt.RXY.dh2); goto ok;
15175 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15176 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15177 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15178 ovl.fmt.RXY.dl2,
15179 ovl.fmt.RXY.dh2); goto ok;
15180 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15181 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15182 ovl.fmt.RXY.dl2,
15183 ovl.fmt.RXY.dh2); goto ok;
15184 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15185 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15186 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15187 ovl.fmt.RXY.dl2,
15188 ovl.fmt.RXY.dh2); goto ok;
15189 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15190 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15191 ovl.fmt.RXY.dl2,
15192 ovl.fmt.RXY.dh2); goto ok;
15193 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15194 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15195 ovl.fmt.RXY.dl2,
15196 ovl.fmt.RXY.dh2); goto ok;
15197 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15198 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15199 ovl.fmt.RXY.dl2,
15200 ovl.fmt.RXY.dh2); goto ok;
15201 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15202 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15203 ovl.fmt.RXY.dl2,
15204 ovl.fmt.RXY.dh2); goto ok;
15205 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15206 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15207 ovl.fmt.RXY.dl2,
15208 ovl.fmt.RXY.dh2); goto ok;
15209 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15210 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15211 ovl.fmt.RXY.dl2,
15212 ovl.fmt.RXY.dh2); goto ok;
15213 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15214 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15215 ovl.fmt.RXY.dl2,
15216 ovl.fmt.RXY.dh2); goto ok;
15217 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15218 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15219 ovl.fmt.RXY.dl2,
15220 ovl.fmt.RXY.dh2); goto ok;
15221 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15222 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15223 ovl.fmt.RXY.dl2,
15224 ovl.fmt.RXY.dh2); goto ok;
15225 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15226 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15227 ovl.fmt.RXY.dl2,
15228 ovl.fmt.RXY.dh2); goto ok;
15229 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15230 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15231 ovl.fmt.RXY.dl2,
15232 ovl.fmt.RXY.dh2); goto ok;
15233 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15234 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15235 ovl.fmt.RXY.dl2,
15236 ovl.fmt.RXY.dh2); goto ok;
15237 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15238 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15239 ovl.fmt.RXY.dl2,
15240 ovl.fmt.RXY.dh2); goto ok;
15241 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15242 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15243 ovl.fmt.RXY.dl2,
15244 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015245 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015246 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15247 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15248 ovl.fmt.RXY.dl2,
15249 ovl.fmt.RXY.dh2); goto ok;
15250 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15251 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15252 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15253 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15254 ovl.fmt.RXY.dh2); goto ok;
15255 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15256 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15257 ovl.fmt.RXY.dl2,
15258 ovl.fmt.RXY.dh2); goto ok;
15259 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15260 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15261 ovl.fmt.RXY.dl2,
15262 ovl.fmt.RXY.dh2); goto ok;
15263 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15264 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15265 ovl.fmt.RXY.dl2,
15266 ovl.fmt.RXY.dh2); goto ok;
15267 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15268 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15269 ovl.fmt.RXY.dl2,
15270 ovl.fmt.RXY.dh2); goto ok;
15271 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15272 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15273 ovl.fmt.RXY.dl2,
15274 ovl.fmt.RXY.dh2); goto ok;
15275 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15276 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15277 ovl.fmt.RXY.dl2,
15278 ovl.fmt.RXY.dh2); goto ok;
15279 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15280 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15281 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15282 ovl.fmt.RXY.dh2); goto ok;
15283 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, 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 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, 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 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, 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 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, 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 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, 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 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, 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 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, 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 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15312 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15313 ovl.fmt.RXY.dl2,
15314 ovl.fmt.RXY.dh2); goto ok;
15315 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15316 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15317 ovl.fmt.RXY.dl2,
15318 ovl.fmt.RXY.dh2); goto ok;
15319 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15320 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15321 ovl.fmt.RXY.dl2,
15322 ovl.fmt.RXY.dh2); goto ok;
15323 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15324 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15325 ovl.fmt.RXY.dl2,
15326 ovl.fmt.RXY.dh2); goto ok;
15327 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15328 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15329 ovl.fmt.RXY.dl2,
15330 ovl.fmt.RXY.dh2); goto ok;
15331 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15332 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15333 ovl.fmt.RXY.dl2,
15334 ovl.fmt.RXY.dh2); goto ok;
15335 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15336 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15337 ovl.fmt.RXY.dl2,
15338 ovl.fmt.RXY.dh2); goto ok;
15339 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15340 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15341 ovl.fmt.RXY.dl2,
15342 ovl.fmt.RXY.dh2); goto ok;
15343 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15344 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15345 ovl.fmt.RXY.dl2,
15346 ovl.fmt.RXY.dh2); goto ok;
15347 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15348 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15349 ovl.fmt.RXY.dl2,
15350 ovl.fmt.RXY.dh2); goto ok;
15351 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15352 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15353 ovl.fmt.RXY.dl2,
15354 ovl.fmt.RXY.dh2); goto ok;
15355 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15356 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15357 ovl.fmt.RXY.dl2,
15358 ovl.fmt.RXY.dh2); goto ok;
15359 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15360 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15361 ovl.fmt.RXY.dl2,
15362 ovl.fmt.RXY.dh2); goto ok;
15363 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15364 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15365 ovl.fmt.RXY.dl2,
15366 ovl.fmt.RXY.dh2); goto ok;
15367 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15368 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15369 ovl.fmt.RXY.dl2,
15370 ovl.fmt.RXY.dh2); goto ok;
15371 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15372 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15373 ovl.fmt.RXY.dl2,
15374 ovl.fmt.RXY.dh2); goto ok;
15375 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15376 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15377 ovl.fmt.RXY.dl2,
15378 ovl.fmt.RXY.dh2); goto ok;
15379 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15380 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15381 ovl.fmt.RXY.dl2,
15382 ovl.fmt.RXY.dh2); goto ok;
15383 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15384 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15385 ovl.fmt.RXY.dl2,
15386 ovl.fmt.RXY.dh2); goto ok;
15387 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15388 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15389 ovl.fmt.RXY.dl2,
15390 ovl.fmt.RXY.dh2); goto ok;
15391 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, 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 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, 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;
florian2289cd42012-12-05 04:23:42 +000015399 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015400 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15401 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15402 ovl.fmt.RXY.dl2,
15403 ovl.fmt.RXY.dh2); goto ok;
15404 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15405 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15406 ovl.fmt.RXY.dl2,
15407 ovl.fmt.RXY.dh2); goto ok;
15408 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15409 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15410 ovl.fmt.RXY.dl2,
15411 ovl.fmt.RXY.dh2); goto ok;
15412 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15413 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15414 ovl.fmt.RXY.dl2,
15415 ovl.fmt.RXY.dh2); goto ok;
15416 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15417 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15418 ovl.fmt.RXY.dl2,
15419 ovl.fmt.RXY.dh2); goto ok;
15420 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15421 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15422 ovl.fmt.RXY.dl2,
15423 ovl.fmt.RXY.dh2); goto ok;
15424 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15425 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15426 ovl.fmt.RXY.dl2,
15427 ovl.fmt.RXY.dh2); goto ok;
15428 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15429 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15430 ovl.fmt.RXY.dl2,
15431 ovl.fmt.RXY.dh2); goto ok;
15432 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15433 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15434 ovl.fmt.RXY.dl2,
15435 ovl.fmt.RXY.dh2); goto ok;
15436 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15437 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15438 ovl.fmt.RXY.dl2,
15439 ovl.fmt.RXY.dh2); goto ok;
15440 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15441 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15442 ovl.fmt.RXY.dl2,
15443 ovl.fmt.RXY.dh2); goto ok;
15444 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15445 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15446 ovl.fmt.RXY.dl2,
15447 ovl.fmt.RXY.dh2); goto ok;
15448 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15449 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15450 ovl.fmt.RXY.dl2,
15451 ovl.fmt.RXY.dh2); goto ok;
15452 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15453 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15454 ovl.fmt.RXY.dl2,
15455 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015456 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15457 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15458 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015459 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, 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 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, 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 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, 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 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, 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 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, 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 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, 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;
florian2289cd42012-12-05 04:23:42 +000015483 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015484 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15485 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15486 ovl.fmt.RXY.dl2,
15487 ovl.fmt.RXY.dh2); goto ok;
15488 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15489 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15490 ovl.fmt.RXY.dl2,
15491 ovl.fmt.RXY.dh2); goto ok;
15492 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15493 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15494 ovl.fmt.RXY.dl2,
15495 ovl.fmt.RXY.dh2); goto ok;
15496 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15497 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15498 ovl.fmt.RXY.dl2,
15499 ovl.fmt.RXY.dh2); goto ok;
15500 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15501 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15502 ovl.fmt.RSY.dl2,
15503 ovl.fmt.RSY.dh2); goto ok;
15504 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15505 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15506 ovl.fmt.RSY.dl2,
15507 ovl.fmt.RSY.dh2); goto ok;
15508 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15509 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15510 ovl.fmt.RSY.dl2,
15511 ovl.fmt.RSY.dh2); goto ok;
15512 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15513 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15514 ovl.fmt.RSY.dl2,
15515 ovl.fmt.RSY.dh2); goto ok;
15516 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15517 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15518 ovl.fmt.RSY.dl2,
15519 ovl.fmt.RSY.dh2); goto ok;
15520 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15521 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15522 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15523 ovl.fmt.RSY.dl2,
15524 ovl.fmt.RSY.dh2); goto ok;
15525 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15526 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15527 ovl.fmt.RSY.dl2,
15528 ovl.fmt.RSY.dh2); goto ok;
15529 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15530 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15531 ovl.fmt.RSY.dl2,
15532 ovl.fmt.RSY.dh2); goto ok;
15533 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15534 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15535 ovl.fmt.RSY.dl2,
15536 ovl.fmt.RSY.dh2); goto ok;
15537 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15538 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15539 ovl.fmt.RSY.dl2,
15540 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015541 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015542 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15543 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15544 ovl.fmt.RSY.dl2,
15545 ovl.fmt.RSY.dh2); goto ok;
15546 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15547 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15548 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15549 ovl.fmt.RSY.dl2,
15550 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015551 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015552 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15553 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15554 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15555 ovl.fmt.RSY.dh2); goto ok;
15556 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15557 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15558 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15559 ovl.fmt.RSY.dh2); goto ok;
15560 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15561 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15562 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15563 ovl.fmt.RSY.dl2,
15564 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015565 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15566 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15567 ovl.fmt.RSY.dl2,
15568 ovl.fmt.RSY.dh2); goto ok;
15569 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15570 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15571 ovl.fmt.RSY.dl2,
15572 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015573 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15574 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15575 ovl.fmt.RSY.dl2,
15576 ovl.fmt.RSY.dh2); goto ok;
15577 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15578 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15579 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15580 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015581 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15582 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15583 ovl.fmt.RSY.dl2,
15584 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015585 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15586 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15587 ovl.fmt.SIY.dh1); goto ok;
15588 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15589 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15590 ovl.fmt.SIY.dh1); goto ok;
15591 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15592 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15593 ovl.fmt.SIY.dh1); goto ok;
15594 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15595 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15596 ovl.fmt.SIY.dh1); goto ok;
15597 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15598 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15599 ovl.fmt.SIY.dh1); goto ok;
15600 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15601 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15602 ovl.fmt.SIY.dh1); goto ok;
15603 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15604 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15605 ovl.fmt.SIY.dh1); goto ok;
15606 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15607 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15608 ovl.fmt.SIY.dh1); goto ok;
15609 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15610 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15611 ovl.fmt.SIY.dh1); goto ok;
15612 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15613 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15614 ovl.fmt.SIY.dh1); goto ok;
15615 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15616 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15617 ovl.fmt.RSY.dl2,
15618 ovl.fmt.RSY.dh2); goto ok;
15619 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15620 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15621 ovl.fmt.RSY.dl2,
15622 ovl.fmt.RSY.dh2); goto ok;
15623 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15624 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15625 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15626 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15627 ovl.fmt.RSY.dl2,
15628 ovl.fmt.RSY.dh2); goto ok;
15629 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15630 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15631 ovl.fmt.RSY.dl2,
15632 ovl.fmt.RSY.dh2); goto ok;
15633 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15634 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15635 ovl.fmt.RSY.dl2,
15636 ovl.fmt.RSY.dh2); goto ok;
15637 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15638 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15639 ovl.fmt.RSY.dl2,
15640 ovl.fmt.RSY.dh2); goto ok;
15641 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15642 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15643 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15644 ovl.fmt.RSY.dh2); goto ok;
15645 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15646 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15647 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15648 ovl.fmt.RSY.dl2,
15649 ovl.fmt.RSY.dh2); goto ok;
15650 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15651 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15652 ovl.fmt.RSY.dl2,
15653 ovl.fmt.RSY.dh2); goto ok;
15654 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15655 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15656 ovl.fmt.RSY.dl2,
15657 ovl.fmt.RSY.dh2); goto ok;
15658 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15659 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15660 ovl.fmt.RSY.dl2,
15661 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015662 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15663 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15664 ovl.fmt.RSY.dl2,
15665 ovl.fmt.RSY.dh2,
15666 S390_XMNM_LOCG); goto ok;
15667 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15668 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15669 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15670 ovl.fmt.RSY.dh2,
15671 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015672 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15673 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15674 ovl.fmt.RSY.dl2,
15675 ovl.fmt.RSY.dh2); goto ok;
15676 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15677 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15678 ovl.fmt.RSY.dl2,
15679 ovl.fmt.RSY.dh2); goto ok;
15680 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15681 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15682 ovl.fmt.RSY.dl2,
15683 ovl.fmt.RSY.dh2); goto ok;
15684 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15685 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15686 ovl.fmt.RSY.dl2,
15687 ovl.fmt.RSY.dh2); goto ok;
15688 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
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;
sewardjd7bde722011-04-05 13:19:33 +000015692 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15693 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15694 ovl.fmt.RSY.dl2,
15695 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15696 goto ok;
15697 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15698 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15699 ovl.fmt.RSY.dl2,
15700 ovl.fmt.RSY.dh2,
15701 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015702 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15703 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15704 ovl.fmt.RSY.dl2,
15705 ovl.fmt.RSY.dh2); goto ok;
15706 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15707 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15708 ovl.fmt.RSY.dl2,
15709 ovl.fmt.RSY.dh2); goto ok;
15710 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15711 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15712 ovl.fmt.RSY.dl2,
15713 ovl.fmt.RSY.dh2); goto ok;
15714 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15715 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15716 ovl.fmt.RSY.dl2,
15717 ovl.fmt.RSY.dh2); goto ok;
15718 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15719 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15720 ovl.fmt.RSY.dl2,
15721 ovl.fmt.RSY.dh2); goto ok;
15722 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15723 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15724 goto ok;
15725 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15726 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15727 goto ok;
15728 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15729 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15730 ovl.fmt.RIE_RRUUU.r1,
15731 ovl.fmt.RIE_RRUUU.r2,
15732 ovl.fmt.RIE_RRUUU.i3,
15733 ovl.fmt.RIE_RRUUU.i4,
15734 ovl.fmt.RIE_RRUUU.i5);
15735 goto ok;
15736 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15737 ovl.fmt.RIE_RRUUU.r1,
15738 ovl.fmt.RIE_RRUUU.r2,
15739 ovl.fmt.RIE_RRUUU.i3,
15740 ovl.fmt.RIE_RRUUU.i4,
15741 ovl.fmt.RIE_RRUUU.i5);
15742 goto ok;
15743 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15744 ovl.fmt.RIE_RRUUU.r1,
15745 ovl.fmt.RIE_RRUUU.r2,
15746 ovl.fmt.RIE_RRUUU.i3,
15747 ovl.fmt.RIE_RRUUU.i4,
15748 ovl.fmt.RIE_RRUUU.i5);
15749 goto ok;
15750 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15751 ovl.fmt.RIE_RRUUU.r1,
15752 ovl.fmt.RIE_RRUUU.r2,
15753 ovl.fmt.RIE_RRUUU.i3,
15754 ovl.fmt.RIE_RRUUU.i4,
15755 ovl.fmt.RIE_RRUUU.i5);
15756 goto ok;
florian2289cd42012-12-05 04:23:42 +000015757 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015758 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15759 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15760 ovl.fmt.RIE_RRPU.r1,
15761 ovl.fmt.RIE_RRPU.r2,
15762 ovl.fmt.RIE_RRPU.i4,
15763 ovl.fmt.RIE_RRPU.m3); goto ok;
15764 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15765 ovl.fmt.RIE_RRPU.r1,
15766 ovl.fmt.RIE_RRPU.r2,
15767 ovl.fmt.RIE_RRPU.i4,
15768 ovl.fmt.RIE_RRPU.m3); goto ok;
15769 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15770 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15771 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15772 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15773 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15774 ovl.fmt.RIE_RRPU.r1,
15775 ovl.fmt.RIE_RRPU.r2,
15776 ovl.fmt.RIE_RRPU.i4,
15777 ovl.fmt.RIE_RRPU.m3); goto ok;
15778 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15779 ovl.fmt.RIE_RRPU.r1,
15780 ovl.fmt.RIE_RRPU.r2,
15781 ovl.fmt.RIE_RRPU.i4,
15782 ovl.fmt.RIE_RRPU.m3); goto ok;
15783 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15784 ovl.fmt.RIEv3.r1,
15785 ovl.fmt.RIEv3.m3,
15786 ovl.fmt.RIEv3.i4,
15787 ovl.fmt.RIEv3.i2); goto ok;
15788 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15789 ovl.fmt.RIEv3.r1,
15790 ovl.fmt.RIEv3.m3,
15791 ovl.fmt.RIEv3.i4,
15792 ovl.fmt.RIEv3.i2); goto ok;
15793 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15794 ovl.fmt.RIEv3.r1,
15795 ovl.fmt.RIEv3.m3,
15796 ovl.fmt.RIEv3.i4,
15797 ovl.fmt.RIEv3.i2); goto ok;
15798 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15799 ovl.fmt.RIEv3.r1,
15800 ovl.fmt.RIEv3.m3,
15801 ovl.fmt.RIEv3.i4,
15802 ovl.fmt.RIEv3.i2); goto ok;
15803 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15804 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15805 goto ok;
15806 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15807 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15808 ovl.fmt.RIE.i2); goto ok;
15809 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15810 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15811 ovl.fmt.RIE.i2); goto ok;
15812 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15813 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15814 ovl.fmt.RIE.i2); goto ok;
15815 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15816 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15817 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15818 goto ok;
15819 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15820 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15821 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15822 goto ok;
15823 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15824 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15825 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15826 goto ok;
15827 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15828 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15829 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15830 goto ok;
15831 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15832 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15833 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15834 ovl.fmt.RIS.i2); goto ok;
15835 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15836 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15837 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15838 ovl.fmt.RIS.i2); goto ok;
15839 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15840 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15841 ovl.fmt.RIS.d4,
15842 ovl.fmt.RIS.i2); goto ok;
15843 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15844 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15845 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15846 ovl.fmt.RIS.i2); goto ok;
15847 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15848 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15849 ovl.fmt.RXE.d2); goto ok;
15850 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15851 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15852 ovl.fmt.RXE.d2); goto ok;
15853 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15854 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15855 ovl.fmt.RXE.d2); goto ok;
15856 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15857 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15858 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15859 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15860 ovl.fmt.RXE.d2); goto ok;
15861 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15862 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15863 ovl.fmt.RXE.d2); goto ok;
15864 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
15865 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15866 ovl.fmt.RXE.d2); goto ok;
15867 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
15868 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
15869 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15870 ovl.fmt.RXE.d2); goto ok;
15871 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
15872 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15873 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15874 ovl.fmt.RXF.r1); goto ok;
15875 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
15876 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15877 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15878 ovl.fmt.RXF.r1); goto ok;
15879 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
15880 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15881 ovl.fmt.RXE.d2); goto ok;
15882 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
15883 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15884 ovl.fmt.RXE.d2); goto ok;
15885 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
15886 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15887 ovl.fmt.RXE.d2); goto ok;
15888 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
15889 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15890 ovl.fmt.RXE.d2); goto ok;
15891 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
15892 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15893 ovl.fmt.RXE.d2); goto ok;
15894 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
15895 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15896 ovl.fmt.RXE.d2); goto ok;
15897 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
15898 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
15899 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15900 ovl.fmt.RXE.d2); goto ok;
15901 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
15902 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15903 ovl.fmt.RXE.d2); goto ok;
15904 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
15905 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15906 ovl.fmt.RXE.d2); goto ok;
15907 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
15908 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15909 ovl.fmt.RXE.d2); goto ok;
15910 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
15911 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15912 ovl.fmt.RXE.d2); goto ok;
15913 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
15914 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15915 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15916 ovl.fmt.RXF.r1); goto ok;
15917 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
15918 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15919 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15920 ovl.fmt.RXF.r1); goto ok;
15921 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
15922 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
15923 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
15924 case 0xed000000002eULL: /* MAE */ goto unimplemented;
15925 case 0xed000000002fULL: /* MSE */ goto unimplemented;
15926 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
15927 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
15928 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
15929 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
15930 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
15931 case 0xed000000003aULL: /* MAY */ goto unimplemented;
15932 case 0xed000000003bULL: /* MY */ goto unimplemented;
15933 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
15934 case 0xed000000003dULL: /* MYH */ goto unimplemented;
15935 case 0xed000000003eULL: /* MAD */ goto unimplemented;
15936 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000015937 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
15938 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15939 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15940 ovl.fmt.RXF.r1); goto ok;
15941 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
15942 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15943 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15944 ovl.fmt.RXF.r1); goto ok;
15945 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
15946 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15947 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15948 ovl.fmt.RXF.r1); goto ok;
15949 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
15950 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15951 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15952 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000015953 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
15954 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15955 ovl.fmt.RXE.d2); goto ok;
15956 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
15957 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15958 ovl.fmt.RXE.d2); goto ok;
15959 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
15960 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15961 ovl.fmt.RXE.d2); goto ok;
15962 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
15963 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15964 ovl.fmt.RXE.d2); goto ok;
15965 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
15966 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15967 ovl.fmt.RXE.d2); goto ok;
15968 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
15969 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15970 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015971 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
15972 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15973 ovl.fmt.RXY.dl2,
15974 ovl.fmt.RXY.dh2); goto ok;
15975 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
15976 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15977 ovl.fmt.RXY.dl2,
15978 ovl.fmt.RXY.dh2); goto ok;
15979 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
15980 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15981 ovl.fmt.RXY.dl2,
15982 ovl.fmt.RXY.dh2); goto ok;
15983 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
15984 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15985 ovl.fmt.RXY.dl2,
15986 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015987 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
15988 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
15989 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
15990 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015991 }
15992
15993 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
15994 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
15995 ovl.fmt.RIL.i2); goto ok;
15996 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
15997 ovl.fmt.RIL.i2); goto ok;
15998 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
15999 ovl.fmt.RIL.i2); goto ok;
16000 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16001 ovl.fmt.RIL.i2); goto ok;
16002 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16003 ovl.fmt.RIL.i2); goto ok;
16004 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16005 ovl.fmt.RIL.i2); goto ok;
16006 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16007 ovl.fmt.RIL.i2); goto ok;
16008 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16009 ovl.fmt.RIL.i2); goto ok;
16010 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16011 ovl.fmt.RIL.i2); goto ok;
16012 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16013 ovl.fmt.RIL.i2); goto ok;
16014 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16015 ovl.fmt.RIL.i2); goto ok;
16016 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16017 ovl.fmt.RIL.i2); goto ok;
16018 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16019 ovl.fmt.RIL.i2); goto ok;
16020 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16021 ovl.fmt.RIL.i2); goto ok;
16022 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16023 ovl.fmt.RIL.i2); goto ok;
16024 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16025 ovl.fmt.RIL.i2); goto ok;
16026 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16027 ovl.fmt.RIL.i2); goto ok;
16028 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16029 ovl.fmt.RIL.i2); goto ok;
16030 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16031 ovl.fmt.RIL.i2); goto ok;
16032 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16033 ovl.fmt.RIL.i2); goto ok;
16034 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16035 ovl.fmt.RIL.i2); goto ok;
16036 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16037 ovl.fmt.RIL.i2); goto ok;
16038 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16039 ovl.fmt.RIL.i2); goto ok;
16040 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16041 ovl.fmt.RIL.i2); goto ok;
16042 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16043 ovl.fmt.RIL.i2); goto ok;
16044 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16045 ovl.fmt.RIL.i2); goto ok;
16046 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16047 ovl.fmt.RIL.i2); goto ok;
16048 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16049 ovl.fmt.RIL.i2); goto ok;
16050 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16051 ovl.fmt.RIL.i2); goto ok;
16052 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16053 ovl.fmt.RIL.i2); goto ok;
16054 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16055 ovl.fmt.RIL.i2); goto ok;
16056 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16057 ovl.fmt.RIL.i2); goto ok;
16058 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16059 ovl.fmt.RIL.i2); goto ok;
16060 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16061 ovl.fmt.RIL.i2); goto ok;
16062 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16063 ovl.fmt.RIL.i2); goto ok;
16064 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16065 ovl.fmt.RIL.i2); goto ok;
16066 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16067 ovl.fmt.RIL.i2); goto ok;
16068 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16069 ovl.fmt.RIL.i2); goto ok;
16070 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16071 ovl.fmt.RIL.i2); goto ok;
16072 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16073 ovl.fmt.RIL.i2); goto ok;
16074 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16075 ovl.fmt.RIL.i2); goto ok;
16076 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16077 ovl.fmt.RIL.i2); goto ok;
16078 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16079 ovl.fmt.RIL.i2); goto ok;
16080 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16081 ovl.fmt.RIL.i2); goto ok;
16082 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16083 ovl.fmt.RIL.i2); goto ok;
16084 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16085 ovl.fmt.RIL.i2); goto ok;
16086 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16087 ovl.fmt.RIL.i2); goto ok;
16088 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16089 ovl.fmt.RIL.i2); goto ok;
16090 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16091 ovl.fmt.RIL.i2); goto ok;
16092 case 0xc800ULL: /* MVCOS */ goto unimplemented;
16093 case 0xc801ULL: /* ECTG */ goto unimplemented;
16094 case 0xc802ULL: /* CSST */ goto unimplemented;
16095 case 0xc804ULL: /* LPD */ goto unimplemented;
16096 case 0xc805ULL: /* LPDG */ goto unimplemented;
16097 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
16098 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16099 ovl.fmt.RIL.i2); goto ok;
16100 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16101 ovl.fmt.RIL.i2); goto ok;
16102 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16103 ovl.fmt.RIL.i2); goto ok;
16104 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16105 ovl.fmt.RIL.i2); goto ok;
16106 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16107 ovl.fmt.RIL.i2); goto ok;
16108 }
16109
16110 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000016111 case 0xc5ULL: /* BPRP */ goto unimplemented;
16112 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016113 case 0xd0ULL: /* TRTR */ goto unimplemented;
16114 case 0xd1ULL: /* MVN */ goto unimplemented;
16115 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16116 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16117 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16118 case 0xd3ULL: /* MVZ */ goto unimplemented;
16119 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16120 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16121 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16122 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16123 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16124 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16125 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16126 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16127 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000016128 case 0xd7ULL:
16129 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16130 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16131 else
16132 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16133 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16134 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16135 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016136 case 0xd9ULL: /* MVCK */ goto unimplemented;
16137 case 0xdaULL: /* MVCP */ goto unimplemented;
16138 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000016139 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16140 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16141 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016142 case 0xddULL: /* TRT */ goto unimplemented;
16143 case 0xdeULL: /* ED */ goto unimplemented;
16144 case 0xdfULL: /* EDMK */ goto unimplemented;
16145 case 0xe1ULL: /* PKU */ goto unimplemented;
16146 case 0xe2ULL: /* UNPKU */ goto unimplemented;
16147 case 0xe8ULL: /* MVCIN */ goto unimplemented;
16148 case 0xe9ULL: /* PKA */ goto unimplemented;
16149 case 0xeaULL: /* UNPKA */ goto unimplemented;
16150 case 0xeeULL: /* PLO */ goto unimplemented;
16151 case 0xefULL: /* LMD */ goto unimplemented;
16152 case 0xf0ULL: /* SRP */ goto unimplemented;
16153 case 0xf1ULL: /* MVO */ goto unimplemented;
16154 case 0xf2ULL: /* PACK */ goto unimplemented;
16155 case 0xf3ULL: /* UNPK */ goto unimplemented;
16156 case 0xf8ULL: /* ZAP */ goto unimplemented;
16157 case 0xf9ULL: /* CP */ goto unimplemented;
16158 case 0xfaULL: /* AP */ goto unimplemented;
16159 case 0xfbULL: /* SP */ goto unimplemented;
16160 case 0xfcULL: /* MP */ goto unimplemented;
16161 case 0xfdULL: /* DP */ goto unimplemented;
16162 }
16163
16164 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16165 case 0xe500ULL: /* LASP */ goto unimplemented;
16166 case 0xe501ULL: /* TPROT */ goto unimplemented;
16167 case 0xe502ULL: /* STRAG */ goto unimplemented;
16168 case 0xe50eULL: /* MVCSK */ goto unimplemented;
16169 case 0xe50fULL: /* MVCDK */ goto unimplemented;
16170 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16171 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16172 goto ok;
16173 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16174 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16175 goto ok;
16176 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16177 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16178 goto ok;
16179 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16180 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16181 goto ok;
16182 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16183 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16184 goto ok;
16185 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16186 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16187 goto ok;
16188 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16189 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16190 goto ok;
16191 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16192 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16193 goto ok;
16194 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16195 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16196 goto ok;
florian2289cd42012-12-05 04:23:42 +000016197 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16198 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016199 }
16200
16201 return S390_DECODE_UNKNOWN_INSN;
16202
16203ok:
16204 return S390_DECODE_OK;
16205
16206unimplemented:
16207 return S390_DECODE_UNIMPLEMENTED_INSN;
16208}
16209
16210/* Handle "special" instructions. */
16211static s390_decode_t
16212s390_decode_special_and_irgen(UChar *bytes)
16213{
16214 s390_decode_t status = S390_DECODE_OK;
16215
16216 /* Got a "Special" instruction preamble. Which one is it? */
16217 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16218 s390_irgen_client_request();
16219 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16220 s390_irgen_guest_NRADDR();
16221 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16222 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016223 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16224 vex_inject_ir(irsb, Iend_BE);
16225
16226 /* Invalidate the current insn. The reason is that the IRop we're
16227 injecting here can change. In which case the translation has to
16228 be redone. For ease of handling, we simply invalidate all the
16229 time. */
16230 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
16231 mkU64(guest_IA_curr_instr)));
16232 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
16233 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16234 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16235 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16236
16237 put_IA(mkaddr_expr(guest_IA_next_instr));
16238 dis_res->whatNext = Dis_StopHere;
16239 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000016240 } else {
16241 /* We don't know what it is. */
16242 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16243 }
16244
16245 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16246
16247 return status;
16248}
16249
16250
16251/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016252static UInt
sewardj2019a972011-03-07 16:04:07 +000016253s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
16254{
16255 s390_decode_t status;
16256
16257 dis_res = dres;
16258
16259 /* Spot the 8-byte preamble: 18ff lr r15,r15
16260 1811 lr r1,r1
16261 1822 lr r2,r2
16262 1833 lr r3,r3 */
16263 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16264 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16265 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16266
16267 /* Handle special instruction that follows that preamble. */
16268 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016269
16270 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16271 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16272
16273 status =
16274 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016275 } else {
16276 /* Handle normal instructions. */
16277 switch (insn_length) {
16278 case 2:
16279 status = s390_decode_2byte_and_irgen(bytes);
16280 break;
16281
16282 case 4:
16283 status = s390_decode_4byte_and_irgen(bytes);
16284 break;
16285
16286 case 6:
16287 status = s390_decode_6byte_and_irgen(bytes);
16288 break;
16289
16290 default:
16291 status = S390_DECODE_ERROR;
16292 break;
16293 }
16294 }
florian5fcbba22011-07-27 20:40:22 +000016295 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016296 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16297 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016298 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016299 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016300 }
16301
16302 if (status == S390_DECODE_OK) return insn_length; /* OK */
16303
16304 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016305 if (sigill_diag) {
16306 vex_printf("vex s390->IR: ");
16307 switch (status) {
16308 case S390_DECODE_UNKNOWN_INSN:
16309 vex_printf("unknown insn: ");
16310 break;
sewardj2019a972011-03-07 16:04:07 +000016311
sewardj442e51a2012-12-06 18:08:04 +000016312 case S390_DECODE_UNIMPLEMENTED_INSN:
16313 vex_printf("unimplemented insn: ");
16314 break;
sewardj2019a972011-03-07 16:04:07 +000016315
sewardj442e51a2012-12-06 18:08:04 +000016316 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16317 vex_printf("unimplemented special insn: ");
16318 break;
sewardj2019a972011-03-07 16:04:07 +000016319
sewardj442e51a2012-12-06 18:08:04 +000016320 default:
16321 case S390_DECODE_ERROR:
16322 vex_printf("decoding error: ");
16323 break;
16324 }
16325
16326 vex_printf("%02x%02x", bytes[0], bytes[1]);
16327 if (insn_length > 2) {
16328 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16329 }
16330 if (insn_length > 4) {
16331 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16332 }
16333 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016334 }
16335
sewardj2019a972011-03-07 16:04:07 +000016336 return 0; /* Failed */
16337}
16338
16339
sewardj2019a972011-03-07 16:04:07 +000016340/* Disassemble a single instruction INSN into IR. */
16341static DisResult
florian420c5012011-07-22 02:12:28 +000016342disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016343{
16344 UChar byte;
16345 UInt insn_length;
16346 DisResult dres;
16347
16348 /* ---------------------------------------------------- */
16349 /* --- Compute instruction length -- */
16350 /* ---------------------------------------------------- */
16351
16352 /* Get the first byte of the insn. */
16353 byte = insn[0];
16354
16355 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16356 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16357 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16358
16359 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16360
16361 /* ---------------------------------------------------- */
16362 /* --- Initialise the DisResult data -- */
16363 /* ---------------------------------------------------- */
16364 dres.whatNext = Dis_Continue;
16365 dres.len = insn_length;
16366 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016367 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000016368
floriana99f20e2011-07-17 14:16:41 +000016369 /* fixs390: consider chasing of conditional jumps */
16370
sewardj2019a972011-03-07 16:04:07 +000016371 /* Normal and special instruction handling starts here. */
16372 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16373 /* All decode failures end up here. The decoder has already issued an
16374 error message.
16375 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016376 not been executed, and (is currently) the next to be executed.
16377 The insn address in the guest state needs to be set to
16378 guest_IA_curr_instr, otherwise the complaint will report an
16379 incorrect address. */
16380 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016381
florian8844a632012-04-13 04:04:06 +000016382 dres.whatNext = Dis_StopHere;
16383 dres.jk_StopHere = Ijk_NoDecode;
16384 dres.continueAt = 0;
16385 dres.len = 0;
16386 } else {
16387 /* Decode success */
16388 switch (dres.whatNext) {
16389 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016390 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016391 break;
16392 case Dis_ResteerU:
16393 case Dis_ResteerC:
16394 put_IA(mkaddr_expr(dres.continueAt));
16395 break;
16396 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016397 if (dres.jk_StopHere == Ijk_EmWarn ||
16398 dres.jk_StopHere == Ijk_EmFail) {
16399 /* We assume here, that emulation warnings are not given for
16400 insns that transfer control. There is no good way to
16401 do that. */
16402 put_IA(mkaddr_expr(guest_IA_next_instr));
16403 }
florian8844a632012-04-13 04:04:06 +000016404 break;
16405 default:
16406 vassert(0);
16407 }
sewardj2019a972011-03-07 16:04:07 +000016408 }
16409
16410 return dres;
16411}
16412
16413
16414/*------------------------------------------------------------*/
16415/*--- Top-level fn ---*/
16416/*------------------------------------------------------------*/
16417
16418/* Disassemble a single instruction into IR. The instruction
16419 is located in host memory at &guest_code[delta]. */
16420
16421DisResult
16422disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000016423 Bool (*resteerOkFn)(void *, Addr64),
16424 Bool resteerCisOk,
16425 void *callback_opaque,
16426 UChar *guest_code,
16427 Long delta,
16428 Addr64 guest_IP,
16429 VexArch guest_arch,
16430 VexArchInfo *archinfo,
16431 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000016432 Bool host_bigendian,
16433 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016434{
16435 vassert(guest_arch == VexArchS390X);
16436
16437 /* The instruction decoder requires a big-endian machine. */
16438 vassert(host_bigendian == True);
16439
16440 /* Set globals (see top of this file) */
16441 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016442 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016443 resteer_fn = resteerOkFn;
16444 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016445 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016446
florian420c5012011-07-22 02:12:28 +000016447 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016448}
16449
16450/*---------------------------------------------------------------*/
16451/*--- end guest_s390_toIR.c ---*/
16452/*---------------------------------------------------------------*/