blob: eb750a87946c30656108f1fe134457b4afcf2563 [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
sewardj89ae8472013-10-18 14:12:58 +000011 Copyright IBM Corp. 2010-2013
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
florian99dd03e2013-01-29 03:56:06 +0000243 return IRExpr_ITE(condition, iftrue, iffalse);
sewardj2019a972011-03-07 16:04:07 +0000244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
florianbafb8262013-05-31 15:41:55 +0000635 /* Make the CC_DEP1 slot appear completely defined.
636 Otherwise, assigning a 32-bit value will cause memcheck
637 to trigger an undefinedness error.
638 */
639 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
640 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
641 stmt(IRStmt_Put(dep1_off, mkU64(0)));
642 }
sewardj2019a972011-03-07 16:04:07 +0000643 op = mkU64(opc);
644 dep1 = mkexpr(d1);
645 dep2 = mkU64(0);
646 ndep = mkU64(0);
647
648 s390_cc_thunk_fill(op, dep1, dep2, ndep);
649}
650
651
652/* Write a floating point value and an integer into the flags thunk. The
653 integer value is zero-extended first. */
654static void
655s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
656{
657 IRExpr *op, *dep1, *dep2, *ndep;
658
florianbafb8262013-05-31 15:41:55 +0000659 /* Make the CC_DEP1 slot appear completely defined.
660 Otherwise, assigning a 32-bit value will cause memcheck
661 to trigger an undefinedness error.
662 */
663 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
664 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
665 stmt(IRStmt_Put(dep1_off, mkU64(0)));
666 }
sewardj2019a972011-03-07 16:04:07 +0000667 op = mkU64(opc);
668 dep1 = mkexpr(d1);
669 dep2 = s390_cc_widen(d2, False);
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, dep1, dep2, ndep);
673}
674
675
676/* Write a 128-bit floating point value into the flags thunk. This is
677 done by splitting the value into two 64-bits values. */
678static void
679s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
680{
681 IRExpr *op, *hi, *lo, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
686 ndep = mkU64(0);
687
688 s390_cc_thunk_fill(op, hi, lo, ndep);
689}
690
691
692/* Write a 128-bit floating point value and an integer into the flags thunk.
693 The integer value is zero-extended first. */
694static void
695s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
696{
697 IRExpr *op, *hi, *lo, *lox, *ndep;
698
699 op = mkU64(opc);
700 hi = unop(Iop_F128HItoF64, mkexpr(d1));
701 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
702 ndep = s390_cc_widen(nd, False);
703
704 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
705
706 s390_cc_thunk_fill(op, hi, lox, ndep);
707}
708
709
floriane38f6412012-12-21 17:32:12 +0000710/* Write a 128-bit decimal floating point value into the flags thunk.
711 This is done by splitting the value into two 64-bits values. */
712static void
713s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
714{
715 IRExpr *op, *hi, *lo, *ndep;
716
717 op = mkU64(opc);
718 hi = unop(Iop_D128HItoD64, mkexpr(d1));
719 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
720 ndep = mkU64(0);
721
722 s390_cc_thunk_fill(op, hi, lo, ndep);
723}
724
725
floriance9e3db2012-12-27 20:14:03 +0000726/* Write a 128-bit decimal floating point value and an integer into the flags
727 thunk. The integer value is zero-extended first. */
728static void
729s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
730{
731 IRExpr *op, *hi, *lo, *lox, *ndep;
732
733 op = mkU64(opc);
734 hi = unop(Iop_D128HItoD64, mkexpr(d1));
735 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
736 ndep = s390_cc_widen(nd, False);
737
738 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
739
740 s390_cc_thunk_fill(op, hi, lox, ndep);
741}
742
743
sewardj2019a972011-03-07 16:04:07 +0000744static void
745s390_cc_set(UInt val)
746{
747 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
748 mkU64(val), mkU64(0), mkU64(0));
749}
750
751/* Build IR to calculate the condition code from flags thunk.
752 Returns an expression of type Ity_I32 */
753static IRExpr *
754s390_call_calculate_cc(void)
755{
756 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
757
florian428dfdd2012-03-27 03:09:49 +0000758 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
759 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
760 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
761 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000762
763 args = mkIRExprVec_4(op, dep1, dep2, ndep);
764 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
765 "s390_calculate_cc", &s390_calculate_cc, args);
766
767 /* Exclude OP and NDEP from definedness checking. We're only
768 interested in DEP1 and DEP2. */
769 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
770
771 return call;
772}
773
774/* Build IR to calculate the internal condition code for a "compare and branch"
775 insn. Returns an expression of type Ity_I32 */
776static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000777s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000778{
florianff9613f2012-05-12 15:26:44 +0000779 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000780
florianff9613f2012-05-12 15:26:44 +0000781 switch (opc) {
782 case S390_CC_OP_SIGNED_COMPARE:
783 dep1 = s390_cc_widen(op1, True);
784 dep2 = s390_cc_widen(op2, True);
785 break;
786
787 case S390_CC_OP_UNSIGNED_COMPARE:
788 dep1 = s390_cc_widen(op1, False);
789 dep2 = s390_cc_widen(op2, False);
790 break;
791
792 default:
793 vpanic("s390_call_calculate_icc");
794 }
795
796 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000797 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000798
florianff9613f2012-05-12 15:26:44 +0000799 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000800 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000801 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000802
florianff9613f2012-05-12 15:26:44 +0000803 /* Exclude the requested condition, OP and NDEP from definedness
804 checking. We're only interested in DEP1 and DEP2. */
805 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000806
807 return call;
808}
809
810/* Build IR to calculate the condition code from flags thunk.
811 Returns an expression of type Ity_I32 */
812static IRExpr *
813s390_call_calculate_cond(UInt m)
814{
815 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
816
817 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000818 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
819 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
820 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
821 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000822
823 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
824 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
825 "s390_calculate_cond", &s390_calculate_cond, args);
826
827 /* Exclude the requested condition, OP and NDEP from definedness
828 checking. We're only interested in DEP1 and DEP2. */
829 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
830
831 return call;
832}
833
834#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
835#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
836#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
837#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
838#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
839#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
840#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
841 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
842#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
843 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000844
845
sewardj2019a972011-03-07 16:04:07 +0000846
847
848/*------------------------------------------------------------*/
849/*--- Guest register access ---*/
850/*------------------------------------------------------------*/
851
852
853/*------------------------------------------------------------*/
854/*--- ar registers ---*/
855/*------------------------------------------------------------*/
856
857/* Return the guest state offset of a ar register. */
858static UInt
859ar_offset(UInt archreg)
860{
861 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000862 S390X_GUEST_OFFSET(guest_a0),
863 S390X_GUEST_OFFSET(guest_a1),
864 S390X_GUEST_OFFSET(guest_a2),
865 S390X_GUEST_OFFSET(guest_a3),
866 S390X_GUEST_OFFSET(guest_a4),
867 S390X_GUEST_OFFSET(guest_a5),
868 S390X_GUEST_OFFSET(guest_a6),
869 S390X_GUEST_OFFSET(guest_a7),
870 S390X_GUEST_OFFSET(guest_a8),
871 S390X_GUEST_OFFSET(guest_a9),
872 S390X_GUEST_OFFSET(guest_a10),
873 S390X_GUEST_OFFSET(guest_a11),
874 S390X_GUEST_OFFSET(guest_a12),
875 S390X_GUEST_OFFSET(guest_a13),
876 S390X_GUEST_OFFSET(guest_a14),
877 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000878 };
879
880 vassert(archreg < 16);
881
882 return offset[archreg];
883}
884
885
886/* Return the guest state offset of word #0 of a ar register. */
887static __inline__ UInt
888ar_w0_offset(UInt archreg)
889{
890 return ar_offset(archreg) + 0;
891}
892
893/* Write word #0 of a ar to the guest state. */
894static __inline__ void
895put_ar_w0(UInt archreg, IRExpr *expr)
896{
897 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
898
899 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
900}
901
902/* Read word #0 of a ar register. */
903static __inline__ IRExpr *
904get_ar_w0(UInt archreg)
905{
906 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
907}
908
909
910/*------------------------------------------------------------*/
911/*--- fpr registers ---*/
912/*------------------------------------------------------------*/
913
914/* Return the guest state offset of a fpr register. */
915static UInt
916fpr_offset(UInt archreg)
917{
918 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000919 S390X_GUEST_OFFSET(guest_f0),
920 S390X_GUEST_OFFSET(guest_f1),
921 S390X_GUEST_OFFSET(guest_f2),
922 S390X_GUEST_OFFSET(guest_f3),
923 S390X_GUEST_OFFSET(guest_f4),
924 S390X_GUEST_OFFSET(guest_f5),
925 S390X_GUEST_OFFSET(guest_f6),
926 S390X_GUEST_OFFSET(guest_f7),
927 S390X_GUEST_OFFSET(guest_f8),
928 S390X_GUEST_OFFSET(guest_f9),
929 S390X_GUEST_OFFSET(guest_f10),
930 S390X_GUEST_OFFSET(guest_f11),
931 S390X_GUEST_OFFSET(guest_f12),
932 S390X_GUEST_OFFSET(guest_f13),
933 S390X_GUEST_OFFSET(guest_f14),
934 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000935 };
936
937 vassert(archreg < 16);
938
939 return offset[archreg];
940}
941
942
943/* Return the guest state offset of word #0 of a fpr register. */
944static __inline__ UInt
945fpr_w0_offset(UInt archreg)
946{
947 return fpr_offset(archreg) + 0;
948}
949
950/* Write word #0 of a fpr to the guest state. */
951static __inline__ void
952put_fpr_w0(UInt archreg, IRExpr *expr)
953{
954 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
955
956 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
957}
958
959/* Read word #0 of a fpr register. */
960static __inline__ IRExpr *
961get_fpr_w0(UInt archreg)
962{
963 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
964}
965
966/* Return the guest state offset of double word #0 of a fpr register. */
967static __inline__ UInt
968fpr_dw0_offset(UInt archreg)
969{
970 return fpr_offset(archreg) + 0;
971}
972
973/* Write double word #0 of a fpr to the guest state. */
974static __inline__ void
975put_fpr_dw0(UInt archreg, IRExpr *expr)
976{
977 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
978
979 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
980}
981
982/* Read double word #0 of a fpr register. */
983static __inline__ IRExpr *
984get_fpr_dw0(UInt archreg)
985{
986 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
987}
988
floriane38f6412012-12-21 17:32:12 +0000989/* Write word #0 of a dpr to the guest state. */
990static __inline__ void
991put_dpr_w0(UInt archreg, IRExpr *expr)
992{
993 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
994
995 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
996}
997
998/* Read word #0 of a dpr register. */
999static __inline__ IRExpr *
1000get_dpr_w0(UInt archreg)
1001{
1002 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1003}
1004
florian12390202012-11-10 22:34:14 +00001005/* Write double word #0 of a fpr containg DFP value to the guest state. */
1006static __inline__ void
1007put_dpr_dw0(UInt archreg, IRExpr *expr)
1008{
1009 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1010
1011 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1012}
1013
1014/* Read double word #0 of a fpr register containing DFP value. */
1015static __inline__ IRExpr *
1016get_dpr_dw0(UInt archreg)
1017{
1018 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1019}
sewardj2019a972011-03-07 16:04:07 +00001020
1021/*------------------------------------------------------------*/
1022/*--- gpr registers ---*/
1023/*------------------------------------------------------------*/
1024
1025/* Return the guest state offset of a gpr register. */
1026static UInt
1027gpr_offset(UInt archreg)
1028{
1029 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001030 S390X_GUEST_OFFSET(guest_r0),
1031 S390X_GUEST_OFFSET(guest_r1),
1032 S390X_GUEST_OFFSET(guest_r2),
1033 S390X_GUEST_OFFSET(guest_r3),
1034 S390X_GUEST_OFFSET(guest_r4),
1035 S390X_GUEST_OFFSET(guest_r5),
1036 S390X_GUEST_OFFSET(guest_r6),
1037 S390X_GUEST_OFFSET(guest_r7),
1038 S390X_GUEST_OFFSET(guest_r8),
1039 S390X_GUEST_OFFSET(guest_r9),
1040 S390X_GUEST_OFFSET(guest_r10),
1041 S390X_GUEST_OFFSET(guest_r11),
1042 S390X_GUEST_OFFSET(guest_r12),
1043 S390X_GUEST_OFFSET(guest_r13),
1044 S390X_GUEST_OFFSET(guest_r14),
1045 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001046 };
1047
1048 vassert(archreg < 16);
1049
1050 return offset[archreg];
1051}
1052
1053
1054/* Return the guest state offset of word #0 of a gpr register. */
1055static __inline__ UInt
1056gpr_w0_offset(UInt archreg)
1057{
1058 return gpr_offset(archreg) + 0;
1059}
1060
1061/* Write word #0 of a gpr to the guest state. */
1062static __inline__ void
1063put_gpr_w0(UInt archreg, IRExpr *expr)
1064{
1065 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1066
1067 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1068}
1069
1070/* Read word #0 of a gpr register. */
1071static __inline__ IRExpr *
1072get_gpr_w0(UInt archreg)
1073{
1074 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1075}
1076
1077/* Return the guest state offset of double word #0 of a gpr register. */
1078static __inline__ UInt
1079gpr_dw0_offset(UInt archreg)
1080{
1081 return gpr_offset(archreg) + 0;
1082}
1083
1084/* Write double word #0 of a gpr to the guest state. */
1085static __inline__ void
1086put_gpr_dw0(UInt archreg, IRExpr *expr)
1087{
1088 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1089
1090 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1091}
1092
1093/* Read double word #0 of a gpr register. */
1094static __inline__ IRExpr *
1095get_gpr_dw0(UInt archreg)
1096{
1097 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1098}
1099
1100/* Return the guest state offset of half word #1 of a gpr register. */
1101static __inline__ UInt
1102gpr_hw1_offset(UInt archreg)
1103{
1104 return gpr_offset(archreg) + 2;
1105}
1106
1107/* Write half word #1 of a gpr to the guest state. */
1108static __inline__ void
1109put_gpr_hw1(UInt archreg, IRExpr *expr)
1110{
1111 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1112
1113 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1114}
1115
1116/* Read half word #1 of a gpr register. */
1117static __inline__ IRExpr *
1118get_gpr_hw1(UInt archreg)
1119{
1120 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1121}
1122
1123/* Return the guest state offset of byte #6 of a gpr register. */
1124static __inline__ UInt
1125gpr_b6_offset(UInt archreg)
1126{
1127 return gpr_offset(archreg) + 6;
1128}
1129
1130/* Write byte #6 of a gpr to the guest state. */
1131static __inline__ void
1132put_gpr_b6(UInt archreg, IRExpr *expr)
1133{
1134 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1135
1136 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1137}
1138
1139/* Read byte #6 of a gpr register. */
1140static __inline__ IRExpr *
1141get_gpr_b6(UInt archreg)
1142{
1143 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1144}
1145
1146/* Return the guest state offset of byte #3 of a gpr register. */
1147static __inline__ UInt
1148gpr_b3_offset(UInt archreg)
1149{
1150 return gpr_offset(archreg) + 3;
1151}
1152
1153/* Write byte #3 of a gpr to the guest state. */
1154static __inline__ void
1155put_gpr_b3(UInt archreg, IRExpr *expr)
1156{
1157 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1158
1159 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1160}
1161
1162/* Read byte #3 of a gpr register. */
1163static __inline__ IRExpr *
1164get_gpr_b3(UInt archreg)
1165{
1166 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1167}
1168
1169/* Return the guest state offset of byte #0 of a gpr register. */
1170static __inline__ UInt
1171gpr_b0_offset(UInt archreg)
1172{
1173 return gpr_offset(archreg) + 0;
1174}
1175
1176/* Write byte #0 of a gpr to the guest state. */
1177static __inline__ void
1178put_gpr_b0(UInt archreg, IRExpr *expr)
1179{
1180 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1181
1182 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1183}
1184
1185/* Read byte #0 of a gpr register. */
1186static __inline__ IRExpr *
1187get_gpr_b0(UInt archreg)
1188{
1189 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1190}
1191
1192/* Return the guest state offset of word #1 of a gpr register. */
1193static __inline__ UInt
1194gpr_w1_offset(UInt archreg)
1195{
1196 return gpr_offset(archreg) + 4;
1197}
1198
1199/* Write word #1 of a gpr to the guest state. */
1200static __inline__ void
1201put_gpr_w1(UInt archreg, IRExpr *expr)
1202{
1203 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1204
1205 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1206}
1207
1208/* Read word #1 of a gpr register. */
1209static __inline__ IRExpr *
1210get_gpr_w1(UInt archreg)
1211{
1212 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1213}
1214
1215/* Return the guest state offset of half word #3 of a gpr register. */
1216static __inline__ UInt
1217gpr_hw3_offset(UInt archreg)
1218{
1219 return gpr_offset(archreg) + 6;
1220}
1221
1222/* Write half word #3 of a gpr to the guest state. */
1223static __inline__ void
1224put_gpr_hw3(UInt archreg, IRExpr *expr)
1225{
1226 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1227
1228 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1229}
1230
1231/* Read half word #3 of a gpr register. */
1232static __inline__ IRExpr *
1233get_gpr_hw3(UInt archreg)
1234{
1235 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1236}
1237
1238/* Return the guest state offset of byte #7 of a gpr register. */
1239static __inline__ UInt
1240gpr_b7_offset(UInt archreg)
1241{
1242 return gpr_offset(archreg) + 7;
1243}
1244
1245/* Write byte #7 of a gpr to the guest state. */
1246static __inline__ void
1247put_gpr_b7(UInt archreg, IRExpr *expr)
1248{
1249 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1250
1251 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1252}
1253
1254/* Read byte #7 of a gpr register. */
1255static __inline__ IRExpr *
1256get_gpr_b7(UInt archreg)
1257{
1258 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1259}
1260
1261/* Return the guest state offset of half word #0 of a gpr register. */
1262static __inline__ UInt
1263gpr_hw0_offset(UInt archreg)
1264{
1265 return gpr_offset(archreg) + 0;
1266}
1267
1268/* Write half word #0 of a gpr to the guest state. */
1269static __inline__ void
1270put_gpr_hw0(UInt archreg, IRExpr *expr)
1271{
1272 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1273
1274 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1275}
1276
1277/* Read half word #0 of a gpr register. */
1278static __inline__ IRExpr *
1279get_gpr_hw0(UInt archreg)
1280{
1281 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1282}
1283
1284/* Return the guest state offset of byte #4 of a gpr register. */
1285static __inline__ UInt
1286gpr_b4_offset(UInt archreg)
1287{
1288 return gpr_offset(archreg) + 4;
1289}
1290
1291/* Write byte #4 of a gpr to the guest state. */
1292static __inline__ void
1293put_gpr_b4(UInt archreg, IRExpr *expr)
1294{
1295 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1296
1297 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1298}
1299
1300/* Read byte #4 of a gpr register. */
1301static __inline__ IRExpr *
1302get_gpr_b4(UInt archreg)
1303{
1304 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1305}
1306
1307/* Return the guest state offset of byte #1 of a gpr register. */
1308static __inline__ UInt
1309gpr_b1_offset(UInt archreg)
1310{
1311 return gpr_offset(archreg) + 1;
1312}
1313
1314/* Write byte #1 of a gpr to the guest state. */
1315static __inline__ void
1316put_gpr_b1(UInt archreg, IRExpr *expr)
1317{
1318 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1319
1320 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1321}
1322
1323/* Read byte #1 of a gpr register. */
1324static __inline__ IRExpr *
1325get_gpr_b1(UInt archreg)
1326{
1327 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1328}
1329
1330/* Return the guest state offset of half word #2 of a gpr register. */
1331static __inline__ UInt
1332gpr_hw2_offset(UInt archreg)
1333{
1334 return gpr_offset(archreg) + 4;
1335}
1336
1337/* Write half word #2 of a gpr to the guest state. */
1338static __inline__ void
1339put_gpr_hw2(UInt archreg, IRExpr *expr)
1340{
1341 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1342
1343 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1344}
1345
1346/* Read half word #2 of a gpr register. */
1347static __inline__ IRExpr *
1348get_gpr_hw2(UInt archreg)
1349{
1350 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1351}
1352
1353/* Return the guest state offset of byte #5 of a gpr register. */
1354static __inline__ UInt
1355gpr_b5_offset(UInt archreg)
1356{
1357 return gpr_offset(archreg) + 5;
1358}
1359
1360/* Write byte #5 of a gpr to the guest state. */
1361static __inline__ void
1362put_gpr_b5(UInt archreg, IRExpr *expr)
1363{
1364 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1365
1366 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1367}
1368
1369/* Read byte #5 of a gpr register. */
1370static __inline__ IRExpr *
1371get_gpr_b5(UInt archreg)
1372{
1373 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1374}
1375
1376/* Return the guest state offset of byte #2 of a gpr register. */
1377static __inline__ UInt
1378gpr_b2_offset(UInt archreg)
1379{
1380 return gpr_offset(archreg) + 2;
1381}
1382
1383/* Write byte #2 of a gpr to the guest state. */
1384static __inline__ void
1385put_gpr_b2(UInt archreg, IRExpr *expr)
1386{
1387 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1388
1389 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1390}
1391
1392/* Read byte #2 of a gpr register. */
1393static __inline__ IRExpr *
1394get_gpr_b2(UInt archreg)
1395{
1396 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1397}
1398
1399/* Return the guest state offset of the counter register. */
1400static UInt
1401counter_offset(void)
1402{
floriane88b3c92011-07-05 02:48:39 +00001403 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001404}
1405
1406/* Return the guest state offset of double word #0 of the counter register. */
1407static __inline__ UInt
1408counter_dw0_offset(void)
1409{
1410 return counter_offset() + 0;
1411}
1412
1413/* Write double word #0 of the counter to the guest state. */
1414static __inline__ void
1415put_counter_dw0(IRExpr *expr)
1416{
1417 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1418
1419 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1420}
1421
1422/* Read double word #0 of the counter register. */
1423static __inline__ IRExpr *
1424get_counter_dw0(void)
1425{
1426 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1427}
1428
1429/* Return the guest state offset of word #0 of the counter register. */
1430static __inline__ UInt
1431counter_w0_offset(void)
1432{
1433 return counter_offset() + 0;
1434}
1435
1436/* Return the guest state offset of word #1 of the counter register. */
1437static __inline__ UInt
1438counter_w1_offset(void)
1439{
1440 return counter_offset() + 4;
1441}
1442
1443/* Write word #0 of the counter to the guest state. */
1444static __inline__ void
1445put_counter_w0(IRExpr *expr)
1446{
1447 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1448
1449 stmt(IRStmt_Put(counter_w0_offset(), expr));
1450}
1451
1452/* Read word #0 of the counter register. */
1453static __inline__ IRExpr *
1454get_counter_w0(void)
1455{
1456 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1457}
1458
1459/* Write word #1 of the counter to the guest state. */
1460static __inline__ void
1461put_counter_w1(IRExpr *expr)
1462{
1463 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1464
1465 stmt(IRStmt_Put(counter_w1_offset(), expr));
1466}
1467
1468/* Read word #1 of the counter register. */
1469static __inline__ IRExpr *
1470get_counter_w1(void)
1471{
1472 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1473}
1474
1475/* Return the guest state offset of the fpc register. */
1476static UInt
1477fpc_offset(void)
1478{
floriane88b3c92011-07-05 02:48:39 +00001479 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001480}
1481
1482/* Return the guest state offset of word #0 of the fpc register. */
1483static __inline__ UInt
1484fpc_w0_offset(void)
1485{
1486 return fpc_offset() + 0;
1487}
1488
1489/* Write word #0 of the fpc to the guest state. */
1490static __inline__ void
1491put_fpc_w0(IRExpr *expr)
1492{
1493 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1494
1495 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1496}
1497
1498/* Read word #0 of the fpc register. */
1499static __inline__ IRExpr *
1500get_fpc_w0(void)
1501{
1502 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1503}
1504
1505
1506/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001507/*--- Rounding modes ---*/
1508/*------------------------------------------------------------*/
1509
florian125e20d2012-10-07 15:42:37 +00001510/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001511 IRRoundingMode:
1512
1513 rounding mode | s390 | IR
1514 -------------------------
1515 to nearest | 00 | 00
1516 to zero | 01 | 11
1517 to +infinity | 10 | 10
1518 to -infinity | 11 | 01
1519
1520 So: IR = (4 - s390) & 3
1521*/
1522static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001523get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001524{
1525 IRTemp fpc_bits = newTemp(Ity_I32);
1526
1527 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1528 Prior to that bits [30:31] contained the bfp rounding mode with
1529 bit 29 being unused and having a value of 0. So we can always
1530 extract the least significant 3 bits. */
1531 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1532
1533 /* fixs390:
1534
1535
1536 if (! s390_host_has_fpext && rounding_mode > 3) {
1537 emulation warning @ runtime and
1538 set fpc to round nearest
1539 }
1540 */
1541
1542 /* For now silently adjust an unsupported rounding mode to "nearest" */
1543 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1544 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001545 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001546
1547 // rm_IR = (4 - rm_s390) & 3;
1548 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1549}
1550
1551/* Encode the s390 rounding mode as it appears in the m3 field of certain
1552 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1553 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1554 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1555 considers the default rounding mode (4.3.3). */
1556static IRTemp
1557encode_bfp_rounding_mode(UChar mode)
1558{
1559 IRExpr *rm;
1560
1561 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001562 case S390_BFP_ROUND_PER_FPC:
1563 rm = get_bfp_rounding_mode_from_fpc();
1564 break;
1565 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1566 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1567 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1568 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1569 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1570 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001571 default:
1572 vpanic("encode_bfp_rounding_mode");
1573 }
1574
1575 return mktemp(Ity_I32, rm);
1576}
1577
florianc8e4f562012-10-27 16:19:31 +00001578/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1579 IRRoundingMode:
1580
1581 rounding mode | s390 | IR
1582 ------------------------------------------------
1583 to nearest, ties to even | 000 | 000
1584 to zero | 001 | 011
1585 to +infinity | 010 | 010
1586 to -infinity | 011 | 001
1587 to nearest, ties away from 0 | 100 | 100
1588 to nearest, ties toward 0 | 101 | 111
1589 to away from 0 | 110 | 110
1590 to prepare for shorter precision | 111 | 101
1591
1592 So: IR = (s390 ^ ((s390 << 1) & 2))
1593*/
florianc8e4f562012-10-27 16:19:31 +00001594static IRExpr *
1595get_dfp_rounding_mode_from_fpc(void)
1596{
1597 IRTemp fpc_bits = newTemp(Ity_I32);
1598
1599 /* The dfp rounding mode is stored in bits [25:27].
1600 extract the bits at 25:27 and right shift 4 times. */
1601 assign(fpc_bits, binop(Iop_Shr32,
1602 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1603 mkU8(4)));
1604
1605 IRExpr *rm_s390 = mkexpr(fpc_bits);
1606 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1607
1608 return binop(Iop_Xor32, rm_s390,
1609 binop( Iop_And32,
1610 binop(Iop_Shl32, rm_s390, mkU8(1)),
1611 mkU32(2)));
1612}
1613
1614/* Encode the s390 rounding mode as it appears in the m3 field of certain
1615 instructions to VEX's IRRoundingMode. */
1616static IRTemp
1617encode_dfp_rounding_mode(UChar mode)
1618{
1619 IRExpr *rm;
1620
1621 switch (mode) {
1622 case S390_DFP_ROUND_PER_FPC_0:
1623 case S390_DFP_ROUND_PER_FPC_2:
1624 rm = get_dfp_rounding_mode_from_fpc(); break;
1625 case S390_DFP_ROUND_NEAREST_EVEN_4:
1626 case S390_DFP_ROUND_NEAREST_EVEN_8:
florian79e5a482013-06-06 19:12:46 +00001627 rm = mkU32(Irrm_NEAREST); break;
florianc8e4f562012-10-27 16:19:31 +00001628 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1629 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
florian79e5a482013-06-06 19:12:46 +00001630 rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
florianc8e4f562012-10-27 16:19:31 +00001631 case S390_DFP_ROUND_PREPARE_SHORT_3:
1632 case S390_DFP_ROUND_PREPARE_SHORT_15:
florian79e5a482013-06-06 19:12:46 +00001633 rm = mkU32(Irrm_PREPARE_SHORTER); break;
florianc8e4f562012-10-27 16:19:31 +00001634 case S390_DFP_ROUND_ZERO_5:
1635 case S390_DFP_ROUND_ZERO_9:
florian79e5a482013-06-06 19:12:46 +00001636 rm = mkU32(Irrm_ZERO ); break;
florianc8e4f562012-10-27 16:19:31 +00001637 case S390_DFP_ROUND_POSINF_6:
1638 case S390_DFP_ROUND_POSINF_10:
florian79e5a482013-06-06 19:12:46 +00001639 rm = mkU32(Irrm_PosINF); break;
florianc8e4f562012-10-27 16:19:31 +00001640 case S390_DFP_ROUND_NEGINF_7:
1641 case S390_DFP_ROUND_NEGINF_11:
florian79e5a482013-06-06 19:12:46 +00001642 rm = mkU32(Irrm_NegINF); break;
florianc8e4f562012-10-27 16:19:31 +00001643 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
florian79e5a482013-06-06 19:12:46 +00001644 rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
florianc8e4f562012-10-27 16:19:31 +00001645 case S390_DFP_ROUND_AWAY_0:
florian79e5a482013-06-06 19:12:46 +00001646 rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
florianc8e4f562012-10-27 16:19:31 +00001647 default:
1648 vpanic("encode_dfp_rounding_mode");
1649 }
1650
1651 return mktemp(Ity_I32, rm);
1652}
florian12390202012-11-10 22:34:14 +00001653
florianc8e4f562012-10-27 16:19:31 +00001654
florian2c74d242012-09-12 19:38:42 +00001655/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001656/*--- Condition code helpers ---*/
1657/*------------------------------------------------------------*/
1658
1659/* The result of a Iop_CmpFxx operation is a condition code. It is
1660 encoded using the values defined in type IRCmpFxxResult.
1661 Before we can store the condition code into the guest state (or do
1662 anything else with it for that matter) we need to convert it to
1663 the encoding that s390 uses. This is what this function does.
1664
1665 s390 VEX b6 b2 b0 cc.1 cc.0
1666 0 0x40 EQ 1 0 0 0 0
1667 1 0x01 LT 0 0 1 0 1
1668 2 0x00 GT 0 0 0 1 0
1669 3 0x45 Unordered 1 1 1 1 1
1670
1671 The following bits from the VEX encoding are interesting:
1672 b0, b2, b6 with b0 being the LSB. We observe:
1673
1674 cc.0 = b0;
1675 cc.1 = b2 | (~b0 & ~b6)
1676
1677 with cc being the s390 condition code.
1678*/
1679static IRExpr *
1680convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1681{
1682 IRTemp cc0 = newTemp(Ity_I32);
1683 IRTemp cc1 = newTemp(Ity_I32);
1684 IRTemp b0 = newTemp(Ity_I32);
1685 IRTemp b2 = newTemp(Ity_I32);
1686 IRTemp b6 = newTemp(Ity_I32);
1687
1688 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1689 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1690 mkU32(1)));
1691 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1692 mkU32(1)));
1693
1694 assign(cc0, mkexpr(b0));
1695 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1696 binop(Iop_And32,
1697 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1698 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1699 )));
1700
1701 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1702}
1703
1704
1705/* The result of a Iop_CmpDxx operation is a condition code. It is
1706 encoded using the values defined in type IRCmpDxxResult.
1707 Before we can store the condition code into the guest state (or do
1708 anything else with it for that matter) we need to convert it to
1709 the encoding that s390 uses. This is what this function does. */
1710static IRExpr *
1711convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1712{
1713 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1714 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001715 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001716}
1717
1718
1719/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001720/*--- Build IR for formats ---*/
1721/*------------------------------------------------------------*/
1722static void
florian55085f82012-11-21 00:36:55 +00001723s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001724 UChar i)
1725{
florian55085f82012-11-21 00:36:55 +00001726 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001727
sewardj7ee97522011-05-09 21:45:04 +00001728 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001729 s390_disasm(ENC2(MNM, UINT), mnm, i);
1730}
1731
1732static void
florian78d5ef72013-05-11 15:02:58 +00001733s390_format_E(const HChar *(*irgen)(void))
1734{
1735 const HChar *mnm = irgen();
1736
1737 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1738 s390_disasm(ENC1(MNM), mnm);
1739}
1740
1741static void
florian55085f82012-11-21 00:36:55 +00001742s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001743 UChar r1, UShort i2)
1744{
1745 irgen(r1, i2);
1746}
1747
1748static void
florian55085f82012-11-21 00:36:55 +00001749s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001750 UChar r1, UShort i2)
1751{
florian55085f82012-11-21 00:36:55 +00001752 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001753
sewardj7ee97522011-05-09 21:45:04 +00001754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001755 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1756}
1757
1758static void
florian55085f82012-11-21 00:36:55 +00001759s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001760 UChar r1, UShort i2)
1761{
florian55085f82012-11-21 00:36:55 +00001762 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001763
sewardj7ee97522011-05-09 21:45:04 +00001764 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001765 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1766}
1767
1768static void
florian55085f82012-11-21 00:36:55 +00001769s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001770 UChar r1, UShort i2)
1771{
florian55085f82012-11-21 00:36:55 +00001772 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001773
sewardj7ee97522011-05-09 21:45:04 +00001774 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001775 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1776}
1777
1778static void
florian55085f82012-11-21 00:36:55 +00001779s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001780 UChar r1, UChar r3, UShort i2)
1781{
florian55085f82012-11-21 00:36:55 +00001782 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001783
sewardj7ee97522011-05-09 21:45:04 +00001784 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001785 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1786}
1787
1788static void
florian55085f82012-11-21 00:36:55 +00001789s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001790 UChar r1, UChar r3, UShort i2)
1791{
florian55085f82012-11-21 00:36:55 +00001792 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001793
sewardj7ee97522011-05-09 21:45:04 +00001794 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001795 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1796}
1797
1798static void
florian55085f82012-11-21 00:36:55 +00001799s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1800 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001801 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1802{
florian55085f82012-11-21 00:36:55 +00001803 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001804
sewardj7ee97522011-05-09 21:45:04 +00001805 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001806 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1807 i5);
1808}
1809
1810static void
florian55085f82012-11-21 00:36:55 +00001811s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1812 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001813 UChar r1, UChar r2, UShort i4, UChar m3)
1814{
florian55085f82012-11-21 00:36:55 +00001815 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001816
sewardj7ee97522011-05-09 21:45:04 +00001817 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001818 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1819 r2, m3, (Int)(Short)i4);
1820}
1821
1822static void
florian55085f82012-11-21 00:36:55 +00001823s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1824 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001825 UChar r1, UChar m3, UShort i4, UChar i2)
1826{
florian55085f82012-11-21 00:36:55 +00001827 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001828
sewardj7ee97522011-05-09 21:45:04 +00001829 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001830 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1831 r1, i2, m3, (Int)(Short)i4);
1832}
1833
1834static void
florian55085f82012-11-21 00:36:55 +00001835s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1836 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001837 UChar r1, UChar m3, UShort i4, UChar i2)
1838{
florian55085f82012-11-21 00:36:55 +00001839 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001840
sewardj7ee97522011-05-09 21:45:04 +00001841 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001842 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1843 (Int)(Char)i2, m3, (Int)(Short)i4);
1844}
1845
1846static void
florian55085f82012-11-21 00:36:55 +00001847s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001848 UChar r1, UInt i2)
1849{
1850 irgen(r1, i2);
1851}
1852
1853static void
florian55085f82012-11-21 00:36:55 +00001854s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001855 UChar r1, UInt i2)
1856{
florian55085f82012-11-21 00:36:55 +00001857 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001858
sewardj7ee97522011-05-09 21:45:04 +00001859 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001860 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1861}
1862
1863static void
florian55085f82012-11-21 00:36:55 +00001864s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001865 UChar r1, UInt i2)
1866{
florian55085f82012-11-21 00:36:55 +00001867 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001868
sewardj7ee97522011-05-09 21:45:04 +00001869 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001870 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1871}
1872
1873static void
florian55085f82012-11-21 00:36:55 +00001874s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001875 UChar r1, UInt i2)
1876{
florian55085f82012-11-21 00:36:55 +00001877 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001878
sewardj7ee97522011-05-09 21:45:04 +00001879 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001880 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1881}
1882
1883static void
florian55085f82012-11-21 00:36:55 +00001884s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001885 UChar r1, UInt i2)
1886{
florian55085f82012-11-21 00:36:55 +00001887 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001888
sewardj7ee97522011-05-09 21:45:04 +00001889 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001890 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1891}
1892
1893static void
florian55085f82012-11-21 00:36:55 +00001894s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001895 IRTemp op4addr),
1896 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1897{
florian55085f82012-11-21 00:36:55 +00001898 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001899 IRTemp op4addr = newTemp(Ity_I64);
1900
1901 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1902 mkU64(0)));
1903
1904 mnm = irgen(r1, m3, i2, op4addr);
1905
sewardj7ee97522011-05-09 21:45:04 +00001906 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001907 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1908 (Int)(Char)i2, m3, d4, 0, b4);
1909}
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001913 IRTemp op4addr),
1914 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1915{
florian55085f82012-11-21 00:36:55 +00001916 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001917 IRTemp op4addr = newTemp(Ity_I64);
1918
1919 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1920 mkU64(0)));
1921
1922 mnm = irgen(r1, m3, i2, op4addr);
1923
sewardj7ee97522011-05-09 21:45:04 +00001924 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001925 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1926 i2, m3, d4, 0, b4);
1927}
1928
1929static void
florian55085f82012-11-21 00:36:55 +00001930s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001931 UChar r1, UChar r2)
1932{
1933 irgen(r1, r2);
1934}
1935
1936static void
florian55085f82012-11-21 00:36:55 +00001937s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001938 UChar r1, UChar r2)
1939{
florian55085f82012-11-21 00:36:55 +00001940 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001941
sewardj7ee97522011-05-09 21:45:04 +00001942 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001943 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1944}
1945
1946static void
florian55085f82012-11-21 00:36:55 +00001947s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001948 UChar r1, UChar r2)
1949{
florian55085f82012-11-21 00:36:55 +00001950 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001951
sewardj7ee97522011-05-09 21:45:04 +00001952 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001953 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1954}
1955
1956static void
florian55085f82012-11-21 00:36:55 +00001957s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001958 UChar r1, UChar r2)
1959{
1960 irgen(r1, r2);
1961}
1962
1963static void
florian55085f82012-11-21 00:36:55 +00001964s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001965 UChar r1, UChar r2)
1966{
florian55085f82012-11-21 00:36:55 +00001967 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001968
sewardj7ee97522011-05-09 21:45:04 +00001969 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001970 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1971}
1972
1973static void
florian55085f82012-11-21 00:36:55 +00001974s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001975 UChar r1, UChar r2)
1976{
florian55085f82012-11-21 00:36:55 +00001977 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001978
sewardj7ee97522011-05-09 21:45:04 +00001979 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001980 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1981}
1982
1983static void
florian55085f82012-11-21 00:36:55 +00001984s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001985 UChar r1, UChar r2)
1986{
florian55085f82012-11-21 00:36:55 +00001987 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001988
sewardj7ee97522011-05-09 21:45:04 +00001989 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001990 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1991}
1992
1993static void
florian55085f82012-11-21 00:36:55 +00001994s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001995 UChar r1, UChar r2)
1996{
florian55085f82012-11-21 00:36:55 +00001997 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001998
sewardj7ee97522011-05-09 21:45:04 +00001999 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002000 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2001}
2002
2003static void
florian55085f82012-11-21 00:36:55 +00002004s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002005 UChar r1)
2006{
florian55085f82012-11-21 00:36:55 +00002007 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002008
sewardj7ee97522011-05-09 21:45:04 +00002009 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002010 s390_disasm(ENC2(MNM, GPR), mnm, r1);
2011}
2012
2013static void
florian55085f82012-11-21 00:36:55 +00002014s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002015 UChar r1)
2016{
florian55085f82012-11-21 00:36:55 +00002017 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002018
sewardj7ee97522011-05-09 21:45:04 +00002019 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002020 s390_disasm(ENC2(MNM, FPR), mnm, r1);
2021}
2022
2023static void
florian55085f82012-11-21 00:36:55 +00002024s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002025 UChar m3, UChar r1, UChar r2)
2026{
florian55085f82012-11-21 00:36:55 +00002027 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002028
2029 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002030 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002031}
2032
2033static void
florian55085f82012-11-21 00:36:55 +00002034s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002035 UChar r1, UChar r3, UChar r2)
2036{
florian55085f82012-11-21 00:36:55 +00002037 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002038
sewardj7ee97522011-05-09 21:45:04 +00002039 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002040 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2041}
2042
2043static void
florian5c539732013-02-14 14:27:12 +00002044s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2045 UChar r3, UChar r1, UChar r2)
2046{
2047 const HChar *mnm = irgen(r3, r1, r2);
2048
2049 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2050 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2051}
2052
2053static void
florian55085f82012-11-21 00:36:55 +00002054s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2055 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002056 UChar m3, UChar m4, UChar r1, UChar r2)
2057{
florian55085f82012-11-21 00:36:55 +00002058 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002059
2060 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2061 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2062}
2063
2064static void
floriane38f6412012-12-21 17:32:12 +00002065s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2066 UChar m4, UChar r1, UChar r2)
2067{
2068 const HChar *mnm = irgen(m4, r1, r2);
2069
2070 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2071 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2072}
2073
2074static void
florian55085f82012-11-21 00:36:55 +00002075s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2076 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002077 UChar m3, UChar m4, UChar r1, UChar r2)
2078{
florian55085f82012-11-21 00:36:55 +00002079 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002080
2081 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2082 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2083}
2084
2085static void
florian55085f82012-11-21 00:36:55 +00002086s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2087 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002088 UChar m3, UChar m4, UChar r1, UChar r2)
2089{
florian55085f82012-11-21 00:36:55 +00002090 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002091
2092 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2093 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2094}
2095
2096
2097static void
florian55085f82012-11-21 00:36:55 +00002098s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002099 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2100{
2101 irgen(m3, r1, r2);
2102
sewardj7ee97522011-05-09 21:45:04 +00002103 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002104 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2105}
2106
2107static void
florian55085f82012-11-21 00:36:55 +00002108s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002109 UChar r3, UChar r1, UChar r2)
2110{
florian55085f82012-11-21 00:36:55 +00002111 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002112
sewardj7ee97522011-05-09 21:45:04 +00002113 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002114 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2115}
2116
2117static void
florian5c539732013-02-14 14:27:12 +00002118s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2119 UChar r3, UChar m4, UChar r1, UChar r2)
2120{
2121 const HChar *mnm = irgen(r3, m4, r1, r2);
2122
2123 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2124 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2125}
2126
2127static void
2128s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2129 UChar r3, UChar m4, UChar r1, UChar r2)
2130{
2131 const HChar *mnm = irgen(r3, m4, r1, r2);
2132
2133 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2134 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2135}
2136
2137static void
florian55085f82012-11-21 00:36:55 +00002138s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002139 UChar r3, UChar m4, UChar r1, UChar r2)
2140{
florian55085f82012-11-21 00:36:55 +00002141 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002142
2143 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2144 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2145}
2146
2147static void
florian55085f82012-11-21 00:36:55 +00002148s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002149 UChar r3, UChar r1, UChar r2)
2150{
florian55085f82012-11-21 00:36:55 +00002151 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002152
sewardj7ee97522011-05-09 21:45:04 +00002153 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002154 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2155}
2156
2157static void
florian55085f82012-11-21 00:36:55 +00002158s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2159 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002160 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2161{
florian55085f82012-11-21 00:36:55 +00002162 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002163 IRTemp op4addr = newTemp(Ity_I64);
2164
2165 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2166 mkU64(0)));
2167
2168 mnm = irgen(r1, r2, m3, op4addr);
2169
sewardj7ee97522011-05-09 21:45:04 +00002170 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002171 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2172 r2, m3, d4, 0, b4);
2173}
2174
2175static void
florian55085f82012-11-21 00:36:55 +00002176s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002177 UChar r1, UChar b2, UShort d2)
2178{
florian55085f82012-11-21 00:36:55 +00002179 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002180 IRTemp op2addr = newTemp(Ity_I64);
2181
2182 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2183 mkU64(0)));
2184
2185 mnm = irgen(r1, op2addr);
2186
sewardj7ee97522011-05-09 21:45:04 +00002187 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002188 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2189}
2190
2191static void
florian55085f82012-11-21 00:36:55 +00002192s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002193 UChar r1, UChar r3, UChar b2, UShort d2)
2194{
florian55085f82012-11-21 00:36:55 +00002195 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002196 IRTemp op2addr = newTemp(Ity_I64);
2197
2198 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2199 mkU64(0)));
2200
2201 mnm = irgen(r1, r3, op2addr);
2202
sewardj7ee97522011-05-09 21:45:04 +00002203 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002204 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2205}
2206
2207static void
florian55085f82012-11-21 00:36:55 +00002208s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002209 UChar r1, UChar r3, UChar b2, UShort d2)
2210{
florian55085f82012-11-21 00:36:55 +00002211 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002212 IRTemp op2addr = newTemp(Ity_I64);
2213
2214 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2215 mkU64(0)));
2216
2217 mnm = irgen(r1, r3, op2addr);
2218
sewardj7ee97522011-05-09 21:45:04 +00002219 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002220 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2221}
2222
2223static void
florian55085f82012-11-21 00:36:55 +00002224s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002225 UChar r1, UChar r3, UChar b2, UShort d2)
2226{
florian55085f82012-11-21 00:36:55 +00002227 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002228 IRTemp op2addr = newTemp(Ity_I64);
2229
2230 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2231 mkU64(0)));
2232
2233 mnm = irgen(r1, r3, op2addr);
2234
sewardj7ee97522011-05-09 21:45:04 +00002235 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002236 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2237}
2238
2239static void
florian55085f82012-11-21 00:36:55 +00002240s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002241 UChar r1, UChar r3, UShort i2)
2242{
florian55085f82012-11-21 00:36:55 +00002243 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002244
sewardj7ee97522011-05-09 21:45:04 +00002245 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002246 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2247}
2248
2249static void
florian55085f82012-11-21 00:36:55 +00002250s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002251 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2252{
florian55085f82012-11-21 00:36:55 +00002253 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002254 IRTemp op2addr = newTemp(Ity_I64);
2255 IRTemp d2 = newTemp(Ity_I64);
2256
2257 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2258 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2259 mkU64(0)));
2260
2261 mnm = irgen(r1, r3, op2addr);
2262
sewardj7ee97522011-05-09 21:45:04 +00002263 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002264 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2265}
2266
2267static void
florian55085f82012-11-21 00:36:55 +00002268s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002269 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2270{
florian55085f82012-11-21 00:36:55 +00002271 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002272 IRTemp op2addr = newTemp(Ity_I64);
2273 IRTemp d2 = newTemp(Ity_I64);
2274
2275 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2276 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2277 mkU64(0)));
2278
2279 mnm = irgen(r1, r3, op2addr);
2280
sewardj7ee97522011-05-09 21:45:04 +00002281 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002282 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2283}
2284
2285static void
florian55085f82012-11-21 00:36:55 +00002286s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002287 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2288{
florian55085f82012-11-21 00:36:55 +00002289 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002290 IRTemp op2addr = newTemp(Ity_I64);
2291 IRTemp d2 = newTemp(Ity_I64);
2292
2293 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2294 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2295 mkU64(0)));
2296
2297 mnm = irgen(r1, r3, op2addr);
2298
sewardj7ee97522011-05-09 21:45:04 +00002299 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002300 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2301}
2302
2303static void
florian55085f82012-11-21 00:36:55 +00002304s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002305 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2306 Int xmnm_kind)
2307{
2308 IRTemp op2addr = newTemp(Ity_I64);
2309 IRTemp d2 = newTemp(Ity_I64);
2310
florian6820ba52012-07-26 02:01:50 +00002311 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2312
sewardjd7bde722011-04-05 13:19:33 +00002313 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2314 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2315 mkU64(0)));
2316
2317 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002318
2319 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002320
sewardj7ee97522011-05-09 21:45:04 +00002321 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002322 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2323}
2324
2325static void
florian55085f82012-11-21 00:36:55 +00002326s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002327 IRTemp op2addr),
2328 UChar r1, UChar x2, UChar b2, UShort d2)
2329{
2330 IRTemp op2addr = newTemp(Ity_I64);
2331
2332 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2333 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2334 mkU64(0)));
2335
2336 irgen(r1, x2, b2, d2, op2addr);
2337}
2338
2339static void
florian55085f82012-11-21 00:36:55 +00002340s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002341 UChar r1, UChar x2, UChar b2, UShort d2)
2342{
florian55085f82012-11-21 00:36:55 +00002343 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002344 IRTemp op2addr = newTemp(Ity_I64);
2345
2346 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2347 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2348 mkU64(0)));
2349
2350 mnm = irgen(r1, op2addr);
2351
sewardj7ee97522011-05-09 21:45:04 +00002352 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002353 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2354}
2355
2356static void
florian55085f82012-11-21 00:36:55 +00002357s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002358 UChar r1, UChar x2, UChar b2, UShort d2)
2359{
florian55085f82012-11-21 00:36:55 +00002360 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002361 IRTemp op2addr = newTemp(Ity_I64);
2362
2363 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2364 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2365 mkU64(0)));
2366
2367 mnm = irgen(r1, op2addr);
2368
sewardj7ee97522011-05-09 21:45:04 +00002369 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002370 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2371}
2372
2373static void
florian55085f82012-11-21 00:36:55 +00002374s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002375 UChar r1, UChar x2, UChar b2, UShort d2)
2376{
florian55085f82012-11-21 00:36:55 +00002377 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002378 IRTemp op2addr = newTemp(Ity_I64);
2379
2380 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2381 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2382 mkU64(0)));
2383
2384 mnm = irgen(r1, op2addr);
2385
sewardj7ee97522011-05-09 21:45:04 +00002386 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002387 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2388}
2389
2390static void
florian55085f82012-11-21 00:36:55 +00002391s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002392 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2393{
florian55085f82012-11-21 00:36:55 +00002394 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002395 IRTemp op2addr = newTemp(Ity_I64);
2396
2397 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2398 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2399 mkU64(0)));
2400
2401 mnm = irgen(r3, op2addr, r1);
2402
sewardj7ee97522011-05-09 21:45:04 +00002403 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002404 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2405}
2406
2407static void
florian55085f82012-11-21 00:36:55 +00002408s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002409 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2410{
florian55085f82012-11-21 00:36:55 +00002411 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002412 IRTemp op2addr = newTemp(Ity_I64);
2413 IRTemp d2 = newTemp(Ity_I64);
2414
2415 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2416 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2417 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2418 mkU64(0)));
2419
2420 mnm = irgen(r1, op2addr);
2421
sewardj7ee97522011-05-09 21:45:04 +00002422 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002423 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2424}
2425
2426static void
florian55085f82012-11-21 00:36:55 +00002427s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002428 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2429{
florian55085f82012-11-21 00:36:55 +00002430 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002431 IRTemp op2addr = newTemp(Ity_I64);
2432 IRTemp d2 = newTemp(Ity_I64);
2433
2434 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2435 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2436 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2437 mkU64(0)));
2438
2439 mnm = irgen(r1, op2addr);
2440
sewardj7ee97522011-05-09 21:45:04 +00002441 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002442 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2443}
2444
2445static void
florian55085f82012-11-21 00:36:55 +00002446s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002447 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2448{
florian55085f82012-11-21 00:36:55 +00002449 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002450 IRTemp op2addr = newTemp(Ity_I64);
2451 IRTemp d2 = newTemp(Ity_I64);
2452
2453 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2454 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2455 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2456 mkU64(0)));
2457
2458 mnm = irgen();
2459
sewardj7ee97522011-05-09 21:45:04 +00002460 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002461 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2462}
2463
2464static void
florian55085f82012-11-21 00:36:55 +00002465s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002466 UChar b2, UShort d2)
2467{
florian55085f82012-11-21 00:36:55 +00002468 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002469 IRTemp op2addr = newTemp(Ity_I64);
2470
2471 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2472 mkU64(0)));
2473
2474 mnm = irgen(op2addr);
2475
sewardj7ee97522011-05-09 21:45:04 +00002476 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002477 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2478}
2479
2480static void
florian55085f82012-11-21 00:36:55 +00002481s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002482 UChar i2, UChar b1, UShort d1)
2483{
florian55085f82012-11-21 00:36:55 +00002484 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002485 IRTemp op1addr = newTemp(Ity_I64);
2486
2487 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2488 mkU64(0)));
2489
2490 mnm = irgen(i2, op1addr);
2491
sewardj7ee97522011-05-09 21:45:04 +00002492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002493 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2494}
2495
2496static void
florian55085f82012-11-21 00:36:55 +00002497s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002498 UChar i2, UChar b1, UShort dl1, UChar dh1)
2499{
florian55085f82012-11-21 00:36:55 +00002500 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002501 IRTemp op1addr = newTemp(Ity_I64);
2502 IRTemp d1 = newTemp(Ity_I64);
2503
2504 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2505 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2506 mkU64(0)));
2507
2508 mnm = irgen(i2, op1addr);
2509
sewardj7ee97522011-05-09 21:45:04 +00002510 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002511 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2512}
2513
2514static void
florian55085f82012-11-21 00:36:55 +00002515s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002516 UChar i2, UChar b1, UShort dl1, UChar dh1)
2517{
florian55085f82012-11-21 00:36:55 +00002518 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002519 IRTemp op1addr = newTemp(Ity_I64);
2520 IRTemp d1 = newTemp(Ity_I64);
2521
2522 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2523 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2524 mkU64(0)));
2525
2526 mnm = irgen(i2, op1addr);
2527
sewardj7ee97522011-05-09 21:45:04 +00002528 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002529 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2530}
2531
2532static void
florian55085f82012-11-21 00:36:55 +00002533s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002534 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2535{
florian55085f82012-11-21 00:36:55 +00002536 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002537 IRTemp op1addr = newTemp(Ity_I64);
2538 IRTemp op2addr = newTemp(Ity_I64);
2539
2540 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2541 mkU64(0)));
2542 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2543 mkU64(0)));
2544
2545 mnm = irgen(l, op1addr, op2addr);
2546
sewardj7ee97522011-05-09 21:45:04 +00002547 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002548 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2549}
2550
2551static void
florian55085f82012-11-21 00:36:55 +00002552s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002553 UChar b1, UShort d1, UShort i2)
2554{
florian55085f82012-11-21 00:36:55 +00002555 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002556 IRTemp op1addr = newTemp(Ity_I64);
2557
2558 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2559 mkU64(0)));
2560
2561 mnm = irgen(i2, op1addr);
2562
sewardj7ee97522011-05-09 21:45:04 +00002563 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002564 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2565}
2566
2567static void
florian55085f82012-11-21 00:36:55 +00002568s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002569 UChar b1, UShort d1, UShort i2)
2570{
florian55085f82012-11-21 00:36:55 +00002571 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002572 IRTemp op1addr = newTemp(Ity_I64);
2573
2574 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2575 mkU64(0)));
2576
2577 mnm = irgen(i2, op1addr);
2578
sewardj7ee97522011-05-09 21:45:04 +00002579 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002580 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2581}
2582
2583
2584
2585/*------------------------------------------------------------*/
2586/*--- Build IR for opcodes ---*/
2587/*------------------------------------------------------------*/
2588
florian55085f82012-11-21 00:36:55 +00002589static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002590s390_irgen_AR(UChar r1, UChar r2)
2591{
2592 IRTemp op1 = newTemp(Ity_I32);
2593 IRTemp op2 = newTemp(Ity_I32);
2594 IRTemp result = newTemp(Ity_I32);
2595
2596 assign(op1, get_gpr_w1(r1));
2597 assign(op2, get_gpr_w1(r2));
2598 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2599 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2600 put_gpr_w1(r1, mkexpr(result));
2601
2602 return "ar";
2603}
2604
florian55085f82012-11-21 00:36:55 +00002605static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002606s390_irgen_AGR(UChar r1, UChar r2)
2607{
2608 IRTemp op1 = newTemp(Ity_I64);
2609 IRTemp op2 = newTemp(Ity_I64);
2610 IRTemp result = newTemp(Ity_I64);
2611
2612 assign(op1, get_gpr_dw0(r1));
2613 assign(op2, get_gpr_dw0(r2));
2614 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2615 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2616 put_gpr_dw0(r1, mkexpr(result));
2617
2618 return "agr";
2619}
2620
florian55085f82012-11-21 00:36:55 +00002621static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002622s390_irgen_AGFR(UChar r1, UChar r2)
2623{
2624 IRTemp op1 = newTemp(Ity_I64);
2625 IRTemp op2 = newTemp(Ity_I64);
2626 IRTemp result = newTemp(Ity_I64);
2627
2628 assign(op1, get_gpr_dw0(r1));
2629 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2630 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2631 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2632 put_gpr_dw0(r1, mkexpr(result));
2633
2634 return "agfr";
2635}
2636
florian55085f82012-11-21 00:36:55 +00002637static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002638s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2639{
2640 IRTemp op2 = newTemp(Ity_I32);
2641 IRTemp op3 = newTemp(Ity_I32);
2642 IRTemp result = newTemp(Ity_I32);
2643
2644 assign(op2, get_gpr_w1(r2));
2645 assign(op3, get_gpr_w1(r3));
2646 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2647 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2648 put_gpr_w1(r1, mkexpr(result));
2649
2650 return "ark";
2651}
2652
florian55085f82012-11-21 00:36:55 +00002653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002654s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2655{
2656 IRTemp op2 = newTemp(Ity_I64);
2657 IRTemp op3 = newTemp(Ity_I64);
2658 IRTemp result = newTemp(Ity_I64);
2659
2660 assign(op2, get_gpr_dw0(r2));
2661 assign(op3, get_gpr_dw0(r3));
2662 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2663 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2664 put_gpr_dw0(r1, mkexpr(result));
2665
2666 return "agrk";
2667}
2668
florian55085f82012-11-21 00:36:55 +00002669static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002670s390_irgen_A(UChar r1, IRTemp op2addr)
2671{
2672 IRTemp op1 = newTemp(Ity_I32);
2673 IRTemp op2 = newTemp(Ity_I32);
2674 IRTemp result = newTemp(Ity_I32);
2675
2676 assign(op1, get_gpr_w1(r1));
2677 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2678 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2679 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2680 put_gpr_w1(r1, mkexpr(result));
2681
2682 return "a";
2683}
2684
florian55085f82012-11-21 00:36:55 +00002685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002686s390_irgen_AY(UChar r1, IRTemp op2addr)
2687{
2688 IRTemp op1 = newTemp(Ity_I32);
2689 IRTemp op2 = newTemp(Ity_I32);
2690 IRTemp result = newTemp(Ity_I32);
2691
2692 assign(op1, get_gpr_w1(r1));
2693 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2694 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2695 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2696 put_gpr_w1(r1, mkexpr(result));
2697
2698 return "ay";
2699}
2700
florian55085f82012-11-21 00:36:55 +00002701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002702s390_irgen_AG(UChar r1, IRTemp op2addr)
2703{
2704 IRTemp op1 = newTemp(Ity_I64);
2705 IRTemp op2 = newTemp(Ity_I64);
2706 IRTemp result = newTemp(Ity_I64);
2707
2708 assign(op1, get_gpr_dw0(r1));
2709 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2710 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2711 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2712 put_gpr_dw0(r1, mkexpr(result));
2713
2714 return "ag";
2715}
2716
florian55085f82012-11-21 00:36:55 +00002717static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002718s390_irgen_AGF(UChar r1, IRTemp op2addr)
2719{
2720 IRTemp op1 = newTemp(Ity_I64);
2721 IRTemp op2 = newTemp(Ity_I64);
2722 IRTemp result = newTemp(Ity_I64);
2723
2724 assign(op1, get_gpr_dw0(r1));
2725 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2726 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2727 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2728 put_gpr_dw0(r1, mkexpr(result));
2729
2730 return "agf";
2731}
2732
florian55085f82012-11-21 00:36:55 +00002733static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002734s390_irgen_AFI(UChar r1, UInt i2)
2735{
2736 IRTemp op1 = newTemp(Ity_I32);
2737 Int op2;
2738 IRTemp result = newTemp(Ity_I32);
2739
2740 assign(op1, get_gpr_w1(r1));
2741 op2 = (Int)i2;
2742 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2743 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2744 mkU32((UInt)op2)));
2745 put_gpr_w1(r1, mkexpr(result));
2746
2747 return "afi";
2748}
2749
florian55085f82012-11-21 00:36:55 +00002750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002751s390_irgen_AGFI(UChar r1, UInt i2)
2752{
2753 IRTemp op1 = newTemp(Ity_I64);
2754 Long op2;
2755 IRTemp result = newTemp(Ity_I64);
2756
2757 assign(op1, get_gpr_dw0(r1));
2758 op2 = (Long)(Int)i2;
2759 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2760 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2761 mkU64((ULong)op2)));
2762 put_gpr_dw0(r1, mkexpr(result));
2763
2764 return "agfi";
2765}
2766
florian55085f82012-11-21 00:36:55 +00002767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002768s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2769{
2770 Int op2;
2771 IRTemp op3 = newTemp(Ity_I32);
2772 IRTemp result = newTemp(Ity_I32);
2773
2774 op2 = (Int)(Short)i2;
2775 assign(op3, get_gpr_w1(r3));
2776 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2777 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2778 op2)), op3);
2779 put_gpr_w1(r1, mkexpr(result));
2780
2781 return "ahik";
2782}
2783
florian55085f82012-11-21 00:36:55 +00002784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002785s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2786{
2787 Long op2;
2788 IRTemp op3 = newTemp(Ity_I64);
2789 IRTemp result = newTemp(Ity_I64);
2790
2791 op2 = (Long)(Short)i2;
2792 assign(op3, get_gpr_dw0(r3));
2793 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2794 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2795 op2)), op3);
2796 put_gpr_dw0(r1, mkexpr(result));
2797
2798 return "aghik";
2799}
2800
florian55085f82012-11-21 00:36:55 +00002801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002802s390_irgen_ASI(UChar i2, IRTemp op1addr)
2803{
2804 IRTemp op1 = newTemp(Ity_I32);
2805 Int op2;
2806 IRTemp result = newTemp(Ity_I32);
2807
2808 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2809 op2 = (Int)(Char)i2;
2810 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2811 store(mkexpr(op1addr), mkexpr(result));
2812 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2813 mkU32((UInt)op2)));
2814
2815 return "asi";
2816}
2817
florian55085f82012-11-21 00:36:55 +00002818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002819s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2820{
2821 IRTemp op1 = newTemp(Ity_I64);
2822 Long op2;
2823 IRTemp result = newTemp(Ity_I64);
2824
2825 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2826 op2 = (Long)(Char)i2;
2827 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2828 store(mkexpr(op1addr), mkexpr(result));
2829 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2830 mkU64((ULong)op2)));
2831
2832 return "agsi";
2833}
2834
florian55085f82012-11-21 00:36:55 +00002835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002836s390_irgen_AH(UChar r1, IRTemp op2addr)
2837{
2838 IRTemp op1 = newTemp(Ity_I32);
2839 IRTemp op2 = newTemp(Ity_I32);
2840 IRTemp result = newTemp(Ity_I32);
2841
2842 assign(op1, get_gpr_w1(r1));
2843 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2844 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2845 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2846 put_gpr_w1(r1, mkexpr(result));
2847
2848 return "ah";
2849}
2850
florian55085f82012-11-21 00:36:55 +00002851static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002852s390_irgen_AHY(UChar r1, IRTemp op2addr)
2853{
2854 IRTemp op1 = newTemp(Ity_I32);
2855 IRTemp op2 = newTemp(Ity_I32);
2856 IRTemp result = newTemp(Ity_I32);
2857
2858 assign(op1, get_gpr_w1(r1));
2859 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2860 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2861 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2862 put_gpr_w1(r1, mkexpr(result));
2863
2864 return "ahy";
2865}
2866
florian55085f82012-11-21 00:36:55 +00002867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002868s390_irgen_AHI(UChar r1, UShort i2)
2869{
2870 IRTemp op1 = newTemp(Ity_I32);
2871 Int op2;
2872 IRTemp result = newTemp(Ity_I32);
2873
2874 assign(op1, get_gpr_w1(r1));
2875 op2 = (Int)(Short)i2;
2876 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2877 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2878 mkU32((UInt)op2)));
2879 put_gpr_w1(r1, mkexpr(result));
2880
2881 return "ahi";
2882}
2883
florian55085f82012-11-21 00:36:55 +00002884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002885s390_irgen_AGHI(UChar r1, UShort i2)
2886{
2887 IRTemp op1 = newTemp(Ity_I64);
2888 Long op2;
2889 IRTemp result = newTemp(Ity_I64);
2890
2891 assign(op1, get_gpr_dw0(r1));
2892 op2 = (Long)(Short)i2;
2893 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2894 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2895 mkU64((ULong)op2)));
2896 put_gpr_dw0(r1, mkexpr(result));
2897
2898 return "aghi";
2899}
2900
florian55085f82012-11-21 00:36:55 +00002901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002902s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2903{
2904 IRTemp op2 = newTemp(Ity_I32);
2905 IRTemp op3 = newTemp(Ity_I32);
2906 IRTemp result = newTemp(Ity_I32);
2907
2908 assign(op2, get_gpr_w0(r2));
2909 assign(op3, get_gpr_w0(r3));
2910 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2911 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2912 put_gpr_w0(r1, mkexpr(result));
2913
2914 return "ahhhr";
2915}
2916
florian55085f82012-11-21 00:36:55 +00002917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002918s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2919{
2920 IRTemp op2 = newTemp(Ity_I32);
2921 IRTemp op3 = newTemp(Ity_I32);
2922 IRTemp result = newTemp(Ity_I32);
2923
2924 assign(op2, get_gpr_w0(r2));
2925 assign(op3, get_gpr_w1(r3));
2926 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2927 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2928 put_gpr_w0(r1, mkexpr(result));
2929
2930 return "ahhlr";
2931}
2932
florian55085f82012-11-21 00:36:55 +00002933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002934s390_irgen_AIH(UChar r1, UInt i2)
2935{
2936 IRTemp op1 = newTemp(Ity_I32);
2937 Int op2;
2938 IRTemp result = newTemp(Ity_I32);
2939
2940 assign(op1, get_gpr_w0(r1));
2941 op2 = (Int)i2;
2942 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2943 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2944 mkU32((UInt)op2)));
2945 put_gpr_w0(r1, mkexpr(result));
2946
2947 return "aih";
2948}
2949
florian55085f82012-11-21 00:36:55 +00002950static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002951s390_irgen_ALR(UChar r1, UChar r2)
2952{
2953 IRTemp op1 = newTemp(Ity_I32);
2954 IRTemp op2 = newTemp(Ity_I32);
2955 IRTemp result = newTemp(Ity_I32);
2956
2957 assign(op1, get_gpr_w1(r1));
2958 assign(op2, get_gpr_w1(r2));
2959 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2960 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2961 put_gpr_w1(r1, mkexpr(result));
2962
2963 return "alr";
2964}
2965
florian55085f82012-11-21 00:36:55 +00002966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002967s390_irgen_ALGR(UChar r1, UChar r2)
2968{
2969 IRTemp op1 = newTemp(Ity_I64);
2970 IRTemp op2 = newTemp(Ity_I64);
2971 IRTemp result = newTemp(Ity_I64);
2972
2973 assign(op1, get_gpr_dw0(r1));
2974 assign(op2, get_gpr_dw0(r2));
2975 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2976 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2977 put_gpr_dw0(r1, mkexpr(result));
2978
2979 return "algr";
2980}
2981
florian55085f82012-11-21 00:36:55 +00002982static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002983s390_irgen_ALGFR(UChar r1, UChar r2)
2984{
2985 IRTemp op1 = newTemp(Ity_I64);
2986 IRTemp op2 = newTemp(Ity_I64);
2987 IRTemp result = newTemp(Ity_I64);
2988
2989 assign(op1, get_gpr_dw0(r1));
2990 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2991 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2992 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2993 put_gpr_dw0(r1, mkexpr(result));
2994
2995 return "algfr";
2996}
2997
florian55085f82012-11-21 00:36:55 +00002998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002999s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
3000{
3001 IRTemp op2 = newTemp(Ity_I32);
3002 IRTemp op3 = newTemp(Ity_I32);
3003 IRTemp result = newTemp(Ity_I32);
3004
3005 assign(op2, get_gpr_w1(r2));
3006 assign(op3, get_gpr_w1(r3));
3007 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3008 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3009 put_gpr_w1(r1, mkexpr(result));
3010
3011 return "alrk";
3012}
3013
florian55085f82012-11-21 00:36:55 +00003014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003015s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
3016{
3017 IRTemp op2 = newTemp(Ity_I64);
3018 IRTemp op3 = newTemp(Ity_I64);
3019 IRTemp result = newTemp(Ity_I64);
3020
3021 assign(op2, get_gpr_dw0(r2));
3022 assign(op3, get_gpr_dw0(r3));
3023 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
3024 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3025 put_gpr_dw0(r1, mkexpr(result));
3026
3027 return "algrk";
3028}
3029
florian55085f82012-11-21 00:36:55 +00003030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003031s390_irgen_AL(UChar r1, IRTemp op2addr)
3032{
3033 IRTemp op1 = newTemp(Ity_I32);
3034 IRTemp op2 = newTemp(Ity_I32);
3035 IRTemp result = newTemp(Ity_I32);
3036
3037 assign(op1, get_gpr_w1(r1));
3038 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3039 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3040 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3041 put_gpr_w1(r1, mkexpr(result));
3042
3043 return "al";
3044}
3045
florian55085f82012-11-21 00:36:55 +00003046static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003047s390_irgen_ALY(UChar r1, IRTemp op2addr)
3048{
3049 IRTemp op1 = newTemp(Ity_I32);
3050 IRTemp op2 = newTemp(Ity_I32);
3051 IRTemp result = newTemp(Ity_I32);
3052
3053 assign(op1, get_gpr_w1(r1));
3054 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3055 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3056 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3057 put_gpr_w1(r1, mkexpr(result));
3058
3059 return "aly";
3060}
3061
florian55085f82012-11-21 00:36:55 +00003062static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003063s390_irgen_ALG(UChar r1, IRTemp op2addr)
3064{
3065 IRTemp op1 = newTemp(Ity_I64);
3066 IRTemp op2 = newTemp(Ity_I64);
3067 IRTemp result = newTemp(Ity_I64);
3068
3069 assign(op1, get_gpr_dw0(r1));
3070 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3071 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3072 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3073 put_gpr_dw0(r1, mkexpr(result));
3074
3075 return "alg";
3076}
3077
florian55085f82012-11-21 00:36:55 +00003078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003079s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3080{
3081 IRTemp op1 = newTemp(Ity_I64);
3082 IRTemp op2 = newTemp(Ity_I64);
3083 IRTemp result = newTemp(Ity_I64);
3084
3085 assign(op1, get_gpr_dw0(r1));
3086 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3087 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3088 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3089 put_gpr_dw0(r1, mkexpr(result));
3090
3091 return "algf";
3092}
3093
florian55085f82012-11-21 00:36:55 +00003094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003095s390_irgen_ALFI(UChar r1, UInt i2)
3096{
3097 IRTemp op1 = newTemp(Ity_I32);
3098 UInt op2;
3099 IRTemp result = newTemp(Ity_I32);
3100
3101 assign(op1, get_gpr_w1(r1));
3102 op2 = i2;
3103 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3104 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3105 mkU32(op2)));
3106 put_gpr_w1(r1, mkexpr(result));
3107
3108 return "alfi";
3109}
3110
florian55085f82012-11-21 00:36:55 +00003111static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003112s390_irgen_ALGFI(UChar r1, UInt i2)
3113{
3114 IRTemp op1 = newTemp(Ity_I64);
3115 ULong op2;
3116 IRTemp result = newTemp(Ity_I64);
3117
3118 assign(op1, get_gpr_dw0(r1));
3119 op2 = (ULong)i2;
3120 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3121 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3122 mkU64(op2)));
3123 put_gpr_dw0(r1, mkexpr(result));
3124
3125 return "algfi";
3126}
3127
florian55085f82012-11-21 00:36:55 +00003128static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003129s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3130{
3131 IRTemp op2 = newTemp(Ity_I32);
3132 IRTemp op3 = newTemp(Ity_I32);
3133 IRTemp result = newTemp(Ity_I32);
3134
3135 assign(op2, get_gpr_w0(r2));
3136 assign(op3, get_gpr_w0(r3));
3137 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3138 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3139 put_gpr_w0(r1, mkexpr(result));
3140
3141 return "alhhhr";
3142}
3143
florian55085f82012-11-21 00:36:55 +00003144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003145s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3146{
3147 IRTemp op2 = newTemp(Ity_I32);
3148 IRTemp op3 = newTemp(Ity_I32);
3149 IRTemp result = newTemp(Ity_I32);
3150
3151 assign(op2, get_gpr_w0(r2));
3152 assign(op3, get_gpr_w1(r3));
3153 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3154 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3155 put_gpr_w0(r1, mkexpr(result));
3156
3157 return "alhhlr";
3158}
3159
florian55085f82012-11-21 00:36:55 +00003160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003161s390_irgen_ALCR(UChar r1, UChar r2)
3162{
3163 IRTemp op1 = newTemp(Ity_I32);
3164 IRTemp op2 = newTemp(Ity_I32);
3165 IRTemp result = newTemp(Ity_I32);
3166 IRTemp carry_in = newTemp(Ity_I32);
3167
3168 assign(op1, get_gpr_w1(r1));
3169 assign(op2, get_gpr_w1(r2));
3170 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3171 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3172 mkexpr(carry_in)));
3173 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3174 put_gpr_w1(r1, mkexpr(result));
3175
3176 return "alcr";
3177}
3178
florian55085f82012-11-21 00:36:55 +00003179static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003180s390_irgen_ALCGR(UChar r1, UChar r2)
3181{
3182 IRTemp op1 = newTemp(Ity_I64);
3183 IRTemp op2 = newTemp(Ity_I64);
3184 IRTemp result = newTemp(Ity_I64);
3185 IRTemp carry_in = newTemp(Ity_I64);
3186
3187 assign(op1, get_gpr_dw0(r1));
3188 assign(op2, get_gpr_dw0(r2));
3189 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3190 mkU8(1))));
3191 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3192 mkexpr(carry_in)));
3193 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3194 put_gpr_dw0(r1, mkexpr(result));
3195
3196 return "alcgr";
3197}
3198
florian55085f82012-11-21 00:36:55 +00003199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003200s390_irgen_ALC(UChar r1, IRTemp op2addr)
3201{
3202 IRTemp op1 = newTemp(Ity_I32);
3203 IRTemp op2 = newTemp(Ity_I32);
3204 IRTemp result = newTemp(Ity_I32);
3205 IRTemp carry_in = newTemp(Ity_I32);
3206
3207 assign(op1, get_gpr_w1(r1));
3208 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3209 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3210 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3211 mkexpr(carry_in)));
3212 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3213 put_gpr_w1(r1, mkexpr(result));
3214
3215 return "alc";
3216}
3217
florian55085f82012-11-21 00:36:55 +00003218static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003219s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3220{
3221 IRTemp op1 = newTemp(Ity_I64);
3222 IRTemp op2 = newTemp(Ity_I64);
3223 IRTemp result = newTemp(Ity_I64);
3224 IRTemp carry_in = newTemp(Ity_I64);
3225
3226 assign(op1, get_gpr_dw0(r1));
3227 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3228 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3229 mkU8(1))));
3230 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3231 mkexpr(carry_in)));
3232 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3233 put_gpr_dw0(r1, mkexpr(result));
3234
3235 return "alcg";
3236}
3237
florian55085f82012-11-21 00:36:55 +00003238static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003239s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3240{
3241 IRTemp op1 = newTemp(Ity_I32);
3242 UInt op2;
3243 IRTemp result = newTemp(Ity_I32);
3244
3245 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3246 op2 = (UInt)(Int)(Char)i2;
3247 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3248 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3249 mkU32(op2)));
3250 store(mkexpr(op1addr), mkexpr(result));
3251
3252 return "alsi";
3253}
3254
florian55085f82012-11-21 00:36:55 +00003255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003256s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3257{
3258 IRTemp op1 = newTemp(Ity_I64);
3259 ULong op2;
3260 IRTemp result = newTemp(Ity_I64);
3261
3262 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3263 op2 = (ULong)(Long)(Char)i2;
3264 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3265 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3266 mkU64(op2)));
3267 store(mkexpr(op1addr), mkexpr(result));
3268
3269 return "algsi";
3270}
3271
florian55085f82012-11-21 00:36:55 +00003272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003273s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3274{
3275 UInt op2;
3276 IRTemp op3 = newTemp(Ity_I32);
3277 IRTemp result = newTemp(Ity_I32);
3278
3279 op2 = (UInt)(Int)(Short)i2;
3280 assign(op3, get_gpr_w1(r3));
3281 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3282 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3283 op3);
3284 put_gpr_w1(r1, mkexpr(result));
3285
3286 return "alhsik";
3287}
3288
florian55085f82012-11-21 00:36:55 +00003289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003290s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3291{
3292 ULong op2;
3293 IRTemp op3 = newTemp(Ity_I64);
3294 IRTemp result = newTemp(Ity_I64);
3295
3296 op2 = (ULong)(Long)(Short)i2;
3297 assign(op3, get_gpr_dw0(r3));
3298 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3299 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3300 op3);
3301 put_gpr_dw0(r1, mkexpr(result));
3302
3303 return "alghsik";
3304}
3305
florian55085f82012-11-21 00:36:55 +00003306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003307s390_irgen_ALSIH(UChar r1, UInt i2)
3308{
3309 IRTemp op1 = newTemp(Ity_I32);
3310 UInt op2;
3311 IRTemp result = newTemp(Ity_I32);
3312
3313 assign(op1, get_gpr_w0(r1));
3314 op2 = i2;
3315 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3316 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3317 mkU32(op2)));
3318 put_gpr_w0(r1, mkexpr(result));
3319
3320 return "alsih";
3321}
3322
florian55085f82012-11-21 00:36:55 +00003323static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003324s390_irgen_ALSIHN(UChar r1, UInt i2)
3325{
3326 IRTemp op1 = newTemp(Ity_I32);
3327 UInt op2;
3328 IRTemp result = newTemp(Ity_I32);
3329
3330 assign(op1, get_gpr_w0(r1));
3331 op2 = i2;
3332 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3333 put_gpr_w0(r1, mkexpr(result));
3334
3335 return "alsihn";
3336}
3337
florian55085f82012-11-21 00:36:55 +00003338static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003339s390_irgen_NR(UChar r1, UChar r2)
3340{
3341 IRTemp op1 = newTemp(Ity_I32);
3342 IRTemp op2 = newTemp(Ity_I32);
3343 IRTemp result = newTemp(Ity_I32);
3344
3345 assign(op1, get_gpr_w1(r1));
3346 assign(op2, get_gpr_w1(r2));
3347 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3348 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3349 put_gpr_w1(r1, mkexpr(result));
3350
3351 return "nr";
3352}
3353
florian55085f82012-11-21 00:36:55 +00003354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003355s390_irgen_NGR(UChar r1, UChar r2)
3356{
3357 IRTemp op1 = newTemp(Ity_I64);
3358 IRTemp op2 = newTemp(Ity_I64);
3359 IRTemp result = newTemp(Ity_I64);
3360
3361 assign(op1, get_gpr_dw0(r1));
3362 assign(op2, get_gpr_dw0(r2));
3363 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3364 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3365 put_gpr_dw0(r1, mkexpr(result));
3366
3367 return "ngr";
3368}
3369
florian55085f82012-11-21 00:36:55 +00003370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003371s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3372{
3373 IRTemp op2 = newTemp(Ity_I32);
3374 IRTemp op3 = newTemp(Ity_I32);
3375 IRTemp result = newTemp(Ity_I32);
3376
3377 assign(op2, get_gpr_w1(r2));
3378 assign(op3, get_gpr_w1(r3));
3379 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3380 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3381 put_gpr_w1(r1, mkexpr(result));
3382
3383 return "nrk";
3384}
3385
florian55085f82012-11-21 00:36:55 +00003386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003387s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3388{
3389 IRTemp op2 = newTemp(Ity_I64);
3390 IRTemp op3 = newTemp(Ity_I64);
3391 IRTemp result = newTemp(Ity_I64);
3392
3393 assign(op2, get_gpr_dw0(r2));
3394 assign(op3, get_gpr_dw0(r3));
3395 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3396 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3397 put_gpr_dw0(r1, mkexpr(result));
3398
3399 return "ngrk";
3400}
3401
florian55085f82012-11-21 00:36:55 +00003402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003403s390_irgen_N(UChar r1, IRTemp op2addr)
3404{
3405 IRTemp op1 = newTemp(Ity_I32);
3406 IRTemp op2 = newTemp(Ity_I32);
3407 IRTemp result = newTemp(Ity_I32);
3408
3409 assign(op1, get_gpr_w1(r1));
3410 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3411 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3412 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3413 put_gpr_w1(r1, mkexpr(result));
3414
3415 return "n";
3416}
3417
florian55085f82012-11-21 00:36:55 +00003418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003419s390_irgen_NY(UChar r1, IRTemp op2addr)
3420{
3421 IRTemp op1 = newTemp(Ity_I32);
3422 IRTemp op2 = newTemp(Ity_I32);
3423 IRTemp result = newTemp(Ity_I32);
3424
3425 assign(op1, get_gpr_w1(r1));
3426 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3427 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3428 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3429 put_gpr_w1(r1, mkexpr(result));
3430
3431 return "ny";
3432}
3433
florian55085f82012-11-21 00:36:55 +00003434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003435s390_irgen_NG(UChar r1, IRTemp op2addr)
3436{
3437 IRTemp op1 = newTemp(Ity_I64);
3438 IRTemp op2 = newTemp(Ity_I64);
3439 IRTemp result = newTemp(Ity_I64);
3440
3441 assign(op1, get_gpr_dw0(r1));
3442 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3443 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3444 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3445 put_gpr_dw0(r1, mkexpr(result));
3446
3447 return "ng";
3448}
3449
florian55085f82012-11-21 00:36:55 +00003450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003451s390_irgen_NI(UChar i2, IRTemp op1addr)
3452{
3453 IRTemp op1 = newTemp(Ity_I8);
3454 UChar op2;
3455 IRTemp result = newTemp(Ity_I8);
3456
3457 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3458 op2 = i2;
3459 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3460 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3461 store(mkexpr(op1addr), mkexpr(result));
3462
3463 return "ni";
3464}
3465
florian55085f82012-11-21 00:36:55 +00003466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003467s390_irgen_NIY(UChar i2, IRTemp op1addr)
3468{
3469 IRTemp op1 = newTemp(Ity_I8);
3470 UChar op2;
3471 IRTemp result = newTemp(Ity_I8);
3472
3473 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3474 op2 = i2;
3475 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3476 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3477 store(mkexpr(op1addr), mkexpr(result));
3478
3479 return "niy";
3480}
3481
florian55085f82012-11-21 00:36:55 +00003482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003483s390_irgen_NIHF(UChar r1, UInt i2)
3484{
3485 IRTemp op1 = newTemp(Ity_I32);
3486 UInt op2;
3487 IRTemp result = newTemp(Ity_I32);
3488
3489 assign(op1, get_gpr_w0(r1));
3490 op2 = i2;
3491 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3492 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3493 put_gpr_w0(r1, mkexpr(result));
3494
3495 return "nihf";
3496}
3497
florian55085f82012-11-21 00:36:55 +00003498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003499s390_irgen_NIHH(UChar r1, UShort i2)
3500{
3501 IRTemp op1 = newTemp(Ity_I16);
3502 UShort op2;
3503 IRTemp result = newTemp(Ity_I16);
3504
3505 assign(op1, get_gpr_hw0(r1));
3506 op2 = i2;
3507 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3508 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3509 put_gpr_hw0(r1, mkexpr(result));
3510
3511 return "nihh";
3512}
3513
florian55085f82012-11-21 00:36:55 +00003514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003515s390_irgen_NIHL(UChar r1, UShort i2)
3516{
3517 IRTemp op1 = newTemp(Ity_I16);
3518 UShort op2;
3519 IRTemp result = newTemp(Ity_I16);
3520
3521 assign(op1, get_gpr_hw1(r1));
3522 op2 = i2;
3523 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3524 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3525 put_gpr_hw1(r1, mkexpr(result));
3526
3527 return "nihl";
3528}
3529
florian55085f82012-11-21 00:36:55 +00003530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003531s390_irgen_NILF(UChar r1, UInt i2)
3532{
3533 IRTemp op1 = newTemp(Ity_I32);
3534 UInt op2;
3535 IRTemp result = newTemp(Ity_I32);
3536
3537 assign(op1, get_gpr_w1(r1));
3538 op2 = i2;
3539 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3540 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3541 put_gpr_w1(r1, mkexpr(result));
3542
3543 return "nilf";
3544}
3545
florian55085f82012-11-21 00:36:55 +00003546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003547s390_irgen_NILH(UChar r1, UShort i2)
3548{
3549 IRTemp op1 = newTemp(Ity_I16);
3550 UShort op2;
3551 IRTemp result = newTemp(Ity_I16);
3552
3553 assign(op1, get_gpr_hw2(r1));
3554 op2 = i2;
3555 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3556 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3557 put_gpr_hw2(r1, mkexpr(result));
3558
3559 return "nilh";
3560}
3561
florian55085f82012-11-21 00:36:55 +00003562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003563s390_irgen_NILL(UChar r1, UShort i2)
3564{
3565 IRTemp op1 = newTemp(Ity_I16);
3566 UShort op2;
3567 IRTemp result = newTemp(Ity_I16);
3568
3569 assign(op1, get_gpr_hw3(r1));
3570 op2 = i2;
3571 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3572 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3573 put_gpr_hw3(r1, mkexpr(result));
3574
3575 return "nill";
3576}
3577
florian55085f82012-11-21 00:36:55 +00003578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003579s390_irgen_BASR(UChar r1, UChar r2)
3580{
3581 IRTemp target = newTemp(Ity_I64);
3582
3583 if (r2 == 0) {
3584 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3585 } else {
3586 if (r1 != r2) {
3587 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3588 call_function(get_gpr_dw0(r2));
3589 } else {
3590 assign(target, get_gpr_dw0(r2));
3591 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3592 call_function(mkexpr(target));
3593 }
3594 }
3595
3596 return "basr";
3597}
3598
florian55085f82012-11-21 00:36:55 +00003599static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003600s390_irgen_BAS(UChar r1, IRTemp op2addr)
3601{
3602 IRTemp target = newTemp(Ity_I64);
3603
3604 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3605 assign(target, mkexpr(op2addr));
3606 call_function(mkexpr(target));
3607
3608 return "bas";
3609}
3610
florian55085f82012-11-21 00:36:55 +00003611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003612s390_irgen_BCR(UChar r1, UChar r2)
3613{
3614 IRTemp cond = newTemp(Ity_I32);
3615
sewardja52e37e2011-04-28 18:48:06 +00003616 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3617 stmt(IRStmt_MBE(Imbe_Fence));
3618 }
3619
sewardj2019a972011-03-07 16:04:07 +00003620 if ((r2 == 0) || (r1 == 0)) {
3621 } else {
3622 if (r1 == 15) {
3623 return_from_function(get_gpr_dw0(r2));
3624 } else {
3625 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003626 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3627 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003628 }
3629 }
sewardj7ee97522011-05-09 21:45:04 +00003630 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003631 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3632
3633 return "bcr";
3634}
3635
florian55085f82012-11-21 00:36:55 +00003636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003637s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3638{
3639 IRTemp cond = newTemp(Ity_I32);
3640
3641 if (r1 == 0) {
3642 } else {
3643 if (r1 == 15) {
3644 always_goto(mkexpr(op2addr));
3645 } else {
3646 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003647 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3648 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003649 }
3650 }
sewardj7ee97522011-05-09 21:45:04 +00003651 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003652 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3653
3654 return "bc";
3655}
3656
florian55085f82012-11-21 00:36:55 +00003657static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003658s390_irgen_BCTR(UChar r1, UChar r2)
3659{
3660 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3661 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003662 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3663 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003664 }
3665
3666 return "bctr";
3667}
3668
florian55085f82012-11-21 00:36:55 +00003669static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003670s390_irgen_BCTGR(UChar r1, UChar r2)
3671{
3672 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3673 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003674 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3675 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003676 }
3677
3678 return "bctgr";
3679}
3680
florian55085f82012-11-21 00:36:55 +00003681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003682s390_irgen_BCT(UChar r1, IRTemp op2addr)
3683{
3684 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003685 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3686 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003687
3688 return "bct";
3689}
3690
florian55085f82012-11-21 00:36:55 +00003691static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003692s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3693{
3694 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003695 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3696 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003697
3698 return "bctg";
3699}
3700
florian55085f82012-11-21 00:36:55 +00003701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003702s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3703{
3704 IRTemp value = newTemp(Ity_I32);
3705
3706 assign(value, get_gpr_w1(r3 | 1));
3707 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003708 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3709 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003710
3711 return "bxh";
3712}
3713
florian55085f82012-11-21 00:36:55 +00003714static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003715s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3716{
3717 IRTemp value = newTemp(Ity_I64);
3718
3719 assign(value, get_gpr_dw0(r3 | 1));
3720 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003721 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3722 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003723
3724 return "bxhg";
3725}
3726
florian55085f82012-11-21 00:36:55 +00003727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003728s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3729{
3730 IRTemp value = newTemp(Ity_I32);
3731
3732 assign(value, get_gpr_w1(r3 | 1));
3733 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003734 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3735 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003736
3737 return "bxle";
3738}
3739
florian55085f82012-11-21 00:36:55 +00003740static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003741s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3742{
3743 IRTemp value = newTemp(Ity_I64);
3744
3745 assign(value, get_gpr_dw0(r3 | 1));
3746 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003747 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3748 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003749
3750 return "bxleg";
3751}
3752
florian55085f82012-11-21 00:36:55 +00003753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003754s390_irgen_BRAS(UChar r1, UShort i2)
3755{
3756 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003757 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003758
3759 return "bras";
3760}
3761
florian55085f82012-11-21 00:36:55 +00003762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003763s390_irgen_BRASL(UChar r1, UInt i2)
3764{
3765 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003766 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003767
3768 return "brasl";
3769}
3770
florian55085f82012-11-21 00:36:55 +00003771static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003772s390_irgen_BRC(UChar r1, UShort i2)
3773{
3774 IRTemp cond = newTemp(Ity_I32);
3775
3776 if (r1 == 0) {
3777 } else {
3778 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003779 always_goto_and_chase(
3780 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003781 } else {
3782 assign(cond, s390_call_calculate_cond(r1));
3783 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3784 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3785
3786 }
3787 }
sewardj7ee97522011-05-09 21:45:04 +00003788 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003789 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3790
3791 return "brc";
3792}
3793
florian55085f82012-11-21 00:36:55 +00003794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003795s390_irgen_BRCL(UChar r1, UInt i2)
3796{
3797 IRTemp cond = newTemp(Ity_I32);
3798
3799 if (r1 == 0) {
3800 } else {
3801 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003802 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003803 } else {
3804 assign(cond, s390_call_calculate_cond(r1));
3805 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3806 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3807 }
3808 }
sewardj7ee97522011-05-09 21:45:04 +00003809 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003810 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3811
3812 return "brcl";
3813}
3814
florian55085f82012-11-21 00:36:55 +00003815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003816s390_irgen_BRCT(UChar r1, UShort i2)
3817{
3818 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3819 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3820 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3821
3822 return "brct";
3823}
3824
florian55085f82012-11-21 00:36:55 +00003825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003826s390_irgen_BRCTG(UChar r1, UShort i2)
3827{
3828 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3829 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3830 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3831
3832 return "brctg";
3833}
3834
florian55085f82012-11-21 00:36:55 +00003835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003836s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3837{
3838 IRTemp value = newTemp(Ity_I32);
3839
3840 assign(value, get_gpr_w1(r3 | 1));
3841 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3842 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3843 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3844
3845 return "brxh";
3846}
3847
florian55085f82012-11-21 00:36:55 +00003848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003849s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3850{
3851 IRTemp value = newTemp(Ity_I64);
3852
3853 assign(value, get_gpr_dw0(r3 | 1));
3854 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3855 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3856 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3857
3858 return "brxhg";
3859}
3860
florian55085f82012-11-21 00:36:55 +00003861static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003862s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3863{
3864 IRTemp value = newTemp(Ity_I32);
3865
3866 assign(value, get_gpr_w1(r3 | 1));
3867 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3868 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3869 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3870
3871 return "brxle";
3872}
3873
florian55085f82012-11-21 00:36:55 +00003874static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003875s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3876{
3877 IRTemp value = newTemp(Ity_I64);
3878
3879 assign(value, get_gpr_dw0(r3 | 1));
3880 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3881 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3882 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3883
3884 return "brxlg";
3885}
3886
florian55085f82012-11-21 00:36:55 +00003887static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003888s390_irgen_CR(UChar r1, UChar r2)
3889{
3890 IRTemp op1 = newTemp(Ity_I32);
3891 IRTemp op2 = newTemp(Ity_I32);
3892
3893 assign(op1, get_gpr_w1(r1));
3894 assign(op2, get_gpr_w1(r2));
3895 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3896
3897 return "cr";
3898}
3899
florian55085f82012-11-21 00:36:55 +00003900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003901s390_irgen_CGR(UChar r1, UChar r2)
3902{
3903 IRTemp op1 = newTemp(Ity_I64);
3904 IRTemp op2 = newTemp(Ity_I64);
3905
3906 assign(op1, get_gpr_dw0(r1));
3907 assign(op2, get_gpr_dw0(r2));
3908 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3909
3910 return "cgr";
3911}
3912
florian55085f82012-11-21 00:36:55 +00003913static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003914s390_irgen_CGFR(UChar r1, UChar r2)
3915{
3916 IRTemp op1 = newTemp(Ity_I64);
3917 IRTemp op2 = newTemp(Ity_I64);
3918
3919 assign(op1, get_gpr_dw0(r1));
3920 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3921 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3922
3923 return "cgfr";
3924}
3925
florian55085f82012-11-21 00:36:55 +00003926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003927s390_irgen_C(UChar r1, IRTemp op2addr)
3928{
3929 IRTemp op1 = newTemp(Ity_I32);
3930 IRTemp op2 = newTemp(Ity_I32);
3931
3932 assign(op1, get_gpr_w1(r1));
3933 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3934 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3935
3936 return "c";
3937}
3938
florian55085f82012-11-21 00:36:55 +00003939static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003940s390_irgen_CY(UChar r1, IRTemp op2addr)
3941{
3942 IRTemp op1 = newTemp(Ity_I32);
3943 IRTemp op2 = newTemp(Ity_I32);
3944
3945 assign(op1, get_gpr_w1(r1));
3946 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3947 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3948
3949 return "cy";
3950}
3951
florian55085f82012-11-21 00:36:55 +00003952static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003953s390_irgen_CG(UChar r1, IRTemp op2addr)
3954{
3955 IRTemp op1 = newTemp(Ity_I64);
3956 IRTemp op2 = newTemp(Ity_I64);
3957
3958 assign(op1, get_gpr_dw0(r1));
3959 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3960 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3961
3962 return "cg";
3963}
3964
florian55085f82012-11-21 00:36:55 +00003965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003966s390_irgen_CGF(UChar r1, IRTemp op2addr)
3967{
3968 IRTemp op1 = newTemp(Ity_I64);
3969 IRTemp op2 = newTemp(Ity_I64);
3970
3971 assign(op1, get_gpr_dw0(r1));
3972 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3973 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3974
3975 return "cgf";
3976}
3977
florian55085f82012-11-21 00:36:55 +00003978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003979s390_irgen_CFI(UChar r1, UInt i2)
3980{
3981 IRTemp op1 = newTemp(Ity_I32);
3982 Int op2;
3983
3984 assign(op1, get_gpr_w1(r1));
3985 op2 = (Int)i2;
3986 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3987 mkU32((UInt)op2)));
3988
3989 return "cfi";
3990}
3991
florian55085f82012-11-21 00:36:55 +00003992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003993s390_irgen_CGFI(UChar r1, UInt i2)
3994{
3995 IRTemp op1 = newTemp(Ity_I64);
3996 Long op2;
3997
3998 assign(op1, get_gpr_dw0(r1));
3999 op2 = (Long)(Int)i2;
4000 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4001 mkU64((ULong)op2)));
4002
4003 return "cgfi";
4004}
4005
florian55085f82012-11-21 00:36:55 +00004006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004007s390_irgen_CRL(UChar r1, UInt i2)
4008{
4009 IRTemp op1 = newTemp(Ity_I32);
4010 IRTemp op2 = newTemp(Ity_I32);
4011
4012 assign(op1, get_gpr_w1(r1));
4013 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4014 i2 << 1))));
4015 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4016
4017 return "crl";
4018}
4019
florian55085f82012-11-21 00:36:55 +00004020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004021s390_irgen_CGRL(UChar r1, UInt i2)
4022{
4023 IRTemp op1 = newTemp(Ity_I64);
4024 IRTemp op2 = newTemp(Ity_I64);
4025
4026 assign(op1, get_gpr_dw0(r1));
4027 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4028 i2 << 1))));
4029 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4030
4031 return "cgrl";
4032}
4033
florian55085f82012-11-21 00:36:55 +00004034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004035s390_irgen_CGFRL(UChar r1, UInt i2)
4036{
4037 IRTemp op1 = newTemp(Ity_I64);
4038 IRTemp op2 = newTemp(Ity_I64);
4039
4040 assign(op1, get_gpr_dw0(r1));
4041 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4042 ((ULong)(Long)(Int)i2 << 1)))));
4043 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4044
4045 return "cgfrl";
4046}
4047
florian55085f82012-11-21 00:36:55 +00004048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004049s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4050{
4051 IRTemp op1 = newTemp(Ity_I32);
4052 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004053 IRTemp cond = newTemp(Ity_I32);
4054
4055 if (m3 == 0) {
4056 } else {
4057 if (m3 == 14) {
4058 always_goto(mkexpr(op4addr));
4059 } else {
4060 assign(op1, get_gpr_w1(r1));
4061 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004062 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4063 op1, op2));
florianf321da72012-07-21 20:32:57 +00004064 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4065 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004066 }
4067 }
4068
4069 return "crb";
4070}
4071
florian55085f82012-11-21 00:36:55 +00004072static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004073s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4074{
4075 IRTemp op1 = newTemp(Ity_I64);
4076 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004077 IRTemp cond = newTemp(Ity_I32);
4078
4079 if (m3 == 0) {
4080 } else {
4081 if (m3 == 14) {
4082 always_goto(mkexpr(op4addr));
4083 } else {
4084 assign(op1, get_gpr_dw0(r1));
4085 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004086 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4087 op1, op2));
florianf321da72012-07-21 20:32:57 +00004088 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4089 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004090 }
4091 }
4092
4093 return "cgrb";
4094}
4095
florian55085f82012-11-21 00:36:55 +00004096static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004097s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4098{
4099 IRTemp op1 = newTemp(Ity_I32);
4100 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004101 IRTemp cond = newTemp(Ity_I32);
4102
4103 if (m3 == 0) {
4104 } else {
4105 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004106 always_goto_and_chase(
4107 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004108 } else {
4109 assign(op1, get_gpr_w1(r1));
4110 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004111 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4112 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004113 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4114 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4115
4116 }
4117 }
4118
4119 return "crj";
4120}
4121
florian55085f82012-11-21 00:36:55 +00004122static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004123s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4124{
4125 IRTemp op1 = newTemp(Ity_I64);
4126 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004127 IRTemp cond = newTemp(Ity_I32);
4128
4129 if (m3 == 0) {
4130 } else {
4131 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004132 always_goto_and_chase(
4133 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004134 } else {
4135 assign(op1, get_gpr_dw0(r1));
4136 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004137 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4138 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004139 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4140 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4141
4142 }
4143 }
4144
4145 return "cgrj";
4146}
4147
florian55085f82012-11-21 00:36:55 +00004148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004149s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4150{
4151 IRTemp op1 = newTemp(Ity_I32);
4152 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004153 IRTemp cond = newTemp(Ity_I32);
4154
4155 if (m3 == 0) {
4156 } else {
4157 if (m3 == 14) {
4158 always_goto(mkexpr(op4addr));
4159 } else {
4160 assign(op1, get_gpr_w1(r1));
4161 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004162 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4163 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004164 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4165 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004166 }
4167 }
4168
4169 return "cib";
4170}
4171
florian55085f82012-11-21 00:36:55 +00004172static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004173s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4174{
4175 IRTemp op1 = newTemp(Ity_I64);
4176 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004177 IRTemp cond = newTemp(Ity_I32);
4178
4179 if (m3 == 0) {
4180 } else {
4181 if (m3 == 14) {
4182 always_goto(mkexpr(op4addr));
4183 } else {
4184 assign(op1, get_gpr_dw0(r1));
4185 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004186 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4187 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004188 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4189 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004190 }
4191 }
4192
4193 return "cgib";
4194}
4195
florian55085f82012-11-21 00:36:55 +00004196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004197s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4198{
4199 IRTemp op1 = newTemp(Ity_I32);
4200 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004201 IRTemp cond = newTemp(Ity_I32);
4202
4203 if (m3 == 0) {
4204 } else {
4205 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004206 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004207 } else {
4208 assign(op1, get_gpr_w1(r1));
4209 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004210 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4211 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004212 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4213 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4214
4215 }
4216 }
4217
4218 return "cij";
4219}
4220
florian55085f82012-11-21 00:36:55 +00004221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004222s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4223{
4224 IRTemp op1 = newTemp(Ity_I64);
4225 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004226 IRTemp cond = newTemp(Ity_I32);
4227
4228 if (m3 == 0) {
4229 } else {
4230 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004231 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004232 } else {
4233 assign(op1, get_gpr_dw0(r1));
4234 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004235 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4236 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004237 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4238 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4239
4240 }
4241 }
4242
4243 return "cgij";
4244}
4245
florian55085f82012-11-21 00:36:55 +00004246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004247s390_irgen_CH(UChar r1, IRTemp op2addr)
4248{
4249 IRTemp op1 = newTemp(Ity_I32);
4250 IRTemp op2 = newTemp(Ity_I32);
4251
4252 assign(op1, get_gpr_w1(r1));
4253 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4254 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4255
4256 return "ch";
4257}
4258
florian55085f82012-11-21 00:36:55 +00004259static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004260s390_irgen_CHY(UChar r1, IRTemp op2addr)
4261{
4262 IRTemp op1 = newTemp(Ity_I32);
4263 IRTemp op2 = newTemp(Ity_I32);
4264
4265 assign(op1, get_gpr_w1(r1));
4266 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4267 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4268
4269 return "chy";
4270}
4271
florian55085f82012-11-21 00:36:55 +00004272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004273s390_irgen_CGH(UChar r1, IRTemp op2addr)
4274{
4275 IRTemp op1 = newTemp(Ity_I64);
4276 IRTemp op2 = newTemp(Ity_I64);
4277
4278 assign(op1, get_gpr_dw0(r1));
4279 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4280 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4281
4282 return "cgh";
4283}
4284
florian55085f82012-11-21 00:36:55 +00004285static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004286s390_irgen_CHI(UChar r1, UShort i2)
4287{
4288 IRTemp op1 = newTemp(Ity_I32);
4289 Int op2;
4290
4291 assign(op1, get_gpr_w1(r1));
4292 op2 = (Int)(Short)i2;
4293 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4294 mkU32((UInt)op2)));
4295
4296 return "chi";
4297}
4298
florian55085f82012-11-21 00:36:55 +00004299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004300s390_irgen_CGHI(UChar r1, UShort i2)
4301{
4302 IRTemp op1 = newTemp(Ity_I64);
4303 Long op2;
4304
4305 assign(op1, get_gpr_dw0(r1));
4306 op2 = (Long)(Short)i2;
4307 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4308 mkU64((ULong)op2)));
4309
4310 return "cghi";
4311}
4312
florian55085f82012-11-21 00:36:55 +00004313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004314s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4315{
4316 IRTemp op1 = newTemp(Ity_I16);
4317 Short op2;
4318
4319 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4320 op2 = (Short)i2;
4321 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4322 mkU16((UShort)op2)));
4323
4324 return "chhsi";
4325}
4326
florian55085f82012-11-21 00:36:55 +00004327static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004328s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4329{
4330 IRTemp op1 = newTemp(Ity_I32);
4331 Int op2;
4332
4333 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4334 op2 = (Int)(Short)i2;
4335 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4336 mkU32((UInt)op2)));
4337
4338 return "chsi";
4339}
4340
florian55085f82012-11-21 00:36:55 +00004341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004342s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4343{
4344 IRTemp op1 = newTemp(Ity_I64);
4345 Long op2;
4346
4347 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4348 op2 = (Long)(Short)i2;
4349 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4350 mkU64((ULong)op2)));
4351
4352 return "cghsi";
4353}
4354
florian55085f82012-11-21 00:36:55 +00004355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004356s390_irgen_CHRL(UChar r1, UInt i2)
4357{
4358 IRTemp op1 = newTemp(Ity_I32);
4359 IRTemp op2 = newTemp(Ity_I32);
4360
4361 assign(op1, get_gpr_w1(r1));
4362 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4363 ((ULong)(Long)(Int)i2 << 1)))));
4364 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4365
4366 return "chrl";
4367}
4368
florian55085f82012-11-21 00:36:55 +00004369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004370s390_irgen_CGHRL(UChar r1, UInt i2)
4371{
4372 IRTemp op1 = newTemp(Ity_I64);
4373 IRTemp op2 = newTemp(Ity_I64);
4374
4375 assign(op1, get_gpr_dw0(r1));
4376 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4377 ((ULong)(Long)(Int)i2 << 1)))));
4378 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4379
4380 return "cghrl";
4381}
4382
florian55085f82012-11-21 00:36:55 +00004383static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004384s390_irgen_CHHR(UChar r1, UChar r2)
4385{
4386 IRTemp op1 = newTemp(Ity_I32);
4387 IRTemp op2 = newTemp(Ity_I32);
4388
4389 assign(op1, get_gpr_w0(r1));
4390 assign(op2, get_gpr_w0(r2));
4391 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4392
4393 return "chhr";
4394}
4395
florian55085f82012-11-21 00:36:55 +00004396static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004397s390_irgen_CHLR(UChar r1, UChar r2)
4398{
4399 IRTemp op1 = newTemp(Ity_I32);
4400 IRTemp op2 = newTemp(Ity_I32);
4401
4402 assign(op1, get_gpr_w0(r1));
4403 assign(op2, get_gpr_w1(r2));
4404 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4405
4406 return "chlr";
4407}
4408
florian55085f82012-11-21 00:36:55 +00004409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004410s390_irgen_CHF(UChar r1, IRTemp op2addr)
4411{
4412 IRTemp op1 = newTemp(Ity_I32);
4413 IRTemp op2 = newTemp(Ity_I32);
4414
4415 assign(op1, get_gpr_w0(r1));
4416 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4417 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4418
4419 return "chf";
4420}
4421
florian55085f82012-11-21 00:36:55 +00004422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004423s390_irgen_CIH(UChar r1, UInt i2)
4424{
4425 IRTemp op1 = newTemp(Ity_I32);
4426 Int op2;
4427
4428 assign(op1, get_gpr_w0(r1));
4429 op2 = (Int)i2;
4430 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4431 mkU32((UInt)op2)));
4432
4433 return "cih";
4434}
4435
florian55085f82012-11-21 00:36:55 +00004436static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004437s390_irgen_CLR(UChar r1, UChar r2)
4438{
4439 IRTemp op1 = newTemp(Ity_I32);
4440 IRTemp op2 = newTemp(Ity_I32);
4441
4442 assign(op1, get_gpr_w1(r1));
4443 assign(op2, get_gpr_w1(r2));
4444 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4445
4446 return "clr";
4447}
4448
florian55085f82012-11-21 00:36:55 +00004449static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004450s390_irgen_CLGR(UChar r1, UChar r2)
4451{
4452 IRTemp op1 = newTemp(Ity_I64);
4453 IRTemp op2 = newTemp(Ity_I64);
4454
4455 assign(op1, get_gpr_dw0(r1));
4456 assign(op2, get_gpr_dw0(r2));
4457 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4458
4459 return "clgr";
4460}
4461
florian55085f82012-11-21 00:36:55 +00004462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004463s390_irgen_CLGFR(UChar r1, UChar r2)
4464{
4465 IRTemp op1 = newTemp(Ity_I64);
4466 IRTemp op2 = newTemp(Ity_I64);
4467
4468 assign(op1, get_gpr_dw0(r1));
4469 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4470 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4471
4472 return "clgfr";
4473}
4474
florian55085f82012-11-21 00:36:55 +00004475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004476s390_irgen_CL(UChar r1, IRTemp op2addr)
4477{
4478 IRTemp op1 = newTemp(Ity_I32);
4479 IRTemp op2 = newTemp(Ity_I32);
4480
4481 assign(op1, get_gpr_w1(r1));
4482 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4483 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4484
4485 return "cl";
4486}
4487
florian55085f82012-11-21 00:36:55 +00004488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004489s390_irgen_CLY(UChar r1, IRTemp op2addr)
4490{
4491 IRTemp op1 = newTemp(Ity_I32);
4492 IRTemp op2 = newTemp(Ity_I32);
4493
4494 assign(op1, get_gpr_w1(r1));
4495 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4496 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4497
4498 return "cly";
4499}
4500
florian55085f82012-11-21 00:36:55 +00004501static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004502s390_irgen_CLG(UChar r1, IRTemp op2addr)
4503{
4504 IRTemp op1 = newTemp(Ity_I64);
4505 IRTemp op2 = newTemp(Ity_I64);
4506
4507 assign(op1, get_gpr_dw0(r1));
4508 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4509 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4510
4511 return "clg";
4512}
4513
florian55085f82012-11-21 00:36:55 +00004514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004515s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4516{
4517 IRTemp op1 = newTemp(Ity_I64);
4518 IRTemp op2 = newTemp(Ity_I64);
4519
4520 assign(op1, get_gpr_dw0(r1));
4521 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4522 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4523
4524 return "clgf";
4525}
4526
florian55085f82012-11-21 00:36:55 +00004527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004528s390_irgen_CLFI(UChar r1, UInt i2)
4529{
4530 IRTemp op1 = newTemp(Ity_I32);
4531 UInt op2;
4532
4533 assign(op1, get_gpr_w1(r1));
4534 op2 = i2;
4535 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4536 mkU32(op2)));
4537
4538 return "clfi";
4539}
4540
florian55085f82012-11-21 00:36:55 +00004541static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004542s390_irgen_CLGFI(UChar r1, UInt i2)
4543{
4544 IRTemp op1 = newTemp(Ity_I64);
4545 ULong op2;
4546
4547 assign(op1, get_gpr_dw0(r1));
4548 op2 = (ULong)i2;
4549 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4550 mkU64(op2)));
4551
4552 return "clgfi";
4553}
4554
florian55085f82012-11-21 00:36:55 +00004555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004556s390_irgen_CLI(UChar i2, IRTemp op1addr)
4557{
4558 IRTemp op1 = newTemp(Ity_I8);
4559 UChar op2;
4560
4561 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4562 op2 = i2;
4563 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4564 mkU8(op2)));
4565
4566 return "cli";
4567}
4568
florian55085f82012-11-21 00:36:55 +00004569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004570s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4571{
4572 IRTemp op1 = newTemp(Ity_I8);
4573 UChar op2;
4574
4575 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4576 op2 = i2;
4577 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4578 mkU8(op2)));
4579
4580 return "cliy";
4581}
4582
florian55085f82012-11-21 00:36:55 +00004583static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004584s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4585{
4586 IRTemp op1 = newTemp(Ity_I32);
4587 UInt op2;
4588
4589 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4590 op2 = (UInt)i2;
4591 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4592 mkU32(op2)));
4593
4594 return "clfhsi";
4595}
4596
florian55085f82012-11-21 00:36:55 +00004597static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004598s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4599{
4600 IRTemp op1 = newTemp(Ity_I64);
4601 ULong op2;
4602
4603 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4604 op2 = (ULong)i2;
4605 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4606 mkU64(op2)));
4607
4608 return "clghsi";
4609}
4610
florian55085f82012-11-21 00:36:55 +00004611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004612s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4613{
4614 IRTemp op1 = newTemp(Ity_I16);
4615 UShort op2;
4616
4617 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4618 op2 = i2;
4619 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4620 mkU16(op2)));
4621
4622 return "clhhsi";
4623}
4624
florian55085f82012-11-21 00:36:55 +00004625static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004626s390_irgen_CLRL(UChar r1, UInt i2)
4627{
4628 IRTemp op1 = newTemp(Ity_I32);
4629 IRTemp op2 = newTemp(Ity_I32);
4630
4631 assign(op1, get_gpr_w1(r1));
4632 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4633 i2 << 1))));
4634 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4635
4636 return "clrl";
4637}
4638
florian55085f82012-11-21 00:36:55 +00004639static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004640s390_irgen_CLGRL(UChar r1, UInt i2)
4641{
4642 IRTemp op1 = newTemp(Ity_I64);
4643 IRTemp op2 = newTemp(Ity_I64);
4644
4645 assign(op1, get_gpr_dw0(r1));
4646 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4647 i2 << 1))));
4648 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4649
4650 return "clgrl";
4651}
4652
florian55085f82012-11-21 00:36:55 +00004653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004654s390_irgen_CLGFRL(UChar r1, UInt i2)
4655{
4656 IRTemp op1 = newTemp(Ity_I64);
4657 IRTemp op2 = newTemp(Ity_I64);
4658
4659 assign(op1, get_gpr_dw0(r1));
4660 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4661 ((ULong)(Long)(Int)i2 << 1)))));
4662 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4663
4664 return "clgfrl";
4665}
4666
florian55085f82012-11-21 00:36:55 +00004667static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004668s390_irgen_CLHRL(UChar r1, UInt i2)
4669{
4670 IRTemp op1 = newTemp(Ity_I32);
4671 IRTemp op2 = newTemp(Ity_I32);
4672
4673 assign(op1, get_gpr_w1(r1));
4674 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4675 ((ULong)(Long)(Int)i2 << 1)))));
4676 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4677
4678 return "clhrl";
4679}
4680
florian55085f82012-11-21 00:36:55 +00004681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004682s390_irgen_CLGHRL(UChar r1, UInt i2)
4683{
4684 IRTemp op1 = newTemp(Ity_I64);
4685 IRTemp op2 = newTemp(Ity_I64);
4686
4687 assign(op1, get_gpr_dw0(r1));
4688 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4689 ((ULong)(Long)(Int)i2 << 1)))));
4690 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4691
4692 return "clghrl";
4693}
4694
florian55085f82012-11-21 00:36:55 +00004695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004696s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4697{
4698 IRTemp op1 = newTemp(Ity_I32);
4699 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004700 IRTemp cond = newTemp(Ity_I32);
4701
4702 if (m3 == 0) {
4703 } else {
4704 if (m3 == 14) {
4705 always_goto(mkexpr(op4addr));
4706 } else {
4707 assign(op1, get_gpr_w1(r1));
4708 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004709 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4710 op1, op2));
florianf321da72012-07-21 20:32:57 +00004711 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4712 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004713 }
4714 }
4715
4716 return "clrb";
4717}
4718
florian55085f82012-11-21 00:36:55 +00004719static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004720s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4721{
4722 IRTemp op1 = newTemp(Ity_I64);
4723 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004724 IRTemp cond = newTemp(Ity_I32);
4725
4726 if (m3 == 0) {
4727 } else {
4728 if (m3 == 14) {
4729 always_goto(mkexpr(op4addr));
4730 } else {
4731 assign(op1, get_gpr_dw0(r1));
4732 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004733 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4734 op1, op2));
florianf321da72012-07-21 20:32:57 +00004735 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4736 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004737 }
4738 }
4739
4740 return "clgrb";
4741}
4742
florian55085f82012-11-21 00:36:55 +00004743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004744s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4745{
4746 IRTemp op1 = newTemp(Ity_I32);
4747 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004748 IRTemp cond = newTemp(Ity_I32);
4749
4750 if (m3 == 0) {
4751 } else {
4752 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004753 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004754 } else {
4755 assign(op1, get_gpr_w1(r1));
4756 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004757 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4758 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004759 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4760 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4761
4762 }
4763 }
4764
4765 return "clrj";
4766}
4767
florian55085f82012-11-21 00:36:55 +00004768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004769s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4770{
4771 IRTemp op1 = newTemp(Ity_I64);
4772 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004773 IRTemp cond = newTemp(Ity_I32);
4774
4775 if (m3 == 0) {
4776 } else {
4777 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004778 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004779 } else {
4780 assign(op1, get_gpr_dw0(r1));
4781 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004782 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4783 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004784 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4785 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4786
4787 }
4788 }
4789
4790 return "clgrj";
4791}
4792
florian55085f82012-11-21 00:36:55 +00004793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004794s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4795{
4796 IRTemp op1 = newTemp(Ity_I32);
4797 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004798 IRTemp cond = newTemp(Ity_I32);
4799
4800 if (m3 == 0) {
4801 } else {
4802 if (m3 == 14) {
4803 always_goto(mkexpr(op4addr));
4804 } else {
4805 assign(op1, get_gpr_w1(r1));
4806 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004807 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4808 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004809 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4810 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004811 }
4812 }
4813
4814 return "clib";
4815}
4816
florian55085f82012-11-21 00:36:55 +00004817static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004818s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4819{
4820 IRTemp op1 = newTemp(Ity_I64);
4821 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004822 IRTemp cond = newTemp(Ity_I32);
4823
4824 if (m3 == 0) {
4825 } else {
4826 if (m3 == 14) {
4827 always_goto(mkexpr(op4addr));
4828 } else {
4829 assign(op1, get_gpr_dw0(r1));
4830 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004831 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4832 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004833 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4834 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004835 }
4836 }
4837
4838 return "clgib";
4839}
4840
florian55085f82012-11-21 00:36:55 +00004841static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004842s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4843{
4844 IRTemp op1 = newTemp(Ity_I32);
4845 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004846 IRTemp cond = newTemp(Ity_I32);
4847
4848 if (m3 == 0) {
4849 } else {
4850 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004851 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004852 } else {
4853 assign(op1, get_gpr_w1(r1));
4854 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004855 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4856 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004857 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4858 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4859
4860 }
4861 }
4862
4863 return "clij";
4864}
4865
florian55085f82012-11-21 00:36:55 +00004866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004867s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4868{
4869 IRTemp op1 = newTemp(Ity_I64);
4870 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004871 IRTemp cond = newTemp(Ity_I32);
4872
4873 if (m3 == 0) {
4874 } else {
4875 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004876 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004877 } else {
4878 assign(op1, get_gpr_dw0(r1));
4879 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004880 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4881 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004882 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4883 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4884
4885 }
4886 }
4887
4888 return "clgij";
4889}
4890
florian55085f82012-11-21 00:36:55 +00004891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004892s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4893{
4894 IRTemp op1 = newTemp(Ity_I32);
4895 IRTemp op2 = newTemp(Ity_I32);
4896 IRTemp b0 = newTemp(Ity_I32);
4897 IRTemp b1 = newTemp(Ity_I32);
4898 IRTemp b2 = newTemp(Ity_I32);
4899 IRTemp b3 = newTemp(Ity_I32);
4900 IRTemp c0 = newTemp(Ity_I32);
4901 IRTemp c1 = newTemp(Ity_I32);
4902 IRTemp c2 = newTemp(Ity_I32);
4903 IRTemp c3 = newTemp(Ity_I32);
4904 UChar n;
4905
4906 n = 0;
4907 if ((r3 & 8) != 0) {
4908 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4909 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4910 n = n + 1;
4911 } else {
4912 assign(b0, mkU32(0));
4913 assign(c0, mkU32(0));
4914 }
4915 if ((r3 & 4) != 0) {
4916 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4917 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4918 mkU64(n)))));
4919 n = n + 1;
4920 } else {
4921 assign(b1, mkU32(0));
4922 assign(c1, mkU32(0));
4923 }
4924 if ((r3 & 2) != 0) {
4925 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4926 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4927 mkU64(n)))));
4928 n = n + 1;
4929 } else {
4930 assign(b2, mkU32(0));
4931 assign(c2, mkU32(0));
4932 }
4933 if ((r3 & 1) != 0) {
4934 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4935 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4936 mkU64(n)))));
4937 n = n + 1;
4938 } else {
4939 assign(b3, mkU32(0));
4940 assign(c3, mkU32(0));
4941 }
4942 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4943 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4944 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4945 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4946 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4947 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4948 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4949
4950 return "clm";
4951}
4952
florian55085f82012-11-21 00:36:55 +00004953static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004954s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4955{
4956 IRTemp op1 = newTemp(Ity_I32);
4957 IRTemp op2 = newTemp(Ity_I32);
4958 IRTemp b0 = newTemp(Ity_I32);
4959 IRTemp b1 = newTemp(Ity_I32);
4960 IRTemp b2 = newTemp(Ity_I32);
4961 IRTemp b3 = newTemp(Ity_I32);
4962 IRTemp c0 = newTemp(Ity_I32);
4963 IRTemp c1 = newTemp(Ity_I32);
4964 IRTemp c2 = newTemp(Ity_I32);
4965 IRTemp c3 = newTemp(Ity_I32);
4966 UChar n;
4967
4968 n = 0;
4969 if ((r3 & 8) != 0) {
4970 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4971 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4972 n = n + 1;
4973 } else {
4974 assign(b0, mkU32(0));
4975 assign(c0, mkU32(0));
4976 }
4977 if ((r3 & 4) != 0) {
4978 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4979 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4980 mkU64(n)))));
4981 n = n + 1;
4982 } else {
4983 assign(b1, mkU32(0));
4984 assign(c1, mkU32(0));
4985 }
4986 if ((r3 & 2) != 0) {
4987 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4988 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4989 mkU64(n)))));
4990 n = n + 1;
4991 } else {
4992 assign(b2, mkU32(0));
4993 assign(c2, mkU32(0));
4994 }
4995 if ((r3 & 1) != 0) {
4996 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4997 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4998 mkU64(n)))));
4999 n = n + 1;
5000 } else {
5001 assign(b3, mkU32(0));
5002 assign(c3, mkU32(0));
5003 }
5004 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5005 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5006 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5007 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5008 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5009 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5010 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5011
5012 return "clmy";
5013}
5014
florian55085f82012-11-21 00:36:55 +00005015static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005016s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5017{
5018 IRTemp op1 = newTemp(Ity_I32);
5019 IRTemp op2 = newTemp(Ity_I32);
5020 IRTemp b0 = newTemp(Ity_I32);
5021 IRTemp b1 = newTemp(Ity_I32);
5022 IRTemp b2 = newTemp(Ity_I32);
5023 IRTemp b3 = newTemp(Ity_I32);
5024 IRTemp c0 = newTemp(Ity_I32);
5025 IRTemp c1 = newTemp(Ity_I32);
5026 IRTemp c2 = newTemp(Ity_I32);
5027 IRTemp c3 = newTemp(Ity_I32);
5028 UChar n;
5029
5030 n = 0;
5031 if ((r3 & 8) != 0) {
5032 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5033 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5034 n = n + 1;
5035 } else {
5036 assign(b0, mkU32(0));
5037 assign(c0, mkU32(0));
5038 }
5039 if ((r3 & 4) != 0) {
5040 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5041 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5042 mkU64(n)))));
5043 n = n + 1;
5044 } else {
5045 assign(b1, mkU32(0));
5046 assign(c1, mkU32(0));
5047 }
5048 if ((r3 & 2) != 0) {
5049 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5050 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5051 mkU64(n)))));
5052 n = n + 1;
5053 } else {
5054 assign(b2, mkU32(0));
5055 assign(c2, mkU32(0));
5056 }
5057 if ((r3 & 1) != 0) {
5058 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5059 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5060 mkU64(n)))));
5061 n = n + 1;
5062 } else {
5063 assign(b3, mkU32(0));
5064 assign(c3, mkU32(0));
5065 }
5066 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5067 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5068 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5069 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5070 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5071 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5072 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5073
5074 return "clmh";
5075}
5076
florian55085f82012-11-21 00:36:55 +00005077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005078s390_irgen_CLHHR(UChar r1, UChar r2)
5079{
5080 IRTemp op1 = newTemp(Ity_I32);
5081 IRTemp op2 = newTemp(Ity_I32);
5082
5083 assign(op1, get_gpr_w0(r1));
5084 assign(op2, get_gpr_w0(r2));
5085 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5086
5087 return "clhhr";
5088}
5089
florian55085f82012-11-21 00:36:55 +00005090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005091s390_irgen_CLHLR(UChar r1, UChar r2)
5092{
5093 IRTemp op1 = newTemp(Ity_I32);
5094 IRTemp op2 = newTemp(Ity_I32);
5095
5096 assign(op1, get_gpr_w0(r1));
5097 assign(op2, get_gpr_w1(r2));
5098 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5099
5100 return "clhlr";
5101}
5102
florian55085f82012-11-21 00:36:55 +00005103static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005104s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5105{
5106 IRTemp op1 = newTemp(Ity_I32);
5107 IRTemp op2 = newTemp(Ity_I32);
5108
5109 assign(op1, get_gpr_w0(r1));
5110 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5111 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5112
5113 return "clhf";
5114}
5115
florian55085f82012-11-21 00:36:55 +00005116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005117s390_irgen_CLIH(UChar r1, UInt i2)
5118{
5119 IRTemp op1 = newTemp(Ity_I32);
5120 UInt op2;
5121
5122 assign(op1, get_gpr_w0(r1));
5123 op2 = i2;
5124 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5125 mkU32(op2)));
5126
5127 return "clih";
5128}
5129
florian55085f82012-11-21 00:36:55 +00005130static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005131s390_irgen_CPYA(UChar r1, UChar r2)
5132{
5133 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005134 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005135 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5136
5137 return "cpya";
5138}
5139
florian55085f82012-11-21 00:36:55 +00005140static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005141s390_irgen_XR(UChar r1, UChar r2)
5142{
5143 IRTemp op1 = newTemp(Ity_I32);
5144 IRTemp op2 = newTemp(Ity_I32);
5145 IRTemp result = newTemp(Ity_I32);
5146
5147 if (r1 == r2) {
5148 assign(result, mkU32(0));
5149 } else {
5150 assign(op1, get_gpr_w1(r1));
5151 assign(op2, get_gpr_w1(r2));
5152 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5153 }
5154 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5155 put_gpr_w1(r1, mkexpr(result));
5156
5157 return "xr";
5158}
5159
florian55085f82012-11-21 00:36:55 +00005160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005161s390_irgen_XGR(UChar r1, UChar r2)
5162{
5163 IRTemp op1 = newTemp(Ity_I64);
5164 IRTemp op2 = newTemp(Ity_I64);
5165 IRTemp result = newTemp(Ity_I64);
5166
5167 if (r1 == r2) {
5168 assign(result, mkU64(0));
5169 } else {
5170 assign(op1, get_gpr_dw0(r1));
5171 assign(op2, get_gpr_dw0(r2));
5172 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5173 }
5174 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5175 put_gpr_dw0(r1, mkexpr(result));
5176
5177 return "xgr";
5178}
5179
florian55085f82012-11-21 00:36:55 +00005180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005181s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5182{
5183 IRTemp op2 = newTemp(Ity_I32);
5184 IRTemp op3 = newTemp(Ity_I32);
5185 IRTemp result = newTemp(Ity_I32);
5186
5187 assign(op2, get_gpr_w1(r2));
5188 assign(op3, get_gpr_w1(r3));
5189 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5190 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5191 put_gpr_w1(r1, mkexpr(result));
5192
5193 return "xrk";
5194}
5195
florian55085f82012-11-21 00:36:55 +00005196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005197s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5198{
5199 IRTemp op2 = newTemp(Ity_I64);
5200 IRTemp op3 = newTemp(Ity_I64);
5201 IRTemp result = newTemp(Ity_I64);
5202
5203 assign(op2, get_gpr_dw0(r2));
5204 assign(op3, get_gpr_dw0(r3));
5205 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5206 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5207 put_gpr_dw0(r1, mkexpr(result));
5208
5209 return "xgrk";
5210}
5211
florian55085f82012-11-21 00:36:55 +00005212static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005213s390_irgen_X(UChar r1, IRTemp op2addr)
5214{
5215 IRTemp op1 = newTemp(Ity_I32);
5216 IRTemp op2 = newTemp(Ity_I32);
5217 IRTemp result = newTemp(Ity_I32);
5218
5219 assign(op1, get_gpr_w1(r1));
5220 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5221 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5222 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5223 put_gpr_w1(r1, mkexpr(result));
5224
5225 return "x";
5226}
5227
florian55085f82012-11-21 00:36:55 +00005228static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005229s390_irgen_XY(UChar r1, IRTemp op2addr)
5230{
5231 IRTemp op1 = newTemp(Ity_I32);
5232 IRTemp op2 = newTemp(Ity_I32);
5233 IRTemp result = newTemp(Ity_I32);
5234
5235 assign(op1, get_gpr_w1(r1));
5236 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5237 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5238 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5239 put_gpr_w1(r1, mkexpr(result));
5240
5241 return "xy";
5242}
5243
florian55085f82012-11-21 00:36:55 +00005244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005245s390_irgen_XG(UChar r1, IRTemp op2addr)
5246{
5247 IRTemp op1 = newTemp(Ity_I64);
5248 IRTemp op2 = newTemp(Ity_I64);
5249 IRTemp result = newTemp(Ity_I64);
5250
5251 assign(op1, get_gpr_dw0(r1));
5252 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5253 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5254 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5255 put_gpr_dw0(r1, mkexpr(result));
5256
5257 return "xg";
5258}
5259
florian55085f82012-11-21 00:36:55 +00005260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005261s390_irgen_XI(UChar i2, IRTemp op1addr)
5262{
5263 IRTemp op1 = newTemp(Ity_I8);
5264 UChar op2;
5265 IRTemp result = newTemp(Ity_I8);
5266
5267 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5268 op2 = i2;
5269 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5270 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5271 store(mkexpr(op1addr), mkexpr(result));
5272
5273 return "xi";
5274}
5275
florian55085f82012-11-21 00:36:55 +00005276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005277s390_irgen_XIY(UChar i2, IRTemp op1addr)
5278{
5279 IRTemp op1 = newTemp(Ity_I8);
5280 UChar op2;
5281 IRTemp result = newTemp(Ity_I8);
5282
5283 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5284 op2 = i2;
5285 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5286 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5287 store(mkexpr(op1addr), mkexpr(result));
5288
5289 return "xiy";
5290}
5291
florian55085f82012-11-21 00:36:55 +00005292static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005293s390_irgen_XIHF(UChar r1, UInt i2)
5294{
5295 IRTemp op1 = newTemp(Ity_I32);
5296 UInt op2;
5297 IRTemp result = newTemp(Ity_I32);
5298
5299 assign(op1, get_gpr_w0(r1));
5300 op2 = i2;
5301 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5302 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5303 put_gpr_w0(r1, mkexpr(result));
5304
5305 return "xihf";
5306}
5307
florian55085f82012-11-21 00:36:55 +00005308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005309s390_irgen_XILF(UChar r1, UInt i2)
5310{
5311 IRTemp op1 = newTemp(Ity_I32);
5312 UInt op2;
5313 IRTemp result = newTemp(Ity_I32);
5314
5315 assign(op1, get_gpr_w1(r1));
5316 op2 = i2;
5317 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5318 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5319 put_gpr_w1(r1, mkexpr(result));
5320
5321 return "xilf";
5322}
5323
florian55085f82012-11-21 00:36:55 +00005324static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005325s390_irgen_EAR(UChar r1, UChar r2)
5326{
5327 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005328 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005329 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5330
5331 return "ear";
5332}
5333
florian55085f82012-11-21 00:36:55 +00005334static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005335s390_irgen_IC(UChar r1, IRTemp op2addr)
5336{
5337 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5338
5339 return "ic";
5340}
5341
florian55085f82012-11-21 00:36:55 +00005342static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005343s390_irgen_ICY(UChar r1, IRTemp op2addr)
5344{
5345 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5346
5347 return "icy";
5348}
5349
florian55085f82012-11-21 00:36:55 +00005350static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005351s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5352{
5353 UChar n;
5354 IRTemp result = newTemp(Ity_I32);
5355 UInt mask;
5356
5357 n = 0;
5358 mask = (UInt)r3;
5359 if ((mask & 8) != 0) {
5360 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5361 n = n + 1;
5362 }
5363 if ((mask & 4) != 0) {
5364 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5365
5366 n = n + 1;
5367 }
5368 if ((mask & 2) != 0) {
5369 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5370
5371 n = n + 1;
5372 }
5373 if ((mask & 1) != 0) {
5374 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5375
5376 n = n + 1;
5377 }
5378 assign(result, get_gpr_w1(r1));
5379 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5380 mkU32(mask)));
5381
5382 return "icm";
5383}
5384
florian55085f82012-11-21 00:36:55 +00005385static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005386s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5387{
5388 UChar n;
5389 IRTemp result = newTemp(Ity_I32);
5390 UInt mask;
5391
5392 n = 0;
5393 mask = (UInt)r3;
5394 if ((mask & 8) != 0) {
5395 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5396 n = n + 1;
5397 }
5398 if ((mask & 4) != 0) {
5399 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5400
5401 n = n + 1;
5402 }
5403 if ((mask & 2) != 0) {
5404 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5405
5406 n = n + 1;
5407 }
5408 if ((mask & 1) != 0) {
5409 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5410
5411 n = n + 1;
5412 }
5413 assign(result, get_gpr_w1(r1));
5414 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5415 mkU32(mask)));
5416
5417 return "icmy";
5418}
5419
florian55085f82012-11-21 00:36:55 +00005420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005421s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5422{
5423 UChar n;
5424 IRTemp result = newTemp(Ity_I32);
5425 UInt mask;
5426
5427 n = 0;
5428 mask = (UInt)r3;
5429 if ((mask & 8) != 0) {
5430 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5431 n = n + 1;
5432 }
5433 if ((mask & 4) != 0) {
5434 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5435
5436 n = n + 1;
5437 }
5438 if ((mask & 2) != 0) {
5439 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5440
5441 n = n + 1;
5442 }
5443 if ((mask & 1) != 0) {
5444 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5445
5446 n = n + 1;
5447 }
5448 assign(result, get_gpr_w0(r1));
5449 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5450 mkU32(mask)));
5451
5452 return "icmh";
5453}
5454
florian55085f82012-11-21 00:36:55 +00005455static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005456s390_irgen_IIHF(UChar r1, UInt i2)
5457{
5458 put_gpr_w0(r1, mkU32(i2));
5459
5460 return "iihf";
5461}
5462
florian55085f82012-11-21 00:36:55 +00005463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005464s390_irgen_IIHH(UChar r1, UShort i2)
5465{
5466 put_gpr_hw0(r1, mkU16(i2));
5467
5468 return "iihh";
5469}
5470
florian55085f82012-11-21 00:36:55 +00005471static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005472s390_irgen_IIHL(UChar r1, UShort i2)
5473{
5474 put_gpr_hw1(r1, mkU16(i2));
5475
5476 return "iihl";
5477}
5478
florian55085f82012-11-21 00:36:55 +00005479static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005480s390_irgen_IILF(UChar r1, UInt i2)
5481{
5482 put_gpr_w1(r1, mkU32(i2));
5483
5484 return "iilf";
5485}
5486
florian55085f82012-11-21 00:36:55 +00005487static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005488s390_irgen_IILH(UChar r1, UShort i2)
5489{
5490 put_gpr_hw2(r1, mkU16(i2));
5491
5492 return "iilh";
5493}
5494
florian55085f82012-11-21 00:36:55 +00005495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005496s390_irgen_IILL(UChar r1, UShort i2)
5497{
5498 put_gpr_hw3(r1, mkU16(i2));
5499
5500 return "iill";
5501}
5502
florian55085f82012-11-21 00:36:55 +00005503static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005504s390_irgen_LR(UChar r1, UChar r2)
5505{
5506 put_gpr_w1(r1, get_gpr_w1(r2));
5507
5508 return "lr";
5509}
5510
florian55085f82012-11-21 00:36:55 +00005511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005512s390_irgen_LGR(UChar r1, UChar r2)
5513{
5514 put_gpr_dw0(r1, get_gpr_dw0(r2));
5515
5516 return "lgr";
5517}
5518
florian55085f82012-11-21 00:36:55 +00005519static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005520s390_irgen_LGFR(UChar r1, UChar r2)
5521{
5522 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5523
5524 return "lgfr";
5525}
5526
florian55085f82012-11-21 00:36:55 +00005527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005528s390_irgen_L(UChar r1, IRTemp op2addr)
5529{
5530 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5531
5532 return "l";
5533}
5534
florian55085f82012-11-21 00:36:55 +00005535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005536s390_irgen_LY(UChar r1, IRTemp op2addr)
5537{
5538 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5539
5540 return "ly";
5541}
5542
florian55085f82012-11-21 00:36:55 +00005543static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005544s390_irgen_LG(UChar r1, IRTemp op2addr)
5545{
5546 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5547
5548 return "lg";
5549}
5550
florian55085f82012-11-21 00:36:55 +00005551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005552s390_irgen_LGF(UChar r1, IRTemp op2addr)
5553{
5554 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5555
5556 return "lgf";
5557}
5558
florian55085f82012-11-21 00:36:55 +00005559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005560s390_irgen_LGFI(UChar r1, UInt i2)
5561{
5562 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5563
5564 return "lgfi";
5565}
5566
florian55085f82012-11-21 00:36:55 +00005567static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005568s390_irgen_LRL(UChar r1, UInt i2)
5569{
5570 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5571 i2 << 1))));
5572
5573 return "lrl";
5574}
5575
florian55085f82012-11-21 00:36:55 +00005576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005577s390_irgen_LGRL(UChar r1, UInt i2)
5578{
5579 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5580 i2 << 1))));
5581
5582 return "lgrl";
5583}
5584
florian55085f82012-11-21 00:36:55 +00005585static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005586s390_irgen_LGFRL(UChar r1, UInt i2)
5587{
5588 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5589 ((ULong)(Long)(Int)i2 << 1)))));
5590
5591 return "lgfrl";
5592}
5593
florian55085f82012-11-21 00:36:55 +00005594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005595s390_irgen_LA(UChar r1, IRTemp op2addr)
5596{
5597 put_gpr_dw0(r1, mkexpr(op2addr));
5598
5599 return "la";
5600}
5601
florian55085f82012-11-21 00:36:55 +00005602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005603s390_irgen_LAY(UChar r1, IRTemp op2addr)
5604{
5605 put_gpr_dw0(r1, mkexpr(op2addr));
5606
5607 return "lay";
5608}
5609
florian55085f82012-11-21 00:36:55 +00005610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005611s390_irgen_LAE(UChar r1, IRTemp op2addr)
5612{
5613 put_gpr_dw0(r1, mkexpr(op2addr));
5614
5615 return "lae";
5616}
5617
florian55085f82012-11-21 00:36:55 +00005618static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005619s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5620{
5621 put_gpr_dw0(r1, mkexpr(op2addr));
5622
5623 return "laey";
5624}
5625
florian55085f82012-11-21 00:36:55 +00005626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005627s390_irgen_LARL(UChar r1, UInt i2)
5628{
5629 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5630
5631 return "larl";
5632}
5633
floriana265ee72012-12-02 20:58:17 +00005634/* The IR representation of LAA and friends is an approximation of what
5635 happens natively. Essentially a loop containing a compare-and-swap is
5636 constructed which will iterate until the CAS succeeds. As a consequence,
5637 instrumenters may see more memory accesses than happen natively. See also
5638 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005639static void
5640s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005641{
floriana265ee72012-12-02 20:58:17 +00005642 IRCAS *cas;
5643 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005644 IRTemp op2 = newTemp(Ity_I32);
5645 IRTemp op3 = newTemp(Ity_I32);
5646 IRTemp result = newTemp(Ity_I32);
5647
5648 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5649 assign(op3, get_gpr_w1(r3));
5650 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005651
5652 /* Place the addition of second operand and third operand at the
5653 second-operand location everytime */
5654 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5655 Iend_BE, mkexpr(op2addr),
5656 NULL, mkexpr(op2), /* expected value */
5657 NULL, mkexpr(result) /* new value */);
5658 stmt(IRStmt_CAS(cas));
5659
florianffc94012012-12-02 21:31:15 +00005660 /* Set CC according to 32-bit addition */
5661 if (is_signed) {
5662 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5663 } else {
5664 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5665 }
floriana265ee72012-12-02 20:58:17 +00005666
5667 /* If old_mem contains the expected value, then the CAS succeeded.
5668 Otherwise, it did not */
5669 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5670 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005671}
5672
5673static void
5674s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5675{
5676 IRCAS *cas;
5677 IRTemp old_mem = newTemp(Ity_I64);
5678 IRTemp op2 = newTemp(Ity_I64);
5679 IRTemp op3 = newTemp(Ity_I64);
5680 IRTemp result = newTemp(Ity_I64);
5681
5682 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5683 assign(op3, get_gpr_dw0(r3));
5684 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5685
5686 /* Place the addition of second operand and third operand at the
5687 second-operand location everytime */
5688 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5689 Iend_BE, mkexpr(op2addr),
5690 NULL, mkexpr(op2), /* expected value */
5691 NULL, mkexpr(result) /* new value */);
5692 stmt(IRStmt_CAS(cas));
5693
5694 /* Set CC according to 64-bit addition */
5695 if (is_signed) {
5696 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5697 } else {
5698 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5699 }
5700
5701 /* If old_mem contains the expected value, then the CAS succeeded.
5702 Otherwise, it did not */
5703 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5704 put_gpr_dw0(r1, mkexpr(old_mem));
5705}
5706
5707static void
5708s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5709{
5710 IRCAS *cas;
5711 IRTemp old_mem = newTemp(Ity_I32);
5712 IRTemp op2 = newTemp(Ity_I32);
5713 IRTemp op3 = newTemp(Ity_I32);
5714 IRTemp result = newTemp(Ity_I32);
5715
5716 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5717 assign(op3, get_gpr_w1(r3));
5718 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5719
5720 /* Place the addition of second operand and third operand at the
5721 second-operand location everytime */
5722 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5723 Iend_BE, mkexpr(op2addr),
5724 NULL, mkexpr(op2), /* expected value */
5725 NULL, mkexpr(result) /* new value */);
5726 stmt(IRStmt_CAS(cas));
5727
5728 /* Set CC according to bitwise operation */
5729 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5730
5731 /* If old_mem contains the expected value, then the CAS succeeded.
5732 Otherwise, it did not */
5733 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5734 put_gpr_w1(r1, mkexpr(old_mem));
5735}
5736
5737static void
5738s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5739{
5740 IRCAS *cas;
5741 IRTemp old_mem = newTemp(Ity_I64);
5742 IRTemp op2 = newTemp(Ity_I64);
5743 IRTemp op3 = newTemp(Ity_I64);
5744 IRTemp result = newTemp(Ity_I64);
5745
5746 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5747 assign(op3, get_gpr_dw0(r3));
5748 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5749
5750 /* Place the addition of second operand and third operand at the
5751 second-operand location everytime */
5752 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5753 Iend_BE, mkexpr(op2addr),
5754 NULL, mkexpr(op2), /* expected value */
5755 NULL, mkexpr(result) /* new value */);
5756 stmt(IRStmt_CAS(cas));
5757
5758 /* Set CC according to bitwise operation */
5759 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5760
5761 /* If old_mem contains the expected value, then the CAS succeeded.
5762 Otherwise, it did not */
5763 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5764 put_gpr_dw0(r1, mkexpr(old_mem));
5765}
5766
5767static const HChar *
5768s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5769{
5770 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005771
5772 return "laa";
5773}
5774
florian55085f82012-11-21 00:36:55 +00005775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005776s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5777{
florianffc94012012-12-02 21:31:15 +00005778 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005779
5780 return "laag";
5781}
5782
florian55085f82012-11-21 00:36:55 +00005783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005784s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5785{
florianffc94012012-12-02 21:31:15 +00005786 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005787
5788 return "laal";
5789}
5790
florian55085f82012-11-21 00:36:55 +00005791static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005792s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5793{
florianffc94012012-12-02 21:31:15 +00005794 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005795
5796 return "laalg";
5797}
5798
florian55085f82012-11-21 00:36:55 +00005799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005800s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5801{
florianffc94012012-12-02 21:31:15 +00005802 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005803
5804 return "lan";
5805}
5806
florian55085f82012-11-21 00:36:55 +00005807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005808s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5809{
florianffc94012012-12-02 21:31:15 +00005810 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005811
5812 return "lang";
5813}
5814
florian55085f82012-11-21 00:36:55 +00005815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005816s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5817{
florianffc94012012-12-02 21:31:15 +00005818 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005819
5820 return "lax";
5821}
5822
florian55085f82012-11-21 00:36:55 +00005823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005824s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5825{
florianffc94012012-12-02 21:31:15 +00005826 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005827
5828 return "laxg";
5829}
5830
florian55085f82012-11-21 00:36:55 +00005831static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005832s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5833{
florianffc94012012-12-02 21:31:15 +00005834 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005835
5836 return "lao";
5837}
5838
florian55085f82012-11-21 00:36:55 +00005839static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005840s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5841{
florianffc94012012-12-02 21:31:15 +00005842 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005843
5844 return "laog";
5845}
5846
florian55085f82012-11-21 00:36:55 +00005847static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005848s390_irgen_LTR(UChar r1, UChar r2)
5849{
5850 IRTemp op2 = newTemp(Ity_I32);
5851
5852 assign(op2, get_gpr_w1(r2));
5853 put_gpr_w1(r1, mkexpr(op2));
5854 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5855
5856 return "ltr";
5857}
5858
florian55085f82012-11-21 00:36:55 +00005859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005860s390_irgen_LTGR(UChar r1, UChar r2)
5861{
5862 IRTemp op2 = newTemp(Ity_I64);
5863
5864 assign(op2, get_gpr_dw0(r2));
5865 put_gpr_dw0(r1, mkexpr(op2));
5866 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5867
5868 return "ltgr";
5869}
5870
florian55085f82012-11-21 00:36:55 +00005871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005872s390_irgen_LTGFR(UChar r1, UChar r2)
5873{
5874 IRTemp op2 = newTemp(Ity_I64);
5875
5876 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5877 put_gpr_dw0(r1, mkexpr(op2));
5878 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5879
5880 return "ltgfr";
5881}
5882
florian55085f82012-11-21 00:36:55 +00005883static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005884s390_irgen_LT(UChar r1, IRTemp op2addr)
5885{
5886 IRTemp op2 = newTemp(Ity_I32);
5887
5888 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5889 put_gpr_w1(r1, mkexpr(op2));
5890 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5891
5892 return "lt";
5893}
5894
florian55085f82012-11-21 00:36:55 +00005895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005896s390_irgen_LTG(UChar r1, IRTemp op2addr)
5897{
5898 IRTemp op2 = newTemp(Ity_I64);
5899
5900 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5901 put_gpr_dw0(r1, mkexpr(op2));
5902 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5903
5904 return "ltg";
5905}
5906
florian55085f82012-11-21 00:36:55 +00005907static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005908s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5909{
5910 IRTemp op2 = newTemp(Ity_I64);
5911
5912 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5913 put_gpr_dw0(r1, mkexpr(op2));
5914 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5915
5916 return "ltgf";
5917}
5918
florian55085f82012-11-21 00:36:55 +00005919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005920s390_irgen_LBR(UChar r1, UChar r2)
5921{
5922 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5923
5924 return "lbr";
5925}
5926
florian55085f82012-11-21 00:36:55 +00005927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005928s390_irgen_LGBR(UChar r1, UChar r2)
5929{
5930 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5931
5932 return "lgbr";
5933}
5934
florian55085f82012-11-21 00:36:55 +00005935static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005936s390_irgen_LB(UChar r1, IRTemp op2addr)
5937{
5938 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5939
5940 return "lb";
5941}
5942
florian55085f82012-11-21 00:36:55 +00005943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005944s390_irgen_LGB(UChar r1, IRTemp op2addr)
5945{
5946 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5947
5948 return "lgb";
5949}
5950
florian55085f82012-11-21 00:36:55 +00005951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005952s390_irgen_LBH(UChar r1, IRTemp op2addr)
5953{
5954 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5955
5956 return "lbh";
5957}
5958
florian55085f82012-11-21 00:36:55 +00005959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005960s390_irgen_LCR(UChar r1, UChar r2)
5961{
5962 Int op1;
5963 IRTemp op2 = newTemp(Ity_I32);
5964 IRTemp result = newTemp(Ity_I32);
5965
5966 op1 = 0;
5967 assign(op2, get_gpr_w1(r2));
5968 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5969 put_gpr_w1(r1, mkexpr(result));
5970 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5971 op1)), op2);
5972
5973 return "lcr";
5974}
5975
florian55085f82012-11-21 00:36:55 +00005976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005977s390_irgen_LCGR(UChar r1, UChar r2)
5978{
5979 Long op1;
5980 IRTemp op2 = newTemp(Ity_I64);
5981 IRTemp result = newTemp(Ity_I64);
5982
5983 op1 = 0ULL;
5984 assign(op2, get_gpr_dw0(r2));
5985 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5986 put_gpr_dw0(r1, mkexpr(result));
5987 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5988 op1)), op2);
5989
5990 return "lcgr";
5991}
5992
florian55085f82012-11-21 00:36:55 +00005993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005994s390_irgen_LCGFR(UChar r1, UChar r2)
5995{
5996 Long op1;
5997 IRTemp op2 = newTemp(Ity_I64);
5998 IRTemp result = newTemp(Ity_I64);
5999
6000 op1 = 0ULL;
6001 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6002 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6003 put_gpr_dw0(r1, mkexpr(result));
6004 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6005 op1)), op2);
6006
6007 return "lcgfr";
6008}
6009
florian55085f82012-11-21 00:36:55 +00006010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006011s390_irgen_LHR(UChar r1, UChar r2)
6012{
6013 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6014
6015 return "lhr";
6016}
6017
florian55085f82012-11-21 00:36:55 +00006018static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006019s390_irgen_LGHR(UChar r1, UChar r2)
6020{
6021 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6022
6023 return "lghr";
6024}
6025
florian55085f82012-11-21 00:36:55 +00006026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006027s390_irgen_LH(UChar r1, IRTemp op2addr)
6028{
6029 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6030
6031 return "lh";
6032}
6033
florian55085f82012-11-21 00:36:55 +00006034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006035s390_irgen_LHY(UChar r1, IRTemp op2addr)
6036{
6037 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6038
6039 return "lhy";
6040}
6041
florian55085f82012-11-21 00:36:55 +00006042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006043s390_irgen_LGH(UChar r1, IRTemp op2addr)
6044{
6045 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6046
6047 return "lgh";
6048}
6049
florian55085f82012-11-21 00:36:55 +00006050static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006051s390_irgen_LHI(UChar r1, UShort i2)
6052{
6053 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6054
6055 return "lhi";
6056}
6057
florian55085f82012-11-21 00:36:55 +00006058static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006059s390_irgen_LGHI(UChar r1, UShort i2)
6060{
6061 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6062
6063 return "lghi";
6064}
6065
florian55085f82012-11-21 00:36:55 +00006066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006067s390_irgen_LHRL(UChar r1, UInt i2)
6068{
6069 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6070 ((ULong)(Long)(Int)i2 << 1)))));
6071
6072 return "lhrl";
6073}
6074
florian55085f82012-11-21 00:36:55 +00006075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006076s390_irgen_LGHRL(UChar r1, UInt i2)
6077{
6078 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6079 ((ULong)(Long)(Int)i2 << 1)))));
6080
6081 return "lghrl";
6082}
6083
florian55085f82012-11-21 00:36:55 +00006084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006085s390_irgen_LHH(UChar r1, IRTemp op2addr)
6086{
6087 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6088
6089 return "lhh";
6090}
6091
florian55085f82012-11-21 00:36:55 +00006092static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006093s390_irgen_LFH(UChar r1, IRTemp op2addr)
6094{
6095 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6096
6097 return "lfh";
6098}
6099
florian55085f82012-11-21 00:36:55 +00006100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006101s390_irgen_LLGFR(UChar r1, UChar r2)
6102{
6103 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6104
6105 return "llgfr";
6106}
6107
florian55085f82012-11-21 00:36:55 +00006108static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006109s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6110{
6111 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6112
6113 return "llgf";
6114}
6115
florian55085f82012-11-21 00:36:55 +00006116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006117s390_irgen_LLGFRL(UChar r1, UInt i2)
6118{
6119 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6120 ((ULong)(Long)(Int)i2 << 1)))));
6121
6122 return "llgfrl";
6123}
6124
florian55085f82012-11-21 00:36:55 +00006125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006126s390_irgen_LLCR(UChar r1, UChar r2)
6127{
6128 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6129
6130 return "llcr";
6131}
6132
florian55085f82012-11-21 00:36:55 +00006133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006134s390_irgen_LLGCR(UChar r1, UChar r2)
6135{
6136 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6137
6138 return "llgcr";
6139}
6140
florian55085f82012-11-21 00:36:55 +00006141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006142s390_irgen_LLC(UChar r1, IRTemp op2addr)
6143{
6144 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6145
6146 return "llc";
6147}
6148
florian55085f82012-11-21 00:36:55 +00006149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006150s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6151{
6152 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6153
6154 return "llgc";
6155}
6156
florian55085f82012-11-21 00:36:55 +00006157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006158s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6159{
6160 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6161
6162 return "llch";
6163}
6164
florian55085f82012-11-21 00:36:55 +00006165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006166s390_irgen_LLHR(UChar r1, UChar r2)
6167{
6168 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6169
6170 return "llhr";
6171}
6172
florian55085f82012-11-21 00:36:55 +00006173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006174s390_irgen_LLGHR(UChar r1, UChar r2)
6175{
6176 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6177
6178 return "llghr";
6179}
6180
florian55085f82012-11-21 00:36:55 +00006181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006182s390_irgen_LLH(UChar r1, IRTemp op2addr)
6183{
6184 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6185
6186 return "llh";
6187}
6188
florian55085f82012-11-21 00:36:55 +00006189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006190s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6191{
6192 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6193
6194 return "llgh";
6195}
6196
florian55085f82012-11-21 00:36:55 +00006197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006198s390_irgen_LLHRL(UChar r1, UInt i2)
6199{
6200 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6201 ((ULong)(Long)(Int)i2 << 1)))));
6202
6203 return "llhrl";
6204}
6205
florian55085f82012-11-21 00:36:55 +00006206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006207s390_irgen_LLGHRL(UChar r1, UInt i2)
6208{
6209 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6210 ((ULong)(Long)(Int)i2 << 1)))));
6211
6212 return "llghrl";
6213}
6214
florian55085f82012-11-21 00:36:55 +00006215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006216s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6217{
6218 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6219
6220 return "llhh";
6221}
6222
florian55085f82012-11-21 00:36:55 +00006223static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006224s390_irgen_LLIHF(UChar r1, UInt i2)
6225{
6226 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6227
6228 return "llihf";
6229}
6230
florian55085f82012-11-21 00:36:55 +00006231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006232s390_irgen_LLIHH(UChar r1, UShort i2)
6233{
6234 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6235
6236 return "llihh";
6237}
6238
florian55085f82012-11-21 00:36:55 +00006239static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006240s390_irgen_LLIHL(UChar r1, UShort i2)
6241{
6242 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6243
6244 return "llihl";
6245}
6246
florian55085f82012-11-21 00:36:55 +00006247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006248s390_irgen_LLILF(UChar r1, UInt i2)
6249{
6250 put_gpr_dw0(r1, mkU64(i2));
6251
6252 return "llilf";
6253}
6254
florian55085f82012-11-21 00:36:55 +00006255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006256s390_irgen_LLILH(UChar r1, UShort i2)
6257{
6258 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6259
6260 return "llilh";
6261}
6262
florian55085f82012-11-21 00:36:55 +00006263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006264s390_irgen_LLILL(UChar r1, UShort i2)
6265{
6266 put_gpr_dw0(r1, mkU64(i2));
6267
6268 return "llill";
6269}
6270
florian55085f82012-11-21 00:36:55 +00006271static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006272s390_irgen_LLGTR(UChar r1, UChar r2)
6273{
6274 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6275 mkU32(2147483647))));
6276
6277 return "llgtr";
6278}
6279
florian55085f82012-11-21 00:36:55 +00006280static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006281s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6282{
6283 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6284 mkexpr(op2addr)), mkU32(2147483647))));
6285
6286 return "llgt";
6287}
6288
florian55085f82012-11-21 00:36:55 +00006289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006290s390_irgen_LNR(UChar r1, UChar r2)
6291{
6292 IRTemp op2 = newTemp(Ity_I32);
6293 IRTemp result = newTemp(Ity_I32);
6294
6295 assign(op2, get_gpr_w1(r2));
6296 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6297 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6298 put_gpr_w1(r1, mkexpr(result));
6299 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6300
6301 return "lnr";
6302}
6303
florian55085f82012-11-21 00:36:55 +00006304static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006305s390_irgen_LNGR(UChar r1, UChar r2)
6306{
6307 IRTemp op2 = newTemp(Ity_I64);
6308 IRTemp result = newTemp(Ity_I64);
6309
6310 assign(op2, get_gpr_dw0(r2));
6311 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6312 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6313 put_gpr_dw0(r1, mkexpr(result));
6314 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6315
6316 return "lngr";
6317}
6318
florian55085f82012-11-21 00:36:55 +00006319static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006320s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6321{
6322 IRTemp op2 = newTemp(Ity_I64);
6323 IRTemp result = newTemp(Ity_I64);
6324
6325 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6326 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6327 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6328 put_gpr_dw0(r1, mkexpr(result));
6329 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6330
6331 return "lngfr";
6332}
6333
florian55085f82012-11-21 00:36:55 +00006334static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006335s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6336{
florian6820ba52012-07-26 02:01:50 +00006337 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006338 put_gpr_w1(r1, get_gpr_w1(r2));
6339
6340 return "locr";
6341}
6342
florian55085f82012-11-21 00:36:55 +00006343static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006344s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6345{
florian6820ba52012-07-26 02:01:50 +00006346 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006347 put_gpr_dw0(r1, get_gpr_dw0(r2));
6348
6349 return "locgr";
6350}
6351
florian55085f82012-11-21 00:36:55 +00006352static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006353s390_irgen_LOC(UChar r1, IRTemp op2addr)
6354{
6355 /* condition is checked in format handler */
6356 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6357
6358 return "loc";
6359}
6360
florian55085f82012-11-21 00:36:55 +00006361static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006362s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6363{
6364 /* condition is checked in format handler */
6365 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6366
6367 return "locg";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006371s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6372{
6373 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6374 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6375 ));
6376
6377 return "lpq";
6378}
6379
florian55085f82012-11-21 00:36:55 +00006380static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006381s390_irgen_LPR(UChar r1, UChar r2)
6382{
6383 IRTemp op2 = newTemp(Ity_I32);
6384 IRTemp result = newTemp(Ity_I32);
6385
6386 assign(op2, get_gpr_w1(r2));
6387 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6388 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6389 put_gpr_w1(r1, mkexpr(result));
6390 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6391
6392 return "lpr";
6393}
6394
florian55085f82012-11-21 00:36:55 +00006395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006396s390_irgen_LPGR(UChar r1, UChar r2)
6397{
6398 IRTemp op2 = newTemp(Ity_I64);
6399 IRTemp result = newTemp(Ity_I64);
6400
6401 assign(op2, get_gpr_dw0(r2));
6402 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6403 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6404 put_gpr_dw0(r1, mkexpr(result));
6405 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6406
6407 return "lpgr";
6408}
6409
florian55085f82012-11-21 00:36:55 +00006410static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006411s390_irgen_LPGFR(UChar r1, UChar r2)
6412{
6413 IRTemp op2 = newTemp(Ity_I64);
6414 IRTemp result = newTemp(Ity_I64);
6415
6416 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6417 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6418 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6419 put_gpr_dw0(r1, mkexpr(result));
6420 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6421
6422 return "lpgfr";
6423}
6424
florian55085f82012-11-21 00:36:55 +00006425static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006426s390_irgen_LRVR(UChar r1, UChar r2)
6427{
6428 IRTemp b0 = newTemp(Ity_I8);
6429 IRTemp b1 = newTemp(Ity_I8);
6430 IRTemp b2 = newTemp(Ity_I8);
6431 IRTemp b3 = newTemp(Ity_I8);
6432
6433 assign(b3, get_gpr_b7(r2));
6434 assign(b2, get_gpr_b6(r2));
6435 assign(b1, get_gpr_b5(r2));
6436 assign(b0, get_gpr_b4(r2));
6437 put_gpr_b4(r1, mkexpr(b3));
6438 put_gpr_b5(r1, mkexpr(b2));
6439 put_gpr_b6(r1, mkexpr(b1));
6440 put_gpr_b7(r1, mkexpr(b0));
6441
6442 return "lrvr";
6443}
6444
florian55085f82012-11-21 00:36:55 +00006445static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006446s390_irgen_LRVGR(UChar r1, UChar r2)
6447{
6448 IRTemp b0 = newTemp(Ity_I8);
6449 IRTemp b1 = newTemp(Ity_I8);
6450 IRTemp b2 = newTemp(Ity_I8);
6451 IRTemp b3 = newTemp(Ity_I8);
6452 IRTemp b4 = newTemp(Ity_I8);
6453 IRTemp b5 = newTemp(Ity_I8);
6454 IRTemp b6 = newTemp(Ity_I8);
6455 IRTemp b7 = newTemp(Ity_I8);
6456
6457 assign(b7, get_gpr_b7(r2));
6458 assign(b6, get_gpr_b6(r2));
6459 assign(b5, get_gpr_b5(r2));
6460 assign(b4, get_gpr_b4(r2));
6461 assign(b3, get_gpr_b3(r2));
6462 assign(b2, get_gpr_b2(r2));
6463 assign(b1, get_gpr_b1(r2));
6464 assign(b0, get_gpr_b0(r2));
6465 put_gpr_b0(r1, mkexpr(b7));
6466 put_gpr_b1(r1, mkexpr(b6));
6467 put_gpr_b2(r1, mkexpr(b5));
6468 put_gpr_b3(r1, mkexpr(b4));
6469 put_gpr_b4(r1, mkexpr(b3));
6470 put_gpr_b5(r1, mkexpr(b2));
6471 put_gpr_b6(r1, mkexpr(b1));
6472 put_gpr_b7(r1, mkexpr(b0));
6473
6474 return "lrvgr";
6475}
6476
florian55085f82012-11-21 00:36:55 +00006477static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006478s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6479{
6480 IRTemp op2 = newTemp(Ity_I16);
6481
6482 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6483 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6484 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6485
6486 return "lrvh";
6487}
6488
florian55085f82012-11-21 00:36:55 +00006489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006490s390_irgen_LRV(UChar r1, IRTemp op2addr)
6491{
6492 IRTemp op2 = newTemp(Ity_I32);
6493
6494 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6495 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6496 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6497 mkU8(8)), mkU32(255))));
6498 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6499 mkU8(16)), mkU32(255))));
6500 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6501 mkU8(24)), mkU32(255))));
6502
6503 return "lrv";
6504}
6505
florian55085f82012-11-21 00:36:55 +00006506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006507s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6508{
6509 IRTemp op2 = newTemp(Ity_I64);
6510
6511 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6512 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6513 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6514 mkU8(8)), mkU64(255))));
6515 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6516 mkU8(16)), mkU64(255))));
6517 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6518 mkU8(24)), mkU64(255))));
6519 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6520 mkU8(32)), mkU64(255))));
6521 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6522 mkU8(40)), mkU64(255))));
6523 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6524 mkU8(48)), mkU64(255))));
6525 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6526 mkU8(56)), mkU64(255))));
6527
6528 return "lrvg";
6529}
6530
florian55085f82012-11-21 00:36:55 +00006531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006532s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6533{
6534 store(mkexpr(op1addr), mkU16(i2));
6535
6536 return "mvhhi";
6537}
6538
florian55085f82012-11-21 00:36:55 +00006539static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006540s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6541{
6542 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6543
6544 return "mvhi";
6545}
6546
florian55085f82012-11-21 00:36:55 +00006547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006548s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6549{
6550 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6551
6552 return "mvghi";
6553}
6554
florian55085f82012-11-21 00:36:55 +00006555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006556s390_irgen_MVI(UChar i2, IRTemp op1addr)
6557{
6558 store(mkexpr(op1addr), mkU8(i2));
6559
6560 return "mvi";
6561}
6562
florian55085f82012-11-21 00:36:55 +00006563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006564s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6565{
6566 store(mkexpr(op1addr), mkU8(i2));
6567
6568 return "mviy";
6569}
6570
florian55085f82012-11-21 00:36:55 +00006571static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006572s390_irgen_MR(UChar r1, UChar r2)
6573{
6574 IRTemp op1 = newTemp(Ity_I32);
6575 IRTemp op2 = newTemp(Ity_I32);
6576 IRTemp result = newTemp(Ity_I64);
6577
6578 assign(op1, get_gpr_w1(r1 + 1));
6579 assign(op2, get_gpr_w1(r2));
6580 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6581 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6582 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6583
6584 return "mr";
6585}
6586
florian55085f82012-11-21 00:36:55 +00006587static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006588s390_irgen_M(UChar r1, IRTemp op2addr)
6589{
6590 IRTemp op1 = newTemp(Ity_I32);
6591 IRTemp op2 = newTemp(Ity_I32);
6592 IRTemp result = newTemp(Ity_I64);
6593
6594 assign(op1, get_gpr_w1(r1 + 1));
6595 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6596 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6597 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6598 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6599
6600 return "m";
6601}
6602
florian55085f82012-11-21 00:36:55 +00006603static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006604s390_irgen_MFY(UChar r1, IRTemp op2addr)
6605{
6606 IRTemp op1 = newTemp(Ity_I32);
6607 IRTemp op2 = newTemp(Ity_I32);
6608 IRTemp result = newTemp(Ity_I64);
6609
6610 assign(op1, get_gpr_w1(r1 + 1));
6611 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6612 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6613 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6614 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6615
6616 return "mfy";
6617}
6618
florian55085f82012-11-21 00:36:55 +00006619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006620s390_irgen_MH(UChar r1, IRTemp op2addr)
6621{
6622 IRTemp op1 = newTemp(Ity_I32);
6623 IRTemp op2 = newTemp(Ity_I16);
6624 IRTemp result = newTemp(Ity_I64);
6625
6626 assign(op1, get_gpr_w1(r1));
6627 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6628 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6629 ));
6630 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6631
6632 return "mh";
6633}
6634
florian55085f82012-11-21 00:36:55 +00006635static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006636s390_irgen_MHY(UChar r1, IRTemp op2addr)
6637{
6638 IRTemp op1 = newTemp(Ity_I32);
6639 IRTemp op2 = newTemp(Ity_I16);
6640 IRTemp result = newTemp(Ity_I64);
6641
6642 assign(op1, get_gpr_w1(r1));
6643 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6644 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6645 ));
6646 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6647
6648 return "mhy";
6649}
6650
florian55085f82012-11-21 00:36:55 +00006651static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006652s390_irgen_MHI(UChar r1, UShort i2)
6653{
6654 IRTemp op1 = newTemp(Ity_I32);
6655 Short op2;
6656 IRTemp result = newTemp(Ity_I64);
6657
6658 assign(op1, get_gpr_w1(r1));
6659 op2 = (Short)i2;
6660 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6661 mkU16((UShort)op2))));
6662 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6663
6664 return "mhi";
6665}
6666
florian55085f82012-11-21 00:36:55 +00006667static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006668s390_irgen_MGHI(UChar r1, UShort i2)
6669{
6670 IRTemp op1 = newTemp(Ity_I64);
6671 Short op2;
6672 IRTemp result = newTemp(Ity_I128);
6673
6674 assign(op1, get_gpr_dw0(r1));
6675 op2 = (Short)i2;
6676 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6677 mkU16((UShort)op2))));
6678 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6679
6680 return "mghi";
6681}
6682
florian55085f82012-11-21 00:36:55 +00006683static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006684s390_irgen_MLR(UChar r1, UChar r2)
6685{
6686 IRTemp op1 = newTemp(Ity_I32);
6687 IRTemp op2 = newTemp(Ity_I32);
6688 IRTemp result = newTemp(Ity_I64);
6689
6690 assign(op1, get_gpr_w1(r1 + 1));
6691 assign(op2, get_gpr_w1(r2));
6692 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6693 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6694 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6695
6696 return "mlr";
6697}
6698
florian55085f82012-11-21 00:36:55 +00006699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006700s390_irgen_MLGR(UChar r1, UChar r2)
6701{
6702 IRTemp op1 = newTemp(Ity_I64);
6703 IRTemp op2 = newTemp(Ity_I64);
6704 IRTemp result = newTemp(Ity_I128);
6705
6706 assign(op1, get_gpr_dw0(r1 + 1));
6707 assign(op2, get_gpr_dw0(r2));
6708 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6709 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6710 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6711
6712 return "mlgr";
6713}
6714
florian55085f82012-11-21 00:36:55 +00006715static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006716s390_irgen_ML(UChar r1, IRTemp op2addr)
6717{
6718 IRTemp op1 = newTemp(Ity_I32);
6719 IRTemp op2 = newTemp(Ity_I32);
6720 IRTemp result = newTemp(Ity_I64);
6721
6722 assign(op1, get_gpr_w1(r1 + 1));
6723 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6724 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6725 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6726 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6727
6728 return "ml";
6729}
6730
florian55085f82012-11-21 00:36:55 +00006731static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006732s390_irgen_MLG(UChar r1, IRTemp op2addr)
6733{
6734 IRTemp op1 = newTemp(Ity_I64);
6735 IRTemp op2 = newTemp(Ity_I64);
6736 IRTemp result = newTemp(Ity_I128);
6737
6738 assign(op1, get_gpr_dw0(r1 + 1));
6739 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6740 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6741 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6742 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6743
6744 return "mlg";
6745}
6746
florian55085f82012-11-21 00:36:55 +00006747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006748s390_irgen_MSR(UChar r1, UChar r2)
6749{
6750 IRTemp op1 = newTemp(Ity_I32);
6751 IRTemp op2 = newTemp(Ity_I32);
6752 IRTemp result = newTemp(Ity_I64);
6753
6754 assign(op1, get_gpr_w1(r1));
6755 assign(op2, get_gpr_w1(r2));
6756 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6757 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6758
6759 return "msr";
6760}
6761
florian55085f82012-11-21 00:36:55 +00006762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006763s390_irgen_MSGR(UChar r1, UChar r2)
6764{
6765 IRTemp op1 = newTemp(Ity_I64);
6766 IRTemp op2 = newTemp(Ity_I64);
6767 IRTemp result = newTemp(Ity_I128);
6768
6769 assign(op1, get_gpr_dw0(r1));
6770 assign(op2, get_gpr_dw0(r2));
6771 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6772 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6773
6774 return "msgr";
6775}
6776
florian55085f82012-11-21 00:36:55 +00006777static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006778s390_irgen_MSGFR(UChar r1, UChar r2)
6779{
6780 IRTemp op1 = newTemp(Ity_I64);
6781 IRTemp op2 = newTemp(Ity_I32);
6782 IRTemp result = newTemp(Ity_I128);
6783
6784 assign(op1, get_gpr_dw0(r1));
6785 assign(op2, get_gpr_w1(r2));
6786 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6787 ));
6788 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6789
6790 return "msgfr";
6791}
6792
florian55085f82012-11-21 00:36:55 +00006793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006794s390_irgen_MS(UChar r1, IRTemp op2addr)
6795{
6796 IRTemp op1 = newTemp(Ity_I32);
6797 IRTemp op2 = newTemp(Ity_I32);
6798 IRTemp result = newTemp(Ity_I64);
6799
6800 assign(op1, get_gpr_w1(r1));
6801 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6802 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6803 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6804
6805 return "ms";
6806}
6807
florian55085f82012-11-21 00:36:55 +00006808static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006809s390_irgen_MSY(UChar r1, IRTemp op2addr)
6810{
6811 IRTemp op1 = newTemp(Ity_I32);
6812 IRTemp op2 = newTemp(Ity_I32);
6813 IRTemp result = newTemp(Ity_I64);
6814
6815 assign(op1, get_gpr_w1(r1));
6816 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6817 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6818 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6819
6820 return "msy";
6821}
6822
florian55085f82012-11-21 00:36:55 +00006823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006824s390_irgen_MSG(UChar r1, IRTemp op2addr)
6825{
6826 IRTemp op1 = newTemp(Ity_I64);
6827 IRTemp op2 = newTemp(Ity_I64);
6828 IRTemp result = newTemp(Ity_I128);
6829
6830 assign(op1, get_gpr_dw0(r1));
6831 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6832 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6833 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6834
6835 return "msg";
6836}
6837
florian55085f82012-11-21 00:36:55 +00006838static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006839s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6840{
6841 IRTemp op1 = newTemp(Ity_I64);
6842 IRTemp op2 = newTemp(Ity_I32);
6843 IRTemp result = newTemp(Ity_I128);
6844
6845 assign(op1, get_gpr_dw0(r1));
6846 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6847 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6848 ));
6849 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6850
6851 return "msgf";
6852}
6853
florian55085f82012-11-21 00:36:55 +00006854static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006855s390_irgen_MSFI(UChar r1, UInt i2)
6856{
6857 IRTemp op1 = newTemp(Ity_I32);
6858 Int op2;
6859 IRTemp result = newTemp(Ity_I64);
6860
6861 assign(op1, get_gpr_w1(r1));
6862 op2 = (Int)i2;
6863 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6864 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6865
6866 return "msfi";
6867}
6868
florian55085f82012-11-21 00:36:55 +00006869static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006870s390_irgen_MSGFI(UChar r1, UInt i2)
6871{
6872 IRTemp op1 = newTemp(Ity_I64);
6873 Int op2;
6874 IRTemp result = newTemp(Ity_I128);
6875
6876 assign(op1, get_gpr_dw0(r1));
6877 op2 = (Int)i2;
6878 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6879 op2))));
6880 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6881
6882 return "msgfi";
6883}
6884
florian55085f82012-11-21 00:36:55 +00006885static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006886s390_irgen_OR(UChar r1, UChar r2)
6887{
6888 IRTemp op1 = newTemp(Ity_I32);
6889 IRTemp op2 = newTemp(Ity_I32);
6890 IRTemp result = newTemp(Ity_I32);
6891
6892 assign(op1, get_gpr_w1(r1));
6893 assign(op2, get_gpr_w1(r2));
6894 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6895 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6896 put_gpr_w1(r1, mkexpr(result));
6897
6898 return "or";
6899}
6900
florian55085f82012-11-21 00:36:55 +00006901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006902s390_irgen_OGR(UChar r1, UChar r2)
6903{
6904 IRTemp op1 = newTemp(Ity_I64);
6905 IRTemp op2 = newTemp(Ity_I64);
6906 IRTemp result = newTemp(Ity_I64);
6907
6908 assign(op1, get_gpr_dw0(r1));
6909 assign(op2, get_gpr_dw0(r2));
6910 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6911 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6912 put_gpr_dw0(r1, mkexpr(result));
6913
6914 return "ogr";
6915}
6916
florian55085f82012-11-21 00:36:55 +00006917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006918s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6919{
6920 IRTemp op2 = newTemp(Ity_I32);
6921 IRTemp op3 = newTemp(Ity_I32);
6922 IRTemp result = newTemp(Ity_I32);
6923
6924 assign(op2, get_gpr_w1(r2));
6925 assign(op3, get_gpr_w1(r3));
6926 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6927 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6928 put_gpr_w1(r1, mkexpr(result));
6929
6930 return "ork";
6931}
6932
florian55085f82012-11-21 00:36:55 +00006933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006934s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6935{
6936 IRTemp op2 = newTemp(Ity_I64);
6937 IRTemp op3 = newTemp(Ity_I64);
6938 IRTemp result = newTemp(Ity_I64);
6939
6940 assign(op2, get_gpr_dw0(r2));
6941 assign(op3, get_gpr_dw0(r3));
6942 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6943 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6944 put_gpr_dw0(r1, mkexpr(result));
6945
6946 return "ogrk";
6947}
6948
florian55085f82012-11-21 00:36:55 +00006949static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006950s390_irgen_O(UChar r1, IRTemp op2addr)
6951{
6952 IRTemp op1 = newTemp(Ity_I32);
6953 IRTemp op2 = newTemp(Ity_I32);
6954 IRTemp result = newTemp(Ity_I32);
6955
6956 assign(op1, get_gpr_w1(r1));
6957 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6958 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6959 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6960 put_gpr_w1(r1, mkexpr(result));
6961
6962 return "o";
6963}
6964
florian55085f82012-11-21 00:36:55 +00006965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006966s390_irgen_OY(UChar r1, IRTemp op2addr)
6967{
6968 IRTemp op1 = newTemp(Ity_I32);
6969 IRTemp op2 = newTemp(Ity_I32);
6970 IRTemp result = newTemp(Ity_I32);
6971
6972 assign(op1, get_gpr_w1(r1));
6973 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6974 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6975 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6976 put_gpr_w1(r1, mkexpr(result));
6977
6978 return "oy";
6979}
6980
florian55085f82012-11-21 00:36:55 +00006981static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006982s390_irgen_OG(UChar r1, IRTemp op2addr)
6983{
6984 IRTemp op1 = newTemp(Ity_I64);
6985 IRTemp op2 = newTemp(Ity_I64);
6986 IRTemp result = newTemp(Ity_I64);
6987
6988 assign(op1, get_gpr_dw0(r1));
6989 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6990 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6991 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6992 put_gpr_dw0(r1, mkexpr(result));
6993
6994 return "og";
6995}
6996
florian55085f82012-11-21 00:36:55 +00006997static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006998s390_irgen_OI(UChar i2, IRTemp op1addr)
6999{
7000 IRTemp op1 = newTemp(Ity_I8);
7001 UChar op2;
7002 IRTemp result = newTemp(Ity_I8);
7003
7004 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7005 op2 = i2;
7006 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7007 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7008 store(mkexpr(op1addr), mkexpr(result));
7009
7010 return "oi";
7011}
7012
florian55085f82012-11-21 00:36:55 +00007013static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007014s390_irgen_OIY(UChar i2, IRTemp op1addr)
7015{
7016 IRTemp op1 = newTemp(Ity_I8);
7017 UChar op2;
7018 IRTemp result = newTemp(Ity_I8);
7019
7020 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7021 op2 = i2;
7022 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7023 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7024 store(mkexpr(op1addr), mkexpr(result));
7025
7026 return "oiy";
7027}
7028
florian55085f82012-11-21 00:36:55 +00007029static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007030s390_irgen_OIHF(UChar r1, UInt i2)
7031{
7032 IRTemp op1 = newTemp(Ity_I32);
7033 UInt op2;
7034 IRTemp result = newTemp(Ity_I32);
7035
7036 assign(op1, get_gpr_w0(r1));
7037 op2 = i2;
7038 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7039 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7040 put_gpr_w0(r1, mkexpr(result));
7041
7042 return "oihf";
7043}
7044
florian55085f82012-11-21 00:36:55 +00007045static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007046s390_irgen_OIHH(UChar r1, UShort i2)
7047{
7048 IRTemp op1 = newTemp(Ity_I16);
7049 UShort op2;
7050 IRTemp result = newTemp(Ity_I16);
7051
7052 assign(op1, get_gpr_hw0(r1));
7053 op2 = i2;
7054 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7055 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7056 put_gpr_hw0(r1, mkexpr(result));
7057
7058 return "oihh";
7059}
7060
florian55085f82012-11-21 00:36:55 +00007061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007062s390_irgen_OIHL(UChar r1, UShort i2)
7063{
7064 IRTemp op1 = newTemp(Ity_I16);
7065 UShort op2;
7066 IRTemp result = newTemp(Ity_I16);
7067
7068 assign(op1, get_gpr_hw1(r1));
7069 op2 = i2;
7070 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7071 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7072 put_gpr_hw1(r1, mkexpr(result));
7073
7074 return "oihl";
7075}
7076
florian55085f82012-11-21 00:36:55 +00007077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007078s390_irgen_OILF(UChar r1, UInt i2)
7079{
7080 IRTemp op1 = newTemp(Ity_I32);
7081 UInt op2;
7082 IRTemp result = newTemp(Ity_I32);
7083
7084 assign(op1, get_gpr_w1(r1));
7085 op2 = i2;
7086 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7087 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7088 put_gpr_w1(r1, mkexpr(result));
7089
7090 return "oilf";
7091}
7092
florian55085f82012-11-21 00:36:55 +00007093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007094s390_irgen_OILH(UChar r1, UShort i2)
7095{
7096 IRTemp op1 = newTemp(Ity_I16);
7097 UShort op2;
7098 IRTemp result = newTemp(Ity_I16);
7099
7100 assign(op1, get_gpr_hw2(r1));
7101 op2 = i2;
7102 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7103 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7104 put_gpr_hw2(r1, mkexpr(result));
7105
7106 return "oilh";
7107}
7108
florian55085f82012-11-21 00:36:55 +00007109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007110s390_irgen_OILL(UChar r1, UShort i2)
7111{
7112 IRTemp op1 = newTemp(Ity_I16);
7113 UShort op2;
7114 IRTemp result = newTemp(Ity_I16);
7115
7116 assign(op1, get_gpr_hw3(r1));
7117 op2 = i2;
7118 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7119 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7120 put_gpr_hw3(r1, mkexpr(result));
7121
7122 return "oill";
7123}
7124
florian55085f82012-11-21 00:36:55 +00007125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007126s390_irgen_PFD(void)
7127{
7128
7129 return "pfd";
7130}
7131
florian55085f82012-11-21 00:36:55 +00007132static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007133s390_irgen_PFDRL(void)
7134{
7135
7136 return "pfdrl";
7137}
7138
florian78d5ef72013-05-11 15:02:58 +00007139static IRExpr *
7140get_rounding_mode_from_gr0(void)
7141{
7142 IRTemp rm_bits = newTemp(Ity_I32);
7143 IRExpr *s390rm;
7144 IRExpr *irrm;
7145
7146 vassert(s390_host_has_pfpo);
7147 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7148 when PFPO insn is called. So, extract the bits at [60:63] */
7149 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7150 s390rm = mkexpr(rm_bits);
7151 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7152 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7153 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7154 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7155 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7156 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7157 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7158 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7159 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7160 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7161 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7162 mkexpr(encode_dfp_rounding_mode(
7163 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7164 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7165 mkexpr(encode_dfp_rounding_mode(
7166 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7167 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7168 mkexpr(encode_dfp_rounding_mode(
7169 S390_DFP_ROUND_AWAY_0)),
7170 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7171 mkexpr(encode_dfp_rounding_mode(
7172 S390_DFP_ROUND_PREPARE_SHORT_15)),
7173 /* if rounding mode is 0 or invalid (2-7)
7174 set S390_DFP_ROUND_PER_FPC_0 */
7175 mkexpr(encode_dfp_rounding_mode(
7176 S390_DFP_ROUND_PER_FPC_0)))))))))));
7177
7178 return irrm;
7179}
7180
7181static IRExpr *
7182s390_call_pfpo_helper(IRExpr *gr0)
7183{
7184 IRExpr **args, *call;
7185
7186 args = mkIRExprVec_1(gr0);
7187 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7188 "s390_do_pfpo", &s390_do_pfpo, args);
7189 /* Nothing is excluded from definedness checking. */
7190 call->Iex.CCall.cee->mcx_mask = 0;
7191
7192 return call;
7193}
7194
7195static const HChar *
7196s390_irgen_PFPO(void)
7197{
7198 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
7199 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7200 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
7201 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
florian7ab421d2013-06-17 21:03:56 +00007202 IRTemp src1 = newTemp(Ity_F32);
7203 IRTemp dst1 = newTemp(Ity_D32);
7204 IRTemp src2 = newTemp(Ity_F32);
7205 IRTemp dst2 = newTemp(Ity_D64);
7206 IRTemp src3 = newTemp(Ity_F32);
florian78d5ef72013-05-11 15:02:58 +00007207 IRTemp dst3 = newTemp(Ity_D128);
florian7ab421d2013-06-17 21:03:56 +00007208 IRTemp src4 = newTemp(Ity_F64);
7209 IRTemp dst4 = newTemp(Ity_D32);
7210 IRTemp src5 = newTemp(Ity_F64);
7211 IRTemp dst5 = newTemp(Ity_D64);
7212 IRTemp src6 = newTemp(Ity_F64);
7213 IRTemp dst6 = newTemp(Ity_D128);
7214 IRTemp src7 = newTemp(Ity_F128);
7215 IRTemp dst7 = newTemp(Ity_D32);
7216 IRTemp src8 = newTemp(Ity_F128);
7217 IRTemp dst8 = newTemp(Ity_D64);
7218 IRTemp src9 = newTemp(Ity_F128);
7219 IRTemp dst9 = newTemp(Ity_D128);
7220 IRTemp src10 = newTemp(Ity_D32);
7221 IRTemp dst10 = newTemp(Ity_F32);
7222 IRTemp src11 = newTemp(Ity_D32);
7223 IRTemp dst11 = newTemp(Ity_F64);
7224 IRTemp src12 = newTemp(Ity_D32);
7225 IRTemp dst12 = newTemp(Ity_F128);
7226 IRTemp src13 = newTemp(Ity_D64);
7227 IRTemp dst13 = newTemp(Ity_F32);
7228 IRTemp src14 = newTemp(Ity_D64);
7229 IRTemp dst14 = newTemp(Ity_F64);
7230 IRTemp src15 = newTemp(Ity_D64);
7231 IRTemp dst15 = newTemp(Ity_F128);
7232 IRTemp src16 = newTemp(Ity_D128);
7233 IRTemp dst16 = newTemp(Ity_F32);
7234 IRTemp src17 = newTemp(Ity_D128);
7235 IRTemp dst17 = newTemp(Ity_F64);
7236 IRTemp src18 = newTemp(Ity_D128);
7237 IRTemp dst18 = newTemp(Ity_F128);
florian78d5ef72013-05-11 15:02:58 +00007238 IRExpr *irrm;
7239
7240 vassert(s390_host_has_pfpo);
7241
7242 assign(gr0, get_gpr_w1(0));
7243 /* get function code */
7244 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7245 mkU32(0x7fffff)));
7246 /* get validity test bit */
7247 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7248 mkU32(0x1)));
7249 irrm = get_rounding_mode_from_gr0();
7250
7251 /* test_bit is 1 */
florian7ab421d2013-06-17 21:03:56 +00007252 assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
florian78d5ef72013-05-11 15:02:58 +00007253 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7254
7255 /* Return code set in GR1 is usually 0. Non-zero value is set only
7256 when exceptions are raised. See Programming Notes point 5 in the
7257 instrcution description of pfpo in POP. Since valgrind does not
7258 model exception, it might be safe to just set 0 to GR 1. */
7259 put_gpr_w1(1, mkU32(0x0));
7260 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7261
7262 /* Check validity of function code in GR 0 */
7263 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
7264
7265 /* fixs390: Function emulation_failure can be used if it takes argument as
7266 IRExpr * instead of VexEmNote. */
7267 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkexpr(ef)));
7268 dis_res->whatNext = Dis_StopHere;
7269 dis_res->jk_StopHere = Ijk_EmFail;
7270
7271 stmt(
7272 IRStmt_Exit(
7273 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7274 Ijk_EmFail,
7275 IRConst_U64(guest_IA_next_instr),
7276 S390X_GUEST_OFFSET(guest_IA)
7277 )
7278 );
7279
florian7ab421d2013-06-17 21:03:56 +00007280 /* F32 -> D32 */
florian78d5ef72013-05-11 15:02:58 +00007281 /* get source from FPR 4,6 - already set in src1 */
florian7ab421d2013-06-17 21:03:56 +00007282 assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7283 put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007284 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007285 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7286 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
florian78d5ef72013-05-11 15:02:58 +00007287
florian7ab421d2013-06-17 21:03:56 +00007288 /* F32 -> D64 */
7289 assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7290 assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7291 put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007292 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007293 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7294 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007295
florian7ab421d2013-06-17 21:03:56 +00007296 /* F32 -> D128 */
7297 assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7298 assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
florian78d5ef72013-05-11 15:02:58 +00007299 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7300 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007301 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7302 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7303
7304 /* F64 -> D32 */
7305 assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7306 assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7307 put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7308 put_gpr_w1(1, mkU32(0x0));
7309 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7310 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7311
7312 /* F64 -> D64 */
7313 assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7314 assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7315 put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7316 put_gpr_w1(1, mkU32(0x0));
7317 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7318 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7319
7320 /* F64 -> D128 */
7321 assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7322 assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7323 put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7324 put_gpr_w1(1, mkU32(0x0));
7325 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
florian78d5ef72013-05-11 15:02:58 +00007326 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7327
florian7ab421d2013-06-17 21:03:56 +00007328 /* F128 -> D32 */
7329 assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7330 assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7331 put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007332 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007333 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7334 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7335
7336 /* F128 -> D64 */
7337 assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7338 assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7339 put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7340 put_gpr_w1(1, mkU32(0x0));
7341 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7342 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007343
7344 /* F128 -> D128 */
florian7ab421d2013-06-17 21:03:56 +00007345 assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7346 assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7347 put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007348 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007349 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
florian78d5ef72013-05-11 15:02:58 +00007350 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7351
florian7ab421d2013-06-17 21:03:56 +00007352 /* D32 -> F32 */
7353 assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7354 assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7355 put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007356 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007357 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7358 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7359
7360 /* D32 -> F64 */
7361 assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7362 assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7363 put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7364 put_gpr_w1(1, mkU32(0x0));
7365 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7366 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7367
7368 /* D32 -> F128 */
7369 assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7370 assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7371 put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7372 put_gpr_w1(1, mkU32(0x0));
7373 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7374 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7375
7376 /* D64 -> F32 */
7377 assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7378 assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7379 put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7380 put_gpr_w1(1, mkU32(0x0));
7381 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7382 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7383
7384 /* D64 -> F64 */
7385 assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7386 assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7387 put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7388 put_gpr_w1(1, mkU32(0x0));
7389 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7390 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7391
7392 /* D64 -> F128 */
7393 assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7394 assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7395 put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7396 put_gpr_w1(1, mkU32(0x0));
7397 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7398 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7399
7400 /* D128 -> F32 */
7401 assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7402 assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7403 put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7404 put_gpr_w1(1, mkU32(0x0));
7405 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7406 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7407
7408 /* D128 -> F64 */
7409 assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7410 assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7411 put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7412 put_gpr_w1(1, mkU32(0x0));
7413 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7414 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7415
7416 /* D128 -> F128 */
7417 assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7418 assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7419 put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7420 put_gpr_w1(1, mkU32(0x0));
7421 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
florian78d5ef72013-05-11 15:02:58 +00007422 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7423
7424 return "pfpo";
7425}
7426
florian55085f82012-11-21 00:36:55 +00007427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007428s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7429{
7430 IRTemp amount = newTemp(Ity_I64);
7431 IRTemp op = newTemp(Ity_I32);
7432
7433 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7434 assign(op, get_gpr_w1(r3));
7435 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7436 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7437 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7438
7439 return "rll";
7440}
7441
florian55085f82012-11-21 00:36:55 +00007442static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007443s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7444{
7445 IRTemp amount = newTemp(Ity_I64);
7446 IRTemp op = newTemp(Ity_I64);
7447
7448 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7449 assign(op, get_gpr_dw0(r3));
7450 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7451 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7452 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7453
7454 return "rllg";
7455}
7456
florian55085f82012-11-21 00:36:55 +00007457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007458s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7459{
7460 UChar from;
7461 UChar to;
7462 UChar rot;
7463 UChar t_bit;
7464 ULong mask;
7465 ULong maskc;
7466 IRTemp result = newTemp(Ity_I64);
7467 IRTemp op2 = newTemp(Ity_I64);
7468
7469 from = i3 & 63;
7470 to = i4 & 63;
7471 rot = i5 & 63;
7472 t_bit = i3 & 128;
7473 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7474 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7475 mkU8(64 - rot))));
7476 if (from <= to) {
7477 mask = ~0ULL;
7478 mask = (mask >> from) & (mask << (63 - to));
7479 maskc = ~mask;
7480 } else {
7481 maskc = ~0ULL;
7482 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7483 mask = ~maskc;
7484 }
7485 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7486 ), mkU64(mask)));
7487 if (t_bit == 0) {
7488 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7489 mkU64(maskc)), mkexpr(result)));
7490 }
7491 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7492
7493 return "rnsbg";
7494}
7495
florian55085f82012-11-21 00:36:55 +00007496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007497s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7498{
7499 UChar from;
7500 UChar to;
7501 UChar rot;
7502 UChar t_bit;
7503 ULong mask;
7504 ULong maskc;
7505 IRTemp result = newTemp(Ity_I64);
7506 IRTemp op2 = newTemp(Ity_I64);
7507
7508 from = i3 & 63;
7509 to = i4 & 63;
7510 rot = i5 & 63;
7511 t_bit = i3 & 128;
7512 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7513 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7514 mkU8(64 - rot))));
7515 if (from <= to) {
7516 mask = ~0ULL;
7517 mask = (mask >> from) & (mask << (63 - to));
7518 maskc = ~mask;
7519 } else {
7520 maskc = ~0ULL;
7521 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7522 mask = ~maskc;
7523 }
7524 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7525 ), mkU64(mask)));
7526 if (t_bit == 0) {
7527 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7528 mkU64(maskc)), mkexpr(result)));
7529 }
7530 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7531
7532 return "rxsbg";
7533}
7534
florian55085f82012-11-21 00:36:55 +00007535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007536s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7537{
7538 UChar from;
7539 UChar to;
7540 UChar rot;
7541 UChar t_bit;
7542 ULong mask;
7543 ULong maskc;
7544 IRTemp result = newTemp(Ity_I64);
7545 IRTemp op2 = newTemp(Ity_I64);
7546
7547 from = i3 & 63;
7548 to = i4 & 63;
7549 rot = i5 & 63;
7550 t_bit = i3 & 128;
7551 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7552 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7553 mkU8(64 - rot))));
7554 if (from <= to) {
7555 mask = ~0ULL;
7556 mask = (mask >> from) & (mask << (63 - to));
7557 maskc = ~mask;
7558 } else {
7559 maskc = ~0ULL;
7560 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7561 mask = ~maskc;
7562 }
7563 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7564 ), mkU64(mask)));
7565 if (t_bit == 0) {
7566 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7567 mkU64(maskc)), mkexpr(result)));
7568 }
7569 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7570
7571 return "rosbg";
7572}
7573
florian55085f82012-11-21 00:36:55 +00007574static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007575s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7576{
7577 UChar from;
7578 UChar to;
7579 UChar rot;
7580 UChar z_bit;
7581 ULong mask;
7582 ULong maskc;
7583 IRTemp op2 = newTemp(Ity_I64);
7584 IRTemp result = newTemp(Ity_I64);
7585
7586 from = i3 & 63;
7587 to = i4 & 63;
7588 rot = i5 & 63;
7589 z_bit = i4 & 128;
7590 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7591 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7592 mkU8(64 - rot))));
7593 if (from <= to) {
7594 mask = ~0ULL;
7595 mask = (mask >> from) & (mask << (63 - to));
7596 maskc = ~mask;
7597 } else {
7598 maskc = ~0ULL;
7599 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7600 mask = ~maskc;
7601 }
7602 if (z_bit == 0) {
7603 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7604 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7605 } else {
7606 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7607 }
7608 assign(result, get_gpr_dw0(r1));
cborntrae03b6002013-11-07 21:37:28 +00007609 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
sewardj2019a972011-03-07 16:04:07 +00007610
7611 return "risbg";
7612}
7613
florian55085f82012-11-21 00:36:55 +00007614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007615s390_irgen_SAR(UChar r1, UChar r2)
7616{
7617 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007618 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007619 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7620
7621 return "sar";
7622}
7623
florian55085f82012-11-21 00:36:55 +00007624static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007625s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7626{
7627 IRTemp p1 = newTemp(Ity_I64);
7628 IRTemp p2 = newTemp(Ity_I64);
7629 IRTemp op = newTemp(Ity_I64);
7630 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007631 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007632 IRTemp shift_amount = newTemp(Ity_I64);
7633
7634 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7635 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7636 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7637 ));
7638 sign_mask = 1ULL << 63;
7639 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7640 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007641 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7642 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007643 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7644 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7645 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7646
7647 return "slda";
7648}
7649
florian55085f82012-11-21 00:36:55 +00007650static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007651s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7652{
7653 IRTemp p1 = newTemp(Ity_I64);
7654 IRTemp p2 = newTemp(Ity_I64);
7655 IRTemp result = newTemp(Ity_I64);
7656
7657 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7658 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7659 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7660 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7661 mkexpr(op2addr), mkU64(63)))));
7662 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7663 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7664
7665 return "sldl";
7666}
7667
florian55085f82012-11-21 00:36:55 +00007668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007669s390_irgen_SLA(UChar r1, IRTemp op2addr)
7670{
7671 IRTemp uop = newTemp(Ity_I32);
7672 IRTemp result = newTemp(Ity_I32);
7673 UInt sign_mask;
7674 IRTemp shift_amount = newTemp(Ity_I64);
7675 IRTemp op = newTemp(Ity_I32);
7676
7677 assign(op, get_gpr_w1(r1));
7678 assign(uop, get_gpr_w1(r1));
7679 sign_mask = 2147483648U;
7680 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7681 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7682 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7683 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7684 put_gpr_w1(r1, mkexpr(result));
7685 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7686
7687 return "sla";
7688}
7689
florian55085f82012-11-21 00:36:55 +00007690static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007691s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7692{
7693 IRTemp uop = newTemp(Ity_I32);
7694 IRTemp result = newTemp(Ity_I32);
7695 UInt sign_mask;
7696 IRTemp shift_amount = newTemp(Ity_I64);
7697 IRTemp op = newTemp(Ity_I32);
7698
7699 assign(op, get_gpr_w1(r3));
7700 assign(uop, get_gpr_w1(r3));
7701 sign_mask = 2147483648U;
7702 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7703 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7704 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7705 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7706 put_gpr_w1(r1, mkexpr(result));
7707 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7708
7709 return "slak";
7710}
7711
florian55085f82012-11-21 00:36:55 +00007712static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007713s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7714{
7715 IRTemp uop = newTemp(Ity_I64);
7716 IRTemp result = newTemp(Ity_I64);
7717 ULong sign_mask;
7718 IRTemp shift_amount = newTemp(Ity_I64);
7719 IRTemp op = newTemp(Ity_I64);
7720
7721 assign(op, get_gpr_dw0(r3));
7722 assign(uop, get_gpr_dw0(r3));
7723 sign_mask = 9223372036854775808ULL;
7724 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7725 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7726 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7727 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7728 put_gpr_dw0(r1, mkexpr(result));
7729 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7730
7731 return "slag";
7732}
7733
florian55085f82012-11-21 00:36:55 +00007734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007735s390_irgen_SLL(UChar r1, IRTemp op2addr)
7736{
7737 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7738 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7739
7740 return "sll";
7741}
7742
florian55085f82012-11-21 00:36:55 +00007743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007744s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7745{
7746 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7747 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7748
7749 return "sllk";
7750}
7751
florian55085f82012-11-21 00:36:55 +00007752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007753s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7754{
7755 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7756 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7757
7758 return "sllg";
7759}
7760
florian55085f82012-11-21 00:36:55 +00007761static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007762s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7763{
7764 IRTemp p1 = newTemp(Ity_I64);
7765 IRTemp p2 = newTemp(Ity_I64);
7766 IRTemp result = newTemp(Ity_I64);
7767
7768 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7769 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7770 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7771 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7772 mkexpr(op2addr), mkU64(63)))));
7773 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7774 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7775 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7776
7777 return "srda";
7778}
7779
florian55085f82012-11-21 00:36:55 +00007780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007781s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7782{
7783 IRTemp p1 = newTemp(Ity_I64);
7784 IRTemp p2 = newTemp(Ity_I64);
7785 IRTemp result = newTemp(Ity_I64);
7786
7787 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7788 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7789 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7790 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7791 mkexpr(op2addr), mkU64(63)))));
7792 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7793 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7794
7795 return "srdl";
7796}
7797
florian55085f82012-11-21 00:36:55 +00007798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007799s390_irgen_SRA(UChar r1, IRTemp op2addr)
7800{
7801 IRTemp result = newTemp(Ity_I32);
7802 IRTemp op = newTemp(Ity_I32);
7803
7804 assign(op, get_gpr_w1(r1));
7805 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7806 mkexpr(op2addr), mkU64(63)))));
7807 put_gpr_w1(r1, mkexpr(result));
7808 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7809
7810 return "sra";
7811}
7812
florian55085f82012-11-21 00:36:55 +00007813static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007814s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7815{
7816 IRTemp result = newTemp(Ity_I32);
7817 IRTemp op = newTemp(Ity_I32);
7818
7819 assign(op, get_gpr_w1(r3));
7820 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7821 mkexpr(op2addr), mkU64(63)))));
7822 put_gpr_w1(r1, mkexpr(result));
7823 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7824
7825 return "srak";
7826}
7827
florian55085f82012-11-21 00:36:55 +00007828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007829s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7830{
7831 IRTemp result = newTemp(Ity_I64);
7832 IRTemp op = newTemp(Ity_I64);
7833
7834 assign(op, get_gpr_dw0(r3));
7835 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7836 mkexpr(op2addr), mkU64(63)))));
7837 put_gpr_dw0(r1, mkexpr(result));
7838 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7839
7840 return "srag";
7841}
7842
florian55085f82012-11-21 00:36:55 +00007843static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007844s390_irgen_SRL(UChar r1, IRTemp op2addr)
7845{
7846 IRTemp op = newTemp(Ity_I32);
7847
7848 assign(op, get_gpr_w1(r1));
7849 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7850 mkexpr(op2addr), mkU64(63)))));
7851
7852 return "srl";
7853}
7854
florian55085f82012-11-21 00:36:55 +00007855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007856s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7857{
7858 IRTemp op = newTemp(Ity_I32);
7859
7860 assign(op, get_gpr_w1(r3));
7861 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7862 mkexpr(op2addr), mkU64(63)))));
7863
7864 return "srlk";
7865}
7866
florian55085f82012-11-21 00:36:55 +00007867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007868s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7869{
7870 IRTemp op = newTemp(Ity_I64);
7871
7872 assign(op, get_gpr_dw0(r3));
7873 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7874 mkexpr(op2addr), mkU64(63)))));
7875
7876 return "srlg";
7877}
7878
florian55085f82012-11-21 00:36:55 +00007879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007880s390_irgen_ST(UChar r1, IRTemp op2addr)
7881{
7882 store(mkexpr(op2addr), get_gpr_w1(r1));
7883
7884 return "st";
7885}
7886
florian55085f82012-11-21 00:36:55 +00007887static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007888s390_irgen_STY(UChar r1, IRTemp op2addr)
7889{
7890 store(mkexpr(op2addr), get_gpr_w1(r1));
7891
7892 return "sty";
7893}
7894
florian55085f82012-11-21 00:36:55 +00007895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007896s390_irgen_STG(UChar r1, IRTemp op2addr)
7897{
7898 store(mkexpr(op2addr), get_gpr_dw0(r1));
7899
7900 return "stg";
7901}
7902
florian55085f82012-11-21 00:36:55 +00007903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007904s390_irgen_STRL(UChar r1, UInt i2)
7905{
7906 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7907 get_gpr_w1(r1));
7908
7909 return "strl";
7910}
7911
florian55085f82012-11-21 00:36:55 +00007912static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007913s390_irgen_STGRL(UChar r1, UInt i2)
7914{
7915 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7916 get_gpr_dw0(r1));
7917
7918 return "stgrl";
7919}
7920
florian55085f82012-11-21 00:36:55 +00007921static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007922s390_irgen_STC(UChar r1, IRTemp op2addr)
7923{
7924 store(mkexpr(op2addr), get_gpr_b7(r1));
7925
7926 return "stc";
7927}
7928
florian55085f82012-11-21 00:36:55 +00007929static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007930s390_irgen_STCY(UChar r1, IRTemp op2addr)
7931{
7932 store(mkexpr(op2addr), get_gpr_b7(r1));
7933
7934 return "stcy";
7935}
7936
florian55085f82012-11-21 00:36:55 +00007937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007938s390_irgen_STCH(UChar r1, IRTemp op2addr)
7939{
7940 store(mkexpr(op2addr), get_gpr_b3(r1));
7941
7942 return "stch";
7943}
7944
florian55085f82012-11-21 00:36:55 +00007945static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007946s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7947{
7948 UChar mask;
7949 UChar n;
7950
7951 mask = (UChar)r3;
7952 n = 0;
7953 if ((mask & 8) != 0) {
7954 store(mkexpr(op2addr), get_gpr_b4(r1));
7955 n = n + 1;
7956 }
7957 if ((mask & 4) != 0) {
7958 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7959 n = n + 1;
7960 }
7961 if ((mask & 2) != 0) {
7962 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7963 n = n + 1;
7964 }
7965 if ((mask & 1) != 0) {
7966 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7967 }
7968
7969 return "stcm";
7970}
7971
florian55085f82012-11-21 00:36:55 +00007972static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007973s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7974{
7975 UChar mask;
7976 UChar n;
7977
7978 mask = (UChar)r3;
7979 n = 0;
7980 if ((mask & 8) != 0) {
7981 store(mkexpr(op2addr), get_gpr_b4(r1));
7982 n = n + 1;
7983 }
7984 if ((mask & 4) != 0) {
7985 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7986 n = n + 1;
7987 }
7988 if ((mask & 2) != 0) {
7989 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7990 n = n + 1;
7991 }
7992 if ((mask & 1) != 0) {
7993 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7994 }
7995
7996 return "stcmy";
7997}
7998
florian55085f82012-11-21 00:36:55 +00007999static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008000s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8001{
8002 UChar mask;
8003 UChar n;
8004
8005 mask = (UChar)r3;
8006 n = 0;
8007 if ((mask & 8) != 0) {
8008 store(mkexpr(op2addr), get_gpr_b0(r1));
8009 n = n + 1;
8010 }
8011 if ((mask & 4) != 0) {
8012 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8013 n = n + 1;
8014 }
8015 if ((mask & 2) != 0) {
8016 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8017 n = n + 1;
8018 }
8019 if ((mask & 1) != 0) {
8020 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8021 }
8022
8023 return "stcmh";
8024}
8025
florian55085f82012-11-21 00:36:55 +00008026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008027s390_irgen_STH(UChar r1, IRTemp op2addr)
8028{
8029 store(mkexpr(op2addr), get_gpr_hw3(r1));
8030
8031 return "sth";
8032}
8033
florian55085f82012-11-21 00:36:55 +00008034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008035s390_irgen_STHY(UChar r1, IRTemp op2addr)
8036{
8037 store(mkexpr(op2addr), get_gpr_hw3(r1));
8038
8039 return "sthy";
8040}
8041
florian55085f82012-11-21 00:36:55 +00008042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008043s390_irgen_STHRL(UChar r1, UInt i2)
8044{
8045 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8046 get_gpr_hw3(r1));
8047
8048 return "sthrl";
8049}
8050
florian55085f82012-11-21 00:36:55 +00008051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008052s390_irgen_STHH(UChar r1, IRTemp op2addr)
8053{
8054 store(mkexpr(op2addr), get_gpr_hw1(r1));
8055
8056 return "sthh";
8057}
8058
florian55085f82012-11-21 00:36:55 +00008059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008060s390_irgen_STFH(UChar r1, IRTemp op2addr)
8061{
8062 store(mkexpr(op2addr), get_gpr_w0(r1));
8063
8064 return "stfh";
8065}
8066
florian55085f82012-11-21 00:36:55 +00008067static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008068s390_irgen_STOC(UChar r1, IRTemp op2addr)
8069{
8070 /* condition is checked in format handler */
8071 store(mkexpr(op2addr), get_gpr_w1(r1));
8072
8073 return "stoc";
8074}
8075
florian55085f82012-11-21 00:36:55 +00008076static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008077s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8078{
8079 /* condition is checked in format handler */
8080 store(mkexpr(op2addr), get_gpr_dw0(r1));
8081
8082 return "stocg";
8083}
8084
florian55085f82012-11-21 00:36:55 +00008085static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008086s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8087{
8088 store(mkexpr(op2addr), get_gpr_dw0(r1));
8089 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8090
8091 return "stpq";
8092}
8093
florian55085f82012-11-21 00:36:55 +00008094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008095s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8096{
8097 store(mkexpr(op2addr), get_gpr_b7(r1));
8098 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8099
8100 return "strvh";
8101}
8102
florian55085f82012-11-21 00:36:55 +00008103static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008104s390_irgen_STRV(UChar r1, IRTemp op2addr)
8105{
8106 store(mkexpr(op2addr), get_gpr_b7(r1));
8107 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8108 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8109 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8110
8111 return "strv";
8112}
8113
florian55085f82012-11-21 00:36:55 +00008114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008115s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8116{
8117 store(mkexpr(op2addr), get_gpr_b7(r1));
8118 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8119 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8120 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8121 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8122 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8123 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8124 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8125
8126 return "strvg";
8127}
8128
florian55085f82012-11-21 00:36:55 +00008129static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008130s390_irgen_SR(UChar r1, UChar r2)
8131{
8132 IRTemp op1 = newTemp(Ity_I32);
8133 IRTemp op2 = newTemp(Ity_I32);
8134 IRTemp result = newTemp(Ity_I32);
8135
8136 assign(op1, get_gpr_w1(r1));
8137 assign(op2, get_gpr_w1(r2));
8138 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8139 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8140 put_gpr_w1(r1, mkexpr(result));
8141
8142 return "sr";
8143}
8144
florian55085f82012-11-21 00:36:55 +00008145static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008146s390_irgen_SGR(UChar r1, UChar r2)
8147{
8148 IRTemp op1 = newTemp(Ity_I64);
8149 IRTemp op2 = newTemp(Ity_I64);
8150 IRTemp result = newTemp(Ity_I64);
8151
8152 assign(op1, get_gpr_dw0(r1));
8153 assign(op2, get_gpr_dw0(r2));
8154 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8155 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8156 put_gpr_dw0(r1, mkexpr(result));
8157
8158 return "sgr";
8159}
8160
florian55085f82012-11-21 00:36:55 +00008161static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008162s390_irgen_SGFR(UChar r1, UChar r2)
8163{
8164 IRTemp op1 = newTemp(Ity_I64);
8165 IRTemp op2 = newTemp(Ity_I64);
8166 IRTemp result = newTemp(Ity_I64);
8167
8168 assign(op1, get_gpr_dw0(r1));
8169 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8170 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8171 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8172 put_gpr_dw0(r1, mkexpr(result));
8173
8174 return "sgfr";
8175}
8176
florian55085f82012-11-21 00:36:55 +00008177static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008178s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8179{
8180 IRTemp op2 = newTemp(Ity_I32);
8181 IRTemp op3 = newTemp(Ity_I32);
8182 IRTemp result = newTemp(Ity_I32);
8183
8184 assign(op2, get_gpr_w1(r2));
8185 assign(op3, get_gpr_w1(r3));
8186 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8187 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8188 put_gpr_w1(r1, mkexpr(result));
8189
8190 return "srk";
8191}
8192
florian55085f82012-11-21 00:36:55 +00008193static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008194s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8195{
8196 IRTemp op2 = newTemp(Ity_I64);
8197 IRTemp op3 = newTemp(Ity_I64);
8198 IRTemp result = newTemp(Ity_I64);
8199
8200 assign(op2, get_gpr_dw0(r2));
8201 assign(op3, get_gpr_dw0(r3));
8202 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8203 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8204 put_gpr_dw0(r1, mkexpr(result));
8205
8206 return "sgrk";
8207}
8208
florian55085f82012-11-21 00:36:55 +00008209static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008210s390_irgen_S(UChar r1, IRTemp op2addr)
8211{
8212 IRTemp op1 = newTemp(Ity_I32);
8213 IRTemp op2 = newTemp(Ity_I32);
8214 IRTemp result = newTemp(Ity_I32);
8215
8216 assign(op1, get_gpr_w1(r1));
8217 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8218 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8219 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8220 put_gpr_w1(r1, mkexpr(result));
8221
8222 return "s";
8223}
8224
florian55085f82012-11-21 00:36:55 +00008225static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008226s390_irgen_SY(UChar r1, IRTemp op2addr)
8227{
8228 IRTemp op1 = newTemp(Ity_I32);
8229 IRTemp op2 = newTemp(Ity_I32);
8230 IRTemp result = newTemp(Ity_I32);
8231
8232 assign(op1, get_gpr_w1(r1));
8233 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8234 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8235 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8236 put_gpr_w1(r1, mkexpr(result));
8237
8238 return "sy";
8239}
8240
florian55085f82012-11-21 00:36:55 +00008241static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008242s390_irgen_SG(UChar r1, IRTemp op2addr)
8243{
8244 IRTemp op1 = newTemp(Ity_I64);
8245 IRTemp op2 = newTemp(Ity_I64);
8246 IRTemp result = newTemp(Ity_I64);
8247
8248 assign(op1, get_gpr_dw0(r1));
8249 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8250 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8251 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8252 put_gpr_dw0(r1, mkexpr(result));
8253
8254 return "sg";
8255}
8256
florian55085f82012-11-21 00:36:55 +00008257static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008258s390_irgen_SGF(UChar r1, IRTemp op2addr)
8259{
8260 IRTemp op1 = newTemp(Ity_I64);
8261 IRTemp op2 = newTemp(Ity_I64);
8262 IRTemp result = newTemp(Ity_I64);
8263
8264 assign(op1, get_gpr_dw0(r1));
8265 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8266 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8267 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8268 put_gpr_dw0(r1, mkexpr(result));
8269
8270 return "sgf";
8271}
8272
florian55085f82012-11-21 00:36:55 +00008273static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008274s390_irgen_SH(UChar r1, IRTemp op2addr)
8275{
8276 IRTemp op1 = newTemp(Ity_I32);
8277 IRTemp op2 = newTemp(Ity_I32);
8278 IRTemp result = newTemp(Ity_I32);
8279
8280 assign(op1, get_gpr_w1(r1));
8281 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8282 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8283 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8284 put_gpr_w1(r1, mkexpr(result));
8285
8286 return "sh";
8287}
8288
florian55085f82012-11-21 00:36:55 +00008289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008290s390_irgen_SHY(UChar r1, IRTemp op2addr)
8291{
8292 IRTemp op1 = newTemp(Ity_I32);
8293 IRTemp op2 = newTemp(Ity_I32);
8294 IRTemp result = newTemp(Ity_I32);
8295
8296 assign(op1, get_gpr_w1(r1));
8297 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8298 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8299 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8300 put_gpr_w1(r1, mkexpr(result));
8301
8302 return "shy";
8303}
8304
florian55085f82012-11-21 00:36:55 +00008305static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008306s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8307{
8308 IRTemp op2 = newTemp(Ity_I32);
8309 IRTemp op3 = newTemp(Ity_I32);
8310 IRTemp result = newTemp(Ity_I32);
8311
8312 assign(op2, get_gpr_w0(r1));
8313 assign(op3, get_gpr_w0(r2));
8314 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8315 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8316 put_gpr_w0(r1, mkexpr(result));
8317
8318 return "shhhr";
8319}
8320
florian55085f82012-11-21 00:36:55 +00008321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008322s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8323{
8324 IRTemp op2 = newTemp(Ity_I32);
8325 IRTemp op3 = newTemp(Ity_I32);
8326 IRTemp result = newTemp(Ity_I32);
8327
8328 assign(op2, get_gpr_w0(r1));
8329 assign(op3, get_gpr_w1(r2));
8330 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8331 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8332 put_gpr_w0(r1, mkexpr(result));
8333
8334 return "shhlr";
8335}
8336
florian55085f82012-11-21 00:36:55 +00008337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008338s390_irgen_SLR(UChar r1, UChar r2)
8339{
8340 IRTemp op1 = newTemp(Ity_I32);
8341 IRTemp op2 = newTemp(Ity_I32);
8342 IRTemp result = newTemp(Ity_I32);
8343
8344 assign(op1, get_gpr_w1(r1));
8345 assign(op2, get_gpr_w1(r2));
8346 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8347 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8348 put_gpr_w1(r1, mkexpr(result));
8349
8350 return "slr";
8351}
8352
florian55085f82012-11-21 00:36:55 +00008353static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008354s390_irgen_SLGR(UChar r1, UChar r2)
8355{
8356 IRTemp op1 = newTemp(Ity_I64);
8357 IRTemp op2 = newTemp(Ity_I64);
8358 IRTemp result = newTemp(Ity_I64);
8359
8360 assign(op1, get_gpr_dw0(r1));
8361 assign(op2, get_gpr_dw0(r2));
8362 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8363 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8364 put_gpr_dw0(r1, mkexpr(result));
8365
8366 return "slgr";
8367}
8368
florian55085f82012-11-21 00:36:55 +00008369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008370s390_irgen_SLGFR(UChar r1, UChar r2)
8371{
8372 IRTemp op1 = newTemp(Ity_I64);
8373 IRTemp op2 = newTemp(Ity_I64);
8374 IRTemp result = newTemp(Ity_I64);
8375
8376 assign(op1, get_gpr_dw0(r1));
8377 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8378 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8379 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8380 put_gpr_dw0(r1, mkexpr(result));
8381
8382 return "slgfr";
8383}
8384
florian55085f82012-11-21 00:36:55 +00008385static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008386s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8387{
8388 IRTemp op2 = newTemp(Ity_I32);
8389 IRTemp op3 = newTemp(Ity_I32);
8390 IRTemp result = newTemp(Ity_I32);
8391
8392 assign(op2, get_gpr_w1(r2));
8393 assign(op3, get_gpr_w1(r3));
8394 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8395 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8396 put_gpr_w1(r1, mkexpr(result));
8397
8398 return "slrk";
8399}
8400
florian55085f82012-11-21 00:36:55 +00008401static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008402s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8403{
8404 IRTemp op2 = newTemp(Ity_I64);
8405 IRTemp op3 = newTemp(Ity_I64);
8406 IRTemp result = newTemp(Ity_I64);
8407
8408 assign(op2, get_gpr_dw0(r2));
8409 assign(op3, get_gpr_dw0(r3));
8410 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8411 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8412 put_gpr_dw0(r1, mkexpr(result));
8413
8414 return "slgrk";
8415}
8416
florian55085f82012-11-21 00:36:55 +00008417static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008418s390_irgen_SL(UChar r1, IRTemp op2addr)
8419{
8420 IRTemp op1 = newTemp(Ity_I32);
8421 IRTemp op2 = newTemp(Ity_I32);
8422 IRTemp result = newTemp(Ity_I32);
8423
8424 assign(op1, get_gpr_w1(r1));
8425 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8426 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8427 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8428 put_gpr_w1(r1, mkexpr(result));
8429
8430 return "sl";
8431}
8432
florian55085f82012-11-21 00:36:55 +00008433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008434s390_irgen_SLY(UChar r1, IRTemp op2addr)
8435{
8436 IRTemp op1 = newTemp(Ity_I32);
8437 IRTemp op2 = newTemp(Ity_I32);
8438 IRTemp result = newTemp(Ity_I32);
8439
8440 assign(op1, get_gpr_w1(r1));
8441 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8442 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8443 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8444 put_gpr_w1(r1, mkexpr(result));
8445
8446 return "sly";
8447}
8448
florian55085f82012-11-21 00:36:55 +00008449static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008450s390_irgen_SLG(UChar r1, IRTemp op2addr)
8451{
8452 IRTemp op1 = newTemp(Ity_I64);
8453 IRTemp op2 = newTemp(Ity_I64);
8454 IRTemp result = newTemp(Ity_I64);
8455
8456 assign(op1, get_gpr_dw0(r1));
8457 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8458 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8459 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8460 put_gpr_dw0(r1, mkexpr(result));
8461
8462 return "slg";
8463}
8464
florian55085f82012-11-21 00:36:55 +00008465static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008466s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8467{
8468 IRTemp op1 = newTemp(Ity_I64);
8469 IRTemp op2 = newTemp(Ity_I64);
8470 IRTemp result = newTemp(Ity_I64);
8471
8472 assign(op1, get_gpr_dw0(r1));
8473 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8474 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8475 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8476 put_gpr_dw0(r1, mkexpr(result));
8477
8478 return "slgf";
8479}
8480
florian55085f82012-11-21 00:36:55 +00008481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008482s390_irgen_SLFI(UChar r1, UInt i2)
8483{
8484 IRTemp op1 = newTemp(Ity_I32);
8485 UInt op2;
8486 IRTemp result = newTemp(Ity_I32);
8487
8488 assign(op1, get_gpr_w1(r1));
8489 op2 = i2;
8490 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8491 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8492 mkU32(op2)));
8493 put_gpr_w1(r1, mkexpr(result));
8494
8495 return "slfi";
8496}
8497
florian55085f82012-11-21 00:36:55 +00008498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008499s390_irgen_SLGFI(UChar r1, UInt i2)
8500{
8501 IRTemp op1 = newTemp(Ity_I64);
8502 ULong op2;
8503 IRTemp result = newTemp(Ity_I64);
8504
8505 assign(op1, get_gpr_dw0(r1));
8506 op2 = (ULong)i2;
8507 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8508 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8509 mkU64(op2)));
8510 put_gpr_dw0(r1, mkexpr(result));
8511
8512 return "slgfi";
8513}
8514
florian55085f82012-11-21 00:36:55 +00008515static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008516s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8517{
8518 IRTemp op2 = newTemp(Ity_I32);
8519 IRTemp op3 = newTemp(Ity_I32);
8520 IRTemp result = newTemp(Ity_I32);
8521
8522 assign(op2, get_gpr_w0(r1));
8523 assign(op3, get_gpr_w0(r2));
8524 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8525 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8526 put_gpr_w0(r1, mkexpr(result));
8527
8528 return "slhhhr";
8529}
8530
florian55085f82012-11-21 00:36:55 +00008531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008532s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8533{
8534 IRTemp op2 = newTemp(Ity_I32);
8535 IRTemp op3 = newTemp(Ity_I32);
8536 IRTemp result = newTemp(Ity_I32);
8537
8538 assign(op2, get_gpr_w0(r1));
8539 assign(op3, get_gpr_w1(r2));
8540 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8541 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8542 put_gpr_w0(r1, mkexpr(result));
8543
8544 return "slhhlr";
8545}
8546
florian55085f82012-11-21 00:36:55 +00008547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008548s390_irgen_SLBR(UChar r1, UChar r2)
8549{
8550 IRTemp op1 = newTemp(Ity_I32);
8551 IRTemp op2 = newTemp(Ity_I32);
8552 IRTemp result = newTemp(Ity_I32);
8553 IRTemp borrow_in = newTemp(Ity_I32);
8554
8555 assign(op1, get_gpr_w1(r1));
8556 assign(op2, get_gpr_w1(r2));
8557 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8558 s390_call_calculate_cc(), mkU8(1))));
8559 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8560 mkexpr(borrow_in)));
8561 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8562 put_gpr_w1(r1, mkexpr(result));
8563
8564 return "slbr";
8565}
8566
florian55085f82012-11-21 00:36:55 +00008567static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008568s390_irgen_SLBGR(UChar r1, UChar r2)
8569{
8570 IRTemp op1 = newTemp(Ity_I64);
8571 IRTemp op2 = newTemp(Ity_I64);
8572 IRTemp result = newTemp(Ity_I64);
8573 IRTemp borrow_in = newTemp(Ity_I64);
8574
8575 assign(op1, get_gpr_dw0(r1));
8576 assign(op2, get_gpr_dw0(r2));
8577 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8578 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8579 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8580 mkexpr(borrow_in)));
8581 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8582 put_gpr_dw0(r1, mkexpr(result));
8583
8584 return "slbgr";
8585}
8586
florian55085f82012-11-21 00:36:55 +00008587static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008588s390_irgen_SLB(UChar r1, IRTemp op2addr)
8589{
8590 IRTemp op1 = newTemp(Ity_I32);
8591 IRTemp op2 = newTemp(Ity_I32);
8592 IRTemp result = newTemp(Ity_I32);
8593 IRTemp borrow_in = newTemp(Ity_I32);
8594
8595 assign(op1, get_gpr_w1(r1));
8596 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8597 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8598 s390_call_calculate_cc(), mkU8(1))));
8599 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8600 mkexpr(borrow_in)));
8601 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8602 put_gpr_w1(r1, mkexpr(result));
8603
8604 return "slb";
8605}
8606
florian55085f82012-11-21 00:36:55 +00008607static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008608s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8609{
8610 IRTemp op1 = newTemp(Ity_I64);
8611 IRTemp op2 = newTemp(Ity_I64);
8612 IRTemp result = newTemp(Ity_I64);
8613 IRTemp borrow_in = newTemp(Ity_I64);
8614
8615 assign(op1, get_gpr_dw0(r1));
8616 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8617 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8618 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8619 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8620 mkexpr(borrow_in)));
8621 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8622 put_gpr_dw0(r1, mkexpr(result));
8623
8624 return "slbg";
8625}
8626
florian55085f82012-11-21 00:36:55 +00008627static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008628s390_irgen_SVC(UChar i)
8629{
8630 IRTemp sysno = newTemp(Ity_I64);
8631
8632 if (i != 0) {
8633 assign(sysno, mkU64(i));
8634 } else {
8635 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8636 }
8637 system_call(mkexpr(sysno));
8638
8639 return "svc";
8640}
8641
florian55085f82012-11-21 00:36:55 +00008642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008643s390_irgen_TM(UChar i2, IRTemp op1addr)
8644{
8645 UChar mask;
8646 IRTemp value = newTemp(Ity_I8);
8647
8648 mask = i2;
8649 assign(value, load(Ity_I8, mkexpr(op1addr)));
8650 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8651 mkU8(mask)));
8652
8653 return "tm";
8654}
8655
florian55085f82012-11-21 00:36:55 +00008656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008657s390_irgen_TMY(UChar i2, IRTemp op1addr)
8658{
8659 UChar mask;
8660 IRTemp value = newTemp(Ity_I8);
8661
8662 mask = i2;
8663 assign(value, load(Ity_I8, mkexpr(op1addr)));
8664 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8665 mkU8(mask)));
8666
8667 return "tmy";
8668}
8669
florian55085f82012-11-21 00:36:55 +00008670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008671s390_irgen_TMHH(UChar r1, UShort i2)
8672{
8673 UShort mask;
8674 IRTemp value = newTemp(Ity_I16);
8675
8676 mask = i2;
8677 assign(value, get_gpr_hw0(r1));
8678 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8679 mkU16(mask)));
8680
8681 return "tmhh";
8682}
8683
florian55085f82012-11-21 00:36:55 +00008684static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008685s390_irgen_TMHL(UChar r1, UShort i2)
8686{
8687 UShort mask;
8688 IRTemp value = newTemp(Ity_I16);
8689
8690 mask = i2;
8691 assign(value, get_gpr_hw1(r1));
8692 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8693 mkU16(mask)));
8694
8695 return "tmhl";
8696}
8697
florian55085f82012-11-21 00:36:55 +00008698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008699s390_irgen_TMLH(UChar r1, UShort i2)
8700{
8701 UShort mask;
8702 IRTemp value = newTemp(Ity_I16);
8703
8704 mask = i2;
8705 assign(value, get_gpr_hw2(r1));
8706 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8707 mkU16(mask)));
8708
8709 return "tmlh";
8710}
8711
florian55085f82012-11-21 00:36:55 +00008712static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008713s390_irgen_TMLL(UChar r1, UShort i2)
8714{
8715 UShort mask;
8716 IRTemp value = newTemp(Ity_I16);
8717
8718 mask = i2;
8719 assign(value, get_gpr_hw3(r1));
8720 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8721 mkU16(mask)));
8722
8723 return "tmll";
8724}
8725
florian55085f82012-11-21 00:36:55 +00008726static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008727s390_irgen_EFPC(UChar r1)
8728{
8729 put_gpr_w1(r1, get_fpc_w0());
8730
8731 return "efpc";
8732}
8733
florian55085f82012-11-21 00:36:55 +00008734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008735s390_irgen_LER(UChar r1, UChar r2)
8736{
8737 put_fpr_w0(r1, get_fpr_w0(r2));
8738
8739 return "ler";
8740}
8741
florian55085f82012-11-21 00:36:55 +00008742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008743s390_irgen_LDR(UChar r1, UChar r2)
8744{
8745 put_fpr_dw0(r1, get_fpr_dw0(r2));
8746
8747 return "ldr";
8748}
8749
florian55085f82012-11-21 00:36:55 +00008750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008751s390_irgen_LXR(UChar r1, UChar r2)
8752{
8753 put_fpr_dw0(r1, get_fpr_dw0(r2));
8754 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8755
8756 return "lxr";
8757}
8758
florian55085f82012-11-21 00:36:55 +00008759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008760s390_irgen_LE(UChar r1, IRTemp op2addr)
8761{
8762 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8763
8764 return "le";
8765}
8766
florian55085f82012-11-21 00:36:55 +00008767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008768s390_irgen_LD(UChar r1, IRTemp op2addr)
8769{
8770 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8771
8772 return "ld";
8773}
8774
florian55085f82012-11-21 00:36:55 +00008775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008776s390_irgen_LEY(UChar r1, IRTemp op2addr)
8777{
8778 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8779
8780 return "ley";
8781}
8782
florian55085f82012-11-21 00:36:55 +00008783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008784s390_irgen_LDY(UChar r1, IRTemp op2addr)
8785{
8786 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8787
8788 return "ldy";
8789}
8790
florian55085f82012-11-21 00:36:55 +00008791static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008792s390_irgen_LFPC(IRTemp op2addr)
8793{
8794 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8795
8796 return "lfpc";
8797}
8798
florian55085f82012-11-21 00:36:55 +00008799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008800s390_irgen_LZER(UChar r1)
8801{
8802 put_fpr_w0(r1, mkF32i(0x0));
8803
8804 return "lzer";
8805}
8806
florian55085f82012-11-21 00:36:55 +00008807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008808s390_irgen_LZDR(UChar r1)
8809{
8810 put_fpr_dw0(r1, mkF64i(0x0));
8811
8812 return "lzdr";
8813}
8814
florian55085f82012-11-21 00:36:55 +00008815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008816s390_irgen_LZXR(UChar r1)
8817{
8818 put_fpr_dw0(r1, mkF64i(0x0));
8819 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8820
8821 return "lzxr";
8822}
8823
florian55085f82012-11-21 00:36:55 +00008824static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008825s390_irgen_SRNM(IRTemp op2addr)
8826{
florianf0fa1be2012-09-18 20:24:38 +00008827 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008828
florianf0fa1be2012-09-18 20:24:38 +00008829 input_mask = 3;
8830 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008831
florianf0fa1be2012-09-18 20:24:38 +00008832 put_fpc_w0(binop(Iop_Or32,
8833 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8834 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8835 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008836 return "srnm";
8837}
8838
florian55085f82012-11-21 00:36:55 +00008839static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008840s390_irgen_SRNMB(IRTemp op2addr)
8841{
8842 UInt input_mask, fpc_mask;
8843
8844 input_mask = 7;
8845 fpc_mask = 7;
8846
8847 put_fpc_w0(binop(Iop_Or32,
8848 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8849 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8850 mkU32(input_mask))));
8851 return "srnmb";
8852}
8853
florian81a4bfe2012-09-20 01:25:28 +00008854static void
florianf0fa1be2012-09-18 20:24:38 +00008855s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8856{
8857 if (b2 == 0) { /* This is the typical case */
8858 if (d2 > 3) {
8859 if (s390_host_has_fpext && d2 == 7) {
8860 /* ok */
8861 } else {
8862 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008863 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008864 }
8865 }
8866 }
8867
8868 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8869}
8870
florian82cdba62013-03-12 01:31:24 +00008871/* Wrapper to validate the parameter as in SRNMB is not required, as all
8872 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8873static const HChar *
8874s390_irgen_SRNMT(IRTemp op2addr)
8875{
8876 UInt input_mask, fpc_mask;
8877
8878 input_mask = 7;
8879 fpc_mask = 0x70;
8880
8881 /* fpc[25:27] <- op2addr[61:63]
8882 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8883 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8884 binop(Iop_Shl32, binop(Iop_And32,
8885 unop(Iop_64to32, mkexpr(op2addr)),
8886 mkU32(input_mask)), mkU8(4))));
8887 return "srnmt";
8888}
8889
florianf0fa1be2012-09-18 20:24:38 +00008890
florian55085f82012-11-21 00:36:55 +00008891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008892s390_irgen_SFPC(UChar r1)
8893{
8894 put_fpc_w0(get_gpr_w1(r1));
8895
8896 return "sfpc";
8897}
8898
florian55085f82012-11-21 00:36:55 +00008899static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008900s390_irgen_STE(UChar r1, IRTemp op2addr)
8901{
8902 store(mkexpr(op2addr), get_fpr_w0(r1));
8903
8904 return "ste";
8905}
8906
florian55085f82012-11-21 00:36:55 +00008907static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008908s390_irgen_STD(UChar r1, IRTemp op2addr)
8909{
8910 store(mkexpr(op2addr), get_fpr_dw0(r1));
8911
8912 return "std";
8913}
8914
florian55085f82012-11-21 00:36:55 +00008915static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008916s390_irgen_STEY(UChar r1, IRTemp op2addr)
8917{
8918 store(mkexpr(op2addr), get_fpr_w0(r1));
8919
8920 return "stey";
8921}
8922
florian55085f82012-11-21 00:36:55 +00008923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008924s390_irgen_STDY(UChar r1, IRTemp op2addr)
8925{
8926 store(mkexpr(op2addr), get_fpr_dw0(r1));
8927
8928 return "stdy";
8929}
8930
florian55085f82012-11-21 00:36:55 +00008931static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008932s390_irgen_STFPC(IRTemp op2addr)
8933{
8934 store(mkexpr(op2addr), get_fpc_w0());
8935
8936 return "stfpc";
8937}
8938
florian55085f82012-11-21 00:36:55 +00008939static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008940s390_irgen_AEBR(UChar r1, UChar r2)
8941{
8942 IRTemp op1 = newTemp(Ity_F32);
8943 IRTemp op2 = newTemp(Ity_F32);
8944 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008945 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008946
8947 assign(op1, get_fpr_w0(r1));
8948 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008949 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008950 mkexpr(op2)));
8951 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8952 put_fpr_w0(r1, mkexpr(result));
8953
8954 return "aebr";
8955}
8956
florian55085f82012-11-21 00:36:55 +00008957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008958s390_irgen_ADBR(UChar r1, UChar r2)
8959{
8960 IRTemp op1 = newTemp(Ity_F64);
8961 IRTemp op2 = newTemp(Ity_F64);
8962 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008963 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008964
8965 assign(op1, get_fpr_dw0(r1));
8966 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008967 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008968 mkexpr(op2)));
8969 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8970 put_fpr_dw0(r1, mkexpr(result));
8971
8972 return "adbr";
8973}
8974
florian55085f82012-11-21 00:36:55 +00008975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008976s390_irgen_AEB(UChar r1, IRTemp op2addr)
8977{
8978 IRTemp op1 = newTemp(Ity_F32);
8979 IRTemp op2 = newTemp(Ity_F32);
8980 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008981 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008982
8983 assign(op1, get_fpr_w0(r1));
8984 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008985 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008986 mkexpr(op2)));
8987 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8988 put_fpr_w0(r1, mkexpr(result));
8989
8990 return "aeb";
8991}
8992
florian55085f82012-11-21 00:36:55 +00008993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008994s390_irgen_ADB(UChar r1, IRTemp op2addr)
8995{
8996 IRTemp op1 = newTemp(Ity_F64);
8997 IRTemp op2 = newTemp(Ity_F64);
8998 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008999 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009000
9001 assign(op1, get_fpr_dw0(r1));
9002 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009003 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009004 mkexpr(op2)));
9005 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9006 put_fpr_dw0(r1, mkexpr(result));
9007
9008 return "adb";
9009}
9010
florian55085f82012-11-21 00:36:55 +00009011static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009012s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9013 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009014{
florian125e20d2012-10-07 15:42:37 +00009015 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009016 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009017 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009018 }
sewardj2019a972011-03-07 16:04:07 +00009019 IRTemp op2 = newTemp(Ity_I32);
9020
9021 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009022 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009023 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009024
9025 return "cefbr";
9026}
9027
florian55085f82012-11-21 00:36:55 +00009028static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009029s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9030 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009031{
9032 IRTemp op2 = newTemp(Ity_I32);
9033
9034 assign(op2, get_gpr_w1(r2));
9035 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9036
9037 return "cdfbr";
9038}
9039
florian55085f82012-11-21 00:36:55 +00009040static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009041s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9042 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009043{
florian125e20d2012-10-07 15:42:37 +00009044 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009045 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009046 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009047 }
sewardj2019a972011-03-07 16:04:07 +00009048 IRTemp op2 = newTemp(Ity_I64);
9049
9050 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009051 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009052 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009053
9054 return "cegbr";
9055}
9056
florian55085f82012-11-21 00:36:55 +00009057static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009058s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9059 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009060{
florian125e20d2012-10-07 15:42:37 +00009061 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009062 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009063 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009064 }
sewardj2019a972011-03-07 16:04:07 +00009065 IRTemp op2 = newTemp(Ity_I64);
9066
9067 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009068 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009069 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009070
9071 return "cdgbr";
9072}
9073
florian55085f82012-11-21 00:36:55 +00009074static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009075s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9076 UChar r1, UChar r2)
9077{
floriane75dafa2012-09-01 17:54:09 +00009078 if (! s390_host_has_fpext) {
9079 emulation_failure(EmFail_S390X_fpext);
9080 } else {
9081 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009082
floriane75dafa2012-09-01 17:54:09 +00009083 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009084 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009085 mkexpr(op2)));
9086 }
florian1c8f7ff2012-09-01 00:12:11 +00009087 return "celfbr";
9088}
9089
florian55085f82012-11-21 00:36:55 +00009090static const HChar *
floriand2129202012-09-01 20:01:39 +00009091s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9092 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00009093{
floriane75dafa2012-09-01 17:54:09 +00009094 if (! s390_host_has_fpext) {
9095 emulation_failure(EmFail_S390X_fpext);
9096 } else {
9097 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009098
floriane75dafa2012-09-01 17:54:09 +00009099 assign(op2, get_gpr_w1(r2));
9100 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9101 }
florian1c8f7ff2012-09-01 00:12:11 +00009102 return "cdlfbr";
9103}
9104
florian55085f82012-11-21 00:36:55 +00009105static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009106s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9107 UChar r1, UChar r2)
9108{
floriane75dafa2012-09-01 17:54:09 +00009109 if (! s390_host_has_fpext) {
9110 emulation_failure(EmFail_S390X_fpext);
9111 } else {
9112 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009113
floriane75dafa2012-09-01 17:54:09 +00009114 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009115 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009116 mkexpr(op2)));
9117 }
florian1c8f7ff2012-09-01 00:12:11 +00009118 return "celgbr";
9119}
9120
florian55085f82012-11-21 00:36:55 +00009121static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009122s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9123 UChar r1, UChar r2)
9124{
floriane75dafa2012-09-01 17:54:09 +00009125 if (! s390_host_has_fpext) {
9126 emulation_failure(EmFail_S390X_fpext);
9127 } else {
9128 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009129
floriane75dafa2012-09-01 17:54:09 +00009130 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009131 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9132 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009133 mkexpr(op2)));
9134 }
florian1c8f7ff2012-09-01 00:12:11 +00009135 return "cdlgbr";
9136}
9137
florian55085f82012-11-21 00:36:55 +00009138static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009139s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9140 UChar r1, UChar r2)
9141{
floriane75dafa2012-09-01 17:54:09 +00009142 if (! s390_host_has_fpext) {
9143 emulation_failure(EmFail_S390X_fpext);
9144 } else {
9145 IRTemp op = newTemp(Ity_F32);
9146 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009147 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009148
floriane75dafa2012-09-01 17:54:09 +00009149 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009150 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009151 mkexpr(op)));
9152 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009153 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009154 }
florian1c8f7ff2012-09-01 00:12:11 +00009155 return "clfebr";
9156}
9157
florian55085f82012-11-21 00:36:55 +00009158static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009159s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9160 UChar r1, UChar r2)
9161{
floriane75dafa2012-09-01 17:54:09 +00009162 if (! s390_host_has_fpext) {
9163 emulation_failure(EmFail_S390X_fpext);
9164 } else {
9165 IRTemp op = newTemp(Ity_F64);
9166 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009167 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009168
floriane75dafa2012-09-01 17:54:09 +00009169 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009170 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009171 mkexpr(op)));
9172 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009173 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009174 }
florian1c8f7ff2012-09-01 00:12:11 +00009175 return "clfdbr";
9176}
9177
florian55085f82012-11-21 00:36:55 +00009178static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009179s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9180 UChar r1, UChar r2)
9181{
floriane75dafa2012-09-01 17:54:09 +00009182 if (! s390_host_has_fpext) {
9183 emulation_failure(EmFail_S390X_fpext);
9184 } else {
9185 IRTemp op = newTemp(Ity_F32);
9186 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009187 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009188
floriane75dafa2012-09-01 17:54:09 +00009189 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009190 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009191 mkexpr(op)));
9192 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009193 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009194 }
florian1c8f7ff2012-09-01 00:12:11 +00009195 return "clgebr";
9196}
9197
florian55085f82012-11-21 00:36:55 +00009198static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009199s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9200 UChar r1, UChar r2)
9201{
floriane75dafa2012-09-01 17:54:09 +00009202 if (! s390_host_has_fpext) {
9203 emulation_failure(EmFail_S390X_fpext);
9204 } else {
9205 IRTemp op = newTemp(Ity_F64);
9206 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009207 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009208
floriane75dafa2012-09-01 17:54:09 +00009209 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009210 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009211 mkexpr(op)));
9212 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009213 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009214 }
florian1c8f7ff2012-09-01 00:12:11 +00009215 return "clgdbr";
9216}
9217
florian55085f82012-11-21 00:36:55 +00009218static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009219s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9220 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009221{
9222 IRTemp op = newTemp(Ity_F32);
9223 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009224 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009225
9226 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009227 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009228 mkexpr(op)));
9229 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009230 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009231
9232 return "cfebr";
9233}
9234
florian55085f82012-11-21 00:36:55 +00009235static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009236s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9237 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009238{
9239 IRTemp op = newTemp(Ity_F64);
9240 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009241 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009242
9243 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009244 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009245 mkexpr(op)));
9246 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009247 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009248
9249 return "cfdbr";
9250}
9251
florian55085f82012-11-21 00:36:55 +00009252static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009253s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9254 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009255{
9256 IRTemp op = newTemp(Ity_F32);
9257 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009258 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009259
9260 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009261 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009262 mkexpr(op)));
9263 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009264 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009265
9266 return "cgebr";
9267}
9268
florian55085f82012-11-21 00:36:55 +00009269static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009270s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9271 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009272{
9273 IRTemp op = newTemp(Ity_F64);
9274 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009275 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009276
9277 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009278 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009279 mkexpr(op)));
9280 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009281 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009282
9283 return "cgdbr";
9284}
9285
florian55085f82012-11-21 00:36:55 +00009286static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009287s390_irgen_DEBR(UChar r1, UChar r2)
9288{
9289 IRTemp op1 = newTemp(Ity_F32);
9290 IRTemp op2 = newTemp(Ity_F32);
9291 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009292 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009293
9294 assign(op1, get_fpr_w0(r1));
9295 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009296 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009297 mkexpr(op2)));
9298 put_fpr_w0(r1, mkexpr(result));
9299
9300 return "debr";
9301}
9302
florian55085f82012-11-21 00:36:55 +00009303static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009304s390_irgen_DDBR(UChar r1, UChar r2)
9305{
9306 IRTemp op1 = newTemp(Ity_F64);
9307 IRTemp op2 = newTemp(Ity_F64);
9308 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009309 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009310
9311 assign(op1, get_fpr_dw0(r1));
9312 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009313 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009314 mkexpr(op2)));
9315 put_fpr_dw0(r1, mkexpr(result));
9316
9317 return "ddbr";
9318}
9319
florian55085f82012-11-21 00:36:55 +00009320static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009321s390_irgen_DEB(UChar r1, IRTemp op2addr)
9322{
9323 IRTemp op1 = newTemp(Ity_F32);
9324 IRTemp op2 = newTemp(Ity_F32);
9325 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009326 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009327
9328 assign(op1, get_fpr_w0(r1));
9329 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009330 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009331 mkexpr(op2)));
9332 put_fpr_w0(r1, mkexpr(result));
9333
9334 return "deb";
9335}
9336
florian55085f82012-11-21 00:36:55 +00009337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009338s390_irgen_DDB(UChar r1, IRTemp op2addr)
9339{
9340 IRTemp op1 = newTemp(Ity_F64);
9341 IRTemp op2 = newTemp(Ity_F64);
9342 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009343 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009344
9345 assign(op1, get_fpr_dw0(r1));
9346 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009347 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009348 mkexpr(op2)));
9349 put_fpr_dw0(r1, mkexpr(result));
9350
9351 return "ddb";
9352}
9353
florian55085f82012-11-21 00:36:55 +00009354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009355s390_irgen_LTEBR(UChar r1, UChar r2)
9356{
9357 IRTemp result = newTemp(Ity_F32);
9358
9359 assign(result, get_fpr_w0(r2));
9360 put_fpr_w0(r1, mkexpr(result));
9361 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9362
9363 return "ltebr";
9364}
9365
florian55085f82012-11-21 00:36:55 +00009366static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009367s390_irgen_LTDBR(UChar r1, UChar r2)
9368{
9369 IRTemp result = newTemp(Ity_F64);
9370
9371 assign(result, get_fpr_dw0(r2));
9372 put_fpr_dw0(r1, mkexpr(result));
9373 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9374
9375 return "ltdbr";
9376}
9377
florian55085f82012-11-21 00:36:55 +00009378static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009379s390_irgen_LCEBR(UChar r1, UChar r2)
9380{
9381 IRTemp result = newTemp(Ity_F32);
9382
9383 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9384 put_fpr_w0(r1, mkexpr(result));
9385 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9386
9387 return "lcebr";
9388}
9389
florian55085f82012-11-21 00:36:55 +00009390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009391s390_irgen_LCDBR(UChar r1, UChar r2)
9392{
9393 IRTemp result = newTemp(Ity_F64);
9394
9395 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9396 put_fpr_dw0(r1, mkexpr(result));
9397 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9398
9399 return "lcdbr";
9400}
9401
florian55085f82012-11-21 00:36:55 +00009402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009403s390_irgen_LDEBR(UChar r1, UChar r2)
9404{
9405 IRTemp op = newTemp(Ity_F32);
9406
9407 assign(op, get_fpr_w0(r2));
9408 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9409
9410 return "ldebr";
9411}
9412
florian55085f82012-11-21 00:36:55 +00009413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009414s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9415{
9416 IRTemp op = newTemp(Ity_F32);
9417
9418 assign(op, load(Ity_F32, mkexpr(op2addr)));
9419 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9420
9421 return "ldeb";
9422}
9423
florian55085f82012-11-21 00:36:55 +00009424static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009425s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9426 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009427{
florian125e20d2012-10-07 15:42:37 +00009428 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009429 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009430 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009431 }
sewardj2019a972011-03-07 16:04:07 +00009432 IRTemp op = newTemp(Ity_F64);
9433
9434 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009435 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009436 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009437
9438 return "ledbr";
9439}
9440
florian55085f82012-11-21 00:36:55 +00009441static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009442s390_irgen_MEEBR(UChar r1, UChar r2)
9443{
9444 IRTemp op1 = newTemp(Ity_F32);
9445 IRTemp op2 = newTemp(Ity_F32);
9446 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009447 IRRoundingMode rounding_mode =
9448 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009449
9450 assign(op1, get_fpr_w0(r1));
9451 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009452 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009453 mkexpr(op2)));
9454 put_fpr_w0(r1, mkexpr(result));
9455
9456 return "meebr";
9457}
9458
florian55085f82012-11-21 00:36:55 +00009459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009460s390_irgen_MDBR(UChar r1, UChar r2)
9461{
9462 IRTemp op1 = newTemp(Ity_F64);
9463 IRTemp op2 = newTemp(Ity_F64);
9464 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009465 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009466
9467 assign(op1, get_fpr_dw0(r1));
9468 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009469 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009470 mkexpr(op2)));
9471 put_fpr_dw0(r1, mkexpr(result));
9472
9473 return "mdbr";
9474}
9475
florian55085f82012-11-21 00:36:55 +00009476static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009477s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9478{
9479 IRTemp op1 = newTemp(Ity_F32);
9480 IRTemp op2 = newTemp(Ity_F32);
9481 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009482 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009483
9484 assign(op1, get_fpr_w0(r1));
9485 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009486 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009487 mkexpr(op2)));
9488 put_fpr_w0(r1, mkexpr(result));
9489
9490 return "meeb";
9491}
9492
florian55085f82012-11-21 00:36:55 +00009493static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009494s390_irgen_MDB(UChar r1, IRTemp op2addr)
9495{
9496 IRTemp op1 = newTemp(Ity_F64);
9497 IRTemp op2 = newTemp(Ity_F64);
9498 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009499 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009500
9501 assign(op1, get_fpr_dw0(r1));
9502 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009503 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009504 mkexpr(op2)));
9505 put_fpr_dw0(r1, mkexpr(result));
9506
9507 return "mdb";
9508}
9509
florian55085f82012-11-21 00:36:55 +00009510static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009511s390_irgen_SEBR(UChar r1, UChar r2)
9512{
9513 IRTemp op1 = newTemp(Ity_F32);
9514 IRTemp op2 = newTemp(Ity_F32);
9515 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009516 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009517
9518 assign(op1, get_fpr_w0(r1));
9519 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009520 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009521 mkexpr(op2)));
9522 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9523 put_fpr_w0(r1, mkexpr(result));
9524
9525 return "sebr";
9526}
9527
florian55085f82012-11-21 00:36:55 +00009528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009529s390_irgen_SDBR(UChar r1, UChar r2)
9530{
9531 IRTemp op1 = newTemp(Ity_F64);
9532 IRTemp op2 = newTemp(Ity_F64);
9533 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009534 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009535
9536 assign(op1, get_fpr_dw0(r1));
9537 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009538 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009539 mkexpr(op2)));
9540 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9541 put_fpr_dw0(r1, mkexpr(result));
9542
9543 return "sdbr";
9544}
9545
florian55085f82012-11-21 00:36:55 +00009546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009547s390_irgen_SEB(UChar r1, IRTemp op2addr)
9548{
9549 IRTemp op1 = newTemp(Ity_F32);
9550 IRTemp op2 = newTemp(Ity_F32);
9551 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009552 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009553
9554 assign(op1, get_fpr_w0(r1));
9555 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009556 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009557 mkexpr(op2)));
9558 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9559 put_fpr_w0(r1, mkexpr(result));
9560
9561 return "seb";
9562}
9563
florian55085f82012-11-21 00:36:55 +00009564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009565s390_irgen_SDB(UChar r1, IRTemp op2addr)
9566{
9567 IRTemp op1 = newTemp(Ity_F64);
9568 IRTemp op2 = newTemp(Ity_F64);
9569 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009570 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009571
9572 assign(op1, get_fpr_dw0(r1));
9573 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009574 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009575 mkexpr(op2)));
9576 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9577 put_fpr_dw0(r1, mkexpr(result));
9578
9579 return "sdb";
9580}
9581
florian55085f82012-11-21 00:36:55 +00009582static const HChar *
florian12390202012-11-10 22:34:14 +00009583s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9584{
9585 IRTemp op1 = newTemp(Ity_D64);
9586 IRTemp op2 = newTemp(Ity_D64);
9587 IRTemp result = newTemp(Ity_D64);
9588 IRTemp rounding_mode;
9589
9590 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009591
9592 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9593 emulation_warning(EmWarn_S390X_fpext_rounding);
9594 m4 = S390_DFP_ROUND_PER_FPC_0;
9595 }
9596
florian12390202012-11-10 22:34:14 +00009597 rounding_mode = encode_dfp_rounding_mode(m4);
9598 assign(op1, get_dpr_dw0(r2));
9599 assign(op2, get_dpr_dw0(r3));
9600 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9601 mkexpr(op2)));
9602 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9603 put_dpr_dw0(r1, mkexpr(result));
9604
9605 return (m4 == 0) ? "adtr" : "adtra";
9606}
9607
florian55085f82012-11-21 00:36:55 +00009608static const HChar *
floriane38f6412012-12-21 17:32:12 +00009609s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9610{
9611 IRTemp op1 = newTemp(Ity_D128);
9612 IRTemp op2 = newTemp(Ity_D128);
9613 IRTemp result = newTemp(Ity_D128);
9614 IRTemp rounding_mode;
9615
9616 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009617
9618 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9619 emulation_warning(EmWarn_S390X_fpext_rounding);
9620 m4 = S390_DFP_ROUND_PER_FPC_0;
9621 }
9622
floriane38f6412012-12-21 17:32:12 +00009623 rounding_mode = encode_dfp_rounding_mode(m4);
9624 assign(op1, get_dpr_pair(r2));
9625 assign(op2, get_dpr_pair(r3));
9626 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9627 mkexpr(op2)));
9628 put_dpr_pair(r1, mkexpr(result));
9629
9630 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9631
9632 return (m4 == 0) ? "axtr" : "axtra";
9633}
9634
9635static const HChar *
9636s390_irgen_CDTR(UChar r1, UChar r2)
9637{
9638 IRTemp op1 = newTemp(Ity_D64);
9639 IRTemp op2 = newTemp(Ity_D64);
9640 IRTemp cc_vex = newTemp(Ity_I32);
9641 IRTemp cc_s390 = newTemp(Ity_I32);
9642
9643 assign(op1, get_dpr_dw0(r1));
9644 assign(op2, get_dpr_dw0(r2));
9645 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9646
florian2d3d87f2012-12-21 21:05:17 +00009647 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009648 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9649
9650 return "cdtr";
9651}
9652
9653static const HChar *
9654s390_irgen_CXTR(UChar r1, UChar r2)
9655{
9656 IRTemp op1 = newTemp(Ity_D128);
9657 IRTemp op2 = newTemp(Ity_D128);
9658 IRTemp cc_vex = newTemp(Ity_I32);
9659 IRTemp cc_s390 = newTemp(Ity_I32);
9660
9661 assign(op1, get_dpr_pair(r1));
9662 assign(op2, get_dpr_pair(r2));
9663 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9664
florian2d3d87f2012-12-21 21:05:17 +00009665 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009666 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9667
9668 return "cxtr";
9669}
9670
9671static const HChar *
florian5f034622013-01-13 02:29:05 +00009672s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9673 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9674{
9675 vassert(s390_host_has_dfp);
9676
9677 if (! s390_host_has_fpext) {
9678 emulation_failure(EmFail_S390X_fpext);
9679 } else {
9680 IRTemp op2 = newTemp(Ity_I32);
9681
9682 assign(op2, get_gpr_w1(r2));
9683 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9684 }
9685 return "cdftr";
9686}
9687
9688static const HChar *
9689s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9690 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9691{
9692 vassert(s390_host_has_dfp);
9693
9694 if (! s390_host_has_fpext) {
9695 emulation_failure(EmFail_S390X_fpext);
9696 } else {
9697 IRTemp op2 = newTemp(Ity_I32);
9698
9699 assign(op2, get_gpr_w1(r2));
9700 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9701 }
9702 return "cxftr";
9703}
9704
9705static const HChar *
floriana887acd2013-02-08 23:32:54 +00009706s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9707 UChar r1, UChar r2)
9708{
9709 IRTemp op2 = newTemp(Ity_I64);
9710
9711 vassert(s390_host_has_dfp);
9712 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9713 emulation_warning(EmWarn_S390X_fpext_rounding);
9714 m3 = S390_DFP_ROUND_PER_FPC_0;
9715 }
9716
9717 assign(op2, get_gpr_dw0(r2));
9718 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9719 mkexpr(op2)));
9720
9721 return (m3 == 0) ? "cdgtr" : "cdgtra";
9722}
9723
9724static const HChar *
9725s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9726 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9727{
9728 IRTemp op2 = newTemp(Ity_I64);
9729
9730 vassert(s390_host_has_dfp);
9731
florian1bb7f6f2013-02-11 00:03:27 +00009732 /* No emulation warning here about an non-zero m3 on hosts without
9733 floating point extension facility. No rounding is performed */
9734
floriana887acd2013-02-08 23:32:54 +00009735 assign(op2, get_gpr_dw0(r2));
9736 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9737
9738 return "cxgtr";
9739}
9740
9741static const HChar *
florian5f034622013-01-13 02:29:05 +00009742s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9743 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9744{
9745 vassert(s390_host_has_dfp);
9746
9747 if (! s390_host_has_fpext) {
9748 emulation_failure(EmFail_S390X_fpext);
9749 } else {
9750 IRTemp op2 = newTemp(Ity_I32);
9751
9752 assign(op2, get_gpr_w1(r2));
9753 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9754 }
9755 return "cdlftr";
9756}
9757
9758static const HChar *
9759s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9760 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9761{
9762 vassert(s390_host_has_dfp);
9763
9764 if (! s390_host_has_fpext) {
9765 emulation_failure(EmFail_S390X_fpext);
9766 } else {
9767 IRTemp op2 = newTemp(Ity_I32);
9768
9769 assign(op2, get_gpr_w1(r2));
9770 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9771 }
9772 return "cxlftr";
9773}
9774
9775static const HChar *
9776s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9777 UChar r1, UChar r2)
9778{
9779 vassert(s390_host_has_dfp);
9780
9781 if (! s390_host_has_fpext) {
9782 emulation_failure(EmFail_S390X_fpext);
9783 } else {
9784 IRTemp op2 = newTemp(Ity_I64);
9785
9786 assign(op2, get_gpr_dw0(r2));
9787 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9788 mkexpr(encode_dfp_rounding_mode(m3)),
9789 mkexpr(op2)));
9790 }
9791 return "cdlgtr";
9792}
9793
9794static const HChar *
9795s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9796 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9797{
9798 vassert(s390_host_has_dfp);
9799
9800 if (! s390_host_has_fpext) {
9801 emulation_failure(EmFail_S390X_fpext);
9802 } else {
9803 IRTemp op2 = newTemp(Ity_I64);
9804
9805 assign(op2, get_gpr_dw0(r2));
9806 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9807 }
9808 return "cxlgtr";
9809}
9810
9811static const HChar *
9812s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9813 UChar r1, UChar r2)
9814{
9815 vassert(s390_host_has_dfp);
9816
9817 if (! s390_host_has_fpext) {
9818 emulation_failure(EmFail_S390X_fpext);
9819 } else {
9820 IRTemp op = newTemp(Ity_D64);
9821 IRTemp result = newTemp(Ity_I32);
9822 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9823
9824 assign(op, get_dpr_dw0(r2));
9825 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9826 mkexpr(op)));
9827 put_gpr_w1(r1, mkexpr(result));
9828 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9829 }
9830 return "cfdtr";
9831}
9832
9833static const HChar *
9834s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9835 UChar r1, UChar r2)
9836{
9837 vassert(s390_host_has_dfp);
9838
9839 if (! s390_host_has_fpext) {
9840 emulation_failure(EmFail_S390X_fpext);
9841 } else {
9842 IRTemp op = newTemp(Ity_D128);
9843 IRTemp result = newTemp(Ity_I32);
9844 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9845
9846 assign(op, get_dpr_pair(r2));
9847 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9848 mkexpr(op)));
9849 put_gpr_w1(r1, mkexpr(result));
9850 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9851 }
9852 return "cfxtr";
9853}
9854
9855static const HChar *
floriana887acd2013-02-08 23:32:54 +00009856s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9857 UChar r1, UChar r2)
9858{
9859 IRTemp op = newTemp(Ity_D64);
9860 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9861
9862 vassert(s390_host_has_dfp);
9863
9864 /* If fpext is not installed and m3 is in 1:7,
9865 rounding mode performed is unpredictable */
9866 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9867 emulation_warning(EmWarn_S390X_fpext_rounding);
9868 m3 = S390_DFP_ROUND_PER_FPC_0;
9869 }
9870
9871 assign(op, get_dpr_dw0(r2));
9872 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9873 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9874
9875 return "cgdtr";
9876}
9877
9878static const HChar *
9879s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9880 UChar r1, UChar r2)
9881{
9882 IRTemp op = newTemp(Ity_D128);
9883 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9884
9885 vassert(s390_host_has_dfp);
9886
9887 /* If fpext is not installed and m3 is in 1:7,
9888 rounding mode performed is unpredictable */
9889 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9890 emulation_warning(EmWarn_S390X_fpext_rounding);
9891 m3 = S390_DFP_ROUND_PER_FPC_0;
9892 }
9893 assign(op, get_dpr_pair(r2));
9894 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9895 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9896
9897 return "cgxtr";
9898}
9899
9900static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009901s390_irgen_CEDTR(UChar r1, UChar r2)
9902{
9903 IRTemp op1 = newTemp(Ity_D64);
9904 IRTemp op2 = newTemp(Ity_D64);
9905 IRTemp cc_vex = newTemp(Ity_I32);
9906 IRTemp cc_s390 = newTemp(Ity_I32);
9907
9908 vassert(s390_host_has_dfp);
9909 assign(op1, get_dpr_dw0(r1));
9910 assign(op2, get_dpr_dw0(r2));
9911 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9912
9913 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9914 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9915
9916 return "cedtr";
9917}
9918
9919static const HChar *
9920s390_irgen_CEXTR(UChar r1, UChar r2)
9921{
9922 IRTemp op1 = newTemp(Ity_D128);
9923 IRTemp op2 = newTemp(Ity_D128);
9924 IRTemp cc_vex = newTemp(Ity_I32);
9925 IRTemp cc_s390 = newTemp(Ity_I32);
9926
9927 vassert(s390_host_has_dfp);
9928 assign(op1, get_dpr_pair(r1));
9929 assign(op2, get_dpr_pair(r2));
9930 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9931
9932 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9933 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9934
9935 return "cextr";
9936}
9937
9938static const HChar *
florian5f034622013-01-13 02:29:05 +00009939s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9940 UChar r1, UChar r2)
9941{
9942 vassert(s390_host_has_dfp);
9943
9944 if (! s390_host_has_fpext) {
9945 emulation_failure(EmFail_S390X_fpext);
9946 } else {
9947 IRTemp op = newTemp(Ity_D64);
9948 IRTemp result = newTemp(Ity_I32);
9949 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9950
9951 assign(op, get_dpr_dw0(r2));
9952 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9953 mkexpr(op)));
9954 put_gpr_w1(r1, mkexpr(result));
9955 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9956 }
9957 return "clfdtr";
9958}
9959
9960static const HChar *
9961s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9962 UChar r1, UChar r2)
9963{
9964 vassert(s390_host_has_dfp);
9965
9966 if (! s390_host_has_fpext) {
9967 emulation_failure(EmFail_S390X_fpext);
9968 } else {
9969 IRTemp op = newTemp(Ity_D128);
9970 IRTemp result = newTemp(Ity_I32);
9971 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9972
9973 assign(op, get_dpr_pair(r2));
9974 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9975 mkexpr(op)));
9976 put_gpr_w1(r1, mkexpr(result));
9977 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9978 }
9979 return "clfxtr";
9980}
9981
9982static const HChar *
9983s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9984 UChar r1, UChar r2)
9985{
9986 vassert(s390_host_has_dfp);
9987
9988 if (! s390_host_has_fpext) {
9989 emulation_failure(EmFail_S390X_fpext);
9990 } else {
9991 IRTemp op = newTemp(Ity_D64);
9992 IRTemp result = newTemp(Ity_I64);
9993 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9994
9995 assign(op, get_dpr_dw0(r2));
9996 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
9997 mkexpr(op)));
9998 put_gpr_dw0(r1, mkexpr(result));
9999 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10000 }
10001 return "clgdtr";
10002}
10003
10004static const HChar *
10005s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10006 UChar r1, UChar r2)
10007{
10008 vassert(s390_host_has_dfp);
10009
10010 if (! s390_host_has_fpext) {
10011 emulation_failure(EmFail_S390X_fpext);
10012 } else {
10013 IRTemp op = newTemp(Ity_D128);
10014 IRTemp result = newTemp(Ity_I64);
10015 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10016
10017 assign(op, get_dpr_pair(r2));
10018 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10019 mkexpr(op)));
10020 put_gpr_dw0(r1, mkexpr(result));
10021 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10022 rounding_mode);
10023 }
10024 return "clgxtr";
10025}
10026
10027static const HChar *
florian12390202012-11-10 22:34:14 +000010028s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10029{
10030 IRTemp op1 = newTemp(Ity_D64);
10031 IRTemp op2 = newTemp(Ity_D64);
10032 IRTemp result = newTemp(Ity_D64);
10033 IRTemp rounding_mode;
10034
10035 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010036
10037 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10038 emulation_warning(EmWarn_S390X_fpext_rounding);
10039 m4 = S390_DFP_ROUND_PER_FPC_0;
10040 }
10041
florian12390202012-11-10 22:34:14 +000010042 rounding_mode = encode_dfp_rounding_mode(m4);
10043 assign(op1, get_dpr_dw0(r2));
10044 assign(op2, get_dpr_dw0(r3));
10045 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10046 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010047 put_dpr_dw0(r1, mkexpr(result));
10048
10049 return (m4 == 0) ? "ddtr" : "ddtra";
10050}
10051
florian55085f82012-11-21 00:36:55 +000010052static const HChar *
floriane38f6412012-12-21 17:32:12 +000010053s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10054{
10055 IRTemp op1 = newTemp(Ity_D128);
10056 IRTemp op2 = newTemp(Ity_D128);
10057 IRTemp result = newTemp(Ity_D128);
10058 IRTemp rounding_mode;
10059
10060 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010061
10062 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10063 emulation_warning(EmWarn_S390X_fpext_rounding);
10064 m4 = S390_DFP_ROUND_PER_FPC_0;
10065 }
10066
floriane38f6412012-12-21 17:32:12 +000010067 rounding_mode = encode_dfp_rounding_mode(m4);
10068 assign(op1, get_dpr_pair(r2));
10069 assign(op2, get_dpr_pair(r3));
10070 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10071 mkexpr(op2)));
10072 put_dpr_pair(r1, mkexpr(result));
10073
10074 return (m4 == 0) ? "dxtr" : "dxtra";
10075}
10076
10077static const HChar *
florian5c539732013-02-14 14:27:12 +000010078s390_irgen_EEDTR(UChar r1, UChar r2)
10079{
10080 vassert(s390_host_has_dfp);
10081
10082 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10083 return "eedtr";
10084}
10085
10086static const HChar *
10087s390_irgen_EEXTR(UChar r1, UChar r2)
10088{
10089 vassert(s390_host_has_dfp);
10090
10091 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10092 return "eextr";
10093}
10094
10095static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010096s390_irgen_ESDTR(UChar r1, UChar r2)
10097{
10098 vassert(s390_host_has_dfp);
10099 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10100 return "esdtr";
10101}
10102
10103static const HChar *
10104s390_irgen_ESXTR(UChar r1, UChar r2)
10105{
10106 vassert(s390_host_has_dfp);
10107 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10108 return "esxtr";
10109}
10110
10111static const HChar *
florian5c539732013-02-14 14:27:12 +000010112s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10113{
10114 IRTemp op1 = newTemp(Ity_I64);
10115 IRTemp op2 = newTemp(Ity_D64);
10116 IRTemp result = newTemp(Ity_D64);
10117
10118 vassert(s390_host_has_dfp);
10119
10120 assign(op1, get_gpr_dw0(r2));
10121 assign(op2, get_dpr_dw0(r3));
10122 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10123 put_dpr_dw0(r1, mkexpr(result));
10124
10125 return "iedtr";
10126}
10127
10128static const HChar *
10129s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10130{
10131 IRTemp op1 = newTemp(Ity_I64);
10132 IRTemp op2 = newTemp(Ity_D128);
10133 IRTemp result = newTemp(Ity_D128);
10134
10135 vassert(s390_host_has_dfp);
10136
10137 assign(op1, get_gpr_dw0(r2));
10138 assign(op2, get_dpr_pair(r3));
10139 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10140 put_dpr_pair(r1, mkexpr(result));
10141
10142 return "iextr";
10143}
10144
10145static const HChar *
floriane38f6412012-12-21 17:32:12 +000010146s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10147{
10148 IRTemp op = newTemp(Ity_D32);
10149
10150 vassert(s390_host_has_dfp);
10151
10152 assign(op, get_dpr_w0(r2));
10153 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10154
10155 return "ldetr";
10156}
10157
10158static const HChar *
10159s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10160{
10161 IRTemp op = newTemp(Ity_D64);
10162
10163 assign(op, get_dpr_dw0(r2));
10164 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10165
10166 return "lxdtr";
10167}
10168
10169static const HChar *
10170s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10171 UChar r1, UChar r2)
10172{
10173 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010174
10175 /* If fpext is not installed and m3 is in 1:7,
10176 rounding mode performed is unpredictable */
10177 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010178 emulation_warning(EmWarn_S390X_fpext_rounding);
10179 m3 = S390_DFP_ROUND_PER_FPC_0;
10180 }
10181 IRTemp result = newTemp(Ity_D64);
10182
10183 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10184 get_dpr_pair(r2)));
10185 put_dpr_dw0(r1, mkexpr(result));
10186
10187 return "ldxtr";
10188}
10189
10190static const HChar *
10191s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10192 UChar r1, UChar r2)
10193{
10194 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010195
10196 /* If fpext is not installed and m3 is in 1:7,
10197 rounding mode performed is unpredictable */
10198 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010199 emulation_warning(EmWarn_S390X_fpext_rounding);
10200 m3 = S390_DFP_ROUND_PER_FPC_0;
10201 }
10202 IRTemp op = newTemp(Ity_D64);
10203
10204 assign(op, get_dpr_dw0(r2));
10205 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10206 mkexpr(op)));
10207
10208 return "ledtr";
10209}
10210
10211static const HChar *
10212s390_irgen_LTDTR(UChar r1, UChar r2)
10213{
10214 IRTemp result = newTemp(Ity_D64);
10215
10216 assign(result, get_dpr_dw0(r2));
10217 put_dpr_dw0(r1, mkexpr(result));
10218 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10219
10220 return "ltdtr";
10221}
10222
10223static const HChar *
10224s390_irgen_LTXTR(UChar r1, UChar r2)
10225{
10226 IRTemp result = newTemp(Ity_D128);
10227
10228 assign(result, get_dpr_pair(r2));
10229 put_dpr_pair(r1, mkexpr(result));
10230 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10231
10232 return "ltxtr";
10233}
10234
10235static const HChar *
florian12390202012-11-10 22:34:14 +000010236s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10237{
10238 IRTemp op1 = newTemp(Ity_D64);
10239 IRTemp op2 = newTemp(Ity_D64);
10240 IRTemp result = newTemp(Ity_D64);
10241 IRTemp rounding_mode;
10242
10243 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010244
10245 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10246 emulation_warning(EmWarn_S390X_fpext_rounding);
10247 m4 = S390_DFP_ROUND_PER_FPC_0;
10248 }
10249
florian12390202012-11-10 22:34:14 +000010250 rounding_mode = encode_dfp_rounding_mode(m4);
10251 assign(op1, get_dpr_dw0(r2));
10252 assign(op2, get_dpr_dw0(r3));
10253 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10254 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010255 put_dpr_dw0(r1, mkexpr(result));
10256
10257 return (m4 == 0) ? "mdtr" : "mdtra";
10258}
10259
florian55085f82012-11-21 00:36:55 +000010260static const HChar *
floriane38f6412012-12-21 17:32:12 +000010261s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10262{
10263 IRTemp op1 = newTemp(Ity_D128);
10264 IRTemp op2 = newTemp(Ity_D128);
10265 IRTemp result = newTemp(Ity_D128);
10266 IRTemp rounding_mode;
10267
10268 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010269
10270 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10271 emulation_warning(EmWarn_S390X_fpext_rounding);
10272 m4 = S390_DFP_ROUND_PER_FPC_0;
10273 }
10274
floriane38f6412012-12-21 17:32:12 +000010275 rounding_mode = encode_dfp_rounding_mode(m4);
10276 assign(op1, get_dpr_pair(r2));
10277 assign(op2, get_dpr_pair(r3));
10278 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10279 mkexpr(op2)));
10280 put_dpr_pair(r1, mkexpr(result));
10281
10282 return (m4 == 0) ? "mxtr" : "mxtra";
10283}
10284
10285static const HChar *
florian5c539732013-02-14 14:27:12 +000010286s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10287{
10288 IRTemp op1 = newTemp(Ity_D64);
10289 IRTemp op2 = newTemp(Ity_D64);
10290 IRTemp result = newTemp(Ity_D64);
10291 IRTemp rounding_mode;
10292
10293 vassert(s390_host_has_dfp);
10294 /* If fpext is not installed and m4 is in 1:7,
10295 rounding mode performed is unpredictable */
10296 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10297 emulation_warning(EmWarn_S390X_fpext_rounding);
10298 m4 = S390_DFP_ROUND_PER_FPC_0;
10299 }
10300
10301 rounding_mode = encode_dfp_rounding_mode(m4);
10302 assign(op1, get_dpr_dw0(r2));
10303 assign(op2, get_dpr_dw0(r3));
10304 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10305 mkexpr(op2)));
10306 put_dpr_dw0(r1, mkexpr(result));
10307
10308 return "qadtr";
10309}
10310
10311static const HChar *
10312s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10313{
10314 IRTemp op1 = newTemp(Ity_D128);
10315 IRTemp op2 = newTemp(Ity_D128);
10316 IRTemp result = newTemp(Ity_D128);
10317 IRTemp rounding_mode;
10318
10319 vassert(s390_host_has_dfp);
10320 /* If fpext is not installed and m4 is in 1:7,
10321 rounding mode performed is unpredictable */
10322 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10323 emulation_warning(EmWarn_S390X_fpext_rounding);
10324 m4 = S390_DFP_ROUND_PER_FPC_0;
10325 }
10326
10327 rounding_mode = encode_dfp_rounding_mode(m4);
10328 assign(op1, get_dpr_pair(r2));
10329 assign(op2, get_dpr_pair(r3));
10330 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10331 mkexpr(op2)));
10332 put_dpr_pair(r1, mkexpr(result));
10333
10334 return "qaxtr";
10335}
10336
10337static const HChar *
10338s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10339{
10340 IRTemp op1 = newTemp(Ity_I8);
10341 IRTemp op2 = newTemp(Ity_D64);
10342 IRTemp result = newTemp(Ity_D64);
10343 IRTemp rounding_mode;
10344
10345 vassert(s390_host_has_dfp);
10346 /* If fpext is not installed and m4 is in 1:7,
10347 rounding mode performed is unpredictable */
10348 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10349 emulation_warning(EmWarn_S390X_fpext_rounding);
10350 m4 = S390_DFP_ROUND_PER_FPC_0;
10351 }
10352
10353 rounding_mode = encode_dfp_rounding_mode(m4);
10354 assign(op1, get_gpr_b7(r2));
10355 assign(op2, get_dpr_dw0(r3));
10356 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10357 mkexpr(op1), mkexpr(op2)));
10358 put_dpr_dw0(r1, mkexpr(result));
10359
10360 return "rrdtr";
10361}
10362
10363static const HChar *
10364s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10365{
10366 IRTemp op1 = newTemp(Ity_I8);
10367 IRTemp op2 = newTemp(Ity_D128);
10368 IRTemp result = newTemp(Ity_D128);
10369 IRTemp rounding_mode;
10370
10371 vassert(s390_host_has_dfp);
10372 /* If fpext is not installed and m4 is in 1:7,
10373 rounding mode performed is unpredictable */
10374 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10375 emulation_warning(EmWarn_S390X_fpext_rounding);
10376 m4 = S390_DFP_ROUND_PER_FPC_0;
10377 }
10378
10379 rounding_mode = encode_dfp_rounding_mode(m4);
10380 assign(op1, get_gpr_b7(r2));
10381 assign(op2, get_dpr_pair(r3));
10382 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10383 mkexpr(op1), mkexpr(op2)));
10384 put_dpr_pair(r1, mkexpr(result));
10385
10386 return "rrxtr";
10387}
10388
10389static const HChar *
florian12390202012-11-10 22:34:14 +000010390s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10391{
10392 IRTemp op1 = newTemp(Ity_D64);
10393 IRTemp op2 = newTemp(Ity_D64);
10394 IRTemp result = newTemp(Ity_D64);
10395 IRTemp rounding_mode;
10396
10397 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010398
10399 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10400 emulation_warning(EmWarn_S390X_fpext_rounding);
10401 m4 = S390_DFP_ROUND_PER_FPC_0;
10402 }
10403
florian12390202012-11-10 22:34:14 +000010404 rounding_mode = encode_dfp_rounding_mode(m4);
10405 assign(op1, get_dpr_dw0(r2));
10406 assign(op2, get_dpr_dw0(r3));
10407 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10408 mkexpr(op2)));
10409 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10410 put_dpr_dw0(r1, mkexpr(result));
10411
10412 return (m4 == 0) ? "sdtr" : "sdtra";
10413}
10414
floriane38f6412012-12-21 17:32:12 +000010415static const HChar *
10416s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10417{
10418 IRTemp op1 = newTemp(Ity_D128);
10419 IRTemp op2 = newTemp(Ity_D128);
10420 IRTemp result = newTemp(Ity_D128);
10421 IRTemp rounding_mode;
10422
10423 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010424
10425 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10426 emulation_warning(EmWarn_S390X_fpext_rounding);
10427 m4 = S390_DFP_ROUND_PER_FPC_0;
10428 }
10429
floriane38f6412012-12-21 17:32:12 +000010430 rounding_mode = encode_dfp_rounding_mode(m4);
10431 assign(op1, get_dpr_pair(r2));
10432 assign(op2, get_dpr_pair(r3));
10433 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10434 mkexpr(op2)));
10435 put_dpr_pair(r1, mkexpr(result));
10436
10437 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10438
10439 return (m4 == 0) ? "sxtr" : "sxtra";
10440}
sewardj2019a972011-03-07 16:04:07 +000010441
florian55085f82012-11-21 00:36:55 +000010442static const HChar *
florian1b901d42013-01-01 22:19:24 +000010443s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10444{
10445 IRTemp op = newTemp(Ity_D64);
10446
10447 vassert(s390_host_has_dfp);
10448
10449 assign(op, get_dpr_dw0(r3));
10450 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
10451 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10452
10453 return "sldt";
10454}
10455
10456static const HChar *
10457s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10458{
10459 IRTemp op = newTemp(Ity_D128);
10460
10461 vassert(s390_host_has_dfp);
10462
10463 assign(op, get_dpr_pair(r3));
10464 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
10465 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10466
10467 return "slxt";
10468}
10469
10470static const HChar *
10471s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10472{
10473 IRTemp op = newTemp(Ity_D64);
10474
10475 vassert(s390_host_has_dfp);
10476
10477 assign(op, get_dpr_dw0(r3));
10478 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
10479 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10480
10481 return "srdt";
10482}
10483
10484static const HChar *
10485s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10486{
10487 IRTemp op = newTemp(Ity_D128);
10488
10489 vassert(s390_host_has_dfp);
10490
10491 assign(op, get_dpr_pair(r3));
10492 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
10493 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10494
10495 return "srxt";
10496}
10497
10498static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010499s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10500{
10501 IRTemp value = newTemp(Ity_D32);
10502
10503 vassert(s390_host_has_dfp);
10504 assign(value, get_dpr_w0(r1));
10505
10506 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10507
10508 return "tdcet";
10509}
10510
10511static const HChar *
10512s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10513{
10514 IRTemp value = newTemp(Ity_D64);
10515
10516 vassert(s390_host_has_dfp);
10517 assign(value, get_dpr_dw0(r1));
10518
10519 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10520
10521 return "tdcdt";
10522}
10523
10524static const HChar *
10525s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10526{
10527 IRTemp value = newTemp(Ity_D128);
10528
10529 vassert(s390_host_has_dfp);
10530 assign(value, get_dpr_pair(r1));
10531
10532 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10533
10534 return "tdcxt";
10535}
10536
10537static const HChar *
10538s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10539{
10540 IRTemp value = newTemp(Ity_D32);
10541
10542 vassert(s390_host_has_dfp);
10543 assign(value, get_dpr_w0(r1));
10544
10545 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10546
10547 return "tdget";
10548}
10549
10550static const HChar *
10551s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10552{
10553 IRTemp value = newTemp(Ity_D64);
10554
10555 vassert(s390_host_has_dfp);
10556 assign(value, get_dpr_dw0(r1));
10557
10558 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10559
10560 return "tdgdt";
10561}
10562
10563static const HChar *
10564s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10565{
10566 IRTemp value = newTemp(Ity_D128);
10567
10568 vassert(s390_host_has_dfp);
10569 assign(value, get_dpr_pair(r1));
10570
10571 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10572
10573 return "tdgxt";
10574}
10575
10576static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010577s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10578{
florian79e839e2012-05-05 02:20:30 +000010579 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010580
florian79e839e2012-05-05 02:20:30 +000010581 assign(len, mkU64(length));
10582 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010583
10584 return "clc";
10585}
10586
florian55085f82012-11-21 00:36:55 +000010587static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010588s390_irgen_CLCL(UChar r1, UChar r2)
10589{
10590 IRTemp addr1 = newTemp(Ity_I64);
10591 IRTemp addr2 = newTemp(Ity_I64);
10592 IRTemp addr1_load = newTemp(Ity_I64);
10593 IRTemp addr2_load = newTemp(Ity_I64);
10594 IRTemp len1 = newTemp(Ity_I32);
10595 IRTemp len2 = newTemp(Ity_I32);
10596 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10597 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10598 IRTemp single1 = newTemp(Ity_I8);
10599 IRTemp single2 = newTemp(Ity_I8);
10600 IRTemp pad = newTemp(Ity_I8);
10601
10602 assign(addr1, get_gpr_dw0(r1));
10603 assign(r1p1, get_gpr_w1(r1 + 1));
10604 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10605 assign(addr2, get_gpr_dw0(r2));
10606 assign(r2p1, get_gpr_w1(r2 + 1));
10607 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10608 assign(pad, get_gpr_b4(r2 + 1));
10609
10610 /* len1 == 0 and len2 == 0? Exit */
10611 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010612 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10613 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010614
10615 /* Because mkite evaluates both the then-clause and the else-clause
10616 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10617 may be NULL and loading from there would segfault. So we provide a
10618 valid dummy address in that case. Loading from there does no harm and
10619 the value will be discarded at runtime. */
10620 assign(addr1_load,
10621 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10622 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10623 assign(single1,
10624 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10625 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10626
10627 assign(addr2_load,
10628 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10629 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10630 assign(single2,
10631 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10632 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10633
10634 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10635 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010636 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010637
10638 /* Update len1 and addr1, unless len1 == 0. */
10639 put_gpr_dw0(r1,
10640 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10641 mkexpr(addr1),
10642 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10643
10644 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10645 put_gpr_w1(r1 + 1,
10646 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10647 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10648 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10649
10650 /* Update len2 and addr2, unless len2 == 0. */
10651 put_gpr_dw0(r2,
10652 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10653 mkexpr(addr2),
10654 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10655
10656 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10657 put_gpr_w1(r2 + 1,
10658 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10659 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10660 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10661
florian6820ba52012-07-26 02:01:50 +000010662 iterate();
florianb0c9a132011-09-08 15:37:39 +000010663
10664 return "clcl";
10665}
10666
florian55085f82012-11-21 00:36:55 +000010667static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010668s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10669{
10670 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10671
10672 addr1 = newTemp(Ity_I64);
10673 addr3 = newTemp(Ity_I64);
10674 addr1_load = newTemp(Ity_I64);
10675 addr3_load = newTemp(Ity_I64);
10676 len1 = newTemp(Ity_I64);
10677 len3 = newTemp(Ity_I64);
10678 single1 = newTemp(Ity_I8);
10679 single3 = newTemp(Ity_I8);
10680
10681 assign(addr1, get_gpr_dw0(r1));
10682 assign(len1, get_gpr_dw0(r1 + 1));
10683 assign(addr3, get_gpr_dw0(r3));
10684 assign(len3, get_gpr_dw0(r3 + 1));
10685
10686 /* len1 == 0 and len3 == 0? Exit */
10687 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010688 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10689 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010690
10691 /* A mux requires both ways to be possible. This is a way to prevent clcle
10692 from reading from addr1 if it should read from the pad. Since the pad
10693 has no address, just read from the instruction, we discard that anyway */
10694 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010695 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10696 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010697
10698 /* same for addr3 */
10699 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010700 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10701 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010702
10703 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010704 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10705 unop(Iop_64to8, mkexpr(pad2)),
10706 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010707
10708 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010709 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10710 unop(Iop_64to8, mkexpr(pad2)),
10711 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010712
10713 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10714 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010715 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010716
10717 /* If a length in 0 we must not change this length and the address */
10718 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010719 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10720 mkexpr(addr1),
10721 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010722
10723 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010724 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10725 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010726
10727 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010728 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10729 mkexpr(addr3),
10730 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010731
10732 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010733 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10734 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010735
florian6820ba52012-07-26 02:01:50 +000010736 iterate();
sewardj2019a972011-03-07 16:04:07 +000010737
10738 return "clcle";
10739}
floriana64c2432011-07-16 02:11:50 +000010740
florianb0bf6602012-05-05 00:01:16 +000010741
sewardj2019a972011-03-07 16:04:07 +000010742static void
10743s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10744{
florianb0bf6602012-05-05 00:01:16 +000010745 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10746}
sewardj2019a972011-03-07 16:04:07 +000010747
sewardj2019a972011-03-07 16:04:07 +000010748
florianb0bf6602012-05-05 00:01:16 +000010749static void
10750s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10751{
10752 s390_irgen_xonc(Iop_And8, length, start1, start2);
10753}
sewardj2019a972011-03-07 16:04:07 +000010754
sewardj2019a972011-03-07 16:04:07 +000010755
florianb0bf6602012-05-05 00:01:16 +000010756static void
10757s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10758{
10759 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010760}
10761
10762
10763static void
10764s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10765{
10766 IRTemp current1 = newTemp(Ity_I8);
10767 IRTemp current2 = newTemp(Ity_I8);
10768 IRTemp counter = newTemp(Ity_I64);
10769
10770 assign(counter, get_counter_dw0());
10771 put_counter_dw0(mkU64(0));
10772
10773 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10774 mkexpr(counter))));
10775 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10776 mkexpr(counter))));
10777 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10778 False);
10779
10780 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010781 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010782
10783 /* Check for end of field */
10784 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010785 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010786 put_counter_dw0(mkU64(0));
10787}
10788
10789static void
10790s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10791{
10792 IRTemp counter = newTemp(Ity_I64);
10793
10794 assign(counter, get_counter_dw0());
10795
10796 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10797 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10798
10799 /* Check for end of field */
10800 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010801 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010802 put_counter_dw0(mkU64(0));
10803}
10804
florianf87d4fb2012-05-05 02:55:24 +000010805static void
10806s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10807{
10808 IRTemp op = newTemp(Ity_I8);
10809 IRTemp op1 = newTemp(Ity_I8);
10810 IRTemp result = newTemp(Ity_I64);
10811 IRTemp counter = newTemp(Ity_I64);
10812
10813 assign(counter, get_counter_dw0());
10814
10815 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10816
10817 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10818
10819 assign(op1, load(Ity_I8, mkexpr(result)));
10820 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10821
10822 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010823 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010824 put_counter_dw0(mkU64(0));
10825}
sewardj2019a972011-03-07 16:04:07 +000010826
10827
10828static void
10829s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010830 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010831 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010832{
10833 struct SS {
10834 unsigned int op : 8;
10835 unsigned int l : 8;
10836 unsigned int b1 : 4;
10837 unsigned int d1 : 12;
10838 unsigned int b2 : 4;
10839 unsigned int d2 : 12;
10840 };
10841 union {
10842 struct SS dec;
10843 unsigned long bytes;
10844 } ss;
10845 IRTemp cond;
10846 IRDirty *d;
10847 IRTemp torun;
10848
10849 IRTemp start1 = newTemp(Ity_I64);
10850 IRTemp start2 = newTemp(Ity_I64);
10851 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10852 cond = newTemp(Ity_I1);
10853 torun = newTemp(Ity_I64);
10854
10855 assign(torun, load(Ity_I64, mkexpr(addr2)));
10856 /* Start with a check that the saved code is still correct */
10857 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10858 /* If not, save the new value */
10859 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10860 mkIRExprVec_1(mkexpr(torun)));
10861 d->guard = mkexpr(cond);
10862 stmt(IRStmt_Dirty(d));
10863
10864 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010865 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10866 mkU64(guest_IA_curr_instr)));
10867 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010868 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010869
10870 ss.bytes = last_execute_target;
10871 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10872 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10873 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10874 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10875 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10876 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10877 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010878
sewardj2019a972011-03-07 16:04:07 +000010879 last_execute_target = 0;
10880}
10881
florian55085f82012-11-21 00:36:55 +000010882static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010883s390_irgen_EX(UChar r1, IRTemp addr2)
10884{
10885 switch(last_execute_target & 0xff00000000000000ULL) {
10886 case 0:
10887 {
10888 /* no code information yet */
10889 IRDirty *d;
10890
10891 /* so safe the code... */
10892 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10893 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10894 stmt(IRStmt_Dirty(d));
10895 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010896 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10897 mkU64(guest_IA_curr_instr)));
10898 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010899 restart_if(IRExpr_Const(IRConst_U1(True)));
10900
sewardj2019a972011-03-07 16:04:07 +000010901 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010902 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010903 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000010904 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000010905 break;
10906 }
10907
10908 case 0xd200000000000000ULL:
10909 /* special case MVC */
10910 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010911 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010912
10913 case 0xd500000000000000ULL:
10914 /* special case CLC */
10915 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010916 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010917
10918 case 0xd700000000000000ULL:
10919 /* special case XC */
10920 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010921 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010922
florianb0bf6602012-05-05 00:01:16 +000010923 case 0xd600000000000000ULL:
10924 /* special case OC */
10925 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010926 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010927
10928 case 0xd400000000000000ULL:
10929 /* special case NC */
10930 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010931 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010932
florianf87d4fb2012-05-05 02:55:24 +000010933 case 0xdc00000000000000ULL:
10934 /* special case TR */
10935 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010936 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010937
sewardj2019a972011-03-07 16:04:07 +000010938 default:
10939 {
10940 /* everything else will get a self checking prefix that also checks the
10941 register content */
10942 IRDirty *d;
10943 UChar *bytes;
10944 IRTemp cond;
10945 IRTemp orperand;
10946 IRTemp torun;
10947
10948 cond = newTemp(Ity_I1);
10949 orperand = newTemp(Ity_I64);
10950 torun = newTemp(Ity_I64);
10951
10952 if (r1 == 0)
10953 assign(orperand, mkU64(0));
10954 else
10955 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10956 /* This code is going to be translated */
10957 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10958 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10959
10960 /* Start with a check that saved code is still correct */
10961 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10962 mkU64(last_execute_target)));
10963 /* If not, save the new value */
10964 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10965 mkIRExprVec_1(mkexpr(torun)));
10966 d->guard = mkexpr(cond);
10967 stmt(IRStmt_Dirty(d));
10968
10969 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010970 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10971 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010972 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010973
10974 /* Now comes the actual translation */
10975 bytes = (UChar *) &last_execute_target;
10976 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10977 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010978 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010979 vex_printf(" which was executed by\n");
10980 /* dont make useless translations in the next execute */
10981 last_execute_target = 0;
10982 }
10983 }
10984 return "ex";
10985}
10986
florian55085f82012-11-21 00:36:55 +000010987static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010988s390_irgen_EXRL(UChar r1, UInt offset)
10989{
10990 IRTemp addr = newTemp(Ity_I64);
10991 /* we might save one round trip because we know the target */
10992 if (!last_execute_target)
10993 last_execute_target = *(ULong *)(HWord)
10994 (guest_IA_curr_instr + offset * 2UL);
10995 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10996 s390_irgen_EX(r1, addr);
10997 return "exrl";
10998}
10999
florian55085f82012-11-21 00:36:55 +000011000static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011001s390_irgen_IPM(UChar r1)
11002{
11003 // As long as we dont support SPM, lets just assume 0 as program mask
11004 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11005 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11006
11007 return "ipm";
11008}
11009
11010
florian55085f82012-11-21 00:36:55 +000011011static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011012s390_irgen_SRST(UChar r1, UChar r2)
11013{
11014 IRTemp address = newTemp(Ity_I64);
11015 IRTemp next = newTemp(Ity_I64);
11016 IRTemp delim = newTemp(Ity_I8);
11017 IRTemp counter = newTemp(Ity_I64);
11018 IRTemp byte = newTemp(Ity_I8);
11019
11020 assign(address, get_gpr_dw0(r2));
11021 assign(next, get_gpr_dw0(r1));
11022
11023 assign(counter, get_counter_dw0());
11024 put_counter_dw0(mkU64(0));
11025
11026 // start = next? CC=2 and out r1 and r2 unchanged
11027 s390_cc_set(2);
11028 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011029 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000011030
11031 assign(byte, load(Ity_I8, mkexpr(address)));
11032 assign(delim, get_gpr_b7(0));
11033
11034 // byte = delim? CC=1, R1=address
11035 s390_cc_set(1);
11036 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000011037 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011038
11039 // else: all equal, no end yet, loop
11040 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11041 put_gpr_dw0(r1, mkexpr(next));
11042 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011043
florian6820ba52012-07-26 02:01:50 +000011044 iterate();
sewardj2019a972011-03-07 16:04:07 +000011045
11046 return "srst";
11047}
11048
florian55085f82012-11-21 00:36:55 +000011049static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011050s390_irgen_CLST(UChar r1, UChar r2)
11051{
11052 IRTemp address1 = newTemp(Ity_I64);
11053 IRTemp address2 = newTemp(Ity_I64);
11054 IRTemp end = newTemp(Ity_I8);
11055 IRTemp counter = newTemp(Ity_I64);
11056 IRTemp byte1 = newTemp(Ity_I8);
11057 IRTemp byte2 = newTemp(Ity_I8);
11058
11059 assign(address1, get_gpr_dw0(r1));
11060 assign(address2, get_gpr_dw0(r2));
11061 assign(end, get_gpr_b7(0));
11062 assign(counter, get_counter_dw0());
11063 put_counter_dw0(mkU64(0));
11064 assign(byte1, load(Ity_I8, mkexpr(address1)));
11065 assign(byte2, load(Ity_I8, mkexpr(address2)));
11066
11067 // end in both? all equal, reset r1 and r2 to start values
11068 s390_cc_set(0);
11069 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11070 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011071 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11072 binop(Iop_Or8,
11073 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11074 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000011075
11076 put_gpr_dw0(r1, mkexpr(address1));
11077 put_gpr_dw0(r2, mkexpr(address2));
11078
11079 // End found in string1
11080 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011081 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000011082
11083 // End found in string2
11084 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011085 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000011086
11087 // string1 < string2
11088 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011089 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11090 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000011091
11092 // string2 < string1
11093 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011094 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11095 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000011096
11097 // else: all equal, no end yet, loop
11098 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11099 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11100 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011101
florian6820ba52012-07-26 02:01:50 +000011102 iterate();
sewardj2019a972011-03-07 16:04:07 +000011103
11104 return "clst";
11105}
11106
11107static void
11108s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11109{
11110 UChar reg;
11111 IRTemp addr = newTemp(Ity_I64);
11112
11113 assign(addr, mkexpr(op2addr));
11114 reg = r1;
11115 do {
11116 IRTemp old = addr;
11117
11118 reg %= 16;
11119 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11120 addr = newTemp(Ity_I64);
11121 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11122 reg++;
11123 } while (reg != (r3 + 1));
11124}
11125
florian55085f82012-11-21 00:36:55 +000011126static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011127s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11128{
11129 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11130
11131 return "lm";
11132}
11133
florian55085f82012-11-21 00:36:55 +000011134static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011135s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11136{
11137 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11138
11139 return "lmy";
11140}
11141
florian55085f82012-11-21 00:36:55 +000011142static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011143s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11144{
11145 UChar reg;
11146 IRTemp addr = newTemp(Ity_I64);
11147
11148 assign(addr, mkexpr(op2addr));
11149 reg = r1;
11150 do {
11151 IRTemp old = addr;
11152
11153 reg %= 16;
11154 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11155 addr = newTemp(Ity_I64);
11156 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11157 reg++;
11158 } while (reg != (r3 + 1));
11159
11160 return "lmh";
11161}
11162
florian55085f82012-11-21 00:36:55 +000011163static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011164s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11165{
11166 UChar reg;
11167 IRTemp addr = newTemp(Ity_I64);
11168
11169 assign(addr, mkexpr(op2addr));
11170 reg = r1;
11171 do {
11172 IRTemp old = addr;
11173
11174 reg %= 16;
11175 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11176 addr = newTemp(Ity_I64);
11177 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11178 reg++;
11179 } while (reg != (r3 + 1));
11180
11181 return "lmg";
11182}
11183
11184static void
11185s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11186{
11187 UChar reg;
11188 IRTemp addr = newTemp(Ity_I64);
11189
11190 assign(addr, mkexpr(op2addr));
11191 reg = r1;
11192 do {
11193 IRTemp old = addr;
11194
11195 reg %= 16;
11196 store(mkexpr(addr), get_gpr_w1(reg));
11197 addr = newTemp(Ity_I64);
11198 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11199 reg++;
11200 } while( reg != (r3 + 1));
11201}
11202
florian55085f82012-11-21 00:36:55 +000011203static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011204s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11205{
11206 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11207
11208 return "stm";
11209}
11210
florian55085f82012-11-21 00:36:55 +000011211static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011212s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11213{
11214 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11215
11216 return "stmy";
11217}
11218
florian55085f82012-11-21 00:36:55 +000011219static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011220s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11221{
11222 UChar reg;
11223 IRTemp addr = newTemp(Ity_I64);
11224
11225 assign(addr, mkexpr(op2addr));
11226 reg = r1;
11227 do {
11228 IRTemp old = addr;
11229
11230 reg %= 16;
11231 store(mkexpr(addr), get_gpr_w0(reg));
11232 addr = newTemp(Ity_I64);
11233 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11234 reg++;
11235 } while( reg != (r3 + 1));
11236
11237 return "stmh";
11238}
11239
florian55085f82012-11-21 00:36:55 +000011240static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011241s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11242{
11243 UChar reg;
11244 IRTemp addr = newTemp(Ity_I64);
11245
11246 assign(addr, mkexpr(op2addr));
11247 reg = r1;
11248 do {
11249 IRTemp old = addr;
11250
11251 reg %= 16;
11252 store(mkexpr(addr), get_gpr_dw0(reg));
11253 addr = newTemp(Ity_I64);
11254 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11255 reg++;
11256 } while( reg != (r3 + 1));
11257
11258 return "stmg";
11259}
11260
11261static void
florianb0bf6602012-05-05 00:01:16 +000011262s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000011263{
11264 IRTemp old1 = newTemp(Ity_I8);
11265 IRTemp old2 = newTemp(Ity_I8);
11266 IRTemp new1 = newTemp(Ity_I8);
11267 IRTemp counter = newTemp(Ity_I32);
11268 IRTemp addr1 = newTemp(Ity_I64);
11269
11270 assign(counter, get_counter_w0());
11271
11272 assign(addr1, binop(Iop_Add64, mkexpr(start1),
11273 unop(Iop_32Uto64, mkexpr(counter))));
11274
11275 assign(old1, load(Ity_I8, mkexpr(addr1)));
11276 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11277 unop(Iop_32Uto64,mkexpr(counter)))));
11278 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11279
11280 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000011281 if (op == Iop_Xor8) {
11282 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000011283 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11284 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000011285 } else
11286 store(mkexpr(addr1), mkexpr(new1));
11287 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11288 get_counter_w1()));
11289
11290 /* Check for end of field */
11291 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011292 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000011293 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11294 False);
11295 put_counter_dw0(mkU64(0));
11296}
11297
florian55085f82012-11-21 00:36:55 +000011298static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011299s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11300{
florianb0bf6602012-05-05 00:01:16 +000011301 IRTemp len = newTemp(Ity_I32);
11302
11303 assign(len, mkU32(length));
11304 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011305
11306 return "xc";
11307}
11308
sewardjb63967e2011-03-24 08:50:04 +000011309static void
11310s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11311{
11312 IRTemp counter = newTemp(Ity_I32);
11313 IRTemp start = newTemp(Ity_I64);
11314 IRTemp addr = newTemp(Ity_I64);
11315
11316 assign(start,
11317 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11318
11319 if (length < 8) {
11320 UInt i;
11321
11322 for (i = 0; i <= length; ++i) {
11323 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11324 }
11325 } else {
11326 assign(counter, get_counter_w0());
11327
11328 assign(addr, binop(Iop_Add64, mkexpr(start),
11329 unop(Iop_32Uto64, mkexpr(counter))));
11330
11331 store(mkexpr(addr), mkU8(0));
11332
11333 /* Check for end of field */
11334 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011335 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011336
11337 /* Reset counter */
11338 put_counter_dw0(mkU64(0));
11339 }
11340
11341 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11342
sewardj7ee97522011-05-09 21:45:04 +000011343 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011344 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11345}
11346
florian55085f82012-11-21 00:36:55 +000011347static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011348s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11349{
florianb0bf6602012-05-05 00:01:16 +000011350 IRTemp len = newTemp(Ity_I32);
11351
11352 assign(len, mkU32(length));
11353 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011354
11355 return "nc";
11356}
11357
florian55085f82012-11-21 00:36:55 +000011358static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011359s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11360{
florianb0bf6602012-05-05 00:01:16 +000011361 IRTemp len = newTemp(Ity_I32);
11362
11363 assign(len, mkU32(length));
11364 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011365
11366 return "oc";
11367}
11368
11369
florian55085f82012-11-21 00:36:55 +000011370static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011371s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11372{
florian79e839e2012-05-05 02:20:30 +000011373 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011374
florian79e839e2012-05-05 02:20:30 +000011375 assign(len, mkU64(length));
11376 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011377
11378 return "mvc";
11379}
11380
florian55085f82012-11-21 00:36:55 +000011381static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011382s390_irgen_MVCL(UChar r1, UChar r2)
11383{
11384 IRTemp addr1 = newTemp(Ity_I64);
11385 IRTemp addr2 = newTemp(Ity_I64);
11386 IRTemp addr2_load = newTemp(Ity_I64);
11387 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11388 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11389 IRTemp len1 = newTemp(Ity_I32);
11390 IRTemp len2 = newTemp(Ity_I32);
11391 IRTemp pad = newTemp(Ity_I8);
11392 IRTemp single = newTemp(Ity_I8);
11393
11394 assign(addr1, get_gpr_dw0(r1));
11395 assign(r1p1, get_gpr_w1(r1 + 1));
11396 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11397 assign(addr2, get_gpr_dw0(r2));
11398 assign(r2p1, get_gpr_w1(r2 + 1));
11399 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11400 assign(pad, get_gpr_b4(r2 + 1));
11401
11402 /* len1 == 0 ? */
11403 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011404 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011405
11406 /* Check for destructive overlap:
11407 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11408 s390_cc_set(3);
11409 IRTemp cond1 = newTemp(Ity_I32);
11410 assign(cond1, unop(Iop_1Uto32,
11411 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11412 IRTemp cond2 = newTemp(Ity_I32);
11413 assign(cond2, unop(Iop_1Uto32,
11414 binop(Iop_CmpLT64U, mkexpr(addr1),
11415 binop(Iop_Add64, mkexpr(addr2),
11416 unop(Iop_32Uto64, mkexpr(len1))))));
11417 IRTemp cond3 = newTemp(Ity_I32);
11418 assign(cond3, unop(Iop_1Uto32,
11419 binop(Iop_CmpLT64U,
11420 mkexpr(addr1),
11421 binop(Iop_Add64, mkexpr(addr2),
11422 unop(Iop_32Uto64, mkexpr(len2))))));
11423
florian6820ba52012-07-26 02:01:50 +000011424 next_insn_if(binop(Iop_CmpEQ32,
11425 binop(Iop_And32,
11426 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11427 mkexpr(cond3)),
11428 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011429
11430 /* See s390_irgen_CLCL for explanation why we cannot load directly
11431 and need two steps. */
11432 assign(addr2_load,
11433 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11434 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11435 assign(single,
11436 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11437 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11438
11439 store(mkexpr(addr1), mkexpr(single));
11440
11441 /* Update addr1 and len1 */
11442 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11443 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11444
11445 /* Update addr2 and len2 */
11446 put_gpr_dw0(r2,
11447 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11448 mkexpr(addr2),
11449 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11450
11451 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11452 put_gpr_w1(r2 + 1,
11453 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11454 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11455 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11456
11457 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011458 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011459
11460 return "mvcl";
11461}
11462
11463
florian55085f82012-11-21 00:36:55 +000011464static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011465s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11466{
11467 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11468
11469 addr1 = newTemp(Ity_I64);
11470 addr3 = newTemp(Ity_I64);
11471 addr3_load = newTemp(Ity_I64);
11472 len1 = newTemp(Ity_I64);
11473 len3 = newTemp(Ity_I64);
11474 single = newTemp(Ity_I8);
11475
11476 assign(addr1, get_gpr_dw0(r1));
11477 assign(len1, get_gpr_dw0(r1 + 1));
11478 assign(addr3, get_gpr_dw0(r3));
11479 assign(len3, get_gpr_dw0(r3 + 1));
11480
11481 // len1 == 0 ?
11482 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011483 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011484
11485 /* This is a hack to prevent mvcle from reading from addr3 if it
11486 should read from the pad. Since the pad has no address, just
11487 read from the instruction, we discard that anyway */
11488 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011489 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11490 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011491
11492 assign(single,
florian6ad49522011-09-09 02:38:55 +000011493 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11494 unop(Iop_64to8, mkexpr(pad2)),
11495 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011496 store(mkexpr(addr1), mkexpr(single));
11497
11498 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11499
11500 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11501
11502 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011503 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11504 mkexpr(addr3),
11505 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011506
11507 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011508 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11509 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011510
sewardj2019a972011-03-07 16:04:07 +000011511 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011512 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011513
11514 return "mvcle";
11515}
11516
florian55085f82012-11-21 00:36:55 +000011517static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011518s390_irgen_MVST(UChar r1, UChar r2)
11519{
11520 IRTemp addr1 = newTemp(Ity_I64);
11521 IRTemp addr2 = newTemp(Ity_I64);
11522 IRTemp end = newTemp(Ity_I8);
11523 IRTemp byte = newTemp(Ity_I8);
11524 IRTemp counter = newTemp(Ity_I64);
11525
11526 assign(addr1, get_gpr_dw0(r1));
11527 assign(addr2, get_gpr_dw0(r2));
11528 assign(counter, get_counter_dw0());
11529 assign(end, get_gpr_b7(0));
11530 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11531 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11532
11533 // We use unlimited as cpu-determined number
11534 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011535 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011536
11537 // and always set cc=1 at the end + update r1
11538 s390_cc_set(1);
11539 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11540 put_counter_dw0(mkU64(0));
11541
11542 return "mvst";
11543}
11544
11545static void
11546s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11547{
11548 IRTemp op1 = newTemp(Ity_I64);
11549 IRTemp result = newTemp(Ity_I64);
11550
11551 assign(op1, binop(Iop_32HLto64,
11552 get_gpr_w1(r1), // high 32 bits
11553 get_gpr_w1(r1 + 1))); // low 32 bits
11554 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11555 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11556 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11557}
11558
11559static void
11560s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11561{
11562 IRTemp op1 = newTemp(Ity_I128);
11563 IRTemp result = newTemp(Ity_I128);
11564
11565 assign(op1, binop(Iop_64HLto128,
11566 get_gpr_dw0(r1), // high 64 bits
11567 get_gpr_dw0(r1 + 1))); // low 64 bits
11568 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11569 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11570 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11571}
11572
11573static void
11574s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11575{
11576 IRTemp op1 = newTemp(Ity_I64);
11577 IRTemp result = newTemp(Ity_I128);
11578
11579 assign(op1, get_gpr_dw0(r1 + 1));
11580 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11581 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11582 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11583}
11584
florian55085f82012-11-21 00:36:55 +000011585static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011586s390_irgen_DR(UChar r1, UChar r2)
11587{
11588 IRTemp op2 = newTemp(Ity_I32);
11589
11590 assign(op2, get_gpr_w1(r2));
11591
11592 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11593
11594 return "dr";
11595}
11596
florian55085f82012-11-21 00:36:55 +000011597static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011598s390_irgen_D(UChar r1, IRTemp op2addr)
11599{
11600 IRTemp op2 = newTemp(Ity_I32);
11601
11602 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11603
11604 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11605
11606 return "d";
11607}
11608
florian55085f82012-11-21 00:36:55 +000011609static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011610s390_irgen_DLR(UChar r1, UChar r2)
11611{
11612 IRTemp op2 = newTemp(Ity_I32);
11613
11614 assign(op2, get_gpr_w1(r2));
11615
11616 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11617
florian7cd1cde2012-08-16 23:57:43 +000011618 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011619}
11620
florian55085f82012-11-21 00:36:55 +000011621static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011622s390_irgen_DL(UChar r1, IRTemp op2addr)
11623{
11624 IRTemp op2 = newTemp(Ity_I32);
11625
11626 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11627
11628 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11629
11630 return "dl";
11631}
11632
florian55085f82012-11-21 00:36:55 +000011633static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011634s390_irgen_DLG(UChar r1, IRTemp op2addr)
11635{
11636 IRTemp op2 = newTemp(Ity_I64);
11637
11638 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11639
11640 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11641
11642 return "dlg";
11643}
11644
florian55085f82012-11-21 00:36:55 +000011645static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011646s390_irgen_DLGR(UChar r1, UChar r2)
11647{
11648 IRTemp op2 = newTemp(Ity_I64);
11649
11650 assign(op2, get_gpr_dw0(r2));
11651
11652 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11653
11654 return "dlgr";
11655}
11656
florian55085f82012-11-21 00:36:55 +000011657static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011658s390_irgen_DSGR(UChar r1, UChar r2)
11659{
11660 IRTemp op2 = newTemp(Ity_I64);
11661
11662 assign(op2, get_gpr_dw0(r2));
11663
11664 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11665
11666 return "dsgr";
11667}
11668
florian55085f82012-11-21 00:36:55 +000011669static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011670s390_irgen_DSG(UChar r1, IRTemp op2addr)
11671{
11672 IRTemp op2 = newTemp(Ity_I64);
11673
11674 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11675
11676 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11677
11678 return "dsg";
11679}
11680
florian55085f82012-11-21 00:36:55 +000011681static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011682s390_irgen_DSGFR(UChar r1, UChar r2)
11683{
11684 IRTemp op2 = newTemp(Ity_I64);
11685
11686 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11687
11688 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11689
11690 return "dsgfr";
11691}
11692
florian55085f82012-11-21 00:36:55 +000011693static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011694s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11695{
11696 IRTemp op2 = newTemp(Ity_I64);
11697
11698 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11699
11700 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11701
11702 return "dsgf";
11703}
11704
11705static void
11706s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11707{
11708 UChar reg;
11709 IRTemp addr = newTemp(Ity_I64);
11710
11711 assign(addr, mkexpr(op2addr));
11712 reg = r1;
11713 do {
11714 IRTemp old = addr;
11715
11716 reg %= 16;
11717 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11718 addr = newTemp(Ity_I64);
11719 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11720 reg++;
11721 } while (reg != (r3 + 1));
11722}
11723
florian55085f82012-11-21 00:36:55 +000011724static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011725s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11726{
11727 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11728
11729 return "lam";
11730}
11731
florian55085f82012-11-21 00:36:55 +000011732static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011733s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11734{
11735 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11736
11737 return "lamy";
11738}
11739
11740static void
11741s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11742{
11743 UChar reg;
11744 IRTemp addr = newTemp(Ity_I64);
11745
11746 assign(addr, mkexpr(op2addr));
11747 reg = r1;
11748 do {
11749 IRTemp old = addr;
11750
11751 reg %= 16;
11752 store(mkexpr(addr), get_ar_w0(reg));
11753 addr = newTemp(Ity_I64);
11754 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11755 reg++;
11756 } while (reg != (r3 + 1));
11757}
11758
florian55085f82012-11-21 00:36:55 +000011759static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011760s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11761{
11762 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11763
11764 return "stam";
11765}
11766
florian55085f82012-11-21 00:36:55 +000011767static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011768s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11769{
11770 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11771
11772 return "stamy";
11773}
11774
11775
11776/* Implementation for 32-bit compare-and-swap */
11777static void
11778s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11779{
11780 IRCAS *cas;
11781 IRTemp op1 = newTemp(Ity_I32);
11782 IRTemp old_mem = newTemp(Ity_I32);
11783 IRTemp op3 = newTemp(Ity_I32);
11784 IRTemp result = newTemp(Ity_I32);
11785 IRTemp nequal = newTemp(Ity_I1);
11786
11787 assign(op1, get_gpr_w1(r1));
11788 assign(op3, get_gpr_w1(r3));
11789
11790 /* The first and second operands are compared. If they are equal,
11791 the third operand is stored at the second- operand location. */
11792 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11793 Iend_BE, mkexpr(op2addr),
11794 NULL, mkexpr(op1), /* expected value */
11795 NULL, mkexpr(op3) /* new value */);
11796 stmt(IRStmt_CAS(cas));
11797
11798 /* Set CC. Operands compared equal -> 0, else 1. */
11799 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11800 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11801
11802 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11803 Otherwise, store the old_value from memory in r1 and yield. */
11804 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11805 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011806 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011807}
11808
florian55085f82012-11-21 00:36:55 +000011809static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011810s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11811{
11812 s390_irgen_cas_32(r1, r3, op2addr);
11813
11814 return "cs";
11815}
11816
florian55085f82012-11-21 00:36:55 +000011817static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011818s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11819{
11820 s390_irgen_cas_32(r1, r3, op2addr);
11821
11822 return "csy";
11823}
11824
florian55085f82012-11-21 00:36:55 +000011825static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011826s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11827{
11828 IRCAS *cas;
11829 IRTemp op1 = newTemp(Ity_I64);
11830 IRTemp old_mem = newTemp(Ity_I64);
11831 IRTemp op3 = newTemp(Ity_I64);
11832 IRTemp result = newTemp(Ity_I64);
11833 IRTemp nequal = newTemp(Ity_I1);
11834
11835 assign(op1, get_gpr_dw0(r1));
11836 assign(op3, get_gpr_dw0(r3));
11837
11838 /* The first and second operands are compared. If they are equal,
11839 the third operand is stored at the second- operand location. */
11840 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11841 Iend_BE, mkexpr(op2addr),
11842 NULL, mkexpr(op1), /* expected value */
11843 NULL, mkexpr(op3) /* new value */);
11844 stmt(IRStmt_CAS(cas));
11845
11846 /* Set CC. Operands compared equal -> 0, else 1. */
11847 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11848 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11849
11850 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11851 Otherwise, store the old_value from memory in r1 and yield. */
11852 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11853 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011854 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011855
11856 return "csg";
11857}
11858
florian448cbba2012-06-06 02:26:01 +000011859/* Implementation for 32-bit compare-double-and-swap */
11860static void
11861s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11862{
11863 IRCAS *cas;
11864 IRTemp op1_high = newTemp(Ity_I32);
11865 IRTemp op1_low = newTemp(Ity_I32);
11866 IRTemp old_mem_high = newTemp(Ity_I32);
11867 IRTemp old_mem_low = newTemp(Ity_I32);
11868 IRTemp op3_high = newTemp(Ity_I32);
11869 IRTemp op3_low = newTemp(Ity_I32);
11870 IRTemp result = newTemp(Ity_I32);
11871 IRTemp nequal = newTemp(Ity_I1);
11872
11873 assign(op1_high, get_gpr_w1(r1));
11874 assign(op1_low, get_gpr_w1(r1+1));
11875 assign(op3_high, get_gpr_w1(r3));
11876 assign(op3_low, get_gpr_w1(r3+1));
11877
11878 /* The first and second operands are compared. If they are equal,
11879 the third operand is stored at the second-operand location. */
11880 cas = mkIRCAS(old_mem_high, old_mem_low,
11881 Iend_BE, mkexpr(op2addr),
11882 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11883 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11884 stmt(IRStmt_CAS(cas));
11885
11886 /* Set CC. Operands compared equal -> 0, else 1. */
11887 assign(result, unop(Iop_1Uto32,
11888 binop(Iop_CmpNE32,
11889 binop(Iop_Or32,
11890 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11891 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11892 mkU32(0))));
11893
11894 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11895
11896 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11897 Otherwise, store the old_value from memory in r1 and yield. */
11898 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11899 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11900 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011901 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011902}
11903
florian55085f82012-11-21 00:36:55 +000011904static const HChar *
florian448cbba2012-06-06 02:26:01 +000011905s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11906{
11907 s390_irgen_cdas_32(r1, r3, op2addr);
11908
11909 return "cds";
11910}
11911
florian55085f82012-11-21 00:36:55 +000011912static const HChar *
florian448cbba2012-06-06 02:26:01 +000011913s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11914{
11915 s390_irgen_cdas_32(r1, r3, op2addr);
11916
11917 return "cdsy";
11918}
11919
florian55085f82012-11-21 00:36:55 +000011920static const HChar *
florian448cbba2012-06-06 02:26:01 +000011921s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11922{
11923 IRCAS *cas;
11924 IRTemp op1_high = newTemp(Ity_I64);
11925 IRTemp op1_low = newTemp(Ity_I64);
11926 IRTemp old_mem_high = newTemp(Ity_I64);
11927 IRTemp old_mem_low = newTemp(Ity_I64);
11928 IRTemp op3_high = newTemp(Ity_I64);
11929 IRTemp op3_low = newTemp(Ity_I64);
11930 IRTemp result = newTemp(Ity_I64);
11931 IRTemp nequal = newTemp(Ity_I1);
11932
11933 assign(op1_high, get_gpr_dw0(r1));
11934 assign(op1_low, get_gpr_dw0(r1+1));
11935 assign(op3_high, get_gpr_dw0(r3));
11936 assign(op3_low, get_gpr_dw0(r3+1));
11937
11938 /* The first and second operands are compared. If they are equal,
11939 the third operand is stored at the second-operand location. */
11940 cas = mkIRCAS(old_mem_high, old_mem_low,
11941 Iend_BE, mkexpr(op2addr),
11942 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11943 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11944 stmt(IRStmt_CAS(cas));
11945
11946 /* Set CC. Operands compared equal -> 0, else 1. */
11947 assign(result, unop(Iop_1Uto64,
11948 binop(Iop_CmpNE64,
11949 binop(Iop_Or64,
11950 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11951 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11952 mkU64(0))));
11953
11954 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11955
11956 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11957 Otherwise, store the old_value from memory in r1 and yield. */
11958 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11959 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11960 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011961 yield_if(mkexpr(nequal));
11962
florian448cbba2012-06-06 02:26:01 +000011963 return "cdsg";
11964}
11965
sewardj2019a972011-03-07 16:04:07 +000011966
11967/* Binary floating point */
11968
florian55085f82012-11-21 00:36:55 +000011969static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011970s390_irgen_AXBR(UChar r1, UChar r2)
11971{
11972 IRTemp op1 = newTemp(Ity_F128);
11973 IRTemp op2 = newTemp(Ity_F128);
11974 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011975 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011976
11977 assign(op1, get_fpr_pair(r1));
11978 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011979 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011980 mkexpr(op2)));
11981 put_fpr_pair(r1, mkexpr(result));
11982
11983 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11984
11985 return "axbr";
11986}
11987
florian55085f82012-11-21 00:36:55 +000011988static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011989s390_irgen_CEBR(UChar r1, UChar r2)
11990{
11991 IRTemp op1 = newTemp(Ity_F32);
11992 IRTemp op2 = newTemp(Ity_F32);
11993 IRTemp cc_vex = newTemp(Ity_I32);
11994 IRTemp cc_s390 = newTemp(Ity_I32);
11995
11996 assign(op1, get_fpr_w0(r1));
11997 assign(op2, get_fpr_w0(r2));
11998 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11999
florian2d3d87f2012-12-21 21:05:17 +000012000 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012001 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12002
12003 return "cebr";
12004}
12005
florian55085f82012-11-21 00:36:55 +000012006static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012007s390_irgen_CDBR(UChar r1, UChar r2)
12008{
12009 IRTemp op1 = newTemp(Ity_F64);
12010 IRTemp op2 = newTemp(Ity_F64);
12011 IRTemp cc_vex = newTemp(Ity_I32);
12012 IRTemp cc_s390 = newTemp(Ity_I32);
12013
12014 assign(op1, get_fpr_dw0(r1));
12015 assign(op2, get_fpr_dw0(r2));
12016 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12017
florian2d3d87f2012-12-21 21:05:17 +000012018 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012019 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12020
12021 return "cdbr";
12022}
12023
florian55085f82012-11-21 00:36:55 +000012024static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012025s390_irgen_CXBR(UChar r1, UChar r2)
12026{
12027 IRTemp op1 = newTemp(Ity_F128);
12028 IRTemp op2 = newTemp(Ity_F128);
12029 IRTemp cc_vex = newTemp(Ity_I32);
12030 IRTemp cc_s390 = newTemp(Ity_I32);
12031
12032 assign(op1, get_fpr_pair(r1));
12033 assign(op2, get_fpr_pair(r2));
12034 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12035
florian2d3d87f2012-12-21 21:05:17 +000012036 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012037 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12038
12039 return "cxbr";
12040}
12041
florian55085f82012-11-21 00:36:55 +000012042static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012043s390_irgen_CEB(UChar r1, IRTemp op2addr)
12044{
12045 IRTemp op1 = newTemp(Ity_F32);
12046 IRTemp op2 = newTemp(Ity_F32);
12047 IRTemp cc_vex = newTemp(Ity_I32);
12048 IRTemp cc_s390 = newTemp(Ity_I32);
12049
12050 assign(op1, get_fpr_w0(r1));
12051 assign(op2, load(Ity_F32, mkexpr(op2addr)));
12052 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12053
florian2d3d87f2012-12-21 21:05:17 +000012054 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012055 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12056
12057 return "ceb";
12058}
12059
florian55085f82012-11-21 00:36:55 +000012060static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012061s390_irgen_CDB(UChar r1, IRTemp op2addr)
12062{
12063 IRTemp op1 = newTemp(Ity_F64);
12064 IRTemp op2 = newTemp(Ity_F64);
12065 IRTemp cc_vex = newTemp(Ity_I32);
12066 IRTemp cc_s390 = newTemp(Ity_I32);
12067
12068 assign(op1, get_fpr_dw0(r1));
12069 assign(op2, load(Ity_F64, mkexpr(op2addr)));
12070 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12071
florian2d3d87f2012-12-21 21:05:17 +000012072 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012073 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12074
12075 return "cdb";
12076}
12077
florian55085f82012-11-21 00:36:55 +000012078static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012079s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12080 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012081{
12082 IRTemp op2 = newTemp(Ity_I32);
12083
12084 assign(op2, get_gpr_w1(r2));
12085 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12086
12087 return "cxfbr";
12088}
12089
florian55085f82012-11-21 00:36:55 +000012090static const HChar *
floriand2129202012-09-01 20:01:39 +000012091s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12092 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012093{
floriane75dafa2012-09-01 17:54:09 +000012094 if (! s390_host_has_fpext) {
12095 emulation_failure(EmFail_S390X_fpext);
12096 } else {
12097 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000012098
floriane75dafa2012-09-01 17:54:09 +000012099 assign(op2, get_gpr_w1(r2));
12100 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12101 }
florian1c8f7ff2012-09-01 00:12:11 +000012102 return "cxlfbr";
12103}
12104
12105
florian55085f82012-11-21 00:36:55 +000012106static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012107s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12108 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012109{
12110 IRTemp op2 = newTemp(Ity_I64);
12111
12112 assign(op2, get_gpr_dw0(r2));
12113 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12114
12115 return "cxgbr";
12116}
12117
florian55085f82012-11-21 00:36:55 +000012118static const HChar *
floriand2129202012-09-01 20:01:39 +000012119s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12120 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012121{
floriane75dafa2012-09-01 17:54:09 +000012122 if (! s390_host_has_fpext) {
12123 emulation_failure(EmFail_S390X_fpext);
12124 } else {
12125 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000012126
floriane75dafa2012-09-01 17:54:09 +000012127 assign(op2, get_gpr_dw0(r2));
12128 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12129 }
florian1c8f7ff2012-09-01 00:12:11 +000012130 return "cxlgbr";
12131}
12132
florian55085f82012-11-21 00:36:55 +000012133static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012134s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12135 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012136{
12137 IRTemp op = newTemp(Ity_F128);
12138 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012139 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012140
12141 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012142 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012143 mkexpr(op)));
12144 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012145 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012146
12147 return "cfxbr";
12148}
12149
florian55085f82012-11-21 00:36:55 +000012150static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012151s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12152 UChar r1, UChar r2)
12153{
floriane75dafa2012-09-01 17:54:09 +000012154 if (! s390_host_has_fpext) {
12155 emulation_failure(EmFail_S390X_fpext);
12156 } else {
12157 IRTemp op = newTemp(Ity_F128);
12158 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012159 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012160
floriane75dafa2012-09-01 17:54:09 +000012161 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012162 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012163 mkexpr(op)));
12164 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012165 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012166 }
florian1c8f7ff2012-09-01 00:12:11 +000012167 return "clfxbr";
12168}
12169
12170
florian55085f82012-11-21 00:36:55 +000012171static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012172s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12173 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012174{
12175 IRTemp op = newTemp(Ity_F128);
12176 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012177 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012178
12179 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012180 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012181 mkexpr(op)));
12182 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012183 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012184
12185 return "cgxbr";
12186}
12187
florian55085f82012-11-21 00:36:55 +000012188static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012189s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12190 UChar r1, UChar r2)
12191{
floriane75dafa2012-09-01 17:54:09 +000012192 if (! s390_host_has_fpext) {
12193 emulation_failure(EmFail_S390X_fpext);
12194 } else {
12195 IRTemp op = newTemp(Ity_F128);
12196 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012197 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012198
floriane75dafa2012-09-01 17:54:09 +000012199 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012200 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012201 mkexpr(op)));
12202 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012203 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12204 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012205 }
florian1c8f7ff2012-09-01 00:12:11 +000012206 return "clgxbr";
12207}
12208
florian55085f82012-11-21 00:36:55 +000012209static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012210s390_irgen_DXBR(UChar r1, UChar r2)
12211{
12212 IRTemp op1 = newTemp(Ity_F128);
12213 IRTemp op2 = newTemp(Ity_F128);
12214 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012215 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012216
12217 assign(op1, get_fpr_pair(r1));
12218 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012219 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012220 mkexpr(op2)));
12221 put_fpr_pair(r1, mkexpr(result));
12222
12223 return "dxbr";
12224}
12225
florian55085f82012-11-21 00:36:55 +000012226static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012227s390_irgen_LTXBR(UChar r1, UChar r2)
12228{
12229 IRTemp result = newTemp(Ity_F128);
12230
12231 assign(result, get_fpr_pair(r2));
12232 put_fpr_pair(r1, mkexpr(result));
12233 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12234
12235 return "ltxbr";
12236}
12237
florian55085f82012-11-21 00:36:55 +000012238static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012239s390_irgen_LCXBR(UChar r1, UChar r2)
12240{
12241 IRTemp result = newTemp(Ity_F128);
12242
12243 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12244 put_fpr_pair(r1, mkexpr(result));
12245 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12246
12247 return "lcxbr";
12248}
12249
florian55085f82012-11-21 00:36:55 +000012250static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012251s390_irgen_LXDBR(UChar r1, UChar r2)
12252{
12253 IRTemp op = newTemp(Ity_F64);
12254
12255 assign(op, get_fpr_dw0(r2));
12256 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12257
12258 return "lxdbr";
12259}
12260
florian55085f82012-11-21 00:36:55 +000012261static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012262s390_irgen_LXEBR(UChar r1, UChar r2)
12263{
12264 IRTemp op = newTemp(Ity_F32);
12265
12266 assign(op, get_fpr_w0(r2));
12267 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12268
12269 return "lxebr";
12270}
12271
florian55085f82012-11-21 00:36:55 +000012272static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012273s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12274{
12275 IRTemp op = newTemp(Ity_F64);
12276
12277 assign(op, load(Ity_F64, mkexpr(op2addr)));
12278 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12279
12280 return "lxdb";
12281}
12282
florian55085f82012-11-21 00:36:55 +000012283static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012284s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12285{
12286 IRTemp op = newTemp(Ity_F32);
12287
12288 assign(op, load(Ity_F32, mkexpr(op2addr)));
12289 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12290
12291 return "lxeb";
12292}
12293
florian55085f82012-11-21 00:36:55 +000012294static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012295s390_irgen_LNEBR(UChar r1, UChar r2)
12296{
12297 IRTemp result = newTemp(Ity_F32);
12298
12299 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12300 put_fpr_w0(r1, mkexpr(result));
12301 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12302
12303 return "lnebr";
12304}
12305
florian55085f82012-11-21 00:36:55 +000012306static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012307s390_irgen_LNDBR(UChar r1, UChar r2)
12308{
12309 IRTemp result = newTemp(Ity_F64);
12310
12311 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12312 put_fpr_dw0(r1, mkexpr(result));
12313 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12314
12315 return "lndbr";
12316}
12317
florian55085f82012-11-21 00:36:55 +000012318static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012319s390_irgen_LNXBR(UChar r1, UChar r2)
12320{
12321 IRTemp result = newTemp(Ity_F128);
12322
12323 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12324 put_fpr_pair(r1, mkexpr(result));
12325 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12326
12327 return "lnxbr";
12328}
12329
florian55085f82012-11-21 00:36:55 +000012330static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012331s390_irgen_LPEBR(UChar r1, UChar r2)
12332{
12333 IRTemp result = newTemp(Ity_F32);
12334
12335 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12336 put_fpr_w0(r1, mkexpr(result));
12337 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12338
12339 return "lpebr";
12340}
12341
florian55085f82012-11-21 00:36:55 +000012342static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012343s390_irgen_LPDBR(UChar r1, UChar r2)
12344{
12345 IRTemp result = newTemp(Ity_F64);
12346
12347 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12348 put_fpr_dw0(r1, mkexpr(result));
12349 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12350
12351 return "lpdbr";
12352}
12353
florian55085f82012-11-21 00:36:55 +000012354static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012355s390_irgen_LPXBR(UChar r1, UChar r2)
12356{
12357 IRTemp result = newTemp(Ity_F128);
12358
12359 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12360 put_fpr_pair(r1, mkexpr(result));
12361 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12362
12363 return "lpxbr";
12364}
12365
florian55085f82012-11-21 00:36:55 +000012366static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012367s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12368 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012369{
florian125e20d2012-10-07 15:42:37 +000012370 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012371 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012372 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012373 }
sewardj2019a972011-03-07 16:04:07 +000012374 IRTemp result = newTemp(Ity_F64);
12375
floriandb4fcaa2012-09-05 19:54:08 +000012376 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012377 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012378 put_fpr_dw0(r1, mkexpr(result));
12379
12380 return "ldxbr";
12381}
12382
florian55085f82012-11-21 00:36:55 +000012383static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012384s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12385 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012386{
florian125e20d2012-10-07 15:42:37 +000012387 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012388 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012389 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012390 }
sewardj2019a972011-03-07 16:04:07 +000012391 IRTemp result = newTemp(Ity_F32);
12392
floriandb4fcaa2012-09-05 19:54:08 +000012393 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012394 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012395 put_fpr_w0(r1, mkexpr(result));
12396
12397 return "lexbr";
12398}
12399
florian55085f82012-11-21 00:36:55 +000012400static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012401s390_irgen_MXBR(UChar r1, UChar r2)
12402{
12403 IRTemp op1 = newTemp(Ity_F128);
12404 IRTemp op2 = newTemp(Ity_F128);
12405 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012406 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012407
12408 assign(op1, get_fpr_pair(r1));
12409 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012410 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012411 mkexpr(op2)));
12412 put_fpr_pair(r1, mkexpr(result));
12413
12414 return "mxbr";
12415}
12416
florian55085f82012-11-21 00:36:55 +000012417static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012418s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12419{
florian125e20d2012-10-07 15:42:37 +000012420 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012421
floriandb4fcaa2012-09-05 19:54:08 +000012422 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012423 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012424
12425 return "maebr";
12426}
12427
florian55085f82012-11-21 00:36:55 +000012428static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012429s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12430{
florian125e20d2012-10-07 15:42:37 +000012431 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012432
floriandb4fcaa2012-09-05 19:54:08 +000012433 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012434 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012435
12436 return "madbr";
12437}
12438
florian55085f82012-11-21 00:36:55 +000012439static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012440s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12441{
12442 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012443 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012444
floriandb4fcaa2012-09-05 19:54:08 +000012445 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012446 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012447
12448 return "maeb";
12449}
12450
florian55085f82012-11-21 00:36:55 +000012451static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012452s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12453{
12454 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012455 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012456
floriandb4fcaa2012-09-05 19:54:08 +000012457 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012458 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012459
12460 return "madb";
12461}
12462
florian55085f82012-11-21 00:36:55 +000012463static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012464s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12465{
florian125e20d2012-10-07 15:42:37 +000012466 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012467
floriandb4fcaa2012-09-05 19:54:08 +000012468 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012469 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012470
12471 return "msebr";
12472}
12473
florian55085f82012-11-21 00:36:55 +000012474static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012475s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12476{
florian125e20d2012-10-07 15:42:37 +000012477 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012478
floriandb4fcaa2012-09-05 19:54:08 +000012479 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012480 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012481
12482 return "msdbr";
12483}
12484
florian55085f82012-11-21 00:36:55 +000012485static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012486s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12487{
12488 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012489 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012490
floriandb4fcaa2012-09-05 19:54:08 +000012491 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012492 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012493
12494 return "mseb";
12495}
12496
florian55085f82012-11-21 00:36:55 +000012497static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012498s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12499{
12500 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012501 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012502
floriandb4fcaa2012-09-05 19:54:08 +000012503 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012504 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012505
12506 return "msdb";
12507}
12508
florian55085f82012-11-21 00:36:55 +000012509static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012510s390_irgen_SQEBR(UChar r1, UChar r2)
12511{
12512 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012513 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012514
floriandb4fcaa2012-09-05 19:54:08 +000012515 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012516 put_fpr_w0(r1, mkexpr(result));
12517
12518 return "sqebr";
12519}
12520
florian55085f82012-11-21 00:36:55 +000012521static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012522s390_irgen_SQDBR(UChar r1, UChar r2)
12523{
12524 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012525 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012526
floriandb4fcaa2012-09-05 19:54:08 +000012527 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012528 put_fpr_dw0(r1, mkexpr(result));
12529
12530 return "sqdbr";
12531}
12532
florian55085f82012-11-21 00:36:55 +000012533static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012534s390_irgen_SQXBR(UChar r1, UChar r2)
12535{
12536 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012537 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012538
floriandb4fcaa2012-09-05 19:54:08 +000012539 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12540 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012541 put_fpr_pair(r1, mkexpr(result));
12542
12543 return "sqxbr";
12544}
12545
florian55085f82012-11-21 00:36:55 +000012546static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012547s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12548{
12549 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012550 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012551
12552 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012553 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012554
12555 return "sqeb";
12556}
12557
florian55085f82012-11-21 00:36:55 +000012558static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012559s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12560{
12561 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012562 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012563
12564 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012565 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012566
12567 return "sqdb";
12568}
12569
florian55085f82012-11-21 00:36:55 +000012570static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012571s390_irgen_SXBR(UChar r1, UChar r2)
12572{
12573 IRTemp op1 = newTemp(Ity_F128);
12574 IRTemp op2 = newTemp(Ity_F128);
12575 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012576 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012577
12578 assign(op1, get_fpr_pair(r1));
12579 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012580 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012581 mkexpr(op2)));
12582 put_fpr_pair(r1, mkexpr(result));
12583 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12584
12585 return "sxbr";
12586}
12587
florian55085f82012-11-21 00:36:55 +000012588static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012589s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12590{
12591 IRTemp value = newTemp(Ity_F32);
12592
12593 assign(value, get_fpr_w0(r1));
12594
12595 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12596
12597 return "tceb";
12598}
12599
florian55085f82012-11-21 00:36:55 +000012600static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012601s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12602{
12603 IRTemp value = newTemp(Ity_F64);
12604
12605 assign(value, get_fpr_dw0(r1));
12606
12607 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12608
12609 return "tcdb";
12610}
12611
florian55085f82012-11-21 00:36:55 +000012612static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012613s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12614{
12615 IRTemp value = newTemp(Ity_F128);
12616
12617 assign(value, get_fpr_pair(r1));
12618
12619 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12620
12621 return "tcxb";
12622}
12623
florian55085f82012-11-21 00:36:55 +000012624static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012625s390_irgen_LCDFR(UChar r1, UChar r2)
12626{
12627 IRTemp result = newTemp(Ity_F64);
12628
12629 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12630 put_fpr_dw0(r1, mkexpr(result));
12631
12632 return "lcdfr";
12633}
12634
florian55085f82012-11-21 00:36:55 +000012635static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012636s390_irgen_LNDFR(UChar r1, UChar r2)
12637{
12638 IRTemp result = newTemp(Ity_F64);
12639
12640 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12641 put_fpr_dw0(r1, mkexpr(result));
12642
12643 return "lndfr";
12644}
12645
florian55085f82012-11-21 00:36:55 +000012646static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012647s390_irgen_LPDFR(UChar r1, UChar r2)
12648{
12649 IRTemp result = newTemp(Ity_F64);
12650
12651 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12652 put_fpr_dw0(r1, mkexpr(result));
12653
12654 return "lpdfr";
12655}
12656
florian55085f82012-11-21 00:36:55 +000012657static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012658s390_irgen_LDGR(UChar r1, UChar r2)
12659{
12660 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12661
12662 return "ldgr";
12663}
12664
florian55085f82012-11-21 00:36:55 +000012665static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012666s390_irgen_LGDR(UChar r1, UChar r2)
12667{
12668 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12669
12670 return "lgdr";
12671}
12672
12673
florian55085f82012-11-21 00:36:55 +000012674static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012675s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12676{
12677 IRTemp sign = newTemp(Ity_I64);
12678 IRTemp value = newTemp(Ity_I64);
12679
12680 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12681 mkU64(1ULL << 63)));
12682 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12683 mkU64((1ULL << 63) - 1)));
12684 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12685 mkexpr(sign))));
12686
12687 return "cpsdr";
12688}
12689
12690
sewardj2019a972011-03-07 16:04:07 +000012691static IRExpr *
12692s390_call_cvb(IRExpr *in)
12693{
12694 IRExpr **args, *call;
12695
12696 args = mkIRExprVec_1(in);
12697 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12698 "s390_do_cvb", &s390_do_cvb, args);
12699
12700 /* Nothing is excluded from definedness checking. */
12701 call->Iex.CCall.cee->mcx_mask = 0;
12702
12703 return call;
12704}
12705
florian55085f82012-11-21 00:36:55 +000012706static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012707s390_irgen_CVB(UChar r1, IRTemp op2addr)
12708{
12709 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12710
12711 return "cvb";
12712}
12713
florian55085f82012-11-21 00:36:55 +000012714static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012715s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12716{
12717 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12718
12719 return "cvby";
12720}
12721
12722
sewardj2019a972011-03-07 16:04:07 +000012723static IRExpr *
12724s390_call_cvd(IRExpr *in)
12725{
12726 IRExpr **args, *call;
12727
12728 args = mkIRExprVec_1(in);
12729 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12730 "s390_do_cvd", &s390_do_cvd, args);
12731
12732 /* Nothing is excluded from definedness checking. */
12733 call->Iex.CCall.cee->mcx_mask = 0;
12734
12735 return call;
12736}
12737
florian55085f82012-11-21 00:36:55 +000012738static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012739s390_irgen_CVD(UChar r1, IRTemp op2addr)
12740{
florian11b8ee82012-08-06 13:35:33 +000012741 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012742
12743 return "cvd";
12744}
12745
florian55085f82012-11-21 00:36:55 +000012746static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012747s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12748{
12749 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12750
12751 return "cvdy";
12752}
12753
florian55085f82012-11-21 00:36:55 +000012754static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012755s390_irgen_FLOGR(UChar r1, UChar r2)
12756{
12757 IRTemp input = newTemp(Ity_I64);
12758 IRTemp not_zero = newTemp(Ity_I64);
12759 IRTemp tmpnum = newTemp(Ity_I64);
12760 IRTemp num = newTemp(Ity_I64);
12761 IRTemp shift_amount = newTemp(Ity_I8);
12762
12763 /* We use the "count leading zeroes" operator because the number of
12764 leading zeroes is identical with the bit position of the first '1' bit.
12765 However, that operator does not work when the input value is zero.
12766 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12767 the modified value. If input == 0, then the result is 64. Otherwise,
12768 the result of Clz64 is what we want. */
12769
12770 assign(input, get_gpr_dw0(r2));
12771 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12772 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12773
12774 /* num = (input == 0) ? 64 : tmpnum */
12775 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12776 /* == 0 */ mkU64(64),
12777 /* != 0 */ mkexpr(tmpnum)));
12778
12779 put_gpr_dw0(r1, mkexpr(num));
12780
12781 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12782 is to first shift the input value by NUM + 1 bits to the left which
12783 causes the leftmost '1' bit to disappear. Then we shift logically to
12784 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12785 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12786 the width of the value-to-be-shifted, we need to special case
12787 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12788 For both such INPUT values the result will be 0. */
12789
12790 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12791 mkU64(1))));
12792
12793 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012794 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12795 /* == 0 || == 1*/ mkU64(0),
12796 /* otherwise */
12797 binop(Iop_Shr64,
12798 binop(Iop_Shl64, mkexpr(input),
12799 mkexpr(shift_amount)),
12800 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012801
12802 /* Compare the original value as an unsigned integer with 0. */
12803 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12804 mktemp(Ity_I64, mkU64(0)), False);
12805
12806 return "flogr";
12807}
12808
florian55085f82012-11-21 00:36:55 +000012809static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012810s390_irgen_STCK(IRTemp op2addr)
12811{
12812 IRDirty *d;
12813 IRTemp cc = newTemp(Ity_I64);
12814
12815 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12816 &s390x_dirtyhelper_STCK,
12817 mkIRExprVec_1(mkexpr(op2addr)));
12818 d->mFx = Ifx_Write;
12819 d->mAddr = mkexpr(op2addr);
12820 d->mSize = 8;
12821 stmt(IRStmt_Dirty(d));
12822 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12823 mkexpr(cc), mkU64(0), mkU64(0));
12824 return "stck";
12825}
12826
florian55085f82012-11-21 00:36:55 +000012827static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012828s390_irgen_STCKF(IRTemp op2addr)
12829{
florianc5c669b2012-08-26 14:32:28 +000012830 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012831 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012832 } else {
12833 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012834
florianc5c669b2012-08-26 14:32:28 +000012835 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12836 &s390x_dirtyhelper_STCKF,
12837 mkIRExprVec_1(mkexpr(op2addr)));
12838 d->mFx = Ifx_Write;
12839 d->mAddr = mkexpr(op2addr);
12840 d->mSize = 8;
12841 stmt(IRStmt_Dirty(d));
12842 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12843 mkexpr(cc), mkU64(0), mkU64(0));
12844 }
sewardj1e5fea62011-05-17 16:18:36 +000012845 return "stckf";
12846}
12847
florian55085f82012-11-21 00:36:55 +000012848static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012849s390_irgen_STCKE(IRTemp op2addr)
12850{
12851 IRDirty *d;
12852 IRTemp cc = newTemp(Ity_I64);
12853
12854 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12855 &s390x_dirtyhelper_STCKE,
12856 mkIRExprVec_1(mkexpr(op2addr)));
12857 d->mFx = Ifx_Write;
12858 d->mAddr = mkexpr(op2addr);
12859 d->mSize = 16;
12860 stmt(IRStmt_Dirty(d));
12861 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12862 mkexpr(cc), mkU64(0), mkU64(0));
12863 return "stcke";
12864}
12865
florian55085f82012-11-21 00:36:55 +000012866static const HChar *
florian933065d2011-07-11 01:48:02 +000012867s390_irgen_STFLE(IRTemp op2addr)
12868{
florian4e0083e2012-08-26 03:41:56 +000012869 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012870 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012871 return "stfle";
12872 }
12873
florian933065d2011-07-11 01:48:02 +000012874 IRDirty *d;
12875 IRTemp cc = newTemp(Ity_I64);
12876
florian90419562013-08-15 20:54:52 +000012877 /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper */
florian933065d2011-07-11 01:48:02 +000012878 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12879 &s390x_dirtyhelper_STFLE,
florian90419562013-08-15 20:54:52 +000012880 mkIRExprVec_2(IRExpr_BBPTR(), mkexpr(op2addr)));
florian933065d2011-07-11 01:48:02 +000012881
sewardjc9069f22012-06-01 16:09:50 +000012882 d->nFxState = 1;
12883 vex_bzero(&d->fxState, sizeof(d->fxState));
12884
florian933065d2011-07-11 01:48:02 +000012885 d->fxState[0].fx = Ifx_Modify; /* read then write */
12886 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12887 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012888
12889 d->mAddr = mkexpr(op2addr);
12890 /* Pretend all double words are written */
12891 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12892 d->mFx = Ifx_Write;
12893
12894 stmt(IRStmt_Dirty(d));
12895
12896 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12897
12898 return "stfle";
12899}
12900
florian55085f82012-11-21 00:36:55 +000012901static const HChar *
floriana4384a32011-08-11 16:58:45 +000012902s390_irgen_CKSM(UChar r1,UChar r2)
12903{
12904 IRTemp addr = newTemp(Ity_I64);
12905 IRTemp op = newTemp(Ity_I32);
12906 IRTemp len = newTemp(Ity_I64);
12907 IRTemp oldval = newTemp(Ity_I32);
12908 IRTemp mask = newTemp(Ity_I32);
12909 IRTemp newop = newTemp(Ity_I32);
12910 IRTemp result = newTemp(Ity_I32);
12911 IRTemp result1 = newTemp(Ity_I32);
12912 IRTemp inc = newTemp(Ity_I64);
12913
12914 assign(oldval, get_gpr_w1(r1));
12915 assign(addr, get_gpr_dw0(r2));
12916 assign(len, get_gpr_dw0(r2+1));
12917
12918 /* Condition code is always zero. */
12919 s390_cc_set(0);
12920
12921 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012922 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012923
12924 /* Assiging the increment variable to adjust address and length
12925 later on. */
12926 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12927 mkexpr(len), mkU64(4)));
12928
12929 /* If length < 4 the final 4-byte 2nd operand value is computed by
12930 appending the remaining bytes to the right with 0. This is done
12931 by AND'ing the 4 bytes loaded from memory with an appropriate
12932 mask. If length >= 4, that mask is simply 0xffffffff. */
12933
12934 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12935 /* Mask computation when len < 4:
12936 0xffffffff << (32 - (len % 4)*8) */
12937 binop(Iop_Shl32, mkU32(0xffffffff),
12938 unop(Iop_32to8,
12939 binop(Iop_Sub32, mkU32(32),
12940 binop(Iop_Shl32,
12941 unop(Iop_64to32,
12942 binop(Iop_And64,
12943 mkexpr(len), mkU64(3))),
12944 mkU8(3))))),
12945 mkU32(0xffffffff)));
12946
12947 assign(op, load(Ity_I32, mkexpr(addr)));
12948 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12949 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12950
12951 /* Checking for carry */
12952 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12953 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12954 mkexpr(result)));
12955
12956 put_gpr_w1(r1, mkexpr(result1));
12957 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12958 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12959
florian6820ba52012-07-26 02:01:50 +000012960 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012961
12962 return "cksm";
12963}
12964
florian55085f82012-11-21 00:36:55 +000012965static const HChar *
florian9af37692012-01-15 21:01:16 +000012966s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12967{
12968 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12969 src_addr = newTemp(Ity_I64);
12970 des_addr = newTemp(Ity_I64);
12971 tab_addr = newTemp(Ity_I64);
12972 test_byte = newTemp(Ity_I8);
12973 src_len = newTemp(Ity_I64);
12974
12975 assign(src_addr, get_gpr_dw0(r2));
12976 assign(des_addr, get_gpr_dw0(r1));
12977 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012978 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012979 assign(test_byte, get_gpr_b7(0));
12980
12981 IRTemp op = newTemp(Ity_I8);
12982 IRTemp op1 = newTemp(Ity_I8);
12983 IRTemp result = newTemp(Ity_I64);
12984
12985 /* End of source string? We're done; proceed to next insn */
12986 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012987 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012988
12989 /* Load character from source string, index translation table and
12990 store translated character in op1. */
12991 assign(op, load(Ity_I8, mkexpr(src_addr)));
12992
12993 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12994 mkexpr(tab_addr)));
12995 assign(op1, load(Ity_I8, mkexpr(result)));
12996
12997 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12998 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012999 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000013000 }
13001 store(get_gpr_dw0(r1), mkexpr(op1));
13002
13003 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13004 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13005 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13006
florian6820ba52012-07-26 02:01:50 +000013007 iterate();
florian9af37692012-01-15 21:01:16 +000013008
13009 return "troo";
13010}
13011
florian55085f82012-11-21 00:36:55 +000013012static const HChar *
florian730448f2012-02-04 17:07:07 +000013013s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13014{
13015 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13016 src_addr = newTemp(Ity_I64);
13017 des_addr = newTemp(Ity_I64);
13018 tab_addr = newTemp(Ity_I64);
13019 test_byte = newTemp(Ity_I8);
13020 src_len = newTemp(Ity_I64);
13021
13022 assign(src_addr, get_gpr_dw0(r2));
13023 assign(des_addr, get_gpr_dw0(r1));
13024 assign(tab_addr, get_gpr_dw0(1));
13025 assign(src_len, get_gpr_dw0(r1+1));
13026 assign(test_byte, get_gpr_b7(0));
13027
13028 IRTemp op = newTemp(Ity_I16);
13029 IRTemp op1 = newTemp(Ity_I8);
13030 IRTemp result = newTemp(Ity_I64);
13031
13032 /* End of source string? We're done; proceed to next insn */
13033 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013034 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013035
13036 /* Load character from source string, index translation table and
13037 store translated character in op1. */
13038 assign(op, load(Ity_I16, mkexpr(src_addr)));
13039
13040 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13041 mkexpr(tab_addr)));
13042
13043 assign(op1, load(Ity_I8, mkexpr(result)));
13044
13045 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13046 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013047 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013048 }
13049 store(get_gpr_dw0(r1), mkexpr(op1));
13050
13051 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13052 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13053 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13054
florian6820ba52012-07-26 02:01:50 +000013055 iterate();
florian730448f2012-02-04 17:07:07 +000013056
13057 return "trto";
13058}
13059
florian55085f82012-11-21 00:36:55 +000013060static const HChar *
florian730448f2012-02-04 17:07:07 +000013061s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13062{
13063 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13064 src_addr = newTemp(Ity_I64);
13065 des_addr = newTemp(Ity_I64);
13066 tab_addr = newTemp(Ity_I64);
13067 test_byte = newTemp(Ity_I16);
13068 src_len = newTemp(Ity_I64);
13069
13070 assign(src_addr, get_gpr_dw0(r2));
13071 assign(des_addr, get_gpr_dw0(r1));
13072 assign(tab_addr, get_gpr_dw0(1));
13073 assign(src_len, get_gpr_dw0(r1+1));
13074 assign(test_byte, get_gpr_hw3(0));
13075
13076 IRTemp op = newTemp(Ity_I8);
13077 IRTemp op1 = newTemp(Ity_I16);
13078 IRTemp result = newTemp(Ity_I64);
13079
13080 /* End of source string? We're done; proceed to next insn */
13081 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013082 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013083
13084 /* Load character from source string, index translation table and
13085 store translated character in op1. */
13086 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13087
13088 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13089 mkexpr(tab_addr)));
13090 assign(op1, load(Ity_I16, mkexpr(result)));
13091
13092 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13093 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013094 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013095 }
13096 store(get_gpr_dw0(r1), mkexpr(op1));
13097
13098 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13099 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13100 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13101
florian6820ba52012-07-26 02:01:50 +000013102 iterate();
florian730448f2012-02-04 17:07:07 +000013103
13104 return "trot";
13105}
13106
florian55085f82012-11-21 00:36:55 +000013107static const HChar *
florian730448f2012-02-04 17:07:07 +000013108s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13109{
13110 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13111 src_addr = newTemp(Ity_I64);
13112 des_addr = newTemp(Ity_I64);
13113 tab_addr = newTemp(Ity_I64);
13114 test_byte = newTemp(Ity_I16);
13115 src_len = newTemp(Ity_I64);
13116
13117 assign(src_addr, get_gpr_dw0(r2));
13118 assign(des_addr, get_gpr_dw0(r1));
13119 assign(tab_addr, get_gpr_dw0(1));
13120 assign(src_len, get_gpr_dw0(r1+1));
13121 assign(test_byte, get_gpr_hw3(0));
13122
13123 IRTemp op = newTemp(Ity_I16);
13124 IRTemp op1 = newTemp(Ity_I16);
13125 IRTemp result = newTemp(Ity_I64);
13126
13127 /* End of source string? We're done; proceed to next insn */
13128 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013129 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013130
13131 /* Load character from source string, index translation table and
13132 store translated character in op1. */
13133 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13134
13135 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13136 mkexpr(tab_addr)));
13137 assign(op1, load(Ity_I16, mkexpr(result)));
13138
13139 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13140 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013141 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013142 }
13143
13144 store(get_gpr_dw0(r1), mkexpr(op1));
13145
13146 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13147 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13148 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13149
florian6820ba52012-07-26 02:01:50 +000013150 iterate();
florian730448f2012-02-04 17:07:07 +000013151
13152 return "trtt";
13153}
13154
florian55085f82012-11-21 00:36:55 +000013155static const HChar *
florian730448f2012-02-04 17:07:07 +000013156s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13157{
florianf87d4fb2012-05-05 02:55:24 +000013158 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000013159
florianf87d4fb2012-05-05 02:55:24 +000013160 assign(len, mkU64(length));
13161 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000013162
13163 return "tr";
13164}
13165
florian55085f82012-11-21 00:36:55 +000013166static const HChar *
florian730448f2012-02-04 17:07:07 +000013167s390_irgen_TRE(UChar r1,UChar r2)
13168{
13169 IRTemp src_addr, tab_addr, src_len, test_byte;
13170 src_addr = newTemp(Ity_I64);
13171 tab_addr = newTemp(Ity_I64);
13172 src_len = newTemp(Ity_I64);
13173 test_byte = newTemp(Ity_I8);
13174
13175 assign(src_addr, get_gpr_dw0(r1));
13176 assign(src_len, get_gpr_dw0(r1+1));
13177 assign(tab_addr, get_gpr_dw0(r2));
13178 assign(test_byte, get_gpr_b7(0));
13179
13180 IRTemp op = newTemp(Ity_I8);
13181 IRTemp op1 = newTemp(Ity_I8);
13182 IRTemp result = newTemp(Ity_I64);
13183
13184 /* End of source string? We're done; proceed to next insn */
13185 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013186 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013187
13188 /* Load character from source string and compare with test byte */
13189 assign(op, load(Ity_I8, mkexpr(src_addr)));
13190
13191 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013192 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013193
13194 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13195 mkexpr(tab_addr)));
13196
13197 assign(op1, load(Ity_I8, mkexpr(result)));
13198
13199 store(get_gpr_dw0(r1), mkexpr(op1));
13200 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13201 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13202
florian6820ba52012-07-26 02:01:50 +000013203 iterate();
florian730448f2012-02-04 17:07:07 +000013204
13205 return "tre";
13206}
13207
floriana0100c92012-07-20 00:06:35 +000013208static IRExpr *
13209s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13210{
13211 IRExpr **args, *call;
13212 args = mkIRExprVec_2(srcval, low_surrogate);
13213 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13214 "s390_do_cu21", &s390_do_cu21, args);
13215
13216 /* Nothing is excluded from definedness checking. */
13217 call->Iex.CCall.cee->mcx_mask = 0;
13218
13219 return call;
13220}
13221
florian55085f82012-11-21 00:36:55 +000013222static const HChar *
floriana0100c92012-07-20 00:06:35 +000013223s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13224{
13225 IRTemp addr1 = newTemp(Ity_I64);
13226 IRTemp addr2 = newTemp(Ity_I64);
13227 IRTemp len1 = newTemp(Ity_I64);
13228 IRTemp len2 = newTemp(Ity_I64);
13229
13230 assign(addr1, get_gpr_dw0(r1));
13231 assign(addr2, get_gpr_dw0(r2));
13232 assign(len1, get_gpr_dw0(r1 + 1));
13233 assign(len2, get_gpr_dw0(r2 + 1));
13234
13235 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13236 there are less than 2 bytes left, then the 2nd operand is exhausted
13237 and we're done here. cc = 0 */
13238 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013239 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000013240
13241 /* There are at least two bytes there. Read them. */
13242 IRTemp srcval = newTemp(Ity_I32);
13243 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13244
13245 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13246 inside the interval [0xd800 - 0xdbff] */
13247 IRTemp is_high_surrogate = newTemp(Ity_I32);
13248 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13249 mkU32(1), mkU32(0));
13250 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13251 mkU32(1), mkU32(0));
13252 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13253
13254 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13255 then the 2nd operand is exhausted and we're done here. cc = 0 */
13256 IRExpr *not_enough_bytes =
13257 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13258
florian6820ba52012-07-26 02:01:50 +000013259 next_insn_if(binop(Iop_CmpEQ32,
13260 binop(Iop_And32, mkexpr(is_high_surrogate),
13261 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000013262
13263 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13264 surrogate, read the next two bytes (low surrogate). */
13265 IRTemp low_surrogate = newTemp(Ity_I32);
13266 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13267
13268 assign(low_surrogate,
13269 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13270 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13271 mkU32(0))); // any value is fine; it will not be used
13272
13273 /* Call the helper */
13274 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013275 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13276 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000013277
13278 /* Before we can test whether the 1st operand is exhausted we need to
13279 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13280 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13281 IRExpr *invalid_low_surrogate =
13282 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13283
13284 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013285 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000013286 }
13287
13288 /* Now test whether the 1st operand is exhausted */
13289 IRTemp num_bytes = newTemp(Ity_I64);
13290 assign(num_bytes, binop(Iop_And64,
13291 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13292 mkU64(0xff)));
13293 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013294 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000013295
13296 /* Extract the bytes to be stored at addr1 */
13297 IRTemp data = newTemp(Ity_I64);
13298 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13299
13300 /* To store the bytes construct 4 dirty helper calls. The helper calls
13301 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13302 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013303 UInt i;
floriana0100c92012-07-20 00:06:35 +000013304 for (i = 1; i <= 4; ++i) {
13305 IRDirty *d;
13306
13307 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13308 &s390x_dirtyhelper_CUxy,
13309 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13310 mkexpr(num_bytes)));
13311 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13312 d->mFx = Ifx_Write;
13313 d->mAddr = mkexpr(addr1);
13314 d->mSize = i;
13315 stmt(IRStmt_Dirty(d));
13316 }
13317
13318 /* Update source address and length */
13319 IRTemp num_src_bytes = newTemp(Ity_I64);
13320 assign(num_src_bytes,
13321 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13322 mkU64(4), mkU64(2)));
13323 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13324 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13325
13326 /* Update destination address and length */
13327 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13328 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13329
florian6820ba52012-07-26 02:01:50 +000013330 iterate();
floriana0100c92012-07-20 00:06:35 +000013331
13332 return "cu21";
13333}
13334
florian2a415a12012-07-21 17:41:36 +000013335static IRExpr *
13336s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13337{
13338 IRExpr **args, *call;
13339 args = mkIRExprVec_2(srcval, low_surrogate);
13340 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13341 "s390_do_cu24", &s390_do_cu24, args);
13342
13343 /* Nothing is excluded from definedness checking. */
13344 call->Iex.CCall.cee->mcx_mask = 0;
13345
13346 return call;
13347}
13348
florian55085f82012-11-21 00:36:55 +000013349static const HChar *
florian2a415a12012-07-21 17:41:36 +000013350s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13351{
13352 IRTemp addr1 = newTemp(Ity_I64);
13353 IRTemp addr2 = newTemp(Ity_I64);
13354 IRTemp len1 = newTemp(Ity_I64);
13355 IRTemp len2 = newTemp(Ity_I64);
13356
13357 assign(addr1, get_gpr_dw0(r1));
13358 assign(addr2, get_gpr_dw0(r2));
13359 assign(len1, get_gpr_dw0(r1 + 1));
13360 assign(len2, get_gpr_dw0(r2 + 1));
13361
13362 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13363 there are less than 2 bytes left, then the 2nd operand is exhausted
13364 and we're done here. cc = 0 */
13365 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013366 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013367
13368 /* There are at least two bytes there. Read them. */
13369 IRTemp srcval = newTemp(Ity_I32);
13370 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13371
13372 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13373 inside the interval [0xd800 - 0xdbff] */
13374 IRTemp is_high_surrogate = newTemp(Ity_I32);
13375 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13376 mkU32(1), mkU32(0));
13377 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13378 mkU32(1), mkU32(0));
13379 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13380
13381 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13382 then the 2nd operand is exhausted and we're done here. cc = 0 */
13383 IRExpr *not_enough_bytes =
13384 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13385
florian6820ba52012-07-26 02:01:50 +000013386 next_insn_if(binop(Iop_CmpEQ32,
13387 binop(Iop_And32, mkexpr(is_high_surrogate),
13388 not_enough_bytes),
13389 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013390
13391 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13392 surrogate, read the next two bytes (low surrogate). */
13393 IRTemp low_surrogate = newTemp(Ity_I32);
13394 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13395
13396 assign(low_surrogate,
13397 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13398 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13399 mkU32(0))); // any value is fine; it will not be used
13400
13401 /* Call the helper */
13402 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013403 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13404 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013405
13406 /* Before we can test whether the 1st operand is exhausted we need to
13407 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13408 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13409 IRExpr *invalid_low_surrogate =
13410 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13411
13412 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013413 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013414 }
13415
13416 /* Now test whether the 1st operand is exhausted */
13417 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013418 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013419
13420 /* Extract the bytes to be stored at addr1 */
13421 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13422
13423 store(mkexpr(addr1), data);
13424
13425 /* Update source address and length */
13426 IRTemp num_src_bytes = newTemp(Ity_I64);
13427 assign(num_src_bytes,
13428 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13429 mkU64(4), mkU64(2)));
13430 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13431 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13432
13433 /* Update destination address and length */
13434 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13435 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13436
florian6820ba52012-07-26 02:01:50 +000013437 iterate();
florian2a415a12012-07-21 17:41:36 +000013438
13439 return "cu24";
13440}
floriana4384a32011-08-11 16:58:45 +000013441
florian956194b2012-07-28 22:18:32 +000013442static IRExpr *
13443s390_call_cu42(IRExpr *srcval)
13444{
13445 IRExpr **args, *call;
13446 args = mkIRExprVec_1(srcval);
13447 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13448 "s390_do_cu42", &s390_do_cu42, args);
13449
13450 /* Nothing is excluded from definedness checking. */
13451 call->Iex.CCall.cee->mcx_mask = 0;
13452
13453 return call;
13454}
13455
florian55085f82012-11-21 00:36:55 +000013456static const HChar *
florian956194b2012-07-28 22:18:32 +000013457s390_irgen_CU42(UChar r1, UChar r2)
13458{
13459 IRTemp addr1 = newTemp(Ity_I64);
13460 IRTemp addr2 = newTemp(Ity_I64);
13461 IRTemp len1 = newTemp(Ity_I64);
13462 IRTemp len2 = newTemp(Ity_I64);
13463
13464 assign(addr1, get_gpr_dw0(r1));
13465 assign(addr2, get_gpr_dw0(r2));
13466 assign(len1, get_gpr_dw0(r1 + 1));
13467 assign(len2, get_gpr_dw0(r2 + 1));
13468
13469 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13470 there are less than 4 bytes left, then the 2nd operand is exhausted
13471 and we're done here. cc = 0 */
13472 s390_cc_set(0);
13473 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13474
13475 /* Read the 2nd operand. */
13476 IRTemp srcval = newTemp(Ity_I32);
13477 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13478
13479 /* Call the helper */
13480 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013481 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013482
13483 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13484 cc=2 outranks cc=1 (1st operand exhausted) */
13485 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13486
13487 s390_cc_set(2);
13488 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13489
13490 /* Now test whether the 1st operand is exhausted */
13491 IRTemp num_bytes = newTemp(Ity_I64);
13492 assign(num_bytes, binop(Iop_And64,
13493 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13494 mkU64(0xff)));
13495 s390_cc_set(1);
13496 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13497
13498 /* Extract the bytes to be stored at addr1 */
13499 IRTemp data = newTemp(Ity_I64);
13500 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13501
13502 /* To store the bytes construct 2 dirty helper calls. The helper calls
13503 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13504 that only one of them will be called at runtime. */
13505
13506 Int i;
13507 for (i = 2; i <= 4; ++i) {
13508 IRDirty *d;
13509
13510 if (i == 3) continue; // skip this one
13511
13512 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13513 &s390x_dirtyhelper_CUxy,
13514 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13515 mkexpr(num_bytes)));
13516 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13517 d->mFx = Ifx_Write;
13518 d->mAddr = mkexpr(addr1);
13519 d->mSize = i;
13520 stmt(IRStmt_Dirty(d));
13521 }
13522
13523 /* Update source address and length */
13524 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13525 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13526
13527 /* Update destination address and length */
13528 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13529 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13530
13531 iterate();
13532
13533 return "cu42";
13534}
13535
florian6d9b9b22012-08-03 18:35:39 +000013536static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013537s390_call_cu41(IRExpr *srcval)
13538{
13539 IRExpr **args, *call;
13540 args = mkIRExprVec_1(srcval);
13541 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13542 "s390_do_cu41", &s390_do_cu41, args);
13543
13544 /* Nothing is excluded from definedness checking. */
13545 call->Iex.CCall.cee->mcx_mask = 0;
13546
13547 return call;
13548}
13549
florian55085f82012-11-21 00:36:55 +000013550static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013551s390_irgen_CU41(UChar r1, UChar r2)
13552{
13553 IRTemp addr1 = newTemp(Ity_I64);
13554 IRTemp addr2 = newTemp(Ity_I64);
13555 IRTemp len1 = newTemp(Ity_I64);
13556 IRTemp len2 = newTemp(Ity_I64);
13557
13558 assign(addr1, get_gpr_dw0(r1));
13559 assign(addr2, get_gpr_dw0(r2));
13560 assign(len1, get_gpr_dw0(r1 + 1));
13561 assign(len2, get_gpr_dw0(r2 + 1));
13562
13563 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13564 there are less than 4 bytes left, then the 2nd operand is exhausted
13565 and we're done here. cc = 0 */
13566 s390_cc_set(0);
13567 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13568
13569 /* Read the 2nd operand. */
13570 IRTemp srcval = newTemp(Ity_I32);
13571 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13572
13573 /* Call the helper */
13574 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013575 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013576
13577 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13578 cc=2 outranks cc=1 (1st operand exhausted) */
13579 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13580
13581 s390_cc_set(2);
13582 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13583
13584 /* Now test whether the 1st operand is exhausted */
13585 IRTemp num_bytes = newTemp(Ity_I64);
13586 assign(num_bytes, binop(Iop_And64,
13587 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13588 mkU64(0xff)));
13589 s390_cc_set(1);
13590 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13591
13592 /* Extract the bytes to be stored at addr1 */
13593 IRTemp data = newTemp(Ity_I64);
13594 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13595
13596 /* To store the bytes construct 4 dirty helper calls. The helper calls
13597 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13598 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013599 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013600 for (i = 1; i <= 4; ++i) {
13601 IRDirty *d;
13602
13603 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13604 &s390x_dirtyhelper_CUxy,
13605 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13606 mkexpr(num_bytes)));
13607 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13608 d->mFx = Ifx_Write;
13609 d->mAddr = mkexpr(addr1);
13610 d->mSize = i;
13611 stmt(IRStmt_Dirty(d));
13612 }
13613
13614 /* Update source address and length */
13615 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13616 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13617
13618 /* Update destination address and length */
13619 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13620 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13621
13622 iterate();
13623
13624 return "cu41";
13625}
13626
13627static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013628s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013629{
13630 IRExpr **args, *call;
13631 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013632 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13633 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013634
13635 /* Nothing is excluded from definedness checking. */
13636 call->Iex.CCall.cee->mcx_mask = 0;
13637
13638 return call;
13639}
13640
13641static IRExpr *
13642s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13643 IRExpr *byte4, IRExpr *stuff)
13644{
13645 IRExpr **args, *call;
13646 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13647 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13648 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13649
13650 /* Nothing is excluded from definedness checking. */
13651 call->Iex.CCall.cee->mcx_mask = 0;
13652
13653 return call;
13654}
13655
florian3f8a96a2012-08-05 02:59:55 +000013656static IRExpr *
13657s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13658 IRExpr *byte4, IRExpr *stuff)
13659{
13660 IRExpr **args, *call;
13661 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13662 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13663 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13664
13665 /* Nothing is excluded from definedness checking. */
13666 call->Iex.CCall.cee->mcx_mask = 0;
13667
13668 return call;
13669}
13670
13671static void
13672s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013673{
13674 IRTemp addr1 = newTemp(Ity_I64);
13675 IRTemp addr2 = newTemp(Ity_I64);
13676 IRTemp len1 = newTemp(Ity_I64);
13677 IRTemp len2 = newTemp(Ity_I64);
13678
13679 assign(addr1, get_gpr_dw0(r1));
13680 assign(addr2, get_gpr_dw0(r2));
13681 assign(len1, get_gpr_dw0(r1 + 1));
13682 assign(len2, get_gpr_dw0(r2 + 1));
13683
13684 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13685
13686 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13687 there is less than 1 byte left, then the 2nd operand is exhausted
13688 and we're done here. cc = 0 */
13689 s390_cc_set(0);
13690 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13691
13692 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013693 IRTemp byte1 = newTemp(Ity_I64);
13694 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013695
13696 /* Call the helper to get number of bytes and invalid byte indicator */
13697 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013698 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013699 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013700
13701 /* Check for invalid 1st byte */
13702 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13703 s390_cc_set(2);
13704 next_insn_if(is_invalid);
13705
13706 /* How many bytes do we have to read? */
13707 IRTemp num_src_bytes = newTemp(Ity_I64);
13708 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13709
13710 /* Now test whether the 2nd operand is exhausted */
13711 s390_cc_set(0);
13712 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13713
13714 /* Read the remaining bytes */
13715 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13716
13717 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13718 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013719 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013720 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13721 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013722 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013723 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13724 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013725 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013726
13727 /* Call the helper to get the converted value and invalid byte indicator.
13728 We can pass at most 5 arguments; therefore some encoding is needed
13729 here */
13730 IRExpr *stuff = binop(Iop_Or64,
13731 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13732 mkU64(extended_checking));
13733 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013734
13735 if (is_cu12) {
13736 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13737 byte4, stuff));
13738 } else {
13739 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13740 byte4, stuff));
13741 }
florian6d9b9b22012-08-03 18:35:39 +000013742
13743 /* Check for invalid character */
13744 s390_cc_set(2);
13745 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13746 next_insn_if(is_invalid);
13747
13748 /* Now test whether the 1st operand is exhausted */
13749 IRTemp num_bytes = newTemp(Ity_I64);
13750 assign(num_bytes, binop(Iop_And64,
13751 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13752 mkU64(0xff)));
13753 s390_cc_set(1);
13754 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13755
13756 /* Extract the bytes to be stored at addr1 */
13757 IRTemp data = newTemp(Ity_I64);
13758 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13759
florian3f8a96a2012-08-05 02:59:55 +000013760 if (is_cu12) {
13761 /* To store the bytes construct 2 dirty helper calls. The helper calls
13762 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13763 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013764
florian3f8a96a2012-08-05 02:59:55 +000013765 Int i;
13766 for (i = 2; i <= 4; ++i) {
13767 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013768
florian3f8a96a2012-08-05 02:59:55 +000013769 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013770
florian3f8a96a2012-08-05 02:59:55 +000013771 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13772 &s390x_dirtyhelper_CUxy,
13773 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13774 mkexpr(num_bytes)));
13775 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13776 d->mFx = Ifx_Write;
13777 d->mAddr = mkexpr(addr1);
13778 d->mSize = i;
13779 stmt(IRStmt_Dirty(d));
13780 }
13781 } else {
13782 // cu14
13783 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013784 }
13785
13786 /* Update source address and length */
13787 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13788 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13789
13790 /* Update destination address and length */
13791 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13792 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13793
13794 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013795}
13796
florian55085f82012-11-21 00:36:55 +000013797static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013798s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13799{
13800 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013801
13802 return "cu12";
13803}
13804
florian55085f82012-11-21 00:36:55 +000013805static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013806s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13807{
13808 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13809
13810 return "cu14";
13811}
13812
florian8c88cb62012-08-26 18:58:13 +000013813static IRExpr *
13814s390_call_ecag(IRExpr *op2addr)
13815{
13816 IRExpr **args, *call;
13817
13818 args = mkIRExprVec_1(op2addr);
13819 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13820 "s390_do_ecag", &s390_do_ecag, args);
13821
13822 /* Nothing is excluded from definedness checking. */
13823 call->Iex.CCall.cee->mcx_mask = 0;
13824
13825 return call;
13826}
13827
florian55085f82012-11-21 00:36:55 +000013828static const HChar *
floriand2129202012-09-01 20:01:39 +000013829s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013830{
13831 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013832 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013833 } else {
13834 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13835 }
13836
13837 return "ecag";
13838}
13839
13840
florianb7def222012-12-04 04:45:32 +000013841/* New insns are added here.
13842 If an insn is contingent on a facility being installed also
13843 check whether the list of supported facilities in function
13844 s390x_dirtyhelper_STFLE needs updating */
13845
sewardj2019a972011-03-07 16:04:07 +000013846/*------------------------------------------------------------*/
13847/*--- Build IR for special instructions ---*/
13848/*------------------------------------------------------------*/
13849
florianb4df7682011-07-05 02:09:01 +000013850static void
sewardj2019a972011-03-07 16:04:07 +000013851s390_irgen_client_request(void)
13852{
13853 if (0)
13854 vex_printf("%%R3 = client_request ( %%R2 )\n");
13855
florianf9e1ed72012-04-17 02:41:56 +000013856 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13857 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013858
florianf9e1ed72012-04-17 02:41:56 +000013859 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013860 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013861
13862 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013863}
13864
florianb4df7682011-07-05 02:09:01 +000013865static void
sewardj2019a972011-03-07 16:04:07 +000013866s390_irgen_guest_NRADDR(void)
13867{
13868 if (0)
13869 vex_printf("%%R3 = guest_NRADDR\n");
13870
floriane88b3c92011-07-05 02:48:39 +000013871 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013872}
13873
florianb4df7682011-07-05 02:09:01 +000013874static void
sewardj2019a972011-03-07 16:04:07 +000013875s390_irgen_call_noredir(void)
13876{
florianf9e1ed72012-04-17 02:41:56 +000013877 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13878 + S390_SPECIAL_OP_SIZE;
13879
sewardj2019a972011-03-07 16:04:07 +000013880 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013881 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013882
13883 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013884 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013885
13886 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013887 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013888}
13889
13890/* Force proper alignment for the structures below. */
13891#pragma pack(1)
13892
13893
13894static s390_decode_t
13895s390_decode_2byte_and_irgen(UChar *bytes)
13896{
13897 typedef union {
13898 struct {
13899 unsigned int op : 16;
13900 } E;
13901 struct {
13902 unsigned int op : 8;
13903 unsigned int i : 8;
13904 } I;
13905 struct {
13906 unsigned int op : 8;
13907 unsigned int r1 : 4;
13908 unsigned int r2 : 4;
13909 } RR;
13910 } formats;
13911 union {
13912 formats fmt;
13913 UShort value;
13914 } ovl;
13915
13916 vassert(sizeof(formats) == 2);
13917
florianffbd84d2012-12-09 02:06:29 +000013918 ((UChar *)(&ovl.value))[0] = bytes[0];
13919 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013920
13921 switch (ovl.value & 0xffff) {
13922 case 0x0101: /* PR */ goto unimplemented;
13923 case 0x0102: /* UPT */ goto unimplemented;
13924 case 0x0104: /* PTFF */ goto unimplemented;
13925 case 0x0107: /* SCKPF */ goto unimplemented;
florian78d5ef72013-05-11 15:02:58 +000013926 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013927 case 0x010b: /* TAM */ goto unimplemented;
13928 case 0x010c: /* SAM24 */ goto unimplemented;
13929 case 0x010d: /* SAM31 */ goto unimplemented;
13930 case 0x010e: /* SAM64 */ goto unimplemented;
13931 case 0x01ff: /* TRAP2 */ goto unimplemented;
13932 }
13933
13934 switch ((ovl.value & 0xff00) >> 8) {
13935 case 0x04: /* SPM */ goto unimplemented;
13936 case 0x05: /* BALR */ goto unimplemented;
13937 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13938 goto ok;
13939 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13940 goto ok;
13941 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13942 case 0x0b: /* BSM */ goto unimplemented;
13943 case 0x0c: /* BASSM */ goto unimplemented;
13944 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13945 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013946 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13947 goto ok;
13948 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13949 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013950 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13951 goto ok;
13952 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13953 goto ok;
13954 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13955 goto ok;
13956 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13957 goto ok;
13958 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13959 goto ok;
13960 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13961 goto ok;
13962 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13963 goto ok;
13964 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13965 goto ok;
13966 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13967 goto ok;
13968 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13969 goto ok;
13970 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13971 goto ok;
13972 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13973 goto ok;
13974 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13975 goto ok;
13976 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13977 goto ok;
13978 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13979 goto ok;
13980 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13981 goto ok;
13982 case 0x20: /* LPDR */ goto unimplemented;
13983 case 0x21: /* LNDR */ goto unimplemented;
13984 case 0x22: /* LTDR */ goto unimplemented;
13985 case 0x23: /* LCDR */ goto unimplemented;
13986 case 0x24: /* HDR */ goto unimplemented;
13987 case 0x25: /* LDXR */ goto unimplemented;
13988 case 0x26: /* MXR */ goto unimplemented;
13989 case 0x27: /* MXDR */ goto unimplemented;
13990 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13991 goto ok;
13992 case 0x29: /* CDR */ goto unimplemented;
13993 case 0x2a: /* ADR */ goto unimplemented;
13994 case 0x2b: /* SDR */ goto unimplemented;
13995 case 0x2c: /* MDR */ goto unimplemented;
13996 case 0x2d: /* DDR */ goto unimplemented;
13997 case 0x2e: /* AWR */ goto unimplemented;
13998 case 0x2f: /* SWR */ goto unimplemented;
13999 case 0x30: /* LPER */ goto unimplemented;
14000 case 0x31: /* LNER */ goto unimplemented;
14001 case 0x32: /* LTER */ goto unimplemented;
14002 case 0x33: /* LCER */ goto unimplemented;
14003 case 0x34: /* HER */ goto unimplemented;
14004 case 0x35: /* LEDR */ goto unimplemented;
14005 case 0x36: /* AXR */ goto unimplemented;
14006 case 0x37: /* SXR */ goto unimplemented;
14007 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14008 goto ok;
14009 case 0x39: /* CER */ goto unimplemented;
14010 case 0x3a: /* AER */ goto unimplemented;
14011 case 0x3b: /* SER */ goto unimplemented;
14012 case 0x3c: /* MDER */ goto unimplemented;
14013 case 0x3d: /* DER */ goto unimplemented;
14014 case 0x3e: /* AUR */ goto unimplemented;
14015 case 0x3f: /* SUR */ goto unimplemented;
14016 }
14017
14018 return S390_DECODE_UNKNOWN_INSN;
14019
14020ok:
14021 return S390_DECODE_OK;
14022
14023unimplemented:
14024 return S390_DECODE_UNIMPLEMENTED_INSN;
14025}
14026
14027static s390_decode_t
14028s390_decode_4byte_and_irgen(UChar *bytes)
14029{
14030 typedef union {
14031 struct {
14032 unsigned int op1 : 8;
14033 unsigned int r1 : 4;
14034 unsigned int op2 : 4;
14035 unsigned int i2 : 16;
14036 } RI;
14037 struct {
14038 unsigned int op : 16;
14039 unsigned int : 8;
14040 unsigned int r1 : 4;
14041 unsigned int r2 : 4;
14042 } RRE;
14043 struct {
14044 unsigned int op : 16;
14045 unsigned int r1 : 4;
14046 unsigned int : 4;
14047 unsigned int r3 : 4;
14048 unsigned int r2 : 4;
14049 } RRF;
14050 struct {
14051 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000014052 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000014053 unsigned int m4 : 4;
14054 unsigned int r1 : 4;
14055 unsigned int r2 : 4;
14056 } RRF2;
14057 struct {
14058 unsigned int op : 16;
14059 unsigned int r3 : 4;
14060 unsigned int : 4;
14061 unsigned int r1 : 4;
14062 unsigned int r2 : 4;
14063 } RRF3;
14064 struct {
14065 unsigned int op : 16;
14066 unsigned int r3 : 4;
14067 unsigned int : 4;
14068 unsigned int r1 : 4;
14069 unsigned int r2 : 4;
14070 } RRR;
14071 struct {
14072 unsigned int op : 16;
14073 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000014074 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000014075 unsigned int r1 : 4;
14076 unsigned int r2 : 4;
14077 } RRF4;
14078 struct {
floriane38f6412012-12-21 17:32:12 +000014079 unsigned int op : 16;
14080 unsigned int : 4;
14081 unsigned int m4 : 4;
14082 unsigned int r1 : 4;
14083 unsigned int r2 : 4;
14084 } RRF5;
14085 struct {
sewardj2019a972011-03-07 16:04:07 +000014086 unsigned int op : 8;
14087 unsigned int r1 : 4;
14088 unsigned int r3 : 4;
14089 unsigned int b2 : 4;
14090 unsigned int d2 : 12;
14091 } RS;
14092 struct {
14093 unsigned int op : 8;
14094 unsigned int r1 : 4;
14095 unsigned int r3 : 4;
14096 unsigned int i2 : 16;
14097 } RSI;
14098 struct {
14099 unsigned int op : 8;
14100 unsigned int r1 : 4;
14101 unsigned int x2 : 4;
14102 unsigned int b2 : 4;
14103 unsigned int d2 : 12;
14104 } RX;
14105 struct {
14106 unsigned int op : 16;
14107 unsigned int b2 : 4;
14108 unsigned int d2 : 12;
14109 } S;
14110 struct {
14111 unsigned int op : 8;
14112 unsigned int i2 : 8;
14113 unsigned int b1 : 4;
14114 unsigned int d1 : 12;
14115 } SI;
14116 } formats;
14117 union {
14118 formats fmt;
14119 UInt value;
14120 } ovl;
14121
14122 vassert(sizeof(formats) == 4);
14123
florianffbd84d2012-12-09 02:06:29 +000014124 ((UChar *)(&ovl.value))[0] = bytes[0];
14125 ((UChar *)(&ovl.value))[1] = bytes[1];
14126 ((UChar *)(&ovl.value))[2] = bytes[2];
14127 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000014128
14129 switch ((ovl.value & 0xff0f0000) >> 16) {
14130 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14131 ovl.fmt.RI.i2); goto ok;
14132 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14133 ovl.fmt.RI.i2); goto ok;
14134 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14135 ovl.fmt.RI.i2); goto ok;
14136 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14137 ovl.fmt.RI.i2); goto ok;
14138 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14139 ovl.fmt.RI.i2); goto ok;
14140 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14141 ovl.fmt.RI.i2); goto ok;
14142 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14143 ovl.fmt.RI.i2); goto ok;
14144 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14145 ovl.fmt.RI.i2); goto ok;
14146 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14147 ovl.fmt.RI.i2); goto ok;
14148 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14149 ovl.fmt.RI.i2); goto ok;
14150 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14151 ovl.fmt.RI.i2); goto ok;
14152 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14153 ovl.fmt.RI.i2); goto ok;
14154 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14155 ovl.fmt.RI.i2); goto ok;
14156 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14157 ovl.fmt.RI.i2); goto ok;
14158 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14159 ovl.fmt.RI.i2); goto ok;
14160 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14161 ovl.fmt.RI.i2); goto ok;
14162 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14163 ovl.fmt.RI.i2); goto ok;
14164 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14165 ovl.fmt.RI.i2); goto ok;
14166 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14167 ovl.fmt.RI.i2); goto ok;
14168 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14169 ovl.fmt.RI.i2); goto ok;
14170 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14171 goto ok;
14172 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14173 ovl.fmt.RI.i2); goto ok;
14174 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14175 ovl.fmt.RI.i2); goto ok;
14176 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14177 ovl.fmt.RI.i2); goto ok;
14178 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14179 goto ok;
14180 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14181 ovl.fmt.RI.i2); goto ok;
14182 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14183 goto ok;
14184 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14185 ovl.fmt.RI.i2); goto ok;
14186 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14187 goto ok;
14188 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14189 ovl.fmt.RI.i2); goto ok;
14190 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14191 goto ok;
14192 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14193 ovl.fmt.RI.i2); goto ok;
14194 }
14195
14196 switch ((ovl.value & 0xffff0000) >> 16) {
14197 case 0x8000: /* SSM */ goto unimplemented;
14198 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014199 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014200 case 0xb202: /* STIDP */ goto unimplemented;
14201 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014202 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14203 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014204 case 0xb206: /* SCKC */ goto unimplemented;
14205 case 0xb207: /* STCKC */ goto unimplemented;
14206 case 0xb208: /* SPT */ goto unimplemented;
14207 case 0xb209: /* STPT */ goto unimplemented;
14208 case 0xb20a: /* SPKA */ goto unimplemented;
14209 case 0xb20b: /* IPK */ goto unimplemented;
14210 case 0xb20d: /* PTLB */ goto unimplemented;
14211 case 0xb210: /* SPX */ goto unimplemented;
14212 case 0xb211: /* STPX */ goto unimplemented;
14213 case 0xb212: /* STAP */ goto unimplemented;
14214 case 0xb214: /* SIE */ goto unimplemented;
14215 case 0xb218: /* PC */ goto unimplemented;
14216 case 0xb219: /* SAC */ goto unimplemented;
14217 case 0xb21a: /* CFC */ goto unimplemented;
14218 case 0xb221: /* IPTE */ goto unimplemented;
14219 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
14220 case 0xb223: /* IVSK */ goto unimplemented;
14221 case 0xb224: /* IAC */ goto unimplemented;
14222 case 0xb225: /* SSAR */ goto unimplemented;
14223 case 0xb226: /* EPAR */ goto unimplemented;
14224 case 0xb227: /* ESAR */ goto unimplemented;
14225 case 0xb228: /* PT */ goto unimplemented;
14226 case 0xb229: /* ISKE */ goto unimplemented;
14227 case 0xb22a: /* RRBE */ goto unimplemented;
14228 case 0xb22b: /* SSKE */ goto unimplemented;
14229 case 0xb22c: /* TB */ goto unimplemented;
14230 case 0xb22d: /* DXR */ goto unimplemented;
14231 case 0xb22e: /* PGIN */ goto unimplemented;
14232 case 0xb22f: /* PGOUT */ goto unimplemented;
14233 case 0xb230: /* CSCH */ goto unimplemented;
14234 case 0xb231: /* HSCH */ goto unimplemented;
14235 case 0xb232: /* MSCH */ goto unimplemented;
14236 case 0xb233: /* SSCH */ goto unimplemented;
14237 case 0xb234: /* STSCH */ goto unimplemented;
14238 case 0xb235: /* TSCH */ goto unimplemented;
14239 case 0xb236: /* TPI */ goto unimplemented;
14240 case 0xb237: /* SAL */ goto unimplemented;
14241 case 0xb238: /* RSCH */ goto unimplemented;
14242 case 0xb239: /* STCRW */ goto unimplemented;
14243 case 0xb23a: /* STCPS */ goto unimplemented;
14244 case 0xb23b: /* RCHP */ goto unimplemented;
14245 case 0xb23c: /* SCHM */ goto unimplemented;
14246 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000014247 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14248 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014249 case 0xb244: /* SQDR */ goto unimplemented;
14250 case 0xb245: /* SQER */ goto unimplemented;
14251 case 0xb246: /* STURA */ goto unimplemented;
14252 case 0xb247: /* MSTA */ goto unimplemented;
14253 case 0xb248: /* PALB */ goto unimplemented;
14254 case 0xb249: /* EREG */ goto unimplemented;
14255 case 0xb24a: /* ESTA */ goto unimplemented;
14256 case 0xb24b: /* LURA */ goto unimplemented;
14257 case 0xb24c: /* TAR */ goto unimplemented;
14258 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14259 ovl.fmt.RRE.r2); goto ok;
14260 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14261 goto ok;
14262 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14263 goto ok;
14264 case 0xb250: /* CSP */ goto unimplemented;
14265 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14266 ovl.fmt.RRE.r2); goto ok;
14267 case 0xb254: /* MVPG */ goto unimplemented;
14268 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14269 ovl.fmt.RRE.r2); goto ok;
14270 case 0xb257: /* CUSE */ goto unimplemented;
14271 case 0xb258: /* BSG */ goto unimplemented;
14272 case 0xb25a: /* BSA */ goto unimplemented;
14273 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14274 ovl.fmt.RRE.r2); goto ok;
14275 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14276 ovl.fmt.RRE.r2); goto ok;
14277 case 0xb263: /* CMPSC */ goto unimplemented;
14278 case 0xb274: /* SIGA */ goto unimplemented;
14279 case 0xb276: /* XSCH */ goto unimplemented;
14280 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014281 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 +000014282 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014283 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 +000014284 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014285 case 0xb280: /* LPP */ goto unimplemented;
14286 case 0xb284: /* LCCTL */ goto unimplemented;
14287 case 0xb285: /* LPCTL */ goto unimplemented;
14288 case 0xb286: /* QSI */ goto unimplemented;
14289 case 0xb287: /* LSCTL */ goto unimplemented;
14290 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014291 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14292 goto ok;
14293 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14294 goto ok;
14295 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14296 goto ok;
florian730448f2012-02-04 17:07:07 +000014297 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 +000014298 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14299 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14300 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000014301 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14302 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14303 goto ok;
florian933065d2011-07-11 01:48:02 +000014304 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14305 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014306 case 0xb2b1: /* STFL */ goto unimplemented;
14307 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000014308 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14309 goto ok;
florian82cdba62013-03-12 01:31:24 +000014310 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14311 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014312 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014313 case 0xb2e0: /* SCCTR */ goto unimplemented;
14314 case 0xb2e1: /* SPCTR */ goto unimplemented;
14315 case 0xb2e4: /* ECCTR */ goto unimplemented;
14316 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014317 case 0xb2e8: /* PPA */ goto unimplemented;
14318 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014319 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014320 case 0xb2f8: /* TEND */ goto unimplemented;
14321 case 0xb2fa: /* NIAI */ goto unimplemented;
14322 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014323 case 0xb2ff: /* TRAP4 */ goto unimplemented;
14324 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14325 ovl.fmt.RRE.r2); goto ok;
14326 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14327 ovl.fmt.RRE.r2); goto ok;
14328 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14329 ovl.fmt.RRE.r2); goto ok;
14330 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14331 ovl.fmt.RRE.r2); goto ok;
14332 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14333 ovl.fmt.RRE.r2); goto ok;
14334 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14335 ovl.fmt.RRE.r2); goto ok;
14336 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14337 ovl.fmt.RRE.r2); goto ok;
14338 case 0xb307: /* MXDBR */ goto unimplemented;
14339 case 0xb308: /* KEBR */ goto unimplemented;
14340 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14341 ovl.fmt.RRE.r2); goto ok;
14342 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14343 ovl.fmt.RRE.r2); goto ok;
14344 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14345 ovl.fmt.RRE.r2); goto ok;
14346 case 0xb30c: /* MDEBR */ goto unimplemented;
14347 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14348 ovl.fmt.RRE.r2); goto ok;
14349 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14350 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14351 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14352 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14353 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14354 ovl.fmt.RRE.r2); goto ok;
14355 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14356 ovl.fmt.RRE.r2); goto ok;
14357 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14358 ovl.fmt.RRE.r2); goto ok;
14359 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14360 ovl.fmt.RRE.r2); goto ok;
14361 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14362 ovl.fmt.RRE.r2); goto ok;
14363 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14364 ovl.fmt.RRE.r2); goto ok;
14365 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14366 ovl.fmt.RRE.r2); goto ok;
14367 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14368 ovl.fmt.RRE.r2); goto ok;
14369 case 0xb318: /* KDBR */ goto unimplemented;
14370 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14371 ovl.fmt.RRE.r2); goto ok;
14372 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14373 ovl.fmt.RRE.r2); goto ok;
14374 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14375 ovl.fmt.RRE.r2); goto ok;
14376 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14377 ovl.fmt.RRE.r2); goto ok;
14378 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14379 ovl.fmt.RRE.r2); goto ok;
14380 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14381 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14382 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14383 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14384 case 0xb324: /* LDER */ goto unimplemented;
14385 case 0xb325: /* LXDR */ goto unimplemented;
14386 case 0xb326: /* LXER */ goto unimplemented;
14387 case 0xb32e: /* MAER */ goto unimplemented;
14388 case 0xb32f: /* MSER */ goto unimplemented;
14389 case 0xb336: /* SQXR */ goto unimplemented;
14390 case 0xb337: /* MEER */ goto unimplemented;
14391 case 0xb338: /* MAYLR */ goto unimplemented;
14392 case 0xb339: /* MYLR */ goto unimplemented;
14393 case 0xb33a: /* MAYR */ goto unimplemented;
14394 case 0xb33b: /* MYR */ goto unimplemented;
14395 case 0xb33c: /* MAYHR */ goto unimplemented;
14396 case 0xb33d: /* MYHR */ goto unimplemented;
14397 case 0xb33e: /* MADR */ goto unimplemented;
14398 case 0xb33f: /* MSDR */ goto unimplemented;
14399 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14400 ovl.fmt.RRE.r2); goto ok;
14401 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14402 ovl.fmt.RRE.r2); goto ok;
14403 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14404 ovl.fmt.RRE.r2); goto ok;
14405 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14406 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014407 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14408 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14409 ovl.fmt.RRF2.r2); goto ok;
14410 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14411 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14412 ovl.fmt.RRF2.r2); goto ok;
14413 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14414 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14415 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014416 case 0xb347: /* FIXBR */ goto unimplemented;
14417 case 0xb348: /* KXBR */ goto unimplemented;
14418 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14419 ovl.fmt.RRE.r2); goto ok;
14420 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14421 ovl.fmt.RRE.r2); goto ok;
14422 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14423 ovl.fmt.RRE.r2); goto ok;
14424 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14425 ovl.fmt.RRE.r2); goto ok;
14426 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14427 ovl.fmt.RRE.r2); goto ok;
14428 case 0xb350: /* TBEDR */ goto unimplemented;
14429 case 0xb351: /* TBDR */ goto unimplemented;
14430 case 0xb353: /* DIEBR */ goto unimplemented;
14431 case 0xb357: /* FIEBR */ goto unimplemented;
14432 case 0xb358: /* THDER */ goto unimplemented;
14433 case 0xb359: /* THDR */ goto unimplemented;
14434 case 0xb35b: /* DIDBR */ goto unimplemented;
14435 case 0xb35f: /* FIDBR */ goto unimplemented;
14436 case 0xb360: /* LPXR */ goto unimplemented;
14437 case 0xb361: /* LNXR */ goto unimplemented;
14438 case 0xb362: /* LTXR */ goto unimplemented;
14439 case 0xb363: /* LCXR */ goto unimplemented;
14440 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14441 ovl.fmt.RRE.r2); goto ok;
14442 case 0xb366: /* LEXR */ goto unimplemented;
14443 case 0xb367: /* FIXR */ goto unimplemented;
14444 case 0xb369: /* CXR */ goto unimplemented;
14445 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14446 ovl.fmt.RRE.r2); goto ok;
14447 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14448 ovl.fmt.RRE.r2); goto ok;
14449 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14450 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14451 goto ok;
14452 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14453 ovl.fmt.RRE.r2); goto ok;
14454 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14455 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14456 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14457 case 0xb377: /* FIER */ goto unimplemented;
14458 case 0xb37f: /* FIDR */ goto unimplemented;
14459 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14460 case 0xb385: /* SFASR */ goto unimplemented;
14461 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014462 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14463 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14464 ovl.fmt.RRF2.r2); goto ok;
14465 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14466 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14467 ovl.fmt.RRF2.r2); goto ok;
14468 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14469 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14470 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014471 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14472 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14473 ovl.fmt.RRF2.r2); goto ok;
14474 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14475 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14476 ovl.fmt.RRF2.r2); goto ok;
14477 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14478 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14479 ovl.fmt.RRF2.r2); goto ok;
14480 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14481 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14482 ovl.fmt.RRF2.r2); goto ok;
14483 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14484 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14485 ovl.fmt.RRF2.r2); goto ok;
14486 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14487 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14488 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014489 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14490 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14491 ovl.fmt.RRF2.r2); goto ok;
14492 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14493 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14494 ovl.fmt.RRF2.r2); goto ok;
14495 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14496 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14497 ovl.fmt.RRF2.r2); goto ok;
14498 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14499 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14500 ovl.fmt.RRF2.r2); goto ok;
14501 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14502 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14503 ovl.fmt.RRF2.r2); goto ok;
14504 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14505 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14506 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014507 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14508 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14509 ovl.fmt.RRF2.r2); goto ok;
14510 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14511 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14512 ovl.fmt.RRF2.r2); goto ok;
14513 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14514 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14515 ovl.fmt.RRF2.r2); goto ok;
14516 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14517 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14518 ovl.fmt.RRF2.r2); goto ok;
14519 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14520 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14521 ovl.fmt.RRF2.r2); goto ok;
14522 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14523 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14524 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014525 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14526 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14527 ovl.fmt.RRF2.r2); goto ok;
14528 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14529 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14530 ovl.fmt.RRF2.r2); goto ok;
14531 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14532 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14533 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014534 case 0xb3b4: /* CEFR */ goto unimplemented;
14535 case 0xb3b5: /* CDFR */ goto unimplemented;
14536 case 0xb3b6: /* CXFR */ goto unimplemented;
14537 case 0xb3b8: /* CFER */ goto unimplemented;
14538 case 0xb3b9: /* CFDR */ goto unimplemented;
14539 case 0xb3ba: /* CFXR */ goto unimplemented;
14540 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14541 ovl.fmt.RRE.r2); goto ok;
14542 case 0xb3c4: /* CEGR */ goto unimplemented;
14543 case 0xb3c5: /* CDGR */ goto unimplemented;
14544 case 0xb3c6: /* CXGR */ goto unimplemented;
14545 case 0xb3c8: /* CGER */ goto unimplemented;
14546 case 0xb3c9: /* CGDR */ goto unimplemented;
14547 case 0xb3ca: /* CGXR */ goto unimplemented;
14548 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14549 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014550 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14551 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14552 ovl.fmt.RRF4.r2); goto ok;
14553 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14554 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14555 ovl.fmt.RRF4.r2); goto ok;
14556 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14557 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14558 ovl.fmt.RRF4.r2); goto ok;
14559 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14560 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14561 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014562 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14563 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14564 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14565 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14566 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014567 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14568 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014569 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014570 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14571 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14572 ovl.fmt.RRF4.r2); goto ok;
14573 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14574 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14575 ovl.fmt.RRF4.r2); goto ok;
14576 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14577 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14578 ovl.fmt.RRF4.r2); goto ok;
14579 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14580 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14581 ovl.fmt.RRF4.r2); goto ok;
14582 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14583 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14584 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14585 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14586 ovl.fmt.RRF2.r2); goto ok;
14587 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14588 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014589 case 0xb3df: /* FIXTR */ goto unimplemented;
14590 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014591 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14592 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14593 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014594 case 0xb3e2: /* CUDTR */ goto unimplemented;
14595 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014596 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14597 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014598 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14599 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014600 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14601 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014602 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014603 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14604 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14605 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014606 case 0xb3ea: /* CUXTR */ goto unimplemented;
14607 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014608 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14609 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014610 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14611 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014612 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14613 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014614 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14615 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14616 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014617 case 0xb3f2: /* CDUTR */ goto unimplemented;
14618 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014619 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14620 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014621 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14622 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14623 ovl.fmt.RRF4.r2); goto ok;
14624 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14625 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14626 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14627 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14628 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014629 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14630 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14631 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014632 case 0xb3fa: /* CXUTR */ goto unimplemented;
14633 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014634 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14635 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014636 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14637 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14638 ovl.fmt.RRF4.r2); goto ok;
14639 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14640 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14641 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14642 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14643 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014644 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14645 ovl.fmt.RRE.r2); goto ok;
14646 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14647 ovl.fmt.RRE.r2); goto ok;
14648 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14649 ovl.fmt.RRE.r2); goto ok;
14650 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14651 ovl.fmt.RRE.r2); goto ok;
14652 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14653 ovl.fmt.RRE.r2); goto ok;
14654 case 0xb905: /* LURAG */ goto unimplemented;
14655 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14656 ovl.fmt.RRE.r2); goto ok;
14657 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14658 ovl.fmt.RRE.r2); goto ok;
14659 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14660 ovl.fmt.RRE.r2); goto ok;
14661 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14662 ovl.fmt.RRE.r2); goto ok;
14663 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14664 ovl.fmt.RRE.r2); goto ok;
14665 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14666 ovl.fmt.RRE.r2); goto ok;
14667 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14668 ovl.fmt.RRE.r2); goto ok;
14669 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14670 ovl.fmt.RRE.r2); goto ok;
14671 case 0xb90e: /* EREGG */ goto unimplemented;
14672 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14673 ovl.fmt.RRE.r2); goto ok;
14674 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14675 ovl.fmt.RRE.r2); goto ok;
14676 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14677 ovl.fmt.RRE.r2); goto ok;
14678 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14679 ovl.fmt.RRE.r2); goto ok;
14680 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14681 ovl.fmt.RRE.r2); goto ok;
14682 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14683 ovl.fmt.RRE.r2); goto ok;
14684 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14685 ovl.fmt.RRE.r2); goto ok;
14686 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14687 ovl.fmt.RRE.r2); goto ok;
14688 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14689 ovl.fmt.RRE.r2); goto ok;
14690 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14691 ovl.fmt.RRE.r2); goto ok;
14692 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14693 ovl.fmt.RRE.r2); goto ok;
14694 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14695 ovl.fmt.RRE.r2); goto ok;
14696 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14697 ovl.fmt.RRE.r2); goto ok;
14698 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14699 ovl.fmt.RRE.r2); goto ok;
14700 case 0xb91e: /* KMAC */ goto unimplemented;
14701 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14702 ovl.fmt.RRE.r2); goto ok;
14703 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14704 ovl.fmt.RRE.r2); goto ok;
14705 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14706 ovl.fmt.RRE.r2); goto ok;
14707 case 0xb925: /* STURG */ goto unimplemented;
14708 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14709 ovl.fmt.RRE.r2); goto ok;
14710 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14711 ovl.fmt.RRE.r2); goto ok;
14712 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014713 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014714 case 0xb92b: /* KMO */ goto unimplemented;
14715 case 0xb92c: /* PCC */ goto unimplemented;
14716 case 0xb92d: /* KMCTR */ goto unimplemented;
14717 case 0xb92e: /* KM */ goto unimplemented;
14718 case 0xb92f: /* KMC */ goto unimplemented;
14719 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14720 ovl.fmt.RRE.r2); goto ok;
14721 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14722 ovl.fmt.RRE.r2); goto ok;
14723 case 0xb93e: /* KIMD */ goto unimplemented;
14724 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014725 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14726 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14727 ovl.fmt.RRF2.r2); goto ok;
14728 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14729 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14730 ovl.fmt.RRF2.r2); goto ok;
14731 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14732 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14733 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014734 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14735 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014736 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14737 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14738 ovl.fmt.RRF2.r2); goto ok;
14739 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14740 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14741 ovl.fmt.RRF2.r2); goto ok;
14742 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14743 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14744 ovl.fmt.RRF2.r2); goto ok;
14745 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14746 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14747 ovl.fmt.RRF2.r2); goto ok;
14748 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14749 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14750 ovl.fmt.RRF2.r2); goto ok;
14751 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14752 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14753 ovl.fmt.RRF2.r2); goto ok;
14754 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14755 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14756 ovl.fmt.RRF2.r2); goto ok;
14757 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14758 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14759 ovl.fmt.RRF2.r2); goto ok;
14760 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14761 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14762 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014763 case 0xb960: /* CGRT */ goto unimplemented;
14764 case 0xb961: /* CLGRT */ goto unimplemented;
14765 case 0xb972: /* CRT */ goto unimplemented;
14766 case 0xb973: /* CLRT */ goto unimplemented;
14767 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14768 ovl.fmt.RRE.r2); goto ok;
14769 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14770 ovl.fmt.RRE.r2); goto ok;
14771 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14772 ovl.fmt.RRE.r2); goto ok;
14773 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14774 ovl.fmt.RRE.r2); goto ok;
14775 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14776 ovl.fmt.RRE.r2); goto ok;
14777 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14778 ovl.fmt.RRE.r2); goto ok;
14779 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14780 ovl.fmt.RRE.r2); goto ok;
14781 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14782 ovl.fmt.RRE.r2); goto ok;
14783 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14784 ovl.fmt.RRE.r2); goto ok;
14785 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14786 ovl.fmt.RRE.r2); goto ok;
14787 case 0xb98a: /* CSPG */ goto unimplemented;
14788 case 0xb98d: /* EPSW */ goto unimplemented;
14789 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014790 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014791 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14792 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14793 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14794 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14795 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14796 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014797 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14798 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014799 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14800 ovl.fmt.RRE.r2); goto ok;
14801 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14802 ovl.fmt.RRE.r2); goto ok;
14803 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14804 ovl.fmt.RRE.r2); goto ok;
14805 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14806 ovl.fmt.RRE.r2); goto ok;
14807 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14808 ovl.fmt.RRE.r2); goto ok;
14809 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14810 ovl.fmt.RRE.r2); goto ok;
14811 case 0xb99a: /* EPAIR */ goto unimplemented;
14812 case 0xb99b: /* ESAIR */ goto unimplemented;
14813 case 0xb99d: /* ESEA */ goto unimplemented;
14814 case 0xb99e: /* PTI */ goto unimplemented;
14815 case 0xb99f: /* SSAIR */ goto unimplemented;
14816 case 0xb9a2: /* PTF */ goto unimplemented;
14817 case 0xb9aa: /* LPTEA */ goto unimplemented;
14818 case 0xb9ae: /* RRBM */ goto unimplemented;
14819 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014820 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14821 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14822 goto ok;
florian2a415a12012-07-21 17:41:36 +000014823 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14824 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14825 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014826 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14827 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014828 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14829 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014830 case 0xb9bd: /* TRTRE */ goto unimplemented;
14831 case 0xb9be: /* SRSTU */ goto unimplemented;
14832 case 0xb9bf: /* TRTE */ goto unimplemented;
14833 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14834 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14835 goto ok;
14836 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14837 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14838 goto ok;
14839 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14840 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14841 goto ok;
14842 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14843 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14844 goto ok;
14845 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14846 ovl.fmt.RRE.r2); goto ok;
14847 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14848 ovl.fmt.RRE.r2); goto ok;
14849 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14850 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14851 goto ok;
14852 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14853 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14854 goto ok;
14855 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14856 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14857 goto ok;
14858 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14859 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14860 goto ok;
14861 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14862 ovl.fmt.RRE.r2); goto ok;
14863 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14864 ovl.fmt.RRE.r2); goto ok;
14865 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014866 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14867 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14868 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014869 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14870 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14871 goto ok;
14872 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14873 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14874 goto ok;
14875 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14876 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14877 goto ok;
14878 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14879 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14880 goto ok;
14881 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14882 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14883 goto ok;
14884 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14885 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14886 goto ok;
14887 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14888 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14889 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014890 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14891 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14892 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014893 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14894 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14895 goto ok;
14896 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14897 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14898 goto ok;
14899 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14900 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14901 goto ok;
14902 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14903 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14904 goto ok;
14905 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14906 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14907 goto ok;
14908 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14909 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14910 goto ok;
14911 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14912 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14913 goto ok;
14914 }
14915
14916 switch ((ovl.value & 0xff000000) >> 24) {
14917 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14918 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14919 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14920 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14921 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14922 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14923 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14924 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14925 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14926 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14927 case 0x45: /* BAL */ goto unimplemented;
14928 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14929 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14930 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14931 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14932 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14933 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14934 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14935 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14936 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14937 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14938 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14939 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14940 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14941 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14942 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14943 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14944 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14945 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14946 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14947 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14948 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14949 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14950 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14951 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14952 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14953 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14954 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14955 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14956 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14957 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14958 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14959 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14960 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14961 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14962 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14963 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14964 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14965 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14966 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14967 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14968 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14969 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14970 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14971 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14972 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14973 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14974 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14975 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14976 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14977 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14978 case 0x67: /* MXD */ goto unimplemented;
14979 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14980 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14981 case 0x69: /* CD */ goto unimplemented;
14982 case 0x6a: /* AD */ goto unimplemented;
14983 case 0x6b: /* SD */ goto unimplemented;
14984 case 0x6c: /* MD */ goto unimplemented;
14985 case 0x6d: /* DD */ goto unimplemented;
14986 case 0x6e: /* AW */ goto unimplemented;
14987 case 0x6f: /* SW */ goto unimplemented;
14988 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14989 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14990 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14991 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14992 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14993 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14994 case 0x79: /* CE */ goto unimplemented;
14995 case 0x7a: /* AE */ goto unimplemented;
14996 case 0x7b: /* SE */ goto unimplemented;
14997 case 0x7c: /* MDE */ goto unimplemented;
14998 case 0x7d: /* DE */ goto unimplemented;
14999 case 0x7e: /* AU */ goto unimplemented;
15000 case 0x7f: /* SU */ goto unimplemented;
15001 case 0x83: /* DIAG */ goto unimplemented;
15002 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15003 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15004 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15005 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15006 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15007 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15008 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15009 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15010 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15011 ovl.fmt.RS.d2); goto ok;
15012 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15013 ovl.fmt.RS.d2); goto ok;
15014 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15015 ovl.fmt.RS.d2); goto ok;
15016 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15017 ovl.fmt.RS.d2); goto ok;
15018 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15019 ovl.fmt.RS.d2); goto ok;
15020 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15021 ovl.fmt.RS.d2); goto ok;
15022 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15023 ovl.fmt.RS.d2); goto ok;
15024 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15025 ovl.fmt.RS.d2); goto ok;
15026 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15027 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15028 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15029 ovl.fmt.SI.d1); goto ok;
15030 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15031 ovl.fmt.SI.d1); goto ok;
15032 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15033 ovl.fmt.SI.d1); goto ok;
15034 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15035 ovl.fmt.SI.d1); goto ok;
15036 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15037 ovl.fmt.SI.d1); goto ok;
15038 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15039 ovl.fmt.SI.d1); goto ok;
15040 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15041 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15042 case 0x99: /* TRACE */ goto unimplemented;
15043 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15044 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15045 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15046 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15047 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15048 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15049 goto ok;
15050 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15051 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15052 goto ok;
15053 case 0xac: /* STNSM */ goto unimplemented;
15054 case 0xad: /* STOSM */ goto unimplemented;
15055 case 0xae: /* SIGP */ goto unimplemented;
15056 case 0xaf: /* MC */ goto unimplemented;
15057 case 0xb1: /* LRA */ goto unimplemented;
15058 case 0xb6: /* STCTL */ goto unimplemented;
15059 case 0xb7: /* LCTL */ goto unimplemented;
15060 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15061 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015062 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15063 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015064 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15065 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15066 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15067 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15068 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15069 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15070 }
15071
15072 return S390_DECODE_UNKNOWN_INSN;
15073
15074ok:
15075 return S390_DECODE_OK;
15076
15077unimplemented:
15078 return S390_DECODE_UNIMPLEMENTED_INSN;
15079}
15080
15081static s390_decode_t
15082s390_decode_6byte_and_irgen(UChar *bytes)
15083{
15084 typedef union {
15085 struct {
15086 unsigned int op1 : 8;
15087 unsigned int r1 : 4;
15088 unsigned int r3 : 4;
15089 unsigned int i2 : 16;
15090 unsigned int : 8;
15091 unsigned int op2 : 8;
15092 } RIE;
15093 struct {
15094 unsigned int op1 : 8;
15095 unsigned int r1 : 4;
15096 unsigned int r2 : 4;
15097 unsigned int i3 : 8;
15098 unsigned int i4 : 8;
15099 unsigned int i5 : 8;
15100 unsigned int op2 : 8;
15101 } RIE_RRUUU;
15102 struct {
15103 unsigned int op1 : 8;
15104 unsigned int r1 : 4;
15105 unsigned int : 4;
15106 unsigned int i2 : 16;
15107 unsigned int m3 : 4;
15108 unsigned int : 4;
15109 unsigned int op2 : 8;
15110 } RIEv1;
15111 struct {
15112 unsigned int op1 : 8;
15113 unsigned int r1 : 4;
15114 unsigned int r2 : 4;
15115 unsigned int i4 : 16;
15116 unsigned int m3 : 4;
15117 unsigned int : 4;
15118 unsigned int op2 : 8;
15119 } RIE_RRPU;
15120 struct {
15121 unsigned int op1 : 8;
15122 unsigned int r1 : 4;
15123 unsigned int m3 : 4;
15124 unsigned int i4 : 16;
15125 unsigned int i2 : 8;
15126 unsigned int op2 : 8;
15127 } RIEv3;
15128 struct {
15129 unsigned int op1 : 8;
15130 unsigned int r1 : 4;
15131 unsigned int op2 : 4;
15132 unsigned int i2 : 32;
15133 } RIL;
15134 struct {
15135 unsigned int op1 : 8;
15136 unsigned int r1 : 4;
15137 unsigned int m3 : 4;
15138 unsigned int b4 : 4;
15139 unsigned int d4 : 12;
15140 unsigned int i2 : 8;
15141 unsigned int op2 : 8;
15142 } RIS;
15143 struct {
15144 unsigned int op1 : 8;
15145 unsigned int r1 : 4;
15146 unsigned int r2 : 4;
15147 unsigned int b4 : 4;
15148 unsigned int d4 : 12;
15149 unsigned int m3 : 4;
15150 unsigned int : 4;
15151 unsigned int op2 : 8;
15152 } RRS;
15153 struct {
15154 unsigned int op1 : 8;
15155 unsigned int l1 : 4;
15156 unsigned int : 4;
15157 unsigned int b1 : 4;
15158 unsigned int d1 : 12;
15159 unsigned int : 8;
15160 unsigned int op2 : 8;
15161 } RSL;
15162 struct {
15163 unsigned int op1 : 8;
15164 unsigned int r1 : 4;
15165 unsigned int r3 : 4;
15166 unsigned int b2 : 4;
15167 unsigned int dl2 : 12;
15168 unsigned int dh2 : 8;
15169 unsigned int op2 : 8;
15170 } RSY;
15171 struct {
15172 unsigned int op1 : 8;
15173 unsigned int r1 : 4;
15174 unsigned int x2 : 4;
15175 unsigned int b2 : 4;
15176 unsigned int d2 : 12;
15177 unsigned int : 8;
15178 unsigned int op2 : 8;
15179 } RXE;
15180 struct {
15181 unsigned int op1 : 8;
15182 unsigned int r3 : 4;
15183 unsigned int x2 : 4;
15184 unsigned int b2 : 4;
15185 unsigned int d2 : 12;
15186 unsigned int r1 : 4;
15187 unsigned int : 4;
15188 unsigned int op2 : 8;
15189 } RXF;
15190 struct {
15191 unsigned int op1 : 8;
15192 unsigned int r1 : 4;
15193 unsigned int x2 : 4;
15194 unsigned int b2 : 4;
15195 unsigned int dl2 : 12;
15196 unsigned int dh2 : 8;
15197 unsigned int op2 : 8;
15198 } RXY;
15199 struct {
15200 unsigned int op1 : 8;
15201 unsigned int i2 : 8;
15202 unsigned int b1 : 4;
15203 unsigned int dl1 : 12;
15204 unsigned int dh1 : 8;
15205 unsigned int op2 : 8;
15206 } SIY;
15207 struct {
15208 unsigned int op : 8;
15209 unsigned int l : 8;
15210 unsigned int b1 : 4;
15211 unsigned int d1 : 12;
15212 unsigned int b2 : 4;
15213 unsigned int d2 : 12;
15214 } SS;
15215 struct {
15216 unsigned int op : 8;
15217 unsigned int l1 : 4;
15218 unsigned int l2 : 4;
15219 unsigned int b1 : 4;
15220 unsigned int d1 : 12;
15221 unsigned int b2 : 4;
15222 unsigned int d2 : 12;
15223 } SS_LLRDRD;
15224 struct {
15225 unsigned int op : 8;
15226 unsigned int r1 : 4;
15227 unsigned int r3 : 4;
15228 unsigned int b2 : 4;
15229 unsigned int d2 : 12;
15230 unsigned int b4 : 4;
15231 unsigned int d4 : 12;
15232 } SS_RRRDRD2;
15233 struct {
15234 unsigned int op : 16;
15235 unsigned int b1 : 4;
15236 unsigned int d1 : 12;
15237 unsigned int b2 : 4;
15238 unsigned int d2 : 12;
15239 } SSE;
15240 struct {
15241 unsigned int op1 : 8;
15242 unsigned int r3 : 4;
15243 unsigned int op2 : 4;
15244 unsigned int b1 : 4;
15245 unsigned int d1 : 12;
15246 unsigned int b2 : 4;
15247 unsigned int d2 : 12;
15248 } SSF;
15249 struct {
15250 unsigned int op : 16;
15251 unsigned int b1 : 4;
15252 unsigned int d1 : 12;
15253 unsigned int i2 : 16;
15254 } SIL;
15255 } formats;
15256 union {
15257 formats fmt;
15258 ULong value;
15259 } ovl;
15260
15261 vassert(sizeof(formats) == 6);
15262
florianffbd84d2012-12-09 02:06:29 +000015263 ((UChar *)(&ovl.value))[0] = bytes[0];
15264 ((UChar *)(&ovl.value))[1] = bytes[1];
15265 ((UChar *)(&ovl.value))[2] = bytes[2];
15266 ((UChar *)(&ovl.value))[3] = bytes[3];
15267 ((UChar *)(&ovl.value))[4] = bytes[4];
15268 ((UChar *)(&ovl.value))[5] = bytes[5];
15269 ((UChar *)(&ovl.value))[6] = 0x0;
15270 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000015271
15272 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15273 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15274 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15275 ovl.fmt.RXY.dl2,
15276 ovl.fmt.RXY.dh2); goto ok;
15277 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15278 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15279 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15280 ovl.fmt.RXY.dl2,
15281 ovl.fmt.RXY.dh2); goto ok;
15282 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15283 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15284 ovl.fmt.RXY.dl2,
15285 ovl.fmt.RXY.dh2); goto ok;
15286 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15287 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15288 ovl.fmt.RXY.dl2,
15289 ovl.fmt.RXY.dh2); goto ok;
15290 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15291 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15292 ovl.fmt.RXY.dl2,
15293 ovl.fmt.RXY.dh2); goto ok;
15294 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15295 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15296 ovl.fmt.RXY.dl2,
15297 ovl.fmt.RXY.dh2); goto ok;
15298 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15299 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15300 ovl.fmt.RXY.dl2,
15301 ovl.fmt.RXY.dh2); goto ok;
15302 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15303 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15304 ovl.fmt.RXY.dl2,
15305 ovl.fmt.RXY.dh2); goto ok;
15306 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15307 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15308 ovl.fmt.RXY.dl2,
15309 ovl.fmt.RXY.dh2); goto ok;
15310 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15311 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, 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 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, 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 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15320 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15321 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15322 ovl.fmt.RXY.dl2,
15323 ovl.fmt.RXY.dh2); goto ok;
15324 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15325 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15326 ovl.fmt.RXY.dl2,
15327 ovl.fmt.RXY.dh2); goto ok;
15328 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15329 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15330 ovl.fmt.RXY.dl2,
15331 ovl.fmt.RXY.dh2); goto ok;
15332 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15333 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15334 ovl.fmt.RXY.dl2,
15335 ovl.fmt.RXY.dh2); goto ok;
15336 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15337 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15338 ovl.fmt.RXY.dl2,
15339 ovl.fmt.RXY.dh2); goto ok;
15340 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15341 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15342 ovl.fmt.RXY.dl2,
15343 ovl.fmt.RXY.dh2); goto ok;
15344 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15345 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15346 ovl.fmt.RXY.dl2,
15347 ovl.fmt.RXY.dh2); goto ok;
15348 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15349 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15350 ovl.fmt.RXY.dl2,
15351 ovl.fmt.RXY.dh2); goto ok;
15352 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15353 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15354 ovl.fmt.RXY.dl2,
15355 ovl.fmt.RXY.dh2); goto ok;
15356 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15357 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15358 ovl.fmt.RXY.dl2,
15359 ovl.fmt.RXY.dh2); goto ok;
15360 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15361 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15362 ovl.fmt.RXY.dl2,
15363 ovl.fmt.RXY.dh2); goto ok;
15364 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15365 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15366 ovl.fmt.RXY.dl2,
15367 ovl.fmt.RXY.dh2); goto ok;
15368 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15369 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15370 ovl.fmt.RXY.dl2,
15371 ovl.fmt.RXY.dh2); goto ok;
15372 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15373 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15374 ovl.fmt.RXY.dl2,
15375 ovl.fmt.RXY.dh2); goto ok;
15376 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15377 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15378 ovl.fmt.RXY.dl2,
15379 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015380 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015381 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15382 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15383 ovl.fmt.RXY.dl2,
15384 ovl.fmt.RXY.dh2); goto ok;
15385 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15386 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15387 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15388 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15389 ovl.fmt.RXY.dh2); goto ok;
15390 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15391 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15392 ovl.fmt.RXY.dl2,
15393 ovl.fmt.RXY.dh2); goto ok;
15394 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15395 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15396 ovl.fmt.RXY.dl2,
15397 ovl.fmt.RXY.dh2); goto ok;
15398 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15399 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15400 ovl.fmt.RXY.dl2,
15401 ovl.fmt.RXY.dh2); goto ok;
15402 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15403 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15404 ovl.fmt.RXY.dl2,
15405 ovl.fmt.RXY.dh2); goto ok;
15406 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15407 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15408 ovl.fmt.RXY.dl2,
15409 ovl.fmt.RXY.dh2); goto ok;
15410 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15411 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15412 ovl.fmt.RXY.dl2,
15413 ovl.fmt.RXY.dh2); goto ok;
15414 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15415 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15416 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15417 ovl.fmt.RXY.dh2); goto ok;
15418 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15419 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15420 ovl.fmt.RXY.dl2,
15421 ovl.fmt.RXY.dh2); goto ok;
15422 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15423 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15424 ovl.fmt.RXY.dl2,
15425 ovl.fmt.RXY.dh2); goto ok;
15426 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15427 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15428 ovl.fmt.RXY.dl2,
15429 ovl.fmt.RXY.dh2); goto ok;
15430 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15431 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15432 ovl.fmt.RXY.dl2,
15433 ovl.fmt.RXY.dh2); goto ok;
15434 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15435 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15436 ovl.fmt.RXY.dl2,
15437 ovl.fmt.RXY.dh2); goto ok;
15438 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15439 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15440 ovl.fmt.RXY.dl2,
15441 ovl.fmt.RXY.dh2); goto ok;
15442 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15443 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15444 ovl.fmt.RXY.dl2,
15445 ovl.fmt.RXY.dh2); goto ok;
15446 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15447 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15448 ovl.fmt.RXY.dl2,
15449 ovl.fmt.RXY.dh2); goto ok;
15450 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15451 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15452 ovl.fmt.RXY.dl2,
15453 ovl.fmt.RXY.dh2); goto ok;
15454 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15455 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15456 ovl.fmt.RXY.dl2,
15457 ovl.fmt.RXY.dh2); goto ok;
15458 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15459 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15460 ovl.fmt.RXY.dl2,
15461 ovl.fmt.RXY.dh2); goto ok;
15462 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15463 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15464 ovl.fmt.RXY.dl2,
15465 ovl.fmt.RXY.dh2); goto ok;
15466 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15467 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15468 ovl.fmt.RXY.dl2,
15469 ovl.fmt.RXY.dh2); goto ok;
15470 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15471 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15472 ovl.fmt.RXY.dl2,
15473 ovl.fmt.RXY.dh2); goto ok;
15474 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15475 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15476 ovl.fmt.RXY.dl2,
15477 ovl.fmt.RXY.dh2); goto ok;
15478 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15479 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15480 ovl.fmt.RXY.dl2,
15481 ovl.fmt.RXY.dh2); goto ok;
15482 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15483 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15484 ovl.fmt.RXY.dl2,
15485 ovl.fmt.RXY.dh2); goto ok;
15486 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15487 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15488 ovl.fmt.RXY.dl2,
15489 ovl.fmt.RXY.dh2); goto ok;
15490 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15491 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15492 ovl.fmt.RXY.dl2,
15493 ovl.fmt.RXY.dh2); goto ok;
15494 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15495 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15496 ovl.fmt.RXY.dl2,
15497 ovl.fmt.RXY.dh2); goto ok;
15498 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15499 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15500 ovl.fmt.RXY.dl2,
15501 ovl.fmt.RXY.dh2); goto ok;
15502 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15503 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15504 ovl.fmt.RXY.dl2,
15505 ovl.fmt.RXY.dh2); goto ok;
15506 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15507 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15508 ovl.fmt.RXY.dl2,
15509 ovl.fmt.RXY.dh2); goto ok;
15510 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15511 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15512 ovl.fmt.RXY.dl2,
15513 ovl.fmt.RXY.dh2); goto ok;
15514 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15515 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15516 ovl.fmt.RXY.dl2,
15517 ovl.fmt.RXY.dh2); goto ok;
15518 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15519 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15520 ovl.fmt.RXY.dl2,
15521 ovl.fmt.RXY.dh2); goto ok;
15522 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15523 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15524 ovl.fmt.RXY.dl2,
15525 ovl.fmt.RXY.dh2); goto ok;
15526 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15527 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15528 ovl.fmt.RXY.dl2,
15529 ovl.fmt.RXY.dh2); goto ok;
15530 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15531 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15532 ovl.fmt.RXY.dl2,
15533 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015534 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015535 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15536 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15537 ovl.fmt.RXY.dl2,
15538 ovl.fmt.RXY.dh2); goto ok;
15539 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15540 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15541 ovl.fmt.RXY.dl2,
15542 ovl.fmt.RXY.dh2); goto ok;
15543 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15544 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15545 ovl.fmt.RXY.dl2,
15546 ovl.fmt.RXY.dh2); goto ok;
15547 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15548 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15549 ovl.fmt.RXY.dl2,
15550 ovl.fmt.RXY.dh2); goto ok;
15551 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15552 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15553 ovl.fmt.RXY.dl2,
15554 ovl.fmt.RXY.dh2); goto ok;
15555 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15556 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15557 ovl.fmt.RXY.dl2,
15558 ovl.fmt.RXY.dh2); goto ok;
15559 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15560 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15561 ovl.fmt.RXY.dl2,
15562 ovl.fmt.RXY.dh2); goto ok;
15563 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15564 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15565 ovl.fmt.RXY.dl2,
15566 ovl.fmt.RXY.dh2); goto ok;
15567 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15568 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15569 ovl.fmt.RXY.dl2,
15570 ovl.fmt.RXY.dh2); goto ok;
15571 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15572 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15573 ovl.fmt.RXY.dl2,
15574 ovl.fmt.RXY.dh2); goto ok;
15575 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15576 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15577 ovl.fmt.RXY.dl2,
15578 ovl.fmt.RXY.dh2); goto ok;
15579 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15580 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15581 ovl.fmt.RXY.dl2,
15582 ovl.fmt.RXY.dh2); goto ok;
15583 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15584 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15585 ovl.fmt.RXY.dl2,
15586 ovl.fmt.RXY.dh2); goto ok;
15587 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15588 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15589 ovl.fmt.RXY.dl2,
15590 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015591 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15592 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15593 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015594 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15595 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15596 ovl.fmt.RXY.dl2,
15597 ovl.fmt.RXY.dh2); goto ok;
15598 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15599 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15600 ovl.fmt.RXY.dl2,
15601 ovl.fmt.RXY.dh2); goto ok;
15602 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15603 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15604 ovl.fmt.RXY.dl2,
15605 ovl.fmt.RXY.dh2); goto ok;
15606 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15607 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15608 ovl.fmt.RXY.dl2,
15609 ovl.fmt.RXY.dh2); goto ok;
15610 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15611 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15612 ovl.fmt.RXY.dl2,
15613 ovl.fmt.RXY.dh2); goto ok;
15614 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15615 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15616 ovl.fmt.RXY.dl2,
15617 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015618 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015619 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15620 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15621 ovl.fmt.RXY.dl2,
15622 ovl.fmt.RXY.dh2); goto ok;
15623 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15624 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15625 ovl.fmt.RXY.dl2,
15626 ovl.fmt.RXY.dh2); goto ok;
15627 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15628 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15629 ovl.fmt.RXY.dl2,
15630 ovl.fmt.RXY.dh2); goto ok;
15631 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15632 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15633 ovl.fmt.RXY.dl2,
15634 ovl.fmt.RXY.dh2); goto ok;
15635 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15636 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15637 ovl.fmt.RSY.dl2,
15638 ovl.fmt.RSY.dh2); goto ok;
15639 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15640 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15641 ovl.fmt.RSY.dl2,
15642 ovl.fmt.RSY.dh2); goto ok;
15643 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15644 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15645 ovl.fmt.RSY.dl2,
15646 ovl.fmt.RSY.dh2); goto ok;
15647 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15648 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15649 ovl.fmt.RSY.dl2,
15650 ovl.fmt.RSY.dh2); goto ok;
15651 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15652 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15653 ovl.fmt.RSY.dl2,
15654 ovl.fmt.RSY.dh2); goto ok;
15655 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15656 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15657 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15658 ovl.fmt.RSY.dl2,
15659 ovl.fmt.RSY.dh2); goto ok;
15660 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15661 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15662 ovl.fmt.RSY.dl2,
15663 ovl.fmt.RSY.dh2); goto ok;
15664 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15665 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15666 ovl.fmt.RSY.dl2,
15667 ovl.fmt.RSY.dh2); goto ok;
15668 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15669 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15670 ovl.fmt.RSY.dl2,
15671 ovl.fmt.RSY.dh2); goto ok;
15672 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, 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;
florian2289cd42012-12-05 04:23:42 +000015676 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015677 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15678 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15679 ovl.fmt.RSY.dl2,
15680 ovl.fmt.RSY.dh2); goto ok;
15681 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15682 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15683 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15684 ovl.fmt.RSY.dl2,
15685 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015686 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015687 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15688 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15689 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15690 ovl.fmt.RSY.dh2); goto ok;
15691 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15692 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15693 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15694 ovl.fmt.RSY.dh2); goto ok;
15695 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15696 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15697 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15698 ovl.fmt.RSY.dl2,
15699 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015700 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15701 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15702 ovl.fmt.RSY.dl2,
15703 ovl.fmt.RSY.dh2); goto ok;
15704 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15705 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15706 ovl.fmt.RSY.dl2,
15707 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015708 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15709 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15710 ovl.fmt.RSY.dl2,
15711 ovl.fmt.RSY.dh2); goto ok;
15712 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15713 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15714 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15715 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015716 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15717 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15718 ovl.fmt.RSY.dl2,
15719 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015720 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15721 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15722 ovl.fmt.SIY.dh1); goto ok;
15723 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15724 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15725 ovl.fmt.SIY.dh1); goto ok;
15726 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15727 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15728 ovl.fmt.SIY.dh1); goto ok;
15729 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15730 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15731 ovl.fmt.SIY.dh1); goto ok;
15732 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15733 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15734 ovl.fmt.SIY.dh1); goto ok;
15735 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15736 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15737 ovl.fmt.SIY.dh1); goto ok;
15738 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15739 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15740 ovl.fmt.SIY.dh1); goto ok;
15741 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15742 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15743 ovl.fmt.SIY.dh1); goto ok;
15744 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15745 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15746 ovl.fmt.SIY.dh1); goto ok;
15747 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15748 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15749 ovl.fmt.SIY.dh1); goto ok;
15750 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15751 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15752 ovl.fmt.RSY.dl2,
15753 ovl.fmt.RSY.dh2); goto ok;
15754 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15755 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15756 ovl.fmt.RSY.dl2,
15757 ovl.fmt.RSY.dh2); goto ok;
15758 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15759 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15760 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15761 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15762 ovl.fmt.RSY.dl2,
15763 ovl.fmt.RSY.dh2); goto ok;
15764 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15765 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15766 ovl.fmt.RSY.dl2,
15767 ovl.fmt.RSY.dh2); goto ok;
15768 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15769 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15770 ovl.fmt.RSY.dl2,
15771 ovl.fmt.RSY.dh2); goto ok;
15772 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15773 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15774 ovl.fmt.RSY.dl2,
15775 ovl.fmt.RSY.dh2); goto ok;
15776 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15777 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15778 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15779 ovl.fmt.RSY.dh2); goto ok;
15780 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15781 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15782 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15783 ovl.fmt.RSY.dl2,
15784 ovl.fmt.RSY.dh2); goto ok;
15785 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15786 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15787 ovl.fmt.RSY.dl2,
15788 ovl.fmt.RSY.dh2); goto ok;
15789 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15790 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15791 ovl.fmt.RSY.dl2,
15792 ovl.fmt.RSY.dh2); goto ok;
15793 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15794 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15795 ovl.fmt.RSY.dl2,
15796 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015797 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15798 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15799 ovl.fmt.RSY.dl2,
15800 ovl.fmt.RSY.dh2,
15801 S390_XMNM_LOCG); goto ok;
15802 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15803 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15804 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15805 ovl.fmt.RSY.dh2,
15806 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015807 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15808 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15809 ovl.fmt.RSY.dl2,
15810 ovl.fmt.RSY.dh2); goto ok;
15811 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15812 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15813 ovl.fmt.RSY.dl2,
15814 ovl.fmt.RSY.dh2); goto ok;
15815 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15816 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15817 ovl.fmt.RSY.dl2,
15818 ovl.fmt.RSY.dh2); goto ok;
15819 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15820 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15821 ovl.fmt.RSY.dl2,
15822 ovl.fmt.RSY.dh2); goto ok;
15823 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15824 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15825 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15826 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015827 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15828 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15829 ovl.fmt.RSY.dl2,
15830 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15831 goto ok;
15832 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15833 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15834 ovl.fmt.RSY.dl2,
15835 ovl.fmt.RSY.dh2,
15836 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015837 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15838 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15839 ovl.fmt.RSY.dl2,
15840 ovl.fmt.RSY.dh2); goto ok;
15841 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15842 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15843 ovl.fmt.RSY.dl2,
15844 ovl.fmt.RSY.dh2); goto ok;
15845 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15846 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15847 ovl.fmt.RSY.dl2,
15848 ovl.fmt.RSY.dh2); goto ok;
15849 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15850 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15851 ovl.fmt.RSY.dl2,
15852 ovl.fmt.RSY.dh2); goto ok;
15853 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15854 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15855 ovl.fmt.RSY.dl2,
15856 ovl.fmt.RSY.dh2); goto ok;
15857 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15858 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15859 goto ok;
15860 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15861 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15862 goto ok;
15863 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15864 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15865 ovl.fmt.RIE_RRUUU.r1,
15866 ovl.fmt.RIE_RRUUU.r2,
15867 ovl.fmt.RIE_RRUUU.i3,
15868 ovl.fmt.RIE_RRUUU.i4,
15869 ovl.fmt.RIE_RRUUU.i5);
15870 goto ok;
15871 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15872 ovl.fmt.RIE_RRUUU.r1,
15873 ovl.fmt.RIE_RRUUU.r2,
15874 ovl.fmt.RIE_RRUUU.i3,
15875 ovl.fmt.RIE_RRUUU.i4,
15876 ovl.fmt.RIE_RRUUU.i5);
15877 goto ok;
15878 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15879 ovl.fmt.RIE_RRUUU.r1,
15880 ovl.fmt.RIE_RRUUU.r2,
15881 ovl.fmt.RIE_RRUUU.i3,
15882 ovl.fmt.RIE_RRUUU.i4,
15883 ovl.fmt.RIE_RRUUU.i5);
15884 goto ok;
15885 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15886 ovl.fmt.RIE_RRUUU.r1,
15887 ovl.fmt.RIE_RRUUU.r2,
15888 ovl.fmt.RIE_RRUUU.i3,
15889 ovl.fmt.RIE_RRUUU.i4,
15890 ovl.fmt.RIE_RRUUU.i5);
15891 goto ok;
florian2289cd42012-12-05 04:23:42 +000015892 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015893 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15894 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15895 ovl.fmt.RIE_RRPU.r1,
15896 ovl.fmt.RIE_RRPU.r2,
15897 ovl.fmt.RIE_RRPU.i4,
15898 ovl.fmt.RIE_RRPU.m3); goto ok;
15899 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15900 ovl.fmt.RIE_RRPU.r1,
15901 ovl.fmt.RIE_RRPU.r2,
15902 ovl.fmt.RIE_RRPU.i4,
15903 ovl.fmt.RIE_RRPU.m3); goto ok;
15904 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15905 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15906 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15907 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15908 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15909 ovl.fmt.RIE_RRPU.r1,
15910 ovl.fmt.RIE_RRPU.r2,
15911 ovl.fmt.RIE_RRPU.i4,
15912 ovl.fmt.RIE_RRPU.m3); goto ok;
15913 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15914 ovl.fmt.RIE_RRPU.r1,
15915 ovl.fmt.RIE_RRPU.r2,
15916 ovl.fmt.RIE_RRPU.i4,
15917 ovl.fmt.RIE_RRPU.m3); goto ok;
15918 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15919 ovl.fmt.RIEv3.r1,
15920 ovl.fmt.RIEv3.m3,
15921 ovl.fmt.RIEv3.i4,
15922 ovl.fmt.RIEv3.i2); goto ok;
15923 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15924 ovl.fmt.RIEv3.r1,
15925 ovl.fmt.RIEv3.m3,
15926 ovl.fmt.RIEv3.i4,
15927 ovl.fmt.RIEv3.i2); goto ok;
15928 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15929 ovl.fmt.RIEv3.r1,
15930 ovl.fmt.RIEv3.m3,
15931 ovl.fmt.RIEv3.i4,
15932 ovl.fmt.RIEv3.i2); goto ok;
15933 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15934 ovl.fmt.RIEv3.r1,
15935 ovl.fmt.RIEv3.m3,
15936 ovl.fmt.RIEv3.i4,
15937 ovl.fmt.RIEv3.i2); goto ok;
15938 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15939 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15940 goto ok;
15941 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15942 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15943 ovl.fmt.RIE.i2); goto ok;
15944 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15945 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15946 ovl.fmt.RIE.i2); goto ok;
15947 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15948 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15949 ovl.fmt.RIE.i2); goto ok;
15950 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15951 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15952 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15953 goto ok;
15954 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15955 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15956 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15957 goto ok;
15958 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15959 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15960 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15961 goto ok;
15962 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15963 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15964 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15965 goto ok;
15966 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15967 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15968 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15969 ovl.fmt.RIS.i2); goto ok;
15970 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15971 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15972 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15973 ovl.fmt.RIS.i2); goto ok;
15974 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15975 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15976 ovl.fmt.RIS.d4,
15977 ovl.fmt.RIS.i2); goto ok;
15978 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15979 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15980 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15981 ovl.fmt.RIS.i2); goto ok;
15982 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15983 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15984 ovl.fmt.RXE.d2); goto ok;
15985 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15986 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15987 ovl.fmt.RXE.d2); goto ok;
15988 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15989 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15990 ovl.fmt.RXE.d2); goto ok;
15991 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15992 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15993 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15994 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15995 ovl.fmt.RXE.d2); goto ok;
15996 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15997 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15998 ovl.fmt.RXE.d2); goto ok;
15999 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16000 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16001 ovl.fmt.RXE.d2); goto ok;
16002 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16003 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16004 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16005 ovl.fmt.RXE.d2); goto ok;
16006 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16007 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16008 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16009 ovl.fmt.RXF.r1); goto ok;
16010 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16011 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16012 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16013 ovl.fmt.RXF.r1); goto ok;
16014 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16015 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16016 ovl.fmt.RXE.d2); goto ok;
16017 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16018 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16019 ovl.fmt.RXE.d2); goto ok;
16020 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16021 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16022 ovl.fmt.RXE.d2); goto ok;
16023 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16024 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16025 ovl.fmt.RXE.d2); goto ok;
16026 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16027 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16028 ovl.fmt.RXE.d2); goto ok;
16029 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16030 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16031 ovl.fmt.RXE.d2); goto ok;
16032 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16033 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16034 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16035 ovl.fmt.RXE.d2); goto ok;
16036 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16037 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16038 ovl.fmt.RXE.d2); goto ok;
16039 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16040 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16041 ovl.fmt.RXE.d2); goto ok;
16042 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16043 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16044 ovl.fmt.RXE.d2); goto ok;
16045 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16046 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16047 ovl.fmt.RXE.d2); goto ok;
16048 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16049 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16050 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16051 ovl.fmt.RXF.r1); goto ok;
16052 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16053 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16054 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16055 ovl.fmt.RXF.r1); goto ok;
16056 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
16057 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16058 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16059 case 0xed000000002eULL: /* MAE */ goto unimplemented;
16060 case 0xed000000002fULL: /* MSE */ goto unimplemented;
16061 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16062 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16063 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16064 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16065 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16066 case 0xed000000003aULL: /* MAY */ goto unimplemented;
16067 case 0xed000000003bULL: /* MY */ goto unimplemented;
16068 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16069 case 0xed000000003dULL: /* MYH */ goto unimplemented;
16070 case 0xed000000003eULL: /* MAD */ goto unimplemented;
16071 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000016072 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16073 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16074 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16075 ovl.fmt.RXF.r1); goto ok;
16076 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16077 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16078 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16079 ovl.fmt.RXF.r1); goto ok;
16080 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16081 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16082 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16083 ovl.fmt.RXF.r1); goto ok;
16084 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16085 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16086 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16087 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000016088 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16089 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16090 ovl.fmt.RXE.d2); goto ok;
16091 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16092 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16093 ovl.fmt.RXE.d2); goto ok;
16094 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16095 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16096 ovl.fmt.RXE.d2); goto ok;
16097 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16098 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16099 ovl.fmt.RXE.d2); goto ok;
16100 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16101 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16102 ovl.fmt.RXE.d2); goto ok;
16103 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16104 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16105 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016106 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16107 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16108 ovl.fmt.RXY.dl2,
16109 ovl.fmt.RXY.dh2); goto ok;
16110 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16111 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16112 ovl.fmt.RXY.dl2,
16113 ovl.fmt.RXY.dh2); goto ok;
16114 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16115 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16116 ovl.fmt.RXY.dl2,
16117 ovl.fmt.RXY.dh2); goto ok;
16118 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16119 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16120 ovl.fmt.RXY.dl2,
16121 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000016122 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16123 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16124 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16125 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016126 }
16127
16128 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16129 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16130 ovl.fmt.RIL.i2); goto ok;
16131 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16132 ovl.fmt.RIL.i2); goto ok;
16133 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16134 ovl.fmt.RIL.i2); goto ok;
16135 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16136 ovl.fmt.RIL.i2); goto ok;
16137 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16138 ovl.fmt.RIL.i2); goto ok;
16139 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16140 ovl.fmt.RIL.i2); goto ok;
16141 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16142 ovl.fmt.RIL.i2); goto ok;
16143 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16144 ovl.fmt.RIL.i2); goto ok;
16145 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16146 ovl.fmt.RIL.i2); goto ok;
16147 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16148 ovl.fmt.RIL.i2); goto ok;
16149 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16150 ovl.fmt.RIL.i2); goto ok;
16151 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16152 ovl.fmt.RIL.i2); goto ok;
16153 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16154 ovl.fmt.RIL.i2); goto ok;
16155 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16156 ovl.fmt.RIL.i2); goto ok;
16157 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16158 ovl.fmt.RIL.i2); goto ok;
16159 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16160 ovl.fmt.RIL.i2); goto ok;
16161 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16162 ovl.fmt.RIL.i2); goto ok;
16163 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16164 ovl.fmt.RIL.i2); goto ok;
16165 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16166 ovl.fmt.RIL.i2); goto ok;
16167 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16168 ovl.fmt.RIL.i2); goto ok;
16169 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16170 ovl.fmt.RIL.i2); goto ok;
16171 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16172 ovl.fmt.RIL.i2); goto ok;
16173 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16174 ovl.fmt.RIL.i2); goto ok;
16175 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16176 ovl.fmt.RIL.i2); goto ok;
16177 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16178 ovl.fmt.RIL.i2); goto ok;
16179 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16180 ovl.fmt.RIL.i2); goto ok;
16181 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16182 ovl.fmt.RIL.i2); goto ok;
16183 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16184 ovl.fmt.RIL.i2); goto ok;
16185 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16186 ovl.fmt.RIL.i2); goto ok;
16187 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16188 ovl.fmt.RIL.i2); goto ok;
16189 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16190 ovl.fmt.RIL.i2); goto ok;
16191 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16192 ovl.fmt.RIL.i2); goto ok;
16193 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16194 ovl.fmt.RIL.i2); goto ok;
16195 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16196 ovl.fmt.RIL.i2); goto ok;
16197 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16198 ovl.fmt.RIL.i2); goto ok;
16199 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16200 ovl.fmt.RIL.i2); goto ok;
16201 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16202 ovl.fmt.RIL.i2); goto ok;
16203 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16204 ovl.fmt.RIL.i2); goto ok;
16205 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16206 ovl.fmt.RIL.i2); goto ok;
16207 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16208 ovl.fmt.RIL.i2); goto ok;
16209 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16210 ovl.fmt.RIL.i2); goto ok;
16211 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16212 ovl.fmt.RIL.i2); goto ok;
16213 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16214 ovl.fmt.RIL.i2); goto ok;
16215 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16216 ovl.fmt.RIL.i2); goto ok;
16217 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16218 ovl.fmt.RIL.i2); goto ok;
16219 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16220 ovl.fmt.RIL.i2); goto ok;
16221 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16222 ovl.fmt.RIL.i2); goto ok;
16223 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16224 ovl.fmt.RIL.i2); goto ok;
16225 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16226 ovl.fmt.RIL.i2); goto ok;
16227 case 0xc800ULL: /* MVCOS */ goto unimplemented;
16228 case 0xc801ULL: /* ECTG */ goto unimplemented;
16229 case 0xc802ULL: /* CSST */ goto unimplemented;
16230 case 0xc804ULL: /* LPD */ goto unimplemented;
16231 case 0xc805ULL: /* LPDG */ goto unimplemented;
16232 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
16233 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16234 ovl.fmt.RIL.i2); goto ok;
16235 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16236 ovl.fmt.RIL.i2); goto ok;
16237 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16238 ovl.fmt.RIL.i2); goto ok;
16239 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16240 ovl.fmt.RIL.i2); goto ok;
16241 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16242 ovl.fmt.RIL.i2); goto ok;
16243 }
16244
16245 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000016246 case 0xc5ULL: /* BPRP */ goto unimplemented;
16247 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016248 case 0xd0ULL: /* TRTR */ goto unimplemented;
16249 case 0xd1ULL: /* MVN */ goto unimplemented;
16250 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16251 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16252 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16253 case 0xd3ULL: /* MVZ */ goto unimplemented;
16254 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16255 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16256 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16257 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16258 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16259 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16260 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16261 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16262 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000016263 case 0xd7ULL:
16264 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16265 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16266 else
16267 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16268 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16269 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16270 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016271 case 0xd9ULL: /* MVCK */ goto unimplemented;
16272 case 0xdaULL: /* MVCP */ goto unimplemented;
16273 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000016274 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16275 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16276 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016277 case 0xddULL: /* TRT */ goto unimplemented;
16278 case 0xdeULL: /* ED */ goto unimplemented;
16279 case 0xdfULL: /* EDMK */ goto unimplemented;
16280 case 0xe1ULL: /* PKU */ goto unimplemented;
16281 case 0xe2ULL: /* UNPKU */ goto unimplemented;
16282 case 0xe8ULL: /* MVCIN */ goto unimplemented;
16283 case 0xe9ULL: /* PKA */ goto unimplemented;
16284 case 0xeaULL: /* UNPKA */ goto unimplemented;
16285 case 0xeeULL: /* PLO */ goto unimplemented;
16286 case 0xefULL: /* LMD */ goto unimplemented;
16287 case 0xf0ULL: /* SRP */ goto unimplemented;
16288 case 0xf1ULL: /* MVO */ goto unimplemented;
16289 case 0xf2ULL: /* PACK */ goto unimplemented;
16290 case 0xf3ULL: /* UNPK */ goto unimplemented;
16291 case 0xf8ULL: /* ZAP */ goto unimplemented;
16292 case 0xf9ULL: /* CP */ goto unimplemented;
16293 case 0xfaULL: /* AP */ goto unimplemented;
16294 case 0xfbULL: /* SP */ goto unimplemented;
16295 case 0xfcULL: /* MP */ goto unimplemented;
16296 case 0xfdULL: /* DP */ goto unimplemented;
16297 }
16298
16299 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16300 case 0xe500ULL: /* LASP */ goto unimplemented;
16301 case 0xe501ULL: /* TPROT */ goto unimplemented;
16302 case 0xe502ULL: /* STRAG */ goto unimplemented;
16303 case 0xe50eULL: /* MVCSK */ goto unimplemented;
16304 case 0xe50fULL: /* MVCDK */ goto unimplemented;
16305 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16306 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16307 goto ok;
16308 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16309 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16310 goto ok;
16311 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16312 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16313 goto ok;
16314 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16315 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16316 goto ok;
16317 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16318 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16319 goto ok;
16320 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16321 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16322 goto ok;
16323 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16324 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16325 goto ok;
16326 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16327 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16328 goto ok;
16329 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16330 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16331 goto ok;
florian2289cd42012-12-05 04:23:42 +000016332 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16333 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016334 }
16335
16336 return S390_DECODE_UNKNOWN_INSN;
16337
16338ok:
16339 return S390_DECODE_OK;
16340
16341unimplemented:
16342 return S390_DECODE_UNIMPLEMENTED_INSN;
16343}
16344
16345/* Handle "special" instructions. */
16346static s390_decode_t
16347s390_decode_special_and_irgen(UChar *bytes)
16348{
16349 s390_decode_t status = S390_DECODE_OK;
16350
16351 /* Got a "Special" instruction preamble. Which one is it? */
16352 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16353 s390_irgen_client_request();
16354 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16355 s390_irgen_guest_NRADDR();
16356 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16357 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016358 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16359 vex_inject_ir(irsb, Iend_BE);
16360
16361 /* Invalidate the current insn. The reason is that the IRop we're
16362 injecting here can change. In which case the translation has to
16363 be redone. For ease of handling, we simply invalidate all the
16364 time. */
16365 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
16366 mkU64(guest_IA_curr_instr)));
16367 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
16368 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16369 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16370 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16371
16372 put_IA(mkaddr_expr(guest_IA_next_instr));
16373 dis_res->whatNext = Dis_StopHere;
16374 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000016375 } else {
16376 /* We don't know what it is. */
16377 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16378 }
16379
16380 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16381
16382 return status;
16383}
16384
16385
16386/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016387static UInt
sewardj2019a972011-03-07 16:04:07 +000016388s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
16389{
16390 s390_decode_t status;
16391
16392 dis_res = dres;
16393
16394 /* Spot the 8-byte preamble: 18ff lr r15,r15
16395 1811 lr r1,r1
16396 1822 lr r2,r2
16397 1833 lr r3,r3 */
16398 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16399 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16400 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16401
16402 /* Handle special instruction that follows that preamble. */
16403 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016404
16405 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16406 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16407
16408 status =
16409 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016410 } else {
16411 /* Handle normal instructions. */
16412 switch (insn_length) {
16413 case 2:
16414 status = s390_decode_2byte_and_irgen(bytes);
16415 break;
16416
16417 case 4:
16418 status = s390_decode_4byte_and_irgen(bytes);
16419 break;
16420
16421 case 6:
16422 status = s390_decode_6byte_and_irgen(bytes);
16423 break;
16424
16425 default:
16426 status = S390_DECODE_ERROR;
16427 break;
16428 }
16429 }
florian5fcbba22011-07-27 20:40:22 +000016430 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016431 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16432 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016433 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016434 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016435 }
16436
16437 if (status == S390_DECODE_OK) return insn_length; /* OK */
16438
16439 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016440 if (sigill_diag) {
16441 vex_printf("vex s390->IR: ");
16442 switch (status) {
16443 case S390_DECODE_UNKNOWN_INSN:
16444 vex_printf("unknown insn: ");
16445 break;
sewardj2019a972011-03-07 16:04:07 +000016446
sewardj442e51a2012-12-06 18:08:04 +000016447 case S390_DECODE_UNIMPLEMENTED_INSN:
16448 vex_printf("unimplemented insn: ");
16449 break;
sewardj2019a972011-03-07 16:04:07 +000016450
sewardj442e51a2012-12-06 18:08:04 +000016451 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16452 vex_printf("unimplemented special insn: ");
16453 break;
sewardj2019a972011-03-07 16:04:07 +000016454
sewardj442e51a2012-12-06 18:08:04 +000016455 default:
16456 case S390_DECODE_ERROR:
16457 vex_printf("decoding error: ");
16458 break;
16459 }
16460
16461 vex_printf("%02x%02x", bytes[0], bytes[1]);
16462 if (insn_length > 2) {
16463 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16464 }
16465 if (insn_length > 4) {
16466 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16467 }
16468 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016469 }
16470
sewardj2019a972011-03-07 16:04:07 +000016471 return 0; /* Failed */
16472}
16473
16474
sewardj2019a972011-03-07 16:04:07 +000016475/* Disassemble a single instruction INSN into IR. */
16476static DisResult
florian420c5012011-07-22 02:12:28 +000016477disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016478{
16479 UChar byte;
16480 UInt insn_length;
16481 DisResult dres;
16482
16483 /* ---------------------------------------------------- */
16484 /* --- Compute instruction length -- */
16485 /* ---------------------------------------------------- */
16486
16487 /* Get the first byte of the insn. */
16488 byte = insn[0];
16489
16490 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16491 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16492 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16493
16494 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16495
16496 /* ---------------------------------------------------- */
16497 /* --- Initialise the DisResult data -- */
16498 /* ---------------------------------------------------- */
16499 dres.whatNext = Dis_Continue;
16500 dres.len = insn_length;
16501 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016502 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000016503
floriana99f20e2011-07-17 14:16:41 +000016504 /* fixs390: consider chasing of conditional jumps */
16505
sewardj2019a972011-03-07 16:04:07 +000016506 /* Normal and special instruction handling starts here. */
16507 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16508 /* All decode failures end up here. The decoder has already issued an
16509 error message.
16510 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016511 not been executed, and (is currently) the next to be executed.
16512 The insn address in the guest state needs to be set to
16513 guest_IA_curr_instr, otherwise the complaint will report an
16514 incorrect address. */
16515 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016516
florian8844a632012-04-13 04:04:06 +000016517 dres.whatNext = Dis_StopHere;
16518 dres.jk_StopHere = Ijk_NoDecode;
16519 dres.continueAt = 0;
16520 dres.len = 0;
16521 } else {
16522 /* Decode success */
16523 switch (dres.whatNext) {
16524 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016525 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016526 break;
16527 case Dis_ResteerU:
16528 case Dis_ResteerC:
16529 put_IA(mkaddr_expr(dres.continueAt));
16530 break;
16531 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016532 if (dres.jk_StopHere == Ijk_EmWarn ||
16533 dres.jk_StopHere == Ijk_EmFail) {
16534 /* We assume here, that emulation warnings are not given for
16535 insns that transfer control. There is no good way to
16536 do that. */
16537 put_IA(mkaddr_expr(guest_IA_next_instr));
16538 }
florian8844a632012-04-13 04:04:06 +000016539 break;
16540 default:
16541 vassert(0);
16542 }
sewardj2019a972011-03-07 16:04:07 +000016543 }
16544
16545 return dres;
16546}
16547
16548
16549/*------------------------------------------------------------*/
16550/*--- Top-level fn ---*/
16551/*------------------------------------------------------------*/
16552
16553/* Disassemble a single instruction into IR. The instruction
16554 is located in host memory at &guest_code[delta]. */
16555
16556DisResult
16557disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000016558 Bool (*resteerOkFn)(void *, Addr64),
16559 Bool resteerCisOk,
16560 void *callback_opaque,
16561 UChar *guest_code,
16562 Long delta,
16563 Addr64 guest_IP,
16564 VexArch guest_arch,
16565 VexArchInfo *archinfo,
16566 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000016567 Bool host_bigendian,
16568 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016569{
16570 vassert(guest_arch == VexArchS390X);
16571
16572 /* The instruction decoder requires a big-endian machine. */
16573 vassert(host_bigendian == True);
16574
16575 /* Set globals (see top of this file) */
16576 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016577 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016578 resteer_fn = resteerOkFn;
16579 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016580 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016581
florian420c5012011-07-22 02:12:28 +000016582 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016583}
16584
16585/*---------------------------------------------------------------*/
16586/*--- end guest_s390_toIR.c ---*/
16587/*---------------------------------------------------------------*/