blob: 2aefba25358e8557d8fc07a3f39436b5f1ac84f4 [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
florian99dd03e2013-01-29 03:56:06 +0000243 return IRExpr_ITE(condition, iftrue, iffalse);
sewardj2019a972011-03-07 16:04:07 +0000244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
florianbafb8262013-05-31 15:41:55 +0000635 /* Make the CC_DEP1 slot appear completely defined.
636 Otherwise, assigning a 32-bit value will cause memcheck
637 to trigger an undefinedness error.
638 */
639 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
640 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
641 stmt(IRStmt_Put(dep1_off, mkU64(0)));
642 }
sewardj2019a972011-03-07 16:04:07 +0000643 op = mkU64(opc);
644 dep1 = mkexpr(d1);
645 dep2 = mkU64(0);
646 ndep = mkU64(0);
647
648 s390_cc_thunk_fill(op, dep1, dep2, ndep);
649}
650
651
652/* Write a floating point value and an integer into the flags thunk. The
653 integer value is zero-extended first. */
654static void
655s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
656{
657 IRExpr *op, *dep1, *dep2, *ndep;
658
florianbafb8262013-05-31 15:41:55 +0000659 /* Make the CC_DEP1 slot appear completely defined.
660 Otherwise, assigning a 32-bit value will cause memcheck
661 to trigger an undefinedness error.
662 */
663 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
664 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
665 stmt(IRStmt_Put(dep1_off, mkU64(0)));
666 }
sewardj2019a972011-03-07 16:04:07 +0000667 op = mkU64(opc);
668 dep1 = mkexpr(d1);
669 dep2 = s390_cc_widen(d2, False);
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, dep1, dep2, ndep);
673}
674
675
676/* Write a 128-bit floating point value into the flags thunk. This is
677 done by splitting the value into two 64-bits values. */
678static void
679s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
680{
681 IRExpr *op, *hi, *lo, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
686 ndep = mkU64(0);
687
688 s390_cc_thunk_fill(op, hi, lo, ndep);
689}
690
691
692/* Write a 128-bit floating point value and an integer into the flags thunk.
693 The integer value is zero-extended first. */
694static void
695s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
696{
697 IRExpr *op, *hi, *lo, *lox, *ndep;
698
699 op = mkU64(opc);
700 hi = unop(Iop_F128HItoF64, mkexpr(d1));
701 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
702 ndep = s390_cc_widen(nd, False);
703
704 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
705
706 s390_cc_thunk_fill(op, hi, lox, ndep);
707}
708
709
floriane38f6412012-12-21 17:32:12 +0000710/* Write a 128-bit decimal floating point value into the flags thunk.
711 This is done by splitting the value into two 64-bits values. */
712static void
713s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
714{
715 IRExpr *op, *hi, *lo, *ndep;
716
717 op = mkU64(opc);
718 hi = unop(Iop_D128HItoD64, mkexpr(d1));
719 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
720 ndep = mkU64(0);
721
722 s390_cc_thunk_fill(op, hi, lo, ndep);
723}
724
725
floriance9e3db2012-12-27 20:14:03 +0000726/* Write a 128-bit decimal floating point value and an integer into the flags
727 thunk. The integer value is zero-extended first. */
728static void
729s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
730{
731 IRExpr *op, *hi, *lo, *lox, *ndep;
732
733 op = mkU64(opc);
734 hi = unop(Iop_D128HItoD64, mkexpr(d1));
735 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
736 ndep = s390_cc_widen(nd, False);
737
738 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
739
740 s390_cc_thunk_fill(op, hi, lox, ndep);
741}
742
743
sewardj2019a972011-03-07 16:04:07 +0000744static void
745s390_cc_set(UInt val)
746{
747 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
748 mkU64(val), mkU64(0), mkU64(0));
749}
750
751/* Build IR to calculate the condition code from flags thunk.
752 Returns an expression of type Ity_I32 */
753static IRExpr *
754s390_call_calculate_cc(void)
755{
756 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
757
florian428dfdd2012-03-27 03:09:49 +0000758 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
759 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
760 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
761 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000762
763 args = mkIRExprVec_4(op, dep1, dep2, ndep);
764 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
765 "s390_calculate_cc", &s390_calculate_cc, args);
766
767 /* Exclude OP and NDEP from definedness checking. We're only
768 interested in DEP1 and DEP2. */
769 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
770
771 return call;
772}
773
774/* Build IR to calculate the internal condition code for a "compare and branch"
775 insn. Returns an expression of type Ity_I32 */
776static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000777s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000778{
florianff9613f2012-05-12 15:26:44 +0000779 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000780
florianff9613f2012-05-12 15:26:44 +0000781 switch (opc) {
782 case S390_CC_OP_SIGNED_COMPARE:
783 dep1 = s390_cc_widen(op1, True);
784 dep2 = s390_cc_widen(op2, True);
785 break;
786
787 case S390_CC_OP_UNSIGNED_COMPARE:
788 dep1 = s390_cc_widen(op1, False);
789 dep2 = s390_cc_widen(op2, False);
790 break;
791
792 default:
793 vpanic("s390_call_calculate_icc");
794 }
795
796 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000797 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000798
florianff9613f2012-05-12 15:26:44 +0000799 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000800 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000801 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000802
florianff9613f2012-05-12 15:26:44 +0000803 /* Exclude the requested condition, OP and NDEP from definedness
804 checking. We're only interested in DEP1 and DEP2. */
805 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000806
807 return call;
808}
809
810/* Build IR to calculate the condition code from flags thunk.
811 Returns an expression of type Ity_I32 */
812static IRExpr *
813s390_call_calculate_cond(UInt m)
814{
815 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
816
817 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000818 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
819 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
820 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
821 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000822
823 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
824 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
825 "s390_calculate_cond", &s390_calculate_cond, args);
826
827 /* Exclude the requested condition, OP and NDEP from definedness
828 checking. We're only interested in DEP1 and DEP2. */
829 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
830
831 return call;
832}
833
834#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
835#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
836#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
837#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
838#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
839#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
840#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
841 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
842#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
843 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000844
845
sewardj2019a972011-03-07 16:04:07 +0000846
847
848/*------------------------------------------------------------*/
849/*--- Guest register access ---*/
850/*------------------------------------------------------------*/
851
852
853/*------------------------------------------------------------*/
854/*--- ar registers ---*/
855/*------------------------------------------------------------*/
856
857/* Return the guest state offset of a ar register. */
858static UInt
859ar_offset(UInt archreg)
860{
861 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000862 S390X_GUEST_OFFSET(guest_a0),
863 S390X_GUEST_OFFSET(guest_a1),
864 S390X_GUEST_OFFSET(guest_a2),
865 S390X_GUEST_OFFSET(guest_a3),
866 S390X_GUEST_OFFSET(guest_a4),
867 S390X_GUEST_OFFSET(guest_a5),
868 S390X_GUEST_OFFSET(guest_a6),
869 S390X_GUEST_OFFSET(guest_a7),
870 S390X_GUEST_OFFSET(guest_a8),
871 S390X_GUEST_OFFSET(guest_a9),
872 S390X_GUEST_OFFSET(guest_a10),
873 S390X_GUEST_OFFSET(guest_a11),
874 S390X_GUEST_OFFSET(guest_a12),
875 S390X_GUEST_OFFSET(guest_a13),
876 S390X_GUEST_OFFSET(guest_a14),
877 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000878 };
879
880 vassert(archreg < 16);
881
882 return offset[archreg];
883}
884
885
886/* Return the guest state offset of word #0 of a ar register. */
887static __inline__ UInt
888ar_w0_offset(UInt archreg)
889{
890 return ar_offset(archreg) + 0;
891}
892
893/* Write word #0 of a ar to the guest state. */
894static __inline__ void
895put_ar_w0(UInt archreg, IRExpr *expr)
896{
897 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
898
899 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
900}
901
902/* Read word #0 of a ar register. */
903static __inline__ IRExpr *
904get_ar_w0(UInt archreg)
905{
906 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
907}
908
909
910/*------------------------------------------------------------*/
911/*--- fpr registers ---*/
912/*------------------------------------------------------------*/
913
914/* Return the guest state offset of a fpr register. */
915static UInt
916fpr_offset(UInt archreg)
917{
918 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000919 S390X_GUEST_OFFSET(guest_f0),
920 S390X_GUEST_OFFSET(guest_f1),
921 S390X_GUEST_OFFSET(guest_f2),
922 S390X_GUEST_OFFSET(guest_f3),
923 S390X_GUEST_OFFSET(guest_f4),
924 S390X_GUEST_OFFSET(guest_f5),
925 S390X_GUEST_OFFSET(guest_f6),
926 S390X_GUEST_OFFSET(guest_f7),
927 S390X_GUEST_OFFSET(guest_f8),
928 S390X_GUEST_OFFSET(guest_f9),
929 S390X_GUEST_OFFSET(guest_f10),
930 S390X_GUEST_OFFSET(guest_f11),
931 S390X_GUEST_OFFSET(guest_f12),
932 S390X_GUEST_OFFSET(guest_f13),
933 S390X_GUEST_OFFSET(guest_f14),
934 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000935 };
936
937 vassert(archreg < 16);
938
939 return offset[archreg];
940}
941
942
943/* Return the guest state offset of word #0 of a fpr register. */
944static __inline__ UInt
945fpr_w0_offset(UInt archreg)
946{
947 return fpr_offset(archreg) + 0;
948}
949
950/* Write word #0 of a fpr to the guest state. */
951static __inline__ void
952put_fpr_w0(UInt archreg, IRExpr *expr)
953{
954 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
955
956 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
957}
958
959/* Read word #0 of a fpr register. */
960static __inline__ IRExpr *
961get_fpr_w0(UInt archreg)
962{
963 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
964}
965
966/* Return the guest state offset of double word #0 of a fpr register. */
967static __inline__ UInt
968fpr_dw0_offset(UInt archreg)
969{
970 return fpr_offset(archreg) + 0;
971}
972
973/* Write double word #0 of a fpr to the guest state. */
974static __inline__ void
975put_fpr_dw0(UInt archreg, IRExpr *expr)
976{
977 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
978
979 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
980}
981
982/* Read double word #0 of a fpr register. */
983static __inline__ IRExpr *
984get_fpr_dw0(UInt archreg)
985{
986 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
987}
988
floriane38f6412012-12-21 17:32:12 +0000989/* Write word #0 of a dpr to the guest state. */
990static __inline__ void
991put_dpr_w0(UInt archreg, IRExpr *expr)
992{
993 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
994
995 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
996}
997
998/* Read word #0 of a dpr register. */
999static __inline__ IRExpr *
1000get_dpr_w0(UInt archreg)
1001{
1002 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1003}
1004
florian12390202012-11-10 22:34:14 +00001005/* Write double word #0 of a fpr containg DFP value to the guest state. */
1006static __inline__ void
1007put_dpr_dw0(UInt archreg, IRExpr *expr)
1008{
1009 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1010
1011 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1012}
1013
1014/* Read double word #0 of a fpr register containing DFP value. */
1015static __inline__ IRExpr *
1016get_dpr_dw0(UInt archreg)
1017{
1018 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1019}
sewardj2019a972011-03-07 16:04:07 +00001020
1021/*------------------------------------------------------------*/
1022/*--- gpr registers ---*/
1023/*------------------------------------------------------------*/
1024
1025/* Return the guest state offset of a gpr register. */
1026static UInt
1027gpr_offset(UInt archreg)
1028{
1029 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001030 S390X_GUEST_OFFSET(guest_r0),
1031 S390X_GUEST_OFFSET(guest_r1),
1032 S390X_GUEST_OFFSET(guest_r2),
1033 S390X_GUEST_OFFSET(guest_r3),
1034 S390X_GUEST_OFFSET(guest_r4),
1035 S390X_GUEST_OFFSET(guest_r5),
1036 S390X_GUEST_OFFSET(guest_r6),
1037 S390X_GUEST_OFFSET(guest_r7),
1038 S390X_GUEST_OFFSET(guest_r8),
1039 S390X_GUEST_OFFSET(guest_r9),
1040 S390X_GUEST_OFFSET(guest_r10),
1041 S390X_GUEST_OFFSET(guest_r11),
1042 S390X_GUEST_OFFSET(guest_r12),
1043 S390X_GUEST_OFFSET(guest_r13),
1044 S390X_GUEST_OFFSET(guest_r14),
1045 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001046 };
1047
1048 vassert(archreg < 16);
1049
1050 return offset[archreg];
1051}
1052
1053
1054/* Return the guest state offset of word #0 of a gpr register. */
1055static __inline__ UInt
1056gpr_w0_offset(UInt archreg)
1057{
1058 return gpr_offset(archreg) + 0;
1059}
1060
1061/* Write word #0 of a gpr to the guest state. */
1062static __inline__ void
1063put_gpr_w0(UInt archreg, IRExpr *expr)
1064{
1065 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1066
1067 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1068}
1069
1070/* Read word #0 of a gpr register. */
1071static __inline__ IRExpr *
1072get_gpr_w0(UInt archreg)
1073{
1074 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1075}
1076
1077/* Return the guest state offset of double word #0 of a gpr register. */
1078static __inline__ UInt
1079gpr_dw0_offset(UInt archreg)
1080{
1081 return gpr_offset(archreg) + 0;
1082}
1083
1084/* Write double word #0 of a gpr to the guest state. */
1085static __inline__ void
1086put_gpr_dw0(UInt archreg, IRExpr *expr)
1087{
1088 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1089
1090 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1091}
1092
1093/* Read double word #0 of a gpr register. */
1094static __inline__ IRExpr *
1095get_gpr_dw0(UInt archreg)
1096{
1097 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1098}
1099
1100/* Return the guest state offset of half word #1 of a gpr register. */
1101static __inline__ UInt
1102gpr_hw1_offset(UInt archreg)
1103{
1104 return gpr_offset(archreg) + 2;
1105}
1106
1107/* Write half word #1 of a gpr to the guest state. */
1108static __inline__ void
1109put_gpr_hw1(UInt archreg, IRExpr *expr)
1110{
1111 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1112
1113 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1114}
1115
1116/* Read half word #1 of a gpr register. */
1117static __inline__ IRExpr *
1118get_gpr_hw1(UInt archreg)
1119{
1120 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1121}
1122
1123/* Return the guest state offset of byte #6 of a gpr register. */
1124static __inline__ UInt
1125gpr_b6_offset(UInt archreg)
1126{
1127 return gpr_offset(archreg) + 6;
1128}
1129
1130/* Write byte #6 of a gpr to the guest state. */
1131static __inline__ void
1132put_gpr_b6(UInt archreg, IRExpr *expr)
1133{
1134 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1135
1136 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1137}
1138
1139/* Read byte #6 of a gpr register. */
1140static __inline__ IRExpr *
1141get_gpr_b6(UInt archreg)
1142{
1143 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1144}
1145
1146/* Return the guest state offset of byte #3 of a gpr register. */
1147static __inline__ UInt
1148gpr_b3_offset(UInt archreg)
1149{
1150 return gpr_offset(archreg) + 3;
1151}
1152
1153/* Write byte #3 of a gpr to the guest state. */
1154static __inline__ void
1155put_gpr_b3(UInt archreg, IRExpr *expr)
1156{
1157 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1158
1159 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1160}
1161
1162/* Read byte #3 of a gpr register. */
1163static __inline__ IRExpr *
1164get_gpr_b3(UInt archreg)
1165{
1166 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1167}
1168
1169/* Return the guest state offset of byte #0 of a gpr register. */
1170static __inline__ UInt
1171gpr_b0_offset(UInt archreg)
1172{
1173 return gpr_offset(archreg) + 0;
1174}
1175
1176/* Write byte #0 of a gpr to the guest state. */
1177static __inline__ void
1178put_gpr_b0(UInt archreg, IRExpr *expr)
1179{
1180 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1181
1182 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1183}
1184
1185/* Read byte #0 of a gpr register. */
1186static __inline__ IRExpr *
1187get_gpr_b0(UInt archreg)
1188{
1189 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1190}
1191
1192/* Return the guest state offset of word #1 of a gpr register. */
1193static __inline__ UInt
1194gpr_w1_offset(UInt archreg)
1195{
1196 return gpr_offset(archreg) + 4;
1197}
1198
1199/* Write word #1 of a gpr to the guest state. */
1200static __inline__ void
1201put_gpr_w1(UInt archreg, IRExpr *expr)
1202{
1203 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1204
1205 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1206}
1207
1208/* Read word #1 of a gpr register. */
1209static __inline__ IRExpr *
1210get_gpr_w1(UInt archreg)
1211{
1212 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1213}
1214
1215/* Return the guest state offset of half word #3 of a gpr register. */
1216static __inline__ UInt
1217gpr_hw3_offset(UInt archreg)
1218{
1219 return gpr_offset(archreg) + 6;
1220}
1221
1222/* Write half word #3 of a gpr to the guest state. */
1223static __inline__ void
1224put_gpr_hw3(UInt archreg, IRExpr *expr)
1225{
1226 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1227
1228 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1229}
1230
1231/* Read half word #3 of a gpr register. */
1232static __inline__ IRExpr *
1233get_gpr_hw3(UInt archreg)
1234{
1235 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1236}
1237
1238/* Return the guest state offset of byte #7 of a gpr register. */
1239static __inline__ UInt
1240gpr_b7_offset(UInt archreg)
1241{
1242 return gpr_offset(archreg) + 7;
1243}
1244
1245/* Write byte #7 of a gpr to the guest state. */
1246static __inline__ void
1247put_gpr_b7(UInt archreg, IRExpr *expr)
1248{
1249 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1250
1251 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1252}
1253
1254/* Read byte #7 of a gpr register. */
1255static __inline__ IRExpr *
1256get_gpr_b7(UInt archreg)
1257{
1258 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1259}
1260
1261/* Return the guest state offset of half word #0 of a gpr register. */
1262static __inline__ UInt
1263gpr_hw0_offset(UInt archreg)
1264{
1265 return gpr_offset(archreg) + 0;
1266}
1267
1268/* Write half word #0 of a gpr to the guest state. */
1269static __inline__ void
1270put_gpr_hw0(UInt archreg, IRExpr *expr)
1271{
1272 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1273
1274 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1275}
1276
1277/* Read half word #0 of a gpr register. */
1278static __inline__ IRExpr *
1279get_gpr_hw0(UInt archreg)
1280{
1281 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1282}
1283
1284/* Return the guest state offset of byte #4 of a gpr register. */
1285static __inline__ UInt
1286gpr_b4_offset(UInt archreg)
1287{
1288 return gpr_offset(archreg) + 4;
1289}
1290
1291/* Write byte #4 of a gpr to the guest state. */
1292static __inline__ void
1293put_gpr_b4(UInt archreg, IRExpr *expr)
1294{
1295 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1296
1297 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1298}
1299
1300/* Read byte #4 of a gpr register. */
1301static __inline__ IRExpr *
1302get_gpr_b4(UInt archreg)
1303{
1304 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1305}
1306
1307/* Return the guest state offset of byte #1 of a gpr register. */
1308static __inline__ UInt
1309gpr_b1_offset(UInt archreg)
1310{
1311 return gpr_offset(archreg) + 1;
1312}
1313
1314/* Write byte #1 of a gpr to the guest state. */
1315static __inline__ void
1316put_gpr_b1(UInt archreg, IRExpr *expr)
1317{
1318 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1319
1320 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1321}
1322
1323/* Read byte #1 of a gpr register. */
1324static __inline__ IRExpr *
1325get_gpr_b1(UInt archreg)
1326{
1327 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1328}
1329
1330/* Return the guest state offset of half word #2 of a gpr register. */
1331static __inline__ UInt
1332gpr_hw2_offset(UInt archreg)
1333{
1334 return gpr_offset(archreg) + 4;
1335}
1336
1337/* Write half word #2 of a gpr to the guest state. */
1338static __inline__ void
1339put_gpr_hw2(UInt archreg, IRExpr *expr)
1340{
1341 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1342
1343 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1344}
1345
1346/* Read half word #2 of a gpr register. */
1347static __inline__ IRExpr *
1348get_gpr_hw2(UInt archreg)
1349{
1350 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1351}
1352
1353/* Return the guest state offset of byte #5 of a gpr register. */
1354static __inline__ UInt
1355gpr_b5_offset(UInt archreg)
1356{
1357 return gpr_offset(archreg) + 5;
1358}
1359
1360/* Write byte #5 of a gpr to the guest state. */
1361static __inline__ void
1362put_gpr_b5(UInt archreg, IRExpr *expr)
1363{
1364 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1365
1366 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1367}
1368
1369/* Read byte #5 of a gpr register. */
1370static __inline__ IRExpr *
1371get_gpr_b5(UInt archreg)
1372{
1373 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1374}
1375
1376/* Return the guest state offset of byte #2 of a gpr register. */
1377static __inline__ UInt
1378gpr_b2_offset(UInt archreg)
1379{
1380 return gpr_offset(archreg) + 2;
1381}
1382
1383/* Write byte #2 of a gpr to the guest state. */
1384static __inline__ void
1385put_gpr_b2(UInt archreg, IRExpr *expr)
1386{
1387 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1388
1389 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1390}
1391
1392/* Read byte #2 of a gpr register. */
1393static __inline__ IRExpr *
1394get_gpr_b2(UInt archreg)
1395{
1396 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1397}
1398
1399/* Return the guest state offset of the counter register. */
1400static UInt
1401counter_offset(void)
1402{
floriane88b3c92011-07-05 02:48:39 +00001403 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001404}
1405
1406/* Return the guest state offset of double word #0 of the counter register. */
1407static __inline__ UInt
1408counter_dw0_offset(void)
1409{
1410 return counter_offset() + 0;
1411}
1412
1413/* Write double word #0 of the counter to the guest state. */
1414static __inline__ void
1415put_counter_dw0(IRExpr *expr)
1416{
1417 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1418
1419 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1420}
1421
1422/* Read double word #0 of the counter register. */
1423static __inline__ IRExpr *
1424get_counter_dw0(void)
1425{
1426 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1427}
1428
1429/* Return the guest state offset of word #0 of the counter register. */
1430static __inline__ UInt
1431counter_w0_offset(void)
1432{
1433 return counter_offset() + 0;
1434}
1435
1436/* Return the guest state offset of word #1 of the counter register. */
1437static __inline__ UInt
1438counter_w1_offset(void)
1439{
1440 return counter_offset() + 4;
1441}
1442
1443/* Write word #0 of the counter to the guest state. */
1444static __inline__ void
1445put_counter_w0(IRExpr *expr)
1446{
1447 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1448
1449 stmt(IRStmt_Put(counter_w0_offset(), expr));
1450}
1451
1452/* Read word #0 of the counter register. */
1453static __inline__ IRExpr *
1454get_counter_w0(void)
1455{
1456 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1457}
1458
1459/* Write word #1 of the counter to the guest state. */
1460static __inline__ void
1461put_counter_w1(IRExpr *expr)
1462{
1463 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1464
1465 stmt(IRStmt_Put(counter_w1_offset(), expr));
1466}
1467
1468/* Read word #1 of the counter register. */
1469static __inline__ IRExpr *
1470get_counter_w1(void)
1471{
1472 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1473}
1474
1475/* Return the guest state offset of the fpc register. */
1476static UInt
1477fpc_offset(void)
1478{
floriane88b3c92011-07-05 02:48:39 +00001479 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001480}
1481
1482/* Return the guest state offset of word #0 of the fpc register. */
1483static __inline__ UInt
1484fpc_w0_offset(void)
1485{
1486 return fpc_offset() + 0;
1487}
1488
1489/* Write word #0 of the fpc to the guest state. */
1490static __inline__ void
1491put_fpc_w0(IRExpr *expr)
1492{
1493 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1494
1495 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1496}
1497
1498/* Read word #0 of the fpc register. */
1499static __inline__ IRExpr *
1500get_fpc_w0(void)
1501{
1502 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1503}
1504
1505
1506/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001507/*--- Rounding modes ---*/
1508/*------------------------------------------------------------*/
1509
florian125e20d2012-10-07 15:42:37 +00001510/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001511 IRRoundingMode:
1512
1513 rounding mode | s390 | IR
1514 -------------------------
1515 to nearest | 00 | 00
1516 to zero | 01 | 11
1517 to +infinity | 10 | 10
1518 to -infinity | 11 | 01
1519
1520 So: IR = (4 - s390) & 3
1521*/
1522static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001523get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001524{
1525 IRTemp fpc_bits = newTemp(Ity_I32);
1526
1527 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1528 Prior to that bits [30:31] contained the bfp rounding mode with
1529 bit 29 being unused and having a value of 0. So we can always
1530 extract the least significant 3 bits. */
1531 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1532
1533 /* fixs390:
1534
1535
1536 if (! s390_host_has_fpext && rounding_mode > 3) {
1537 emulation warning @ runtime and
1538 set fpc to round nearest
1539 }
1540 */
1541
1542 /* For now silently adjust an unsupported rounding mode to "nearest" */
1543 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1544 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001545 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001546
1547 // rm_IR = (4 - rm_s390) & 3;
1548 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1549}
1550
1551/* Encode the s390 rounding mode as it appears in the m3 field of certain
1552 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1553 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1554 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1555 considers the default rounding mode (4.3.3). */
1556static IRTemp
1557encode_bfp_rounding_mode(UChar mode)
1558{
1559 IRExpr *rm;
1560
1561 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001562 case S390_BFP_ROUND_PER_FPC:
1563 rm = get_bfp_rounding_mode_from_fpc();
1564 break;
1565 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1566 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1567 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1568 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1569 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1570 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001571 default:
1572 vpanic("encode_bfp_rounding_mode");
1573 }
1574
1575 return mktemp(Ity_I32, rm);
1576}
1577
florianc8e4f562012-10-27 16:19:31 +00001578/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1579 IRRoundingMode:
1580
1581 rounding mode | s390 | IR
1582 ------------------------------------------------
1583 to nearest, ties to even | 000 | 000
1584 to zero | 001 | 011
1585 to +infinity | 010 | 010
1586 to -infinity | 011 | 001
1587 to nearest, ties away from 0 | 100 | 100
1588 to nearest, ties toward 0 | 101 | 111
1589 to away from 0 | 110 | 110
1590 to prepare for shorter precision | 111 | 101
1591
1592 So: IR = (s390 ^ ((s390 << 1) & 2))
1593*/
florianc8e4f562012-10-27 16:19:31 +00001594static IRExpr *
1595get_dfp_rounding_mode_from_fpc(void)
1596{
1597 IRTemp fpc_bits = newTemp(Ity_I32);
1598
1599 /* The dfp rounding mode is stored in bits [25:27].
1600 extract the bits at 25:27 and right shift 4 times. */
1601 assign(fpc_bits, binop(Iop_Shr32,
1602 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1603 mkU8(4)));
1604
1605 IRExpr *rm_s390 = mkexpr(fpc_bits);
1606 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1607
1608 return binop(Iop_Xor32, rm_s390,
1609 binop( Iop_And32,
1610 binop(Iop_Shl32, rm_s390, mkU8(1)),
1611 mkU32(2)));
1612}
1613
1614/* Encode the s390 rounding mode as it appears in the m3 field of certain
1615 instructions to VEX's IRRoundingMode. */
1616static IRTemp
1617encode_dfp_rounding_mode(UChar mode)
1618{
1619 IRExpr *rm;
1620
1621 switch (mode) {
1622 case S390_DFP_ROUND_PER_FPC_0:
1623 case S390_DFP_ROUND_PER_FPC_2:
1624 rm = get_dfp_rounding_mode_from_fpc(); break;
1625 case S390_DFP_ROUND_NEAREST_EVEN_4:
1626 case S390_DFP_ROUND_NEAREST_EVEN_8:
florian79e5a482013-06-06 19:12:46 +00001627 rm = mkU32(Irrm_NEAREST); break;
florianc8e4f562012-10-27 16:19:31 +00001628 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1629 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
florian79e5a482013-06-06 19:12:46 +00001630 rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
florianc8e4f562012-10-27 16:19:31 +00001631 case S390_DFP_ROUND_PREPARE_SHORT_3:
1632 case S390_DFP_ROUND_PREPARE_SHORT_15:
florian79e5a482013-06-06 19:12:46 +00001633 rm = mkU32(Irrm_PREPARE_SHORTER); break;
florianc8e4f562012-10-27 16:19:31 +00001634 case S390_DFP_ROUND_ZERO_5:
1635 case S390_DFP_ROUND_ZERO_9:
florian79e5a482013-06-06 19:12:46 +00001636 rm = mkU32(Irrm_ZERO ); break;
florianc8e4f562012-10-27 16:19:31 +00001637 case S390_DFP_ROUND_POSINF_6:
1638 case S390_DFP_ROUND_POSINF_10:
florian79e5a482013-06-06 19:12:46 +00001639 rm = mkU32(Irrm_PosINF); break;
florianc8e4f562012-10-27 16:19:31 +00001640 case S390_DFP_ROUND_NEGINF_7:
1641 case S390_DFP_ROUND_NEGINF_11:
florian79e5a482013-06-06 19:12:46 +00001642 rm = mkU32(Irrm_NegINF); break;
florianc8e4f562012-10-27 16:19:31 +00001643 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
florian79e5a482013-06-06 19:12:46 +00001644 rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
florianc8e4f562012-10-27 16:19:31 +00001645 case S390_DFP_ROUND_AWAY_0:
florian79e5a482013-06-06 19:12:46 +00001646 rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
florianc8e4f562012-10-27 16:19:31 +00001647 default:
1648 vpanic("encode_dfp_rounding_mode");
1649 }
1650
1651 return mktemp(Ity_I32, rm);
1652}
florian12390202012-11-10 22:34:14 +00001653
florianc8e4f562012-10-27 16:19:31 +00001654
florian2c74d242012-09-12 19:38:42 +00001655/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001656/*--- Condition code helpers ---*/
1657/*------------------------------------------------------------*/
1658
1659/* The result of a Iop_CmpFxx operation is a condition code. It is
1660 encoded using the values defined in type IRCmpFxxResult.
1661 Before we can store the condition code into the guest state (or do
1662 anything else with it for that matter) we need to convert it to
1663 the encoding that s390 uses. This is what this function does.
1664
1665 s390 VEX b6 b2 b0 cc.1 cc.0
1666 0 0x40 EQ 1 0 0 0 0
1667 1 0x01 LT 0 0 1 0 1
1668 2 0x00 GT 0 0 0 1 0
1669 3 0x45 Unordered 1 1 1 1 1
1670
1671 The following bits from the VEX encoding are interesting:
1672 b0, b2, b6 with b0 being the LSB. We observe:
1673
1674 cc.0 = b0;
1675 cc.1 = b2 | (~b0 & ~b6)
1676
1677 with cc being the s390 condition code.
1678*/
1679static IRExpr *
1680convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1681{
1682 IRTemp cc0 = newTemp(Ity_I32);
1683 IRTemp cc1 = newTemp(Ity_I32);
1684 IRTemp b0 = newTemp(Ity_I32);
1685 IRTemp b2 = newTemp(Ity_I32);
1686 IRTemp b6 = newTemp(Ity_I32);
1687
1688 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1689 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1690 mkU32(1)));
1691 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1692 mkU32(1)));
1693
1694 assign(cc0, mkexpr(b0));
1695 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1696 binop(Iop_And32,
1697 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1698 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1699 )));
1700
1701 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1702}
1703
1704
1705/* The result of a Iop_CmpDxx operation is a condition code. It is
1706 encoded using the values defined in type IRCmpDxxResult.
1707 Before we can store the condition code into the guest state (or do
1708 anything else with it for that matter) we need to convert it to
1709 the encoding that s390 uses. This is what this function does. */
1710static IRExpr *
1711convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1712{
1713 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1714 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001715 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001716}
1717
1718
1719/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001720/*--- Build IR for formats ---*/
1721/*------------------------------------------------------------*/
1722static void
florian55085f82012-11-21 00:36:55 +00001723s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001724 UChar i)
1725{
florian55085f82012-11-21 00:36:55 +00001726 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001727
sewardj7ee97522011-05-09 21:45:04 +00001728 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001729 s390_disasm(ENC2(MNM, UINT), mnm, i);
1730}
1731
1732static void
florian78d5ef72013-05-11 15:02:58 +00001733s390_format_E(const HChar *(*irgen)(void))
1734{
1735 const HChar *mnm = irgen();
1736
1737 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1738 s390_disasm(ENC1(MNM), mnm);
1739}
1740
1741static void
florian55085f82012-11-21 00:36:55 +00001742s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001743 UChar r1, UShort i2)
1744{
1745 irgen(r1, i2);
1746}
1747
1748static void
florian55085f82012-11-21 00:36:55 +00001749s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001750 UChar r1, UShort i2)
1751{
florian55085f82012-11-21 00:36:55 +00001752 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001753
sewardj7ee97522011-05-09 21:45:04 +00001754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001755 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1756}
1757
1758static void
florian55085f82012-11-21 00:36:55 +00001759s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001760 UChar r1, UShort i2)
1761{
florian55085f82012-11-21 00:36:55 +00001762 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001763
sewardj7ee97522011-05-09 21:45:04 +00001764 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001765 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1766}
1767
1768static void
florian55085f82012-11-21 00:36:55 +00001769s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001770 UChar r1, UShort i2)
1771{
florian55085f82012-11-21 00:36:55 +00001772 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001773
sewardj7ee97522011-05-09 21:45:04 +00001774 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001775 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1776}
1777
1778static void
florian55085f82012-11-21 00:36:55 +00001779s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001780 UChar r1, UChar r3, UShort i2)
1781{
florian55085f82012-11-21 00:36:55 +00001782 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001783
sewardj7ee97522011-05-09 21:45:04 +00001784 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001785 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1786}
1787
1788static void
florian55085f82012-11-21 00:36:55 +00001789s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001790 UChar r1, UChar r3, UShort i2)
1791{
florian55085f82012-11-21 00:36:55 +00001792 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001793
sewardj7ee97522011-05-09 21:45:04 +00001794 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001795 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1796}
1797
1798static void
florian55085f82012-11-21 00:36:55 +00001799s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1800 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001801 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1802{
florian55085f82012-11-21 00:36:55 +00001803 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001804
sewardj7ee97522011-05-09 21:45:04 +00001805 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001806 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1807 i5);
1808}
1809
1810static void
florian55085f82012-11-21 00:36:55 +00001811s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1812 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001813 UChar r1, UChar r2, UShort i4, UChar m3)
1814{
florian55085f82012-11-21 00:36:55 +00001815 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001816
sewardj7ee97522011-05-09 21:45:04 +00001817 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001818 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1819 r2, m3, (Int)(Short)i4);
1820}
1821
1822static void
florian55085f82012-11-21 00:36:55 +00001823s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1824 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001825 UChar r1, UChar m3, UShort i4, UChar i2)
1826{
florian55085f82012-11-21 00:36:55 +00001827 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001828
sewardj7ee97522011-05-09 21:45:04 +00001829 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001830 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1831 r1, i2, m3, (Int)(Short)i4);
1832}
1833
1834static void
florian55085f82012-11-21 00:36:55 +00001835s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1836 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001837 UChar r1, UChar m3, UShort i4, UChar i2)
1838{
florian55085f82012-11-21 00:36:55 +00001839 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001840
sewardj7ee97522011-05-09 21:45:04 +00001841 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001842 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1843 (Int)(Char)i2, m3, (Int)(Short)i4);
1844}
1845
1846static void
florian55085f82012-11-21 00:36:55 +00001847s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001848 UChar r1, UInt i2)
1849{
1850 irgen(r1, i2);
1851}
1852
1853static void
florian55085f82012-11-21 00:36:55 +00001854s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001855 UChar r1, UInt i2)
1856{
florian55085f82012-11-21 00:36:55 +00001857 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001858
sewardj7ee97522011-05-09 21:45:04 +00001859 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001860 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1861}
1862
1863static void
florian55085f82012-11-21 00:36:55 +00001864s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001865 UChar r1, UInt i2)
1866{
florian55085f82012-11-21 00:36:55 +00001867 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001868
sewardj7ee97522011-05-09 21:45:04 +00001869 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001870 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1871}
1872
1873static void
florian55085f82012-11-21 00:36:55 +00001874s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001875 UChar r1, UInt i2)
1876{
florian55085f82012-11-21 00:36:55 +00001877 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001878
sewardj7ee97522011-05-09 21:45:04 +00001879 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001880 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1881}
1882
1883static void
florian55085f82012-11-21 00:36:55 +00001884s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001885 UChar r1, UInt i2)
1886{
florian55085f82012-11-21 00:36:55 +00001887 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001888
sewardj7ee97522011-05-09 21:45:04 +00001889 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001890 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1891}
1892
1893static void
florian55085f82012-11-21 00:36:55 +00001894s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001895 IRTemp op4addr),
1896 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1897{
florian55085f82012-11-21 00:36:55 +00001898 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001899 IRTemp op4addr = newTemp(Ity_I64);
1900
1901 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1902 mkU64(0)));
1903
1904 mnm = irgen(r1, m3, i2, op4addr);
1905
sewardj7ee97522011-05-09 21:45:04 +00001906 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001907 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1908 (Int)(Char)i2, m3, d4, 0, b4);
1909}
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001913 IRTemp op4addr),
1914 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1915{
florian55085f82012-11-21 00:36:55 +00001916 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001917 IRTemp op4addr = newTemp(Ity_I64);
1918
1919 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1920 mkU64(0)));
1921
1922 mnm = irgen(r1, m3, i2, op4addr);
1923
sewardj7ee97522011-05-09 21:45:04 +00001924 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001925 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1926 i2, m3, d4, 0, b4);
1927}
1928
1929static void
florian55085f82012-11-21 00:36:55 +00001930s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001931 UChar r1, UChar r2)
1932{
1933 irgen(r1, r2);
1934}
1935
1936static void
florian55085f82012-11-21 00:36:55 +00001937s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001938 UChar r1, UChar r2)
1939{
florian55085f82012-11-21 00:36:55 +00001940 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001941
sewardj7ee97522011-05-09 21:45:04 +00001942 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001943 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1944}
1945
1946static void
florian55085f82012-11-21 00:36:55 +00001947s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001948 UChar r1, UChar r2)
1949{
florian55085f82012-11-21 00:36:55 +00001950 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001951
sewardj7ee97522011-05-09 21:45:04 +00001952 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001953 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1954}
1955
1956static void
florian55085f82012-11-21 00:36:55 +00001957s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001958 UChar r1, UChar r2)
1959{
1960 irgen(r1, r2);
1961}
1962
1963static void
florian55085f82012-11-21 00:36:55 +00001964s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001965 UChar r1, UChar r2)
1966{
florian55085f82012-11-21 00:36:55 +00001967 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001968
sewardj7ee97522011-05-09 21:45:04 +00001969 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001970 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1971}
1972
1973static void
florian55085f82012-11-21 00:36:55 +00001974s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001975 UChar r1, UChar r2)
1976{
florian55085f82012-11-21 00:36:55 +00001977 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001978
sewardj7ee97522011-05-09 21:45:04 +00001979 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001980 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1981}
1982
1983static void
florian55085f82012-11-21 00:36:55 +00001984s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001985 UChar r1, UChar r2)
1986{
florian55085f82012-11-21 00:36:55 +00001987 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001988
sewardj7ee97522011-05-09 21:45:04 +00001989 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001990 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1991}
1992
1993static void
florian55085f82012-11-21 00:36:55 +00001994s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001995 UChar r1, UChar r2)
1996{
florian55085f82012-11-21 00:36:55 +00001997 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001998
sewardj7ee97522011-05-09 21:45:04 +00001999 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002000 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2001}
2002
2003static void
florian55085f82012-11-21 00:36:55 +00002004s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002005 UChar r1)
2006{
florian55085f82012-11-21 00:36:55 +00002007 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002008
sewardj7ee97522011-05-09 21:45:04 +00002009 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002010 s390_disasm(ENC2(MNM, GPR), mnm, r1);
2011}
2012
2013static void
florian55085f82012-11-21 00:36:55 +00002014s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002015 UChar r1)
2016{
florian55085f82012-11-21 00:36:55 +00002017 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002018
sewardj7ee97522011-05-09 21:45:04 +00002019 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002020 s390_disasm(ENC2(MNM, FPR), mnm, r1);
2021}
2022
2023static void
florian55085f82012-11-21 00:36:55 +00002024s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002025 UChar m3, UChar r1, UChar r2)
2026{
florian55085f82012-11-21 00:36:55 +00002027 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002028
2029 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002030 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002031}
2032
2033static void
florian55085f82012-11-21 00:36:55 +00002034s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002035 UChar r1, UChar r3, UChar r2)
2036{
florian55085f82012-11-21 00:36:55 +00002037 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002038
sewardj7ee97522011-05-09 21:45:04 +00002039 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002040 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2041}
2042
2043static void
florian5c539732013-02-14 14:27:12 +00002044s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2045 UChar r3, UChar r1, UChar r2)
2046{
2047 const HChar *mnm = irgen(r3, r1, r2);
2048
2049 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2050 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2051}
2052
2053static void
florian55085f82012-11-21 00:36:55 +00002054s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2055 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002056 UChar m3, UChar m4, UChar r1, UChar r2)
2057{
florian55085f82012-11-21 00:36:55 +00002058 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002059
2060 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2061 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2062}
2063
2064static void
floriane38f6412012-12-21 17:32:12 +00002065s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2066 UChar m4, UChar r1, UChar r2)
2067{
2068 const HChar *mnm = irgen(m4, r1, r2);
2069
2070 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2071 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2072}
2073
2074static void
florian55085f82012-11-21 00:36:55 +00002075s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2076 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002077 UChar m3, UChar m4, UChar r1, UChar r2)
2078{
florian55085f82012-11-21 00:36:55 +00002079 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002080
2081 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2082 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2083}
2084
2085static void
florian55085f82012-11-21 00:36:55 +00002086s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2087 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002088 UChar m3, UChar m4, UChar r1, UChar r2)
2089{
florian55085f82012-11-21 00:36:55 +00002090 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002091
2092 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2093 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2094}
2095
2096
2097static void
florian55085f82012-11-21 00:36:55 +00002098s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002099 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2100{
2101 irgen(m3, r1, r2);
2102
sewardj7ee97522011-05-09 21:45:04 +00002103 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002104 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2105}
2106
2107static void
florian55085f82012-11-21 00:36:55 +00002108s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002109 UChar r3, UChar r1, UChar r2)
2110{
florian55085f82012-11-21 00:36:55 +00002111 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002112
sewardj7ee97522011-05-09 21:45:04 +00002113 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002114 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2115}
2116
2117static void
florian5c539732013-02-14 14:27:12 +00002118s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2119 UChar r3, UChar m4, UChar r1, UChar r2)
2120{
2121 const HChar *mnm = irgen(r3, m4, r1, r2);
2122
2123 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2124 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2125}
2126
2127static void
2128s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2129 UChar r3, UChar m4, UChar r1, UChar r2)
2130{
2131 const HChar *mnm = irgen(r3, m4, r1, r2);
2132
2133 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2134 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2135}
2136
2137static void
florian55085f82012-11-21 00:36:55 +00002138s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002139 UChar r3, UChar m4, UChar r1, UChar r2)
2140{
florian55085f82012-11-21 00:36:55 +00002141 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002142
2143 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2144 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2145}
2146
2147static void
florian55085f82012-11-21 00:36:55 +00002148s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002149 UChar r3, UChar r1, UChar r2)
2150{
florian55085f82012-11-21 00:36:55 +00002151 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002152
sewardj7ee97522011-05-09 21:45:04 +00002153 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002154 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2155}
2156
2157static void
florian55085f82012-11-21 00:36:55 +00002158s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2159 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002160 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2161{
florian55085f82012-11-21 00:36:55 +00002162 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002163 IRTemp op4addr = newTemp(Ity_I64);
2164
2165 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2166 mkU64(0)));
2167
2168 mnm = irgen(r1, r2, m3, op4addr);
2169
sewardj7ee97522011-05-09 21:45:04 +00002170 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002171 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2172 r2, m3, d4, 0, b4);
2173}
2174
2175static void
florian55085f82012-11-21 00:36:55 +00002176s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002177 UChar r1, UChar b2, UShort d2)
2178{
florian55085f82012-11-21 00:36:55 +00002179 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002180 IRTemp op2addr = newTemp(Ity_I64);
2181
2182 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2183 mkU64(0)));
2184
2185 mnm = irgen(r1, op2addr);
2186
sewardj7ee97522011-05-09 21:45:04 +00002187 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002188 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2189}
2190
2191static void
florian55085f82012-11-21 00:36:55 +00002192s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002193 UChar r1, UChar r3, UChar b2, UShort d2)
2194{
florian55085f82012-11-21 00:36:55 +00002195 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002196 IRTemp op2addr = newTemp(Ity_I64);
2197
2198 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2199 mkU64(0)));
2200
2201 mnm = irgen(r1, r3, op2addr);
2202
sewardj7ee97522011-05-09 21:45:04 +00002203 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002204 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2205}
2206
2207static void
florian55085f82012-11-21 00:36:55 +00002208s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002209 UChar r1, UChar r3, UChar b2, UShort d2)
2210{
florian55085f82012-11-21 00:36:55 +00002211 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002212 IRTemp op2addr = newTemp(Ity_I64);
2213
2214 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2215 mkU64(0)));
2216
2217 mnm = irgen(r1, r3, op2addr);
2218
sewardj7ee97522011-05-09 21:45:04 +00002219 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002220 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2221}
2222
2223static void
florian55085f82012-11-21 00:36:55 +00002224s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002225 UChar r1, UChar r3, UChar b2, UShort d2)
2226{
florian55085f82012-11-21 00:36:55 +00002227 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002228 IRTemp op2addr = newTemp(Ity_I64);
2229
2230 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2231 mkU64(0)));
2232
2233 mnm = irgen(r1, r3, op2addr);
2234
sewardj7ee97522011-05-09 21:45:04 +00002235 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002236 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2237}
2238
2239static void
florian55085f82012-11-21 00:36:55 +00002240s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002241 UChar r1, UChar r3, UShort i2)
2242{
florian55085f82012-11-21 00:36:55 +00002243 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002244
sewardj7ee97522011-05-09 21:45:04 +00002245 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002246 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2247}
2248
2249static void
florian55085f82012-11-21 00:36:55 +00002250s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002251 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2252{
florian55085f82012-11-21 00:36:55 +00002253 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002254 IRTemp op2addr = newTemp(Ity_I64);
2255 IRTemp d2 = newTemp(Ity_I64);
2256
2257 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2258 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2259 mkU64(0)));
2260
2261 mnm = irgen(r1, r3, op2addr);
2262
sewardj7ee97522011-05-09 21:45:04 +00002263 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002264 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2265}
2266
2267static void
florian55085f82012-11-21 00:36:55 +00002268s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002269 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2270{
florian55085f82012-11-21 00:36:55 +00002271 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002272 IRTemp op2addr = newTemp(Ity_I64);
2273 IRTemp d2 = newTemp(Ity_I64);
2274
2275 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2276 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2277 mkU64(0)));
2278
2279 mnm = irgen(r1, r3, op2addr);
2280
sewardj7ee97522011-05-09 21:45:04 +00002281 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002282 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2283}
2284
2285static void
florian55085f82012-11-21 00:36:55 +00002286s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002287 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2288{
florian55085f82012-11-21 00:36:55 +00002289 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002290 IRTemp op2addr = newTemp(Ity_I64);
2291 IRTemp d2 = newTemp(Ity_I64);
2292
2293 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2294 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2295 mkU64(0)));
2296
2297 mnm = irgen(r1, r3, op2addr);
2298
sewardj7ee97522011-05-09 21:45:04 +00002299 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002300 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2301}
2302
2303static void
florian55085f82012-11-21 00:36:55 +00002304s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002305 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2306 Int xmnm_kind)
2307{
2308 IRTemp op2addr = newTemp(Ity_I64);
2309 IRTemp d2 = newTemp(Ity_I64);
2310
florian6820ba52012-07-26 02:01:50 +00002311 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2312
sewardjd7bde722011-04-05 13:19:33 +00002313 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2314 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2315 mkU64(0)));
2316
2317 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002318
2319 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002320
sewardj7ee97522011-05-09 21:45:04 +00002321 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002322 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2323}
2324
2325static void
florian55085f82012-11-21 00:36:55 +00002326s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002327 IRTemp op2addr),
2328 UChar r1, UChar x2, UChar b2, UShort d2)
2329{
2330 IRTemp op2addr = newTemp(Ity_I64);
2331
2332 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2333 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2334 mkU64(0)));
2335
2336 irgen(r1, x2, b2, d2, op2addr);
2337}
2338
2339static void
florian55085f82012-11-21 00:36:55 +00002340s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002341 UChar r1, UChar x2, UChar b2, UShort d2)
2342{
florian55085f82012-11-21 00:36:55 +00002343 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002344 IRTemp op2addr = newTemp(Ity_I64);
2345
2346 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2347 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2348 mkU64(0)));
2349
2350 mnm = irgen(r1, op2addr);
2351
sewardj7ee97522011-05-09 21:45:04 +00002352 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002353 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2354}
2355
2356static void
florian55085f82012-11-21 00:36:55 +00002357s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002358 UChar r1, UChar x2, UChar b2, UShort d2)
2359{
florian55085f82012-11-21 00:36:55 +00002360 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002361 IRTemp op2addr = newTemp(Ity_I64);
2362
2363 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2364 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2365 mkU64(0)));
2366
2367 mnm = irgen(r1, op2addr);
2368
sewardj7ee97522011-05-09 21:45:04 +00002369 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002370 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2371}
2372
2373static void
florian55085f82012-11-21 00:36:55 +00002374s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002375 UChar r1, UChar x2, UChar b2, UShort d2)
2376{
florian55085f82012-11-21 00:36:55 +00002377 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002378 IRTemp op2addr = newTemp(Ity_I64);
2379
2380 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2381 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2382 mkU64(0)));
2383
2384 mnm = irgen(r1, op2addr);
2385
sewardj7ee97522011-05-09 21:45:04 +00002386 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002387 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2388}
2389
2390static void
florian55085f82012-11-21 00:36:55 +00002391s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002392 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2393{
florian55085f82012-11-21 00:36:55 +00002394 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002395 IRTemp op2addr = newTemp(Ity_I64);
2396
2397 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2398 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2399 mkU64(0)));
2400
2401 mnm = irgen(r3, op2addr, r1);
2402
sewardj7ee97522011-05-09 21:45:04 +00002403 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002404 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2405}
2406
2407static void
florian55085f82012-11-21 00:36:55 +00002408s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002409 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2410{
florian55085f82012-11-21 00:36:55 +00002411 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002412 IRTemp op2addr = newTemp(Ity_I64);
2413 IRTemp d2 = newTemp(Ity_I64);
2414
2415 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2416 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2417 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2418 mkU64(0)));
2419
2420 mnm = irgen(r1, op2addr);
2421
sewardj7ee97522011-05-09 21:45:04 +00002422 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002423 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2424}
2425
2426static void
florian55085f82012-11-21 00:36:55 +00002427s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002428 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2429{
florian55085f82012-11-21 00:36:55 +00002430 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002431 IRTemp op2addr = newTemp(Ity_I64);
2432 IRTemp d2 = newTemp(Ity_I64);
2433
2434 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2435 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2436 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2437 mkU64(0)));
2438
2439 mnm = irgen(r1, op2addr);
2440
sewardj7ee97522011-05-09 21:45:04 +00002441 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002442 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2443}
2444
2445static void
florian55085f82012-11-21 00:36:55 +00002446s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002447 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2448{
florian55085f82012-11-21 00:36:55 +00002449 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002450 IRTemp op2addr = newTemp(Ity_I64);
2451 IRTemp d2 = newTemp(Ity_I64);
2452
2453 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2454 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2455 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2456 mkU64(0)));
2457
2458 mnm = irgen();
2459
sewardj7ee97522011-05-09 21:45:04 +00002460 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002461 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2462}
2463
2464static void
florian55085f82012-11-21 00:36:55 +00002465s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002466 UChar b2, UShort d2)
2467{
florian55085f82012-11-21 00:36:55 +00002468 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002469 IRTemp op2addr = newTemp(Ity_I64);
2470
2471 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2472 mkU64(0)));
2473
2474 mnm = irgen(op2addr);
2475
sewardj7ee97522011-05-09 21:45:04 +00002476 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002477 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2478}
2479
2480static void
florian55085f82012-11-21 00:36:55 +00002481s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002482 UChar i2, UChar b1, UShort d1)
2483{
florian55085f82012-11-21 00:36:55 +00002484 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002485 IRTemp op1addr = newTemp(Ity_I64);
2486
2487 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2488 mkU64(0)));
2489
2490 mnm = irgen(i2, op1addr);
2491
sewardj7ee97522011-05-09 21:45:04 +00002492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002493 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2494}
2495
2496static void
florian55085f82012-11-21 00:36:55 +00002497s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002498 UChar i2, UChar b1, UShort dl1, UChar dh1)
2499{
florian55085f82012-11-21 00:36:55 +00002500 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002501 IRTemp op1addr = newTemp(Ity_I64);
2502 IRTemp d1 = newTemp(Ity_I64);
2503
2504 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2505 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2506 mkU64(0)));
2507
2508 mnm = irgen(i2, op1addr);
2509
sewardj7ee97522011-05-09 21:45:04 +00002510 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002511 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2512}
2513
2514static void
florian55085f82012-11-21 00:36:55 +00002515s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002516 UChar i2, UChar b1, UShort dl1, UChar dh1)
2517{
florian55085f82012-11-21 00:36:55 +00002518 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002519 IRTemp op1addr = newTemp(Ity_I64);
2520 IRTemp d1 = newTemp(Ity_I64);
2521
2522 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2523 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2524 mkU64(0)));
2525
2526 mnm = irgen(i2, op1addr);
2527
sewardj7ee97522011-05-09 21:45:04 +00002528 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002529 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2530}
2531
2532static void
florian55085f82012-11-21 00:36:55 +00002533s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002534 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2535{
florian55085f82012-11-21 00:36:55 +00002536 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002537 IRTemp op1addr = newTemp(Ity_I64);
2538 IRTemp op2addr = newTemp(Ity_I64);
2539
2540 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2541 mkU64(0)));
2542 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2543 mkU64(0)));
2544
2545 mnm = irgen(l, op1addr, op2addr);
2546
sewardj7ee97522011-05-09 21:45:04 +00002547 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002548 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2549}
2550
2551static void
florian55085f82012-11-21 00:36:55 +00002552s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002553 UChar b1, UShort d1, UShort i2)
2554{
florian55085f82012-11-21 00:36:55 +00002555 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002556 IRTemp op1addr = newTemp(Ity_I64);
2557
2558 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2559 mkU64(0)));
2560
2561 mnm = irgen(i2, op1addr);
2562
sewardj7ee97522011-05-09 21:45:04 +00002563 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002564 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2565}
2566
2567static void
florian55085f82012-11-21 00:36:55 +00002568s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002569 UChar b1, UShort d1, UShort i2)
2570{
florian55085f82012-11-21 00:36:55 +00002571 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002572 IRTemp op1addr = newTemp(Ity_I64);
2573
2574 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2575 mkU64(0)));
2576
2577 mnm = irgen(i2, op1addr);
2578
sewardj7ee97522011-05-09 21:45:04 +00002579 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002580 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2581}
2582
2583
2584
2585/*------------------------------------------------------------*/
2586/*--- Build IR for opcodes ---*/
2587/*------------------------------------------------------------*/
2588
florian55085f82012-11-21 00:36:55 +00002589static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002590s390_irgen_AR(UChar r1, UChar r2)
2591{
2592 IRTemp op1 = newTemp(Ity_I32);
2593 IRTemp op2 = newTemp(Ity_I32);
2594 IRTemp result = newTemp(Ity_I32);
2595
2596 assign(op1, get_gpr_w1(r1));
2597 assign(op2, get_gpr_w1(r2));
2598 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2599 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2600 put_gpr_w1(r1, mkexpr(result));
2601
2602 return "ar";
2603}
2604
florian55085f82012-11-21 00:36:55 +00002605static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002606s390_irgen_AGR(UChar r1, UChar r2)
2607{
2608 IRTemp op1 = newTemp(Ity_I64);
2609 IRTemp op2 = newTemp(Ity_I64);
2610 IRTemp result = newTemp(Ity_I64);
2611
2612 assign(op1, get_gpr_dw0(r1));
2613 assign(op2, get_gpr_dw0(r2));
2614 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2615 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2616 put_gpr_dw0(r1, mkexpr(result));
2617
2618 return "agr";
2619}
2620
florian55085f82012-11-21 00:36:55 +00002621static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002622s390_irgen_AGFR(UChar r1, UChar r2)
2623{
2624 IRTemp op1 = newTemp(Ity_I64);
2625 IRTemp op2 = newTemp(Ity_I64);
2626 IRTemp result = newTemp(Ity_I64);
2627
2628 assign(op1, get_gpr_dw0(r1));
2629 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2630 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2631 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2632 put_gpr_dw0(r1, mkexpr(result));
2633
2634 return "agfr";
2635}
2636
florian55085f82012-11-21 00:36:55 +00002637static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002638s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2639{
2640 IRTemp op2 = newTemp(Ity_I32);
2641 IRTemp op3 = newTemp(Ity_I32);
2642 IRTemp result = newTemp(Ity_I32);
2643
2644 assign(op2, get_gpr_w1(r2));
2645 assign(op3, get_gpr_w1(r3));
2646 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2647 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2648 put_gpr_w1(r1, mkexpr(result));
2649
2650 return "ark";
2651}
2652
florian55085f82012-11-21 00:36:55 +00002653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002654s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2655{
2656 IRTemp op2 = newTemp(Ity_I64);
2657 IRTemp op3 = newTemp(Ity_I64);
2658 IRTemp result = newTemp(Ity_I64);
2659
2660 assign(op2, get_gpr_dw0(r2));
2661 assign(op3, get_gpr_dw0(r3));
2662 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2663 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2664 put_gpr_dw0(r1, mkexpr(result));
2665
2666 return "agrk";
2667}
2668
florian55085f82012-11-21 00:36:55 +00002669static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002670s390_irgen_A(UChar r1, IRTemp op2addr)
2671{
2672 IRTemp op1 = newTemp(Ity_I32);
2673 IRTemp op2 = newTemp(Ity_I32);
2674 IRTemp result = newTemp(Ity_I32);
2675
2676 assign(op1, get_gpr_w1(r1));
2677 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2678 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2679 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2680 put_gpr_w1(r1, mkexpr(result));
2681
2682 return "a";
2683}
2684
florian55085f82012-11-21 00:36:55 +00002685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002686s390_irgen_AY(UChar r1, IRTemp op2addr)
2687{
2688 IRTemp op1 = newTemp(Ity_I32);
2689 IRTemp op2 = newTemp(Ity_I32);
2690 IRTemp result = newTemp(Ity_I32);
2691
2692 assign(op1, get_gpr_w1(r1));
2693 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2694 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2695 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2696 put_gpr_w1(r1, mkexpr(result));
2697
2698 return "ay";
2699}
2700
florian55085f82012-11-21 00:36:55 +00002701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002702s390_irgen_AG(UChar r1, IRTemp op2addr)
2703{
2704 IRTemp op1 = newTemp(Ity_I64);
2705 IRTemp op2 = newTemp(Ity_I64);
2706 IRTemp result = newTemp(Ity_I64);
2707
2708 assign(op1, get_gpr_dw0(r1));
2709 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2710 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2711 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2712 put_gpr_dw0(r1, mkexpr(result));
2713
2714 return "ag";
2715}
2716
florian55085f82012-11-21 00:36:55 +00002717static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002718s390_irgen_AGF(UChar r1, IRTemp op2addr)
2719{
2720 IRTemp op1 = newTemp(Ity_I64);
2721 IRTemp op2 = newTemp(Ity_I64);
2722 IRTemp result = newTemp(Ity_I64);
2723
2724 assign(op1, get_gpr_dw0(r1));
2725 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2726 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2727 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2728 put_gpr_dw0(r1, mkexpr(result));
2729
2730 return "agf";
2731}
2732
florian55085f82012-11-21 00:36:55 +00002733static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002734s390_irgen_AFI(UChar r1, UInt i2)
2735{
2736 IRTemp op1 = newTemp(Ity_I32);
2737 Int op2;
2738 IRTemp result = newTemp(Ity_I32);
2739
2740 assign(op1, get_gpr_w1(r1));
2741 op2 = (Int)i2;
2742 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2743 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2744 mkU32((UInt)op2)));
2745 put_gpr_w1(r1, mkexpr(result));
2746
2747 return "afi";
2748}
2749
florian55085f82012-11-21 00:36:55 +00002750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002751s390_irgen_AGFI(UChar r1, UInt i2)
2752{
2753 IRTemp op1 = newTemp(Ity_I64);
2754 Long op2;
2755 IRTemp result = newTemp(Ity_I64);
2756
2757 assign(op1, get_gpr_dw0(r1));
2758 op2 = (Long)(Int)i2;
2759 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2760 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2761 mkU64((ULong)op2)));
2762 put_gpr_dw0(r1, mkexpr(result));
2763
2764 return "agfi";
2765}
2766
florian55085f82012-11-21 00:36:55 +00002767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002768s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2769{
2770 Int op2;
2771 IRTemp op3 = newTemp(Ity_I32);
2772 IRTemp result = newTemp(Ity_I32);
2773
2774 op2 = (Int)(Short)i2;
2775 assign(op3, get_gpr_w1(r3));
2776 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2777 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2778 op2)), op3);
2779 put_gpr_w1(r1, mkexpr(result));
2780
2781 return "ahik";
2782}
2783
florian55085f82012-11-21 00:36:55 +00002784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002785s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2786{
2787 Long op2;
2788 IRTemp op3 = newTemp(Ity_I64);
2789 IRTemp result = newTemp(Ity_I64);
2790
2791 op2 = (Long)(Short)i2;
2792 assign(op3, get_gpr_dw0(r3));
2793 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2794 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2795 op2)), op3);
2796 put_gpr_dw0(r1, mkexpr(result));
2797
2798 return "aghik";
2799}
2800
florian55085f82012-11-21 00:36:55 +00002801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002802s390_irgen_ASI(UChar i2, IRTemp op1addr)
2803{
2804 IRTemp op1 = newTemp(Ity_I32);
2805 Int op2;
2806 IRTemp result = newTemp(Ity_I32);
2807
2808 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2809 op2 = (Int)(Char)i2;
2810 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2811 store(mkexpr(op1addr), mkexpr(result));
2812 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2813 mkU32((UInt)op2)));
2814
2815 return "asi";
2816}
2817
florian55085f82012-11-21 00:36:55 +00002818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002819s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2820{
2821 IRTemp op1 = newTemp(Ity_I64);
2822 Long op2;
2823 IRTemp result = newTemp(Ity_I64);
2824
2825 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2826 op2 = (Long)(Char)i2;
2827 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2828 store(mkexpr(op1addr), mkexpr(result));
2829 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2830 mkU64((ULong)op2)));
2831
2832 return "agsi";
2833}
2834
florian55085f82012-11-21 00:36:55 +00002835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002836s390_irgen_AH(UChar r1, IRTemp op2addr)
2837{
2838 IRTemp op1 = newTemp(Ity_I32);
2839 IRTemp op2 = newTemp(Ity_I32);
2840 IRTemp result = newTemp(Ity_I32);
2841
2842 assign(op1, get_gpr_w1(r1));
2843 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2844 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2845 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2846 put_gpr_w1(r1, mkexpr(result));
2847
2848 return "ah";
2849}
2850
florian55085f82012-11-21 00:36:55 +00002851static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002852s390_irgen_AHY(UChar r1, IRTemp op2addr)
2853{
2854 IRTemp op1 = newTemp(Ity_I32);
2855 IRTemp op2 = newTemp(Ity_I32);
2856 IRTemp result = newTemp(Ity_I32);
2857
2858 assign(op1, get_gpr_w1(r1));
2859 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2860 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2861 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2862 put_gpr_w1(r1, mkexpr(result));
2863
2864 return "ahy";
2865}
2866
florian55085f82012-11-21 00:36:55 +00002867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002868s390_irgen_AHI(UChar r1, UShort i2)
2869{
2870 IRTemp op1 = newTemp(Ity_I32);
2871 Int op2;
2872 IRTemp result = newTemp(Ity_I32);
2873
2874 assign(op1, get_gpr_w1(r1));
2875 op2 = (Int)(Short)i2;
2876 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2877 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2878 mkU32((UInt)op2)));
2879 put_gpr_w1(r1, mkexpr(result));
2880
2881 return "ahi";
2882}
2883
florian55085f82012-11-21 00:36:55 +00002884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002885s390_irgen_AGHI(UChar r1, UShort i2)
2886{
2887 IRTemp op1 = newTemp(Ity_I64);
2888 Long op2;
2889 IRTemp result = newTemp(Ity_I64);
2890
2891 assign(op1, get_gpr_dw0(r1));
2892 op2 = (Long)(Short)i2;
2893 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2894 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2895 mkU64((ULong)op2)));
2896 put_gpr_dw0(r1, mkexpr(result));
2897
2898 return "aghi";
2899}
2900
florian55085f82012-11-21 00:36:55 +00002901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002902s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2903{
2904 IRTemp op2 = newTemp(Ity_I32);
2905 IRTemp op3 = newTemp(Ity_I32);
2906 IRTemp result = newTemp(Ity_I32);
2907
2908 assign(op2, get_gpr_w0(r2));
2909 assign(op3, get_gpr_w0(r3));
2910 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2911 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2912 put_gpr_w0(r1, mkexpr(result));
2913
2914 return "ahhhr";
2915}
2916
florian55085f82012-11-21 00:36:55 +00002917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002918s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2919{
2920 IRTemp op2 = newTemp(Ity_I32);
2921 IRTemp op3 = newTemp(Ity_I32);
2922 IRTemp result = newTemp(Ity_I32);
2923
2924 assign(op2, get_gpr_w0(r2));
2925 assign(op3, get_gpr_w1(r3));
2926 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2927 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2928 put_gpr_w0(r1, mkexpr(result));
2929
2930 return "ahhlr";
2931}
2932
florian55085f82012-11-21 00:36:55 +00002933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002934s390_irgen_AIH(UChar r1, UInt i2)
2935{
2936 IRTemp op1 = newTemp(Ity_I32);
2937 Int op2;
2938 IRTemp result = newTemp(Ity_I32);
2939
2940 assign(op1, get_gpr_w0(r1));
2941 op2 = (Int)i2;
2942 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2943 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2944 mkU32((UInt)op2)));
2945 put_gpr_w0(r1, mkexpr(result));
2946
2947 return "aih";
2948}
2949
florian55085f82012-11-21 00:36:55 +00002950static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002951s390_irgen_ALR(UChar r1, UChar r2)
2952{
2953 IRTemp op1 = newTemp(Ity_I32);
2954 IRTemp op2 = newTemp(Ity_I32);
2955 IRTemp result = newTemp(Ity_I32);
2956
2957 assign(op1, get_gpr_w1(r1));
2958 assign(op2, get_gpr_w1(r2));
2959 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2960 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2961 put_gpr_w1(r1, mkexpr(result));
2962
2963 return "alr";
2964}
2965
florian55085f82012-11-21 00:36:55 +00002966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002967s390_irgen_ALGR(UChar r1, UChar r2)
2968{
2969 IRTemp op1 = newTemp(Ity_I64);
2970 IRTemp op2 = newTemp(Ity_I64);
2971 IRTemp result = newTemp(Ity_I64);
2972
2973 assign(op1, get_gpr_dw0(r1));
2974 assign(op2, get_gpr_dw0(r2));
2975 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2976 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2977 put_gpr_dw0(r1, mkexpr(result));
2978
2979 return "algr";
2980}
2981
florian55085f82012-11-21 00:36:55 +00002982static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002983s390_irgen_ALGFR(UChar r1, UChar r2)
2984{
2985 IRTemp op1 = newTemp(Ity_I64);
2986 IRTemp op2 = newTemp(Ity_I64);
2987 IRTemp result = newTemp(Ity_I64);
2988
2989 assign(op1, get_gpr_dw0(r1));
2990 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2991 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2992 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2993 put_gpr_dw0(r1, mkexpr(result));
2994
2995 return "algfr";
2996}
2997
florian55085f82012-11-21 00:36:55 +00002998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002999s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
3000{
3001 IRTemp op2 = newTemp(Ity_I32);
3002 IRTemp op3 = newTemp(Ity_I32);
3003 IRTemp result = newTemp(Ity_I32);
3004
3005 assign(op2, get_gpr_w1(r2));
3006 assign(op3, get_gpr_w1(r3));
3007 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3008 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3009 put_gpr_w1(r1, mkexpr(result));
3010
3011 return "alrk";
3012}
3013
florian55085f82012-11-21 00:36:55 +00003014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003015s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
3016{
3017 IRTemp op2 = newTemp(Ity_I64);
3018 IRTemp op3 = newTemp(Ity_I64);
3019 IRTemp result = newTemp(Ity_I64);
3020
3021 assign(op2, get_gpr_dw0(r2));
3022 assign(op3, get_gpr_dw0(r3));
3023 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
3024 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3025 put_gpr_dw0(r1, mkexpr(result));
3026
3027 return "algrk";
3028}
3029
florian55085f82012-11-21 00:36:55 +00003030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003031s390_irgen_AL(UChar r1, IRTemp op2addr)
3032{
3033 IRTemp op1 = newTemp(Ity_I32);
3034 IRTemp op2 = newTemp(Ity_I32);
3035 IRTemp result = newTemp(Ity_I32);
3036
3037 assign(op1, get_gpr_w1(r1));
3038 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3039 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3040 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3041 put_gpr_w1(r1, mkexpr(result));
3042
3043 return "al";
3044}
3045
florian55085f82012-11-21 00:36:55 +00003046static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003047s390_irgen_ALY(UChar r1, IRTemp op2addr)
3048{
3049 IRTemp op1 = newTemp(Ity_I32);
3050 IRTemp op2 = newTemp(Ity_I32);
3051 IRTemp result = newTemp(Ity_I32);
3052
3053 assign(op1, get_gpr_w1(r1));
3054 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3055 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3056 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3057 put_gpr_w1(r1, mkexpr(result));
3058
3059 return "aly";
3060}
3061
florian55085f82012-11-21 00:36:55 +00003062static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003063s390_irgen_ALG(UChar r1, IRTemp op2addr)
3064{
3065 IRTemp op1 = newTemp(Ity_I64);
3066 IRTemp op2 = newTemp(Ity_I64);
3067 IRTemp result = newTemp(Ity_I64);
3068
3069 assign(op1, get_gpr_dw0(r1));
3070 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3071 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3072 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3073 put_gpr_dw0(r1, mkexpr(result));
3074
3075 return "alg";
3076}
3077
florian55085f82012-11-21 00:36:55 +00003078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003079s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3080{
3081 IRTemp op1 = newTemp(Ity_I64);
3082 IRTemp op2 = newTemp(Ity_I64);
3083 IRTemp result = newTemp(Ity_I64);
3084
3085 assign(op1, get_gpr_dw0(r1));
3086 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3087 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3088 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3089 put_gpr_dw0(r1, mkexpr(result));
3090
3091 return "algf";
3092}
3093
florian55085f82012-11-21 00:36:55 +00003094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003095s390_irgen_ALFI(UChar r1, UInt i2)
3096{
3097 IRTemp op1 = newTemp(Ity_I32);
3098 UInt op2;
3099 IRTemp result = newTemp(Ity_I32);
3100
3101 assign(op1, get_gpr_w1(r1));
3102 op2 = i2;
3103 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3104 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3105 mkU32(op2)));
3106 put_gpr_w1(r1, mkexpr(result));
3107
3108 return "alfi";
3109}
3110
florian55085f82012-11-21 00:36:55 +00003111static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003112s390_irgen_ALGFI(UChar r1, UInt i2)
3113{
3114 IRTemp op1 = newTemp(Ity_I64);
3115 ULong op2;
3116 IRTemp result = newTemp(Ity_I64);
3117
3118 assign(op1, get_gpr_dw0(r1));
3119 op2 = (ULong)i2;
3120 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3121 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3122 mkU64(op2)));
3123 put_gpr_dw0(r1, mkexpr(result));
3124
3125 return "algfi";
3126}
3127
florian55085f82012-11-21 00:36:55 +00003128static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003129s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3130{
3131 IRTemp op2 = newTemp(Ity_I32);
3132 IRTemp op3 = newTemp(Ity_I32);
3133 IRTemp result = newTemp(Ity_I32);
3134
3135 assign(op2, get_gpr_w0(r2));
3136 assign(op3, get_gpr_w0(r3));
3137 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3138 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3139 put_gpr_w0(r1, mkexpr(result));
3140
3141 return "alhhhr";
3142}
3143
florian55085f82012-11-21 00:36:55 +00003144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003145s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3146{
3147 IRTemp op2 = newTemp(Ity_I32);
3148 IRTemp op3 = newTemp(Ity_I32);
3149 IRTemp result = newTemp(Ity_I32);
3150
3151 assign(op2, get_gpr_w0(r2));
3152 assign(op3, get_gpr_w1(r3));
3153 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3154 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3155 put_gpr_w0(r1, mkexpr(result));
3156
3157 return "alhhlr";
3158}
3159
florian55085f82012-11-21 00:36:55 +00003160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003161s390_irgen_ALCR(UChar r1, UChar r2)
3162{
3163 IRTemp op1 = newTemp(Ity_I32);
3164 IRTemp op2 = newTemp(Ity_I32);
3165 IRTemp result = newTemp(Ity_I32);
3166 IRTemp carry_in = newTemp(Ity_I32);
3167
3168 assign(op1, get_gpr_w1(r1));
3169 assign(op2, get_gpr_w1(r2));
3170 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3171 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3172 mkexpr(carry_in)));
3173 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3174 put_gpr_w1(r1, mkexpr(result));
3175
3176 return "alcr";
3177}
3178
florian55085f82012-11-21 00:36:55 +00003179static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003180s390_irgen_ALCGR(UChar r1, UChar r2)
3181{
3182 IRTemp op1 = newTemp(Ity_I64);
3183 IRTemp op2 = newTemp(Ity_I64);
3184 IRTemp result = newTemp(Ity_I64);
3185 IRTemp carry_in = newTemp(Ity_I64);
3186
3187 assign(op1, get_gpr_dw0(r1));
3188 assign(op2, get_gpr_dw0(r2));
3189 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3190 mkU8(1))));
3191 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3192 mkexpr(carry_in)));
3193 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3194 put_gpr_dw0(r1, mkexpr(result));
3195
3196 return "alcgr";
3197}
3198
florian55085f82012-11-21 00:36:55 +00003199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003200s390_irgen_ALC(UChar r1, IRTemp op2addr)
3201{
3202 IRTemp op1 = newTemp(Ity_I32);
3203 IRTemp op2 = newTemp(Ity_I32);
3204 IRTemp result = newTemp(Ity_I32);
3205 IRTemp carry_in = newTemp(Ity_I32);
3206
3207 assign(op1, get_gpr_w1(r1));
3208 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3209 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3210 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3211 mkexpr(carry_in)));
3212 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3213 put_gpr_w1(r1, mkexpr(result));
3214
3215 return "alc";
3216}
3217
florian55085f82012-11-21 00:36:55 +00003218static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003219s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3220{
3221 IRTemp op1 = newTemp(Ity_I64);
3222 IRTemp op2 = newTemp(Ity_I64);
3223 IRTemp result = newTemp(Ity_I64);
3224 IRTemp carry_in = newTemp(Ity_I64);
3225
3226 assign(op1, get_gpr_dw0(r1));
3227 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3228 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3229 mkU8(1))));
3230 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3231 mkexpr(carry_in)));
3232 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3233 put_gpr_dw0(r1, mkexpr(result));
3234
3235 return "alcg";
3236}
3237
florian55085f82012-11-21 00:36:55 +00003238static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003239s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3240{
3241 IRTemp op1 = newTemp(Ity_I32);
3242 UInt op2;
3243 IRTemp result = newTemp(Ity_I32);
3244
3245 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3246 op2 = (UInt)(Int)(Char)i2;
3247 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3248 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3249 mkU32(op2)));
3250 store(mkexpr(op1addr), mkexpr(result));
3251
3252 return "alsi";
3253}
3254
florian55085f82012-11-21 00:36:55 +00003255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003256s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3257{
3258 IRTemp op1 = newTemp(Ity_I64);
3259 ULong op2;
3260 IRTemp result = newTemp(Ity_I64);
3261
3262 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3263 op2 = (ULong)(Long)(Char)i2;
3264 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3265 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3266 mkU64(op2)));
3267 store(mkexpr(op1addr), mkexpr(result));
3268
3269 return "algsi";
3270}
3271
florian55085f82012-11-21 00:36:55 +00003272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003273s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3274{
3275 UInt op2;
3276 IRTemp op3 = newTemp(Ity_I32);
3277 IRTemp result = newTemp(Ity_I32);
3278
3279 op2 = (UInt)(Int)(Short)i2;
3280 assign(op3, get_gpr_w1(r3));
3281 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3282 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3283 op3);
3284 put_gpr_w1(r1, mkexpr(result));
3285
3286 return "alhsik";
3287}
3288
florian55085f82012-11-21 00:36:55 +00003289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003290s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3291{
3292 ULong op2;
3293 IRTemp op3 = newTemp(Ity_I64);
3294 IRTemp result = newTemp(Ity_I64);
3295
3296 op2 = (ULong)(Long)(Short)i2;
3297 assign(op3, get_gpr_dw0(r3));
3298 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3299 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3300 op3);
3301 put_gpr_dw0(r1, mkexpr(result));
3302
3303 return "alghsik";
3304}
3305
florian55085f82012-11-21 00:36:55 +00003306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003307s390_irgen_ALSIH(UChar r1, UInt i2)
3308{
3309 IRTemp op1 = newTemp(Ity_I32);
3310 UInt op2;
3311 IRTemp result = newTemp(Ity_I32);
3312
3313 assign(op1, get_gpr_w0(r1));
3314 op2 = i2;
3315 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3316 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3317 mkU32(op2)));
3318 put_gpr_w0(r1, mkexpr(result));
3319
3320 return "alsih";
3321}
3322
florian55085f82012-11-21 00:36:55 +00003323static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003324s390_irgen_ALSIHN(UChar r1, UInt i2)
3325{
3326 IRTemp op1 = newTemp(Ity_I32);
3327 UInt op2;
3328 IRTemp result = newTemp(Ity_I32);
3329
3330 assign(op1, get_gpr_w0(r1));
3331 op2 = i2;
3332 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3333 put_gpr_w0(r1, mkexpr(result));
3334
3335 return "alsihn";
3336}
3337
florian55085f82012-11-21 00:36:55 +00003338static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003339s390_irgen_NR(UChar r1, UChar r2)
3340{
3341 IRTemp op1 = newTemp(Ity_I32);
3342 IRTemp op2 = newTemp(Ity_I32);
3343 IRTemp result = newTemp(Ity_I32);
3344
3345 assign(op1, get_gpr_w1(r1));
3346 assign(op2, get_gpr_w1(r2));
3347 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3348 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3349 put_gpr_w1(r1, mkexpr(result));
3350
3351 return "nr";
3352}
3353
florian55085f82012-11-21 00:36:55 +00003354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003355s390_irgen_NGR(UChar r1, UChar r2)
3356{
3357 IRTemp op1 = newTemp(Ity_I64);
3358 IRTemp op2 = newTemp(Ity_I64);
3359 IRTemp result = newTemp(Ity_I64);
3360
3361 assign(op1, get_gpr_dw0(r1));
3362 assign(op2, get_gpr_dw0(r2));
3363 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3364 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3365 put_gpr_dw0(r1, mkexpr(result));
3366
3367 return "ngr";
3368}
3369
florian55085f82012-11-21 00:36:55 +00003370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003371s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3372{
3373 IRTemp op2 = newTemp(Ity_I32);
3374 IRTemp op3 = newTemp(Ity_I32);
3375 IRTemp result = newTemp(Ity_I32);
3376
3377 assign(op2, get_gpr_w1(r2));
3378 assign(op3, get_gpr_w1(r3));
3379 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3380 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3381 put_gpr_w1(r1, mkexpr(result));
3382
3383 return "nrk";
3384}
3385
florian55085f82012-11-21 00:36:55 +00003386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003387s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3388{
3389 IRTemp op2 = newTemp(Ity_I64);
3390 IRTemp op3 = newTemp(Ity_I64);
3391 IRTemp result = newTemp(Ity_I64);
3392
3393 assign(op2, get_gpr_dw0(r2));
3394 assign(op3, get_gpr_dw0(r3));
3395 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3396 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3397 put_gpr_dw0(r1, mkexpr(result));
3398
3399 return "ngrk";
3400}
3401
florian55085f82012-11-21 00:36:55 +00003402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003403s390_irgen_N(UChar r1, IRTemp op2addr)
3404{
3405 IRTemp op1 = newTemp(Ity_I32);
3406 IRTemp op2 = newTemp(Ity_I32);
3407 IRTemp result = newTemp(Ity_I32);
3408
3409 assign(op1, get_gpr_w1(r1));
3410 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3411 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3412 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3413 put_gpr_w1(r1, mkexpr(result));
3414
3415 return "n";
3416}
3417
florian55085f82012-11-21 00:36:55 +00003418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003419s390_irgen_NY(UChar r1, IRTemp op2addr)
3420{
3421 IRTemp op1 = newTemp(Ity_I32);
3422 IRTemp op2 = newTemp(Ity_I32);
3423 IRTemp result = newTemp(Ity_I32);
3424
3425 assign(op1, get_gpr_w1(r1));
3426 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3427 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3428 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3429 put_gpr_w1(r1, mkexpr(result));
3430
3431 return "ny";
3432}
3433
florian55085f82012-11-21 00:36:55 +00003434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003435s390_irgen_NG(UChar r1, IRTemp op2addr)
3436{
3437 IRTemp op1 = newTemp(Ity_I64);
3438 IRTemp op2 = newTemp(Ity_I64);
3439 IRTemp result = newTemp(Ity_I64);
3440
3441 assign(op1, get_gpr_dw0(r1));
3442 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3443 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3444 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3445 put_gpr_dw0(r1, mkexpr(result));
3446
3447 return "ng";
3448}
3449
florian55085f82012-11-21 00:36:55 +00003450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003451s390_irgen_NI(UChar i2, IRTemp op1addr)
3452{
3453 IRTemp op1 = newTemp(Ity_I8);
3454 UChar op2;
3455 IRTemp result = newTemp(Ity_I8);
3456
3457 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3458 op2 = i2;
3459 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3460 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3461 store(mkexpr(op1addr), mkexpr(result));
3462
3463 return "ni";
3464}
3465
florian55085f82012-11-21 00:36:55 +00003466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003467s390_irgen_NIY(UChar i2, IRTemp op1addr)
3468{
3469 IRTemp op1 = newTemp(Ity_I8);
3470 UChar op2;
3471 IRTemp result = newTemp(Ity_I8);
3472
3473 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3474 op2 = i2;
3475 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3476 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3477 store(mkexpr(op1addr), mkexpr(result));
3478
3479 return "niy";
3480}
3481
florian55085f82012-11-21 00:36:55 +00003482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003483s390_irgen_NIHF(UChar r1, UInt i2)
3484{
3485 IRTemp op1 = newTemp(Ity_I32);
3486 UInt op2;
3487 IRTemp result = newTemp(Ity_I32);
3488
3489 assign(op1, get_gpr_w0(r1));
3490 op2 = i2;
3491 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3492 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3493 put_gpr_w0(r1, mkexpr(result));
3494
3495 return "nihf";
3496}
3497
florian55085f82012-11-21 00:36:55 +00003498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003499s390_irgen_NIHH(UChar r1, UShort i2)
3500{
3501 IRTemp op1 = newTemp(Ity_I16);
3502 UShort op2;
3503 IRTemp result = newTemp(Ity_I16);
3504
3505 assign(op1, get_gpr_hw0(r1));
3506 op2 = i2;
3507 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3508 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3509 put_gpr_hw0(r1, mkexpr(result));
3510
3511 return "nihh";
3512}
3513
florian55085f82012-11-21 00:36:55 +00003514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003515s390_irgen_NIHL(UChar r1, UShort i2)
3516{
3517 IRTemp op1 = newTemp(Ity_I16);
3518 UShort op2;
3519 IRTemp result = newTemp(Ity_I16);
3520
3521 assign(op1, get_gpr_hw1(r1));
3522 op2 = i2;
3523 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3524 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3525 put_gpr_hw1(r1, mkexpr(result));
3526
3527 return "nihl";
3528}
3529
florian55085f82012-11-21 00:36:55 +00003530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003531s390_irgen_NILF(UChar r1, UInt i2)
3532{
3533 IRTemp op1 = newTemp(Ity_I32);
3534 UInt op2;
3535 IRTemp result = newTemp(Ity_I32);
3536
3537 assign(op1, get_gpr_w1(r1));
3538 op2 = i2;
3539 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3540 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3541 put_gpr_w1(r1, mkexpr(result));
3542
3543 return "nilf";
3544}
3545
florian55085f82012-11-21 00:36:55 +00003546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003547s390_irgen_NILH(UChar r1, UShort i2)
3548{
3549 IRTemp op1 = newTemp(Ity_I16);
3550 UShort op2;
3551 IRTemp result = newTemp(Ity_I16);
3552
3553 assign(op1, get_gpr_hw2(r1));
3554 op2 = i2;
3555 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3556 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3557 put_gpr_hw2(r1, mkexpr(result));
3558
3559 return "nilh";
3560}
3561
florian55085f82012-11-21 00:36:55 +00003562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003563s390_irgen_NILL(UChar r1, UShort i2)
3564{
3565 IRTemp op1 = newTemp(Ity_I16);
3566 UShort op2;
3567 IRTemp result = newTemp(Ity_I16);
3568
3569 assign(op1, get_gpr_hw3(r1));
3570 op2 = i2;
3571 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3572 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3573 put_gpr_hw3(r1, mkexpr(result));
3574
3575 return "nill";
3576}
3577
florian55085f82012-11-21 00:36:55 +00003578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003579s390_irgen_BASR(UChar r1, UChar r2)
3580{
3581 IRTemp target = newTemp(Ity_I64);
3582
3583 if (r2 == 0) {
3584 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3585 } else {
3586 if (r1 != r2) {
3587 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3588 call_function(get_gpr_dw0(r2));
3589 } else {
3590 assign(target, get_gpr_dw0(r2));
3591 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3592 call_function(mkexpr(target));
3593 }
3594 }
3595
3596 return "basr";
3597}
3598
florian55085f82012-11-21 00:36:55 +00003599static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003600s390_irgen_BAS(UChar r1, IRTemp op2addr)
3601{
3602 IRTemp target = newTemp(Ity_I64);
3603
3604 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3605 assign(target, mkexpr(op2addr));
3606 call_function(mkexpr(target));
3607
3608 return "bas";
3609}
3610
florian55085f82012-11-21 00:36:55 +00003611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003612s390_irgen_BCR(UChar r1, UChar r2)
3613{
3614 IRTemp cond = newTemp(Ity_I32);
3615
sewardja52e37e2011-04-28 18:48:06 +00003616 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3617 stmt(IRStmt_MBE(Imbe_Fence));
3618 }
3619
sewardj2019a972011-03-07 16:04:07 +00003620 if ((r2 == 0) || (r1 == 0)) {
3621 } else {
3622 if (r1 == 15) {
3623 return_from_function(get_gpr_dw0(r2));
3624 } else {
3625 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003626 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3627 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003628 }
3629 }
sewardj7ee97522011-05-09 21:45:04 +00003630 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003631 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3632
3633 return "bcr";
3634}
3635
florian55085f82012-11-21 00:36:55 +00003636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003637s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3638{
3639 IRTemp cond = newTemp(Ity_I32);
3640
3641 if (r1 == 0) {
3642 } else {
3643 if (r1 == 15) {
3644 always_goto(mkexpr(op2addr));
3645 } else {
3646 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003647 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3648 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003649 }
3650 }
sewardj7ee97522011-05-09 21:45:04 +00003651 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003652 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3653
3654 return "bc";
3655}
3656
florian55085f82012-11-21 00:36:55 +00003657static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003658s390_irgen_BCTR(UChar r1, UChar r2)
3659{
3660 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3661 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003662 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3663 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003664 }
3665
3666 return "bctr";
3667}
3668
florian55085f82012-11-21 00:36:55 +00003669static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003670s390_irgen_BCTGR(UChar r1, UChar r2)
3671{
3672 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3673 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003674 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3675 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003676 }
3677
3678 return "bctgr";
3679}
3680
florian55085f82012-11-21 00:36:55 +00003681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003682s390_irgen_BCT(UChar r1, IRTemp op2addr)
3683{
3684 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003685 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3686 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003687
3688 return "bct";
3689}
3690
florian55085f82012-11-21 00:36:55 +00003691static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003692s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3693{
3694 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003695 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3696 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003697
3698 return "bctg";
3699}
3700
florian55085f82012-11-21 00:36:55 +00003701static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003702s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3703{
3704 IRTemp value = newTemp(Ity_I32);
3705
3706 assign(value, get_gpr_w1(r3 | 1));
3707 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003708 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3709 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003710
3711 return "bxh";
3712}
3713
florian55085f82012-11-21 00:36:55 +00003714static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003715s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3716{
3717 IRTemp value = newTemp(Ity_I64);
3718
3719 assign(value, get_gpr_dw0(r3 | 1));
3720 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003721 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3722 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003723
3724 return "bxhg";
3725}
3726
florian55085f82012-11-21 00:36:55 +00003727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003728s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3729{
3730 IRTemp value = newTemp(Ity_I32);
3731
3732 assign(value, get_gpr_w1(r3 | 1));
3733 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003734 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3735 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003736
3737 return "bxle";
3738}
3739
florian55085f82012-11-21 00:36:55 +00003740static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003741s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3742{
3743 IRTemp value = newTemp(Ity_I64);
3744
3745 assign(value, get_gpr_dw0(r3 | 1));
3746 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003747 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3748 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003749
3750 return "bxleg";
3751}
3752
florian55085f82012-11-21 00:36:55 +00003753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003754s390_irgen_BRAS(UChar r1, UShort i2)
3755{
3756 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003757 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003758
3759 return "bras";
3760}
3761
florian55085f82012-11-21 00:36:55 +00003762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003763s390_irgen_BRASL(UChar r1, UInt i2)
3764{
3765 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003766 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003767
3768 return "brasl";
3769}
3770
florian55085f82012-11-21 00:36:55 +00003771static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003772s390_irgen_BRC(UChar r1, UShort i2)
3773{
3774 IRTemp cond = newTemp(Ity_I32);
3775
3776 if (r1 == 0) {
3777 } else {
3778 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003779 always_goto_and_chase(
3780 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003781 } else {
3782 assign(cond, s390_call_calculate_cond(r1));
3783 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3784 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3785
3786 }
3787 }
sewardj7ee97522011-05-09 21:45:04 +00003788 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003789 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3790
3791 return "brc";
3792}
3793
florian55085f82012-11-21 00:36:55 +00003794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003795s390_irgen_BRCL(UChar r1, UInt i2)
3796{
3797 IRTemp cond = newTemp(Ity_I32);
3798
3799 if (r1 == 0) {
3800 } else {
3801 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003802 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003803 } else {
3804 assign(cond, s390_call_calculate_cond(r1));
3805 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3806 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3807 }
3808 }
sewardj7ee97522011-05-09 21:45:04 +00003809 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003810 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3811
3812 return "brcl";
3813}
3814
florian55085f82012-11-21 00:36:55 +00003815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003816s390_irgen_BRCT(UChar r1, UShort i2)
3817{
3818 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3819 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3820 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3821
3822 return "brct";
3823}
3824
florian55085f82012-11-21 00:36:55 +00003825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003826s390_irgen_BRCTG(UChar r1, UShort i2)
3827{
3828 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3829 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3830 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3831
3832 return "brctg";
3833}
3834
florian55085f82012-11-21 00:36:55 +00003835static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003836s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3837{
3838 IRTemp value = newTemp(Ity_I32);
3839
3840 assign(value, get_gpr_w1(r3 | 1));
3841 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3842 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3843 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3844
3845 return "brxh";
3846}
3847
florian55085f82012-11-21 00:36:55 +00003848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003849s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3850{
3851 IRTemp value = newTemp(Ity_I64);
3852
3853 assign(value, get_gpr_dw0(r3 | 1));
3854 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3855 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3856 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3857
3858 return "brxhg";
3859}
3860
florian55085f82012-11-21 00:36:55 +00003861static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003862s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3863{
3864 IRTemp value = newTemp(Ity_I32);
3865
3866 assign(value, get_gpr_w1(r3 | 1));
3867 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3868 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3869 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3870
3871 return "brxle";
3872}
3873
florian55085f82012-11-21 00:36:55 +00003874static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003875s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3876{
3877 IRTemp value = newTemp(Ity_I64);
3878
3879 assign(value, get_gpr_dw0(r3 | 1));
3880 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3881 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3882 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3883
3884 return "brxlg";
3885}
3886
florian55085f82012-11-21 00:36:55 +00003887static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003888s390_irgen_CR(UChar r1, UChar r2)
3889{
3890 IRTemp op1 = newTemp(Ity_I32);
3891 IRTemp op2 = newTemp(Ity_I32);
3892
3893 assign(op1, get_gpr_w1(r1));
3894 assign(op2, get_gpr_w1(r2));
3895 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3896
3897 return "cr";
3898}
3899
florian55085f82012-11-21 00:36:55 +00003900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003901s390_irgen_CGR(UChar r1, UChar r2)
3902{
3903 IRTemp op1 = newTemp(Ity_I64);
3904 IRTemp op2 = newTemp(Ity_I64);
3905
3906 assign(op1, get_gpr_dw0(r1));
3907 assign(op2, get_gpr_dw0(r2));
3908 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3909
3910 return "cgr";
3911}
3912
florian55085f82012-11-21 00:36:55 +00003913static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003914s390_irgen_CGFR(UChar r1, UChar r2)
3915{
3916 IRTemp op1 = newTemp(Ity_I64);
3917 IRTemp op2 = newTemp(Ity_I64);
3918
3919 assign(op1, get_gpr_dw0(r1));
3920 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3921 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3922
3923 return "cgfr";
3924}
3925
florian55085f82012-11-21 00:36:55 +00003926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003927s390_irgen_C(UChar r1, IRTemp op2addr)
3928{
3929 IRTemp op1 = newTemp(Ity_I32);
3930 IRTemp op2 = newTemp(Ity_I32);
3931
3932 assign(op1, get_gpr_w1(r1));
3933 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3934 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3935
3936 return "c";
3937}
3938
florian55085f82012-11-21 00:36:55 +00003939static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003940s390_irgen_CY(UChar r1, IRTemp op2addr)
3941{
3942 IRTemp op1 = newTemp(Ity_I32);
3943 IRTemp op2 = newTemp(Ity_I32);
3944
3945 assign(op1, get_gpr_w1(r1));
3946 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3947 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3948
3949 return "cy";
3950}
3951
florian55085f82012-11-21 00:36:55 +00003952static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003953s390_irgen_CG(UChar r1, IRTemp op2addr)
3954{
3955 IRTemp op1 = newTemp(Ity_I64);
3956 IRTemp op2 = newTemp(Ity_I64);
3957
3958 assign(op1, get_gpr_dw0(r1));
3959 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3960 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3961
3962 return "cg";
3963}
3964
florian55085f82012-11-21 00:36:55 +00003965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003966s390_irgen_CGF(UChar r1, IRTemp op2addr)
3967{
3968 IRTemp op1 = newTemp(Ity_I64);
3969 IRTemp op2 = newTemp(Ity_I64);
3970
3971 assign(op1, get_gpr_dw0(r1));
3972 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3973 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3974
3975 return "cgf";
3976}
3977
florian55085f82012-11-21 00:36:55 +00003978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003979s390_irgen_CFI(UChar r1, UInt i2)
3980{
3981 IRTemp op1 = newTemp(Ity_I32);
3982 Int op2;
3983
3984 assign(op1, get_gpr_w1(r1));
3985 op2 = (Int)i2;
3986 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3987 mkU32((UInt)op2)));
3988
3989 return "cfi";
3990}
3991
florian55085f82012-11-21 00:36:55 +00003992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003993s390_irgen_CGFI(UChar r1, UInt i2)
3994{
3995 IRTemp op1 = newTemp(Ity_I64);
3996 Long op2;
3997
3998 assign(op1, get_gpr_dw0(r1));
3999 op2 = (Long)(Int)i2;
4000 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4001 mkU64((ULong)op2)));
4002
4003 return "cgfi";
4004}
4005
florian55085f82012-11-21 00:36:55 +00004006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004007s390_irgen_CRL(UChar r1, UInt i2)
4008{
4009 IRTemp op1 = newTemp(Ity_I32);
4010 IRTemp op2 = newTemp(Ity_I32);
4011
4012 assign(op1, get_gpr_w1(r1));
4013 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4014 i2 << 1))));
4015 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4016
4017 return "crl";
4018}
4019
florian55085f82012-11-21 00:36:55 +00004020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004021s390_irgen_CGRL(UChar r1, UInt i2)
4022{
4023 IRTemp op1 = newTemp(Ity_I64);
4024 IRTemp op2 = newTemp(Ity_I64);
4025
4026 assign(op1, get_gpr_dw0(r1));
4027 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4028 i2 << 1))));
4029 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4030
4031 return "cgrl";
4032}
4033
florian55085f82012-11-21 00:36:55 +00004034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004035s390_irgen_CGFRL(UChar r1, UInt i2)
4036{
4037 IRTemp op1 = newTemp(Ity_I64);
4038 IRTemp op2 = newTemp(Ity_I64);
4039
4040 assign(op1, get_gpr_dw0(r1));
4041 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4042 ((ULong)(Long)(Int)i2 << 1)))));
4043 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4044
4045 return "cgfrl";
4046}
4047
florian55085f82012-11-21 00:36:55 +00004048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004049s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4050{
4051 IRTemp op1 = newTemp(Ity_I32);
4052 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004053 IRTemp cond = newTemp(Ity_I32);
4054
4055 if (m3 == 0) {
4056 } else {
4057 if (m3 == 14) {
4058 always_goto(mkexpr(op4addr));
4059 } else {
4060 assign(op1, get_gpr_w1(r1));
4061 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004062 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4063 op1, op2));
florianf321da72012-07-21 20:32:57 +00004064 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4065 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004066 }
4067 }
4068
4069 return "crb";
4070}
4071
florian55085f82012-11-21 00:36:55 +00004072static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004073s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4074{
4075 IRTemp op1 = newTemp(Ity_I64);
4076 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004077 IRTemp cond = newTemp(Ity_I32);
4078
4079 if (m3 == 0) {
4080 } else {
4081 if (m3 == 14) {
4082 always_goto(mkexpr(op4addr));
4083 } else {
4084 assign(op1, get_gpr_dw0(r1));
4085 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004086 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4087 op1, op2));
florianf321da72012-07-21 20:32:57 +00004088 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4089 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004090 }
4091 }
4092
4093 return "cgrb";
4094}
4095
florian55085f82012-11-21 00:36:55 +00004096static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004097s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4098{
4099 IRTemp op1 = newTemp(Ity_I32);
4100 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004101 IRTemp cond = newTemp(Ity_I32);
4102
4103 if (m3 == 0) {
4104 } else {
4105 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004106 always_goto_and_chase(
4107 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004108 } else {
4109 assign(op1, get_gpr_w1(r1));
4110 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004111 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4112 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004113 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4114 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4115
4116 }
4117 }
4118
4119 return "crj";
4120}
4121
florian55085f82012-11-21 00:36:55 +00004122static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004123s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4124{
4125 IRTemp op1 = newTemp(Ity_I64);
4126 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004127 IRTemp cond = newTemp(Ity_I32);
4128
4129 if (m3 == 0) {
4130 } else {
4131 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004132 always_goto_and_chase(
4133 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004134 } else {
4135 assign(op1, get_gpr_dw0(r1));
4136 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004137 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4138 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004139 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4140 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4141
4142 }
4143 }
4144
4145 return "cgrj";
4146}
4147
florian55085f82012-11-21 00:36:55 +00004148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004149s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4150{
4151 IRTemp op1 = newTemp(Ity_I32);
4152 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004153 IRTemp cond = newTemp(Ity_I32);
4154
4155 if (m3 == 0) {
4156 } else {
4157 if (m3 == 14) {
4158 always_goto(mkexpr(op4addr));
4159 } else {
4160 assign(op1, get_gpr_w1(r1));
4161 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004162 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4163 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004164 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4165 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004166 }
4167 }
4168
4169 return "cib";
4170}
4171
florian55085f82012-11-21 00:36:55 +00004172static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004173s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4174{
4175 IRTemp op1 = newTemp(Ity_I64);
4176 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004177 IRTemp cond = newTemp(Ity_I32);
4178
4179 if (m3 == 0) {
4180 } else {
4181 if (m3 == 14) {
4182 always_goto(mkexpr(op4addr));
4183 } else {
4184 assign(op1, get_gpr_dw0(r1));
4185 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004186 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4187 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004188 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4189 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004190 }
4191 }
4192
4193 return "cgib";
4194}
4195
florian55085f82012-11-21 00:36:55 +00004196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004197s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4198{
4199 IRTemp op1 = newTemp(Ity_I32);
4200 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004201 IRTemp cond = newTemp(Ity_I32);
4202
4203 if (m3 == 0) {
4204 } else {
4205 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004206 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004207 } else {
4208 assign(op1, get_gpr_w1(r1));
4209 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004210 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4211 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004212 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4213 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4214
4215 }
4216 }
4217
4218 return "cij";
4219}
4220
florian55085f82012-11-21 00:36:55 +00004221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004222s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4223{
4224 IRTemp op1 = newTemp(Ity_I64);
4225 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004226 IRTemp cond = newTemp(Ity_I32);
4227
4228 if (m3 == 0) {
4229 } else {
4230 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004231 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004232 } else {
4233 assign(op1, get_gpr_dw0(r1));
4234 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004235 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4236 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004237 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4238 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4239
4240 }
4241 }
4242
4243 return "cgij";
4244}
4245
florian55085f82012-11-21 00:36:55 +00004246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004247s390_irgen_CH(UChar r1, IRTemp op2addr)
4248{
4249 IRTemp op1 = newTemp(Ity_I32);
4250 IRTemp op2 = newTemp(Ity_I32);
4251
4252 assign(op1, get_gpr_w1(r1));
4253 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4254 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4255
4256 return "ch";
4257}
4258
florian55085f82012-11-21 00:36:55 +00004259static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004260s390_irgen_CHY(UChar r1, IRTemp op2addr)
4261{
4262 IRTemp op1 = newTemp(Ity_I32);
4263 IRTemp op2 = newTemp(Ity_I32);
4264
4265 assign(op1, get_gpr_w1(r1));
4266 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4267 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4268
4269 return "chy";
4270}
4271
florian55085f82012-11-21 00:36:55 +00004272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004273s390_irgen_CGH(UChar r1, IRTemp op2addr)
4274{
4275 IRTemp op1 = newTemp(Ity_I64);
4276 IRTemp op2 = newTemp(Ity_I64);
4277
4278 assign(op1, get_gpr_dw0(r1));
4279 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4280 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4281
4282 return "cgh";
4283}
4284
florian55085f82012-11-21 00:36:55 +00004285static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004286s390_irgen_CHI(UChar r1, UShort i2)
4287{
4288 IRTemp op1 = newTemp(Ity_I32);
4289 Int op2;
4290
4291 assign(op1, get_gpr_w1(r1));
4292 op2 = (Int)(Short)i2;
4293 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4294 mkU32((UInt)op2)));
4295
4296 return "chi";
4297}
4298
florian55085f82012-11-21 00:36:55 +00004299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004300s390_irgen_CGHI(UChar r1, UShort i2)
4301{
4302 IRTemp op1 = newTemp(Ity_I64);
4303 Long op2;
4304
4305 assign(op1, get_gpr_dw0(r1));
4306 op2 = (Long)(Short)i2;
4307 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4308 mkU64((ULong)op2)));
4309
4310 return "cghi";
4311}
4312
florian55085f82012-11-21 00:36:55 +00004313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004314s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4315{
4316 IRTemp op1 = newTemp(Ity_I16);
4317 Short op2;
4318
4319 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4320 op2 = (Short)i2;
4321 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4322 mkU16((UShort)op2)));
4323
4324 return "chhsi";
4325}
4326
florian55085f82012-11-21 00:36:55 +00004327static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004328s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4329{
4330 IRTemp op1 = newTemp(Ity_I32);
4331 Int op2;
4332
4333 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4334 op2 = (Int)(Short)i2;
4335 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4336 mkU32((UInt)op2)));
4337
4338 return "chsi";
4339}
4340
florian55085f82012-11-21 00:36:55 +00004341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004342s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4343{
4344 IRTemp op1 = newTemp(Ity_I64);
4345 Long op2;
4346
4347 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4348 op2 = (Long)(Short)i2;
4349 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4350 mkU64((ULong)op2)));
4351
4352 return "cghsi";
4353}
4354
florian55085f82012-11-21 00:36:55 +00004355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004356s390_irgen_CHRL(UChar r1, UInt i2)
4357{
4358 IRTemp op1 = newTemp(Ity_I32);
4359 IRTemp op2 = newTemp(Ity_I32);
4360
4361 assign(op1, get_gpr_w1(r1));
4362 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4363 ((ULong)(Long)(Int)i2 << 1)))));
4364 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4365
4366 return "chrl";
4367}
4368
florian55085f82012-11-21 00:36:55 +00004369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004370s390_irgen_CGHRL(UChar r1, UInt i2)
4371{
4372 IRTemp op1 = newTemp(Ity_I64);
4373 IRTemp op2 = newTemp(Ity_I64);
4374
4375 assign(op1, get_gpr_dw0(r1));
4376 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4377 ((ULong)(Long)(Int)i2 << 1)))));
4378 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4379
4380 return "cghrl";
4381}
4382
florian55085f82012-11-21 00:36:55 +00004383static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004384s390_irgen_CHHR(UChar r1, UChar r2)
4385{
4386 IRTemp op1 = newTemp(Ity_I32);
4387 IRTemp op2 = newTemp(Ity_I32);
4388
4389 assign(op1, get_gpr_w0(r1));
4390 assign(op2, get_gpr_w0(r2));
4391 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4392
4393 return "chhr";
4394}
4395
florian55085f82012-11-21 00:36:55 +00004396static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004397s390_irgen_CHLR(UChar r1, UChar r2)
4398{
4399 IRTemp op1 = newTemp(Ity_I32);
4400 IRTemp op2 = newTemp(Ity_I32);
4401
4402 assign(op1, get_gpr_w0(r1));
4403 assign(op2, get_gpr_w1(r2));
4404 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4405
4406 return "chlr";
4407}
4408
florian55085f82012-11-21 00:36:55 +00004409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004410s390_irgen_CHF(UChar r1, IRTemp op2addr)
4411{
4412 IRTemp op1 = newTemp(Ity_I32);
4413 IRTemp op2 = newTemp(Ity_I32);
4414
4415 assign(op1, get_gpr_w0(r1));
4416 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4417 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4418
4419 return "chf";
4420}
4421
florian55085f82012-11-21 00:36:55 +00004422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004423s390_irgen_CIH(UChar r1, UInt i2)
4424{
4425 IRTemp op1 = newTemp(Ity_I32);
4426 Int op2;
4427
4428 assign(op1, get_gpr_w0(r1));
4429 op2 = (Int)i2;
4430 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4431 mkU32((UInt)op2)));
4432
4433 return "cih";
4434}
4435
florian55085f82012-11-21 00:36:55 +00004436static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004437s390_irgen_CLR(UChar r1, UChar r2)
4438{
4439 IRTemp op1 = newTemp(Ity_I32);
4440 IRTemp op2 = newTemp(Ity_I32);
4441
4442 assign(op1, get_gpr_w1(r1));
4443 assign(op2, get_gpr_w1(r2));
4444 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4445
4446 return "clr";
4447}
4448
florian55085f82012-11-21 00:36:55 +00004449static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004450s390_irgen_CLGR(UChar r1, UChar r2)
4451{
4452 IRTemp op1 = newTemp(Ity_I64);
4453 IRTemp op2 = newTemp(Ity_I64);
4454
4455 assign(op1, get_gpr_dw0(r1));
4456 assign(op2, get_gpr_dw0(r2));
4457 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4458
4459 return "clgr";
4460}
4461
florian55085f82012-11-21 00:36:55 +00004462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004463s390_irgen_CLGFR(UChar r1, UChar r2)
4464{
4465 IRTemp op1 = newTemp(Ity_I64);
4466 IRTemp op2 = newTemp(Ity_I64);
4467
4468 assign(op1, get_gpr_dw0(r1));
4469 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4470 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4471
4472 return "clgfr";
4473}
4474
florian55085f82012-11-21 00:36:55 +00004475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004476s390_irgen_CL(UChar r1, IRTemp op2addr)
4477{
4478 IRTemp op1 = newTemp(Ity_I32);
4479 IRTemp op2 = newTemp(Ity_I32);
4480
4481 assign(op1, get_gpr_w1(r1));
4482 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4483 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4484
4485 return "cl";
4486}
4487
florian55085f82012-11-21 00:36:55 +00004488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004489s390_irgen_CLY(UChar r1, IRTemp op2addr)
4490{
4491 IRTemp op1 = newTemp(Ity_I32);
4492 IRTemp op2 = newTemp(Ity_I32);
4493
4494 assign(op1, get_gpr_w1(r1));
4495 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4496 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4497
4498 return "cly";
4499}
4500
florian55085f82012-11-21 00:36:55 +00004501static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004502s390_irgen_CLG(UChar r1, IRTemp op2addr)
4503{
4504 IRTemp op1 = newTemp(Ity_I64);
4505 IRTemp op2 = newTemp(Ity_I64);
4506
4507 assign(op1, get_gpr_dw0(r1));
4508 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4509 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4510
4511 return "clg";
4512}
4513
florian55085f82012-11-21 00:36:55 +00004514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004515s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4516{
4517 IRTemp op1 = newTemp(Ity_I64);
4518 IRTemp op2 = newTemp(Ity_I64);
4519
4520 assign(op1, get_gpr_dw0(r1));
4521 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4522 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4523
4524 return "clgf";
4525}
4526
florian55085f82012-11-21 00:36:55 +00004527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004528s390_irgen_CLFI(UChar r1, UInt i2)
4529{
4530 IRTemp op1 = newTemp(Ity_I32);
4531 UInt op2;
4532
4533 assign(op1, get_gpr_w1(r1));
4534 op2 = i2;
4535 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4536 mkU32(op2)));
4537
4538 return "clfi";
4539}
4540
florian55085f82012-11-21 00:36:55 +00004541static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004542s390_irgen_CLGFI(UChar r1, UInt i2)
4543{
4544 IRTemp op1 = newTemp(Ity_I64);
4545 ULong op2;
4546
4547 assign(op1, get_gpr_dw0(r1));
4548 op2 = (ULong)i2;
4549 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4550 mkU64(op2)));
4551
4552 return "clgfi";
4553}
4554
florian55085f82012-11-21 00:36:55 +00004555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004556s390_irgen_CLI(UChar i2, IRTemp op1addr)
4557{
4558 IRTemp op1 = newTemp(Ity_I8);
4559 UChar op2;
4560
4561 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4562 op2 = i2;
4563 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4564 mkU8(op2)));
4565
4566 return "cli";
4567}
4568
florian55085f82012-11-21 00:36:55 +00004569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004570s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4571{
4572 IRTemp op1 = newTemp(Ity_I8);
4573 UChar op2;
4574
4575 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4576 op2 = i2;
4577 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4578 mkU8(op2)));
4579
4580 return "cliy";
4581}
4582
florian55085f82012-11-21 00:36:55 +00004583static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004584s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4585{
4586 IRTemp op1 = newTemp(Ity_I32);
4587 UInt op2;
4588
4589 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4590 op2 = (UInt)i2;
4591 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4592 mkU32(op2)));
4593
4594 return "clfhsi";
4595}
4596
florian55085f82012-11-21 00:36:55 +00004597static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004598s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4599{
4600 IRTemp op1 = newTemp(Ity_I64);
4601 ULong op2;
4602
4603 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4604 op2 = (ULong)i2;
4605 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4606 mkU64(op2)));
4607
4608 return "clghsi";
4609}
4610
florian55085f82012-11-21 00:36:55 +00004611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004612s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4613{
4614 IRTemp op1 = newTemp(Ity_I16);
4615 UShort op2;
4616
4617 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4618 op2 = i2;
4619 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4620 mkU16(op2)));
4621
4622 return "clhhsi";
4623}
4624
florian55085f82012-11-21 00:36:55 +00004625static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004626s390_irgen_CLRL(UChar r1, UInt i2)
4627{
4628 IRTemp op1 = newTemp(Ity_I32);
4629 IRTemp op2 = newTemp(Ity_I32);
4630
4631 assign(op1, get_gpr_w1(r1));
4632 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4633 i2 << 1))));
4634 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4635
4636 return "clrl";
4637}
4638
florian55085f82012-11-21 00:36:55 +00004639static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004640s390_irgen_CLGRL(UChar r1, UInt i2)
4641{
4642 IRTemp op1 = newTemp(Ity_I64);
4643 IRTemp op2 = newTemp(Ity_I64);
4644
4645 assign(op1, get_gpr_dw0(r1));
4646 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4647 i2 << 1))));
4648 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4649
4650 return "clgrl";
4651}
4652
florian55085f82012-11-21 00:36:55 +00004653static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004654s390_irgen_CLGFRL(UChar r1, UInt i2)
4655{
4656 IRTemp op1 = newTemp(Ity_I64);
4657 IRTemp op2 = newTemp(Ity_I64);
4658
4659 assign(op1, get_gpr_dw0(r1));
4660 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4661 ((ULong)(Long)(Int)i2 << 1)))));
4662 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4663
4664 return "clgfrl";
4665}
4666
florian55085f82012-11-21 00:36:55 +00004667static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004668s390_irgen_CLHRL(UChar r1, UInt i2)
4669{
4670 IRTemp op1 = newTemp(Ity_I32);
4671 IRTemp op2 = newTemp(Ity_I32);
4672
4673 assign(op1, get_gpr_w1(r1));
4674 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4675 ((ULong)(Long)(Int)i2 << 1)))));
4676 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4677
4678 return "clhrl";
4679}
4680
florian55085f82012-11-21 00:36:55 +00004681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004682s390_irgen_CLGHRL(UChar r1, UInt i2)
4683{
4684 IRTemp op1 = newTemp(Ity_I64);
4685 IRTemp op2 = newTemp(Ity_I64);
4686
4687 assign(op1, get_gpr_dw0(r1));
4688 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4689 ((ULong)(Long)(Int)i2 << 1)))));
4690 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4691
4692 return "clghrl";
4693}
4694
florian55085f82012-11-21 00:36:55 +00004695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004696s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4697{
4698 IRTemp op1 = newTemp(Ity_I32);
4699 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004700 IRTemp cond = newTemp(Ity_I32);
4701
4702 if (m3 == 0) {
4703 } else {
4704 if (m3 == 14) {
4705 always_goto(mkexpr(op4addr));
4706 } else {
4707 assign(op1, get_gpr_w1(r1));
4708 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004709 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4710 op1, op2));
florianf321da72012-07-21 20:32:57 +00004711 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4712 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004713 }
4714 }
4715
4716 return "clrb";
4717}
4718
florian55085f82012-11-21 00:36:55 +00004719static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004720s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4721{
4722 IRTemp op1 = newTemp(Ity_I64);
4723 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004724 IRTemp cond = newTemp(Ity_I32);
4725
4726 if (m3 == 0) {
4727 } else {
4728 if (m3 == 14) {
4729 always_goto(mkexpr(op4addr));
4730 } else {
4731 assign(op1, get_gpr_dw0(r1));
4732 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004733 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4734 op1, op2));
florianf321da72012-07-21 20:32:57 +00004735 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4736 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004737 }
4738 }
4739
4740 return "clgrb";
4741}
4742
florian55085f82012-11-21 00:36:55 +00004743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004744s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4745{
4746 IRTemp op1 = newTemp(Ity_I32);
4747 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004748 IRTemp cond = newTemp(Ity_I32);
4749
4750 if (m3 == 0) {
4751 } else {
4752 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004753 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004754 } else {
4755 assign(op1, get_gpr_w1(r1));
4756 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004757 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4758 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004759 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4760 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4761
4762 }
4763 }
4764
4765 return "clrj";
4766}
4767
florian55085f82012-11-21 00:36:55 +00004768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004769s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4770{
4771 IRTemp op1 = newTemp(Ity_I64);
4772 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004773 IRTemp cond = newTemp(Ity_I32);
4774
4775 if (m3 == 0) {
4776 } else {
4777 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004778 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004779 } else {
4780 assign(op1, get_gpr_dw0(r1));
4781 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004782 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4783 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004784 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4785 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4786
4787 }
4788 }
4789
4790 return "clgrj";
4791}
4792
florian55085f82012-11-21 00:36:55 +00004793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004794s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4795{
4796 IRTemp op1 = newTemp(Ity_I32);
4797 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004798 IRTemp cond = newTemp(Ity_I32);
4799
4800 if (m3 == 0) {
4801 } else {
4802 if (m3 == 14) {
4803 always_goto(mkexpr(op4addr));
4804 } else {
4805 assign(op1, get_gpr_w1(r1));
4806 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004807 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4808 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004809 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4810 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004811 }
4812 }
4813
4814 return "clib";
4815}
4816
florian55085f82012-11-21 00:36:55 +00004817static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004818s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4819{
4820 IRTemp op1 = newTemp(Ity_I64);
4821 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004822 IRTemp cond = newTemp(Ity_I32);
4823
4824 if (m3 == 0) {
4825 } else {
4826 if (m3 == 14) {
4827 always_goto(mkexpr(op4addr));
4828 } else {
4829 assign(op1, get_gpr_dw0(r1));
4830 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004831 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4832 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004833 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4834 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004835 }
4836 }
4837
4838 return "clgib";
4839}
4840
florian55085f82012-11-21 00:36:55 +00004841static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004842s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4843{
4844 IRTemp op1 = newTemp(Ity_I32);
4845 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004846 IRTemp cond = newTemp(Ity_I32);
4847
4848 if (m3 == 0) {
4849 } else {
4850 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004851 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004852 } else {
4853 assign(op1, get_gpr_w1(r1));
4854 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004855 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4856 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004857 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4858 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4859
4860 }
4861 }
4862
4863 return "clij";
4864}
4865
florian55085f82012-11-21 00:36:55 +00004866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004867s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4868{
4869 IRTemp op1 = newTemp(Ity_I64);
4870 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004871 IRTemp cond = newTemp(Ity_I32);
4872
4873 if (m3 == 0) {
4874 } else {
4875 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004876 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004877 } else {
4878 assign(op1, get_gpr_dw0(r1));
4879 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004880 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4881 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004882 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4883 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4884
4885 }
4886 }
4887
4888 return "clgij";
4889}
4890
florian55085f82012-11-21 00:36:55 +00004891static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004892s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4893{
4894 IRTemp op1 = newTemp(Ity_I32);
4895 IRTemp op2 = newTemp(Ity_I32);
4896 IRTemp b0 = newTemp(Ity_I32);
4897 IRTemp b1 = newTemp(Ity_I32);
4898 IRTemp b2 = newTemp(Ity_I32);
4899 IRTemp b3 = newTemp(Ity_I32);
4900 IRTemp c0 = newTemp(Ity_I32);
4901 IRTemp c1 = newTemp(Ity_I32);
4902 IRTemp c2 = newTemp(Ity_I32);
4903 IRTemp c3 = newTemp(Ity_I32);
4904 UChar n;
4905
4906 n = 0;
4907 if ((r3 & 8) != 0) {
4908 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4909 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4910 n = n + 1;
4911 } else {
4912 assign(b0, mkU32(0));
4913 assign(c0, mkU32(0));
4914 }
4915 if ((r3 & 4) != 0) {
4916 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4917 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4918 mkU64(n)))));
4919 n = n + 1;
4920 } else {
4921 assign(b1, mkU32(0));
4922 assign(c1, mkU32(0));
4923 }
4924 if ((r3 & 2) != 0) {
4925 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4926 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4927 mkU64(n)))));
4928 n = n + 1;
4929 } else {
4930 assign(b2, mkU32(0));
4931 assign(c2, mkU32(0));
4932 }
4933 if ((r3 & 1) != 0) {
4934 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4935 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4936 mkU64(n)))));
4937 n = n + 1;
4938 } else {
4939 assign(b3, mkU32(0));
4940 assign(c3, mkU32(0));
4941 }
4942 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4943 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4944 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4945 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4946 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4947 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4948 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4949
4950 return "clm";
4951}
4952
florian55085f82012-11-21 00:36:55 +00004953static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004954s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4955{
4956 IRTemp op1 = newTemp(Ity_I32);
4957 IRTemp op2 = newTemp(Ity_I32);
4958 IRTemp b0 = newTemp(Ity_I32);
4959 IRTemp b1 = newTemp(Ity_I32);
4960 IRTemp b2 = newTemp(Ity_I32);
4961 IRTemp b3 = newTemp(Ity_I32);
4962 IRTemp c0 = newTemp(Ity_I32);
4963 IRTemp c1 = newTemp(Ity_I32);
4964 IRTemp c2 = newTemp(Ity_I32);
4965 IRTemp c3 = newTemp(Ity_I32);
4966 UChar n;
4967
4968 n = 0;
4969 if ((r3 & 8) != 0) {
4970 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4971 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4972 n = n + 1;
4973 } else {
4974 assign(b0, mkU32(0));
4975 assign(c0, mkU32(0));
4976 }
4977 if ((r3 & 4) != 0) {
4978 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4979 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4980 mkU64(n)))));
4981 n = n + 1;
4982 } else {
4983 assign(b1, mkU32(0));
4984 assign(c1, mkU32(0));
4985 }
4986 if ((r3 & 2) != 0) {
4987 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4988 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4989 mkU64(n)))));
4990 n = n + 1;
4991 } else {
4992 assign(b2, mkU32(0));
4993 assign(c2, mkU32(0));
4994 }
4995 if ((r3 & 1) != 0) {
4996 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4997 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4998 mkU64(n)))));
4999 n = n + 1;
5000 } else {
5001 assign(b3, mkU32(0));
5002 assign(c3, mkU32(0));
5003 }
5004 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5005 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5006 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5007 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5008 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5009 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5010 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5011
5012 return "clmy";
5013}
5014
florian55085f82012-11-21 00:36:55 +00005015static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005016s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5017{
5018 IRTemp op1 = newTemp(Ity_I32);
5019 IRTemp op2 = newTemp(Ity_I32);
5020 IRTemp b0 = newTemp(Ity_I32);
5021 IRTemp b1 = newTemp(Ity_I32);
5022 IRTemp b2 = newTemp(Ity_I32);
5023 IRTemp b3 = newTemp(Ity_I32);
5024 IRTemp c0 = newTemp(Ity_I32);
5025 IRTemp c1 = newTemp(Ity_I32);
5026 IRTemp c2 = newTemp(Ity_I32);
5027 IRTemp c3 = newTemp(Ity_I32);
5028 UChar n;
5029
5030 n = 0;
5031 if ((r3 & 8) != 0) {
5032 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5033 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5034 n = n + 1;
5035 } else {
5036 assign(b0, mkU32(0));
5037 assign(c0, mkU32(0));
5038 }
5039 if ((r3 & 4) != 0) {
5040 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5041 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5042 mkU64(n)))));
5043 n = n + 1;
5044 } else {
5045 assign(b1, mkU32(0));
5046 assign(c1, mkU32(0));
5047 }
5048 if ((r3 & 2) != 0) {
5049 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5050 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5051 mkU64(n)))));
5052 n = n + 1;
5053 } else {
5054 assign(b2, mkU32(0));
5055 assign(c2, mkU32(0));
5056 }
5057 if ((r3 & 1) != 0) {
5058 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5059 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5060 mkU64(n)))));
5061 n = n + 1;
5062 } else {
5063 assign(b3, mkU32(0));
5064 assign(c3, mkU32(0));
5065 }
5066 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5067 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5068 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5069 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5070 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5071 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5072 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5073
5074 return "clmh";
5075}
5076
florian55085f82012-11-21 00:36:55 +00005077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005078s390_irgen_CLHHR(UChar r1, UChar r2)
5079{
5080 IRTemp op1 = newTemp(Ity_I32);
5081 IRTemp op2 = newTemp(Ity_I32);
5082
5083 assign(op1, get_gpr_w0(r1));
5084 assign(op2, get_gpr_w0(r2));
5085 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5086
5087 return "clhhr";
5088}
5089
florian55085f82012-11-21 00:36:55 +00005090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005091s390_irgen_CLHLR(UChar r1, UChar r2)
5092{
5093 IRTemp op1 = newTemp(Ity_I32);
5094 IRTemp op2 = newTemp(Ity_I32);
5095
5096 assign(op1, get_gpr_w0(r1));
5097 assign(op2, get_gpr_w1(r2));
5098 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5099
5100 return "clhlr";
5101}
5102
florian55085f82012-11-21 00:36:55 +00005103static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005104s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5105{
5106 IRTemp op1 = newTemp(Ity_I32);
5107 IRTemp op2 = newTemp(Ity_I32);
5108
5109 assign(op1, get_gpr_w0(r1));
5110 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5111 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5112
5113 return "clhf";
5114}
5115
florian55085f82012-11-21 00:36:55 +00005116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005117s390_irgen_CLIH(UChar r1, UInt i2)
5118{
5119 IRTemp op1 = newTemp(Ity_I32);
5120 UInt op2;
5121
5122 assign(op1, get_gpr_w0(r1));
5123 op2 = i2;
5124 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5125 mkU32(op2)));
5126
5127 return "clih";
5128}
5129
florian55085f82012-11-21 00:36:55 +00005130static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005131s390_irgen_CPYA(UChar r1, UChar r2)
5132{
5133 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005134 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005135 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5136
5137 return "cpya";
5138}
5139
florian55085f82012-11-21 00:36:55 +00005140static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005141s390_irgen_XR(UChar r1, UChar r2)
5142{
5143 IRTemp op1 = newTemp(Ity_I32);
5144 IRTemp op2 = newTemp(Ity_I32);
5145 IRTemp result = newTemp(Ity_I32);
5146
5147 if (r1 == r2) {
5148 assign(result, mkU32(0));
5149 } else {
5150 assign(op1, get_gpr_w1(r1));
5151 assign(op2, get_gpr_w1(r2));
5152 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5153 }
5154 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5155 put_gpr_w1(r1, mkexpr(result));
5156
5157 return "xr";
5158}
5159
florian55085f82012-11-21 00:36:55 +00005160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005161s390_irgen_XGR(UChar r1, UChar r2)
5162{
5163 IRTemp op1 = newTemp(Ity_I64);
5164 IRTemp op2 = newTemp(Ity_I64);
5165 IRTemp result = newTemp(Ity_I64);
5166
5167 if (r1 == r2) {
5168 assign(result, mkU64(0));
5169 } else {
5170 assign(op1, get_gpr_dw0(r1));
5171 assign(op2, get_gpr_dw0(r2));
5172 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5173 }
5174 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5175 put_gpr_dw0(r1, mkexpr(result));
5176
5177 return "xgr";
5178}
5179
florian55085f82012-11-21 00:36:55 +00005180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005181s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5182{
5183 IRTemp op2 = newTemp(Ity_I32);
5184 IRTemp op3 = newTemp(Ity_I32);
5185 IRTemp result = newTemp(Ity_I32);
5186
5187 assign(op2, get_gpr_w1(r2));
5188 assign(op3, get_gpr_w1(r3));
5189 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5190 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5191 put_gpr_w1(r1, mkexpr(result));
5192
5193 return "xrk";
5194}
5195
florian55085f82012-11-21 00:36:55 +00005196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005197s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5198{
5199 IRTemp op2 = newTemp(Ity_I64);
5200 IRTemp op3 = newTemp(Ity_I64);
5201 IRTemp result = newTemp(Ity_I64);
5202
5203 assign(op2, get_gpr_dw0(r2));
5204 assign(op3, get_gpr_dw0(r3));
5205 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5206 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5207 put_gpr_dw0(r1, mkexpr(result));
5208
5209 return "xgrk";
5210}
5211
florian55085f82012-11-21 00:36:55 +00005212static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005213s390_irgen_X(UChar r1, IRTemp op2addr)
5214{
5215 IRTemp op1 = newTemp(Ity_I32);
5216 IRTemp op2 = newTemp(Ity_I32);
5217 IRTemp result = newTemp(Ity_I32);
5218
5219 assign(op1, get_gpr_w1(r1));
5220 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5221 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5222 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5223 put_gpr_w1(r1, mkexpr(result));
5224
5225 return "x";
5226}
5227
florian55085f82012-11-21 00:36:55 +00005228static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005229s390_irgen_XY(UChar r1, IRTemp op2addr)
5230{
5231 IRTemp op1 = newTemp(Ity_I32);
5232 IRTemp op2 = newTemp(Ity_I32);
5233 IRTemp result = newTemp(Ity_I32);
5234
5235 assign(op1, get_gpr_w1(r1));
5236 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5237 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5238 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5239 put_gpr_w1(r1, mkexpr(result));
5240
5241 return "xy";
5242}
5243
florian55085f82012-11-21 00:36:55 +00005244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005245s390_irgen_XG(UChar r1, IRTemp op2addr)
5246{
5247 IRTemp op1 = newTemp(Ity_I64);
5248 IRTemp op2 = newTemp(Ity_I64);
5249 IRTemp result = newTemp(Ity_I64);
5250
5251 assign(op1, get_gpr_dw0(r1));
5252 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5253 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5254 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5255 put_gpr_dw0(r1, mkexpr(result));
5256
5257 return "xg";
5258}
5259
florian55085f82012-11-21 00:36:55 +00005260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005261s390_irgen_XI(UChar i2, IRTemp op1addr)
5262{
5263 IRTemp op1 = newTemp(Ity_I8);
5264 UChar op2;
5265 IRTemp result = newTemp(Ity_I8);
5266
5267 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5268 op2 = i2;
5269 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5270 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5271 store(mkexpr(op1addr), mkexpr(result));
5272
5273 return "xi";
5274}
5275
florian55085f82012-11-21 00:36:55 +00005276static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005277s390_irgen_XIY(UChar i2, IRTemp op1addr)
5278{
5279 IRTemp op1 = newTemp(Ity_I8);
5280 UChar op2;
5281 IRTemp result = newTemp(Ity_I8);
5282
5283 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5284 op2 = i2;
5285 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5286 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5287 store(mkexpr(op1addr), mkexpr(result));
5288
5289 return "xiy";
5290}
5291
florian55085f82012-11-21 00:36:55 +00005292static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005293s390_irgen_XIHF(UChar r1, UInt i2)
5294{
5295 IRTemp op1 = newTemp(Ity_I32);
5296 UInt op2;
5297 IRTemp result = newTemp(Ity_I32);
5298
5299 assign(op1, get_gpr_w0(r1));
5300 op2 = i2;
5301 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5302 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5303 put_gpr_w0(r1, mkexpr(result));
5304
5305 return "xihf";
5306}
5307
florian55085f82012-11-21 00:36:55 +00005308static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005309s390_irgen_XILF(UChar r1, UInt i2)
5310{
5311 IRTemp op1 = newTemp(Ity_I32);
5312 UInt op2;
5313 IRTemp result = newTemp(Ity_I32);
5314
5315 assign(op1, get_gpr_w1(r1));
5316 op2 = i2;
5317 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5318 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5319 put_gpr_w1(r1, mkexpr(result));
5320
5321 return "xilf";
5322}
5323
florian55085f82012-11-21 00:36:55 +00005324static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005325s390_irgen_EAR(UChar r1, UChar r2)
5326{
5327 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005328 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005329 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5330
5331 return "ear";
5332}
5333
florian55085f82012-11-21 00:36:55 +00005334static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005335s390_irgen_IC(UChar r1, IRTemp op2addr)
5336{
5337 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5338
5339 return "ic";
5340}
5341
florian55085f82012-11-21 00:36:55 +00005342static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005343s390_irgen_ICY(UChar r1, IRTemp op2addr)
5344{
5345 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5346
5347 return "icy";
5348}
5349
florian55085f82012-11-21 00:36:55 +00005350static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005351s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5352{
5353 UChar n;
5354 IRTemp result = newTemp(Ity_I32);
5355 UInt mask;
5356
5357 n = 0;
5358 mask = (UInt)r3;
5359 if ((mask & 8) != 0) {
5360 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5361 n = n + 1;
5362 }
5363 if ((mask & 4) != 0) {
5364 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5365
5366 n = n + 1;
5367 }
5368 if ((mask & 2) != 0) {
5369 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5370
5371 n = n + 1;
5372 }
5373 if ((mask & 1) != 0) {
5374 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5375
5376 n = n + 1;
5377 }
5378 assign(result, get_gpr_w1(r1));
5379 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5380 mkU32(mask)));
5381
5382 return "icm";
5383}
5384
florian55085f82012-11-21 00:36:55 +00005385static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005386s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5387{
5388 UChar n;
5389 IRTemp result = newTemp(Ity_I32);
5390 UInt mask;
5391
5392 n = 0;
5393 mask = (UInt)r3;
5394 if ((mask & 8) != 0) {
5395 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5396 n = n + 1;
5397 }
5398 if ((mask & 4) != 0) {
5399 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5400
5401 n = n + 1;
5402 }
5403 if ((mask & 2) != 0) {
5404 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5405
5406 n = n + 1;
5407 }
5408 if ((mask & 1) != 0) {
5409 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5410
5411 n = n + 1;
5412 }
5413 assign(result, get_gpr_w1(r1));
5414 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5415 mkU32(mask)));
5416
5417 return "icmy";
5418}
5419
florian55085f82012-11-21 00:36:55 +00005420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005421s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5422{
5423 UChar n;
5424 IRTemp result = newTemp(Ity_I32);
5425 UInt mask;
5426
5427 n = 0;
5428 mask = (UInt)r3;
5429 if ((mask & 8) != 0) {
5430 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5431 n = n + 1;
5432 }
5433 if ((mask & 4) != 0) {
5434 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5435
5436 n = n + 1;
5437 }
5438 if ((mask & 2) != 0) {
5439 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5440
5441 n = n + 1;
5442 }
5443 if ((mask & 1) != 0) {
5444 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5445
5446 n = n + 1;
5447 }
5448 assign(result, get_gpr_w0(r1));
5449 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5450 mkU32(mask)));
5451
5452 return "icmh";
5453}
5454
florian55085f82012-11-21 00:36:55 +00005455static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005456s390_irgen_IIHF(UChar r1, UInt i2)
5457{
5458 put_gpr_w0(r1, mkU32(i2));
5459
5460 return "iihf";
5461}
5462
florian55085f82012-11-21 00:36:55 +00005463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005464s390_irgen_IIHH(UChar r1, UShort i2)
5465{
5466 put_gpr_hw0(r1, mkU16(i2));
5467
5468 return "iihh";
5469}
5470
florian55085f82012-11-21 00:36:55 +00005471static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005472s390_irgen_IIHL(UChar r1, UShort i2)
5473{
5474 put_gpr_hw1(r1, mkU16(i2));
5475
5476 return "iihl";
5477}
5478
florian55085f82012-11-21 00:36:55 +00005479static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005480s390_irgen_IILF(UChar r1, UInt i2)
5481{
5482 put_gpr_w1(r1, mkU32(i2));
5483
5484 return "iilf";
5485}
5486
florian55085f82012-11-21 00:36:55 +00005487static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005488s390_irgen_IILH(UChar r1, UShort i2)
5489{
5490 put_gpr_hw2(r1, mkU16(i2));
5491
5492 return "iilh";
5493}
5494
florian55085f82012-11-21 00:36:55 +00005495static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005496s390_irgen_IILL(UChar r1, UShort i2)
5497{
5498 put_gpr_hw3(r1, mkU16(i2));
5499
5500 return "iill";
5501}
5502
florian55085f82012-11-21 00:36:55 +00005503static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005504s390_irgen_LR(UChar r1, UChar r2)
5505{
5506 put_gpr_w1(r1, get_gpr_w1(r2));
5507
5508 return "lr";
5509}
5510
florian55085f82012-11-21 00:36:55 +00005511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005512s390_irgen_LGR(UChar r1, UChar r2)
5513{
5514 put_gpr_dw0(r1, get_gpr_dw0(r2));
5515
5516 return "lgr";
5517}
5518
florian55085f82012-11-21 00:36:55 +00005519static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005520s390_irgen_LGFR(UChar r1, UChar r2)
5521{
5522 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5523
5524 return "lgfr";
5525}
5526
florian55085f82012-11-21 00:36:55 +00005527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005528s390_irgen_L(UChar r1, IRTemp op2addr)
5529{
5530 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5531
5532 return "l";
5533}
5534
florian55085f82012-11-21 00:36:55 +00005535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005536s390_irgen_LY(UChar r1, IRTemp op2addr)
5537{
5538 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5539
5540 return "ly";
5541}
5542
florian55085f82012-11-21 00:36:55 +00005543static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005544s390_irgen_LG(UChar r1, IRTemp op2addr)
5545{
5546 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5547
5548 return "lg";
5549}
5550
florian55085f82012-11-21 00:36:55 +00005551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005552s390_irgen_LGF(UChar r1, IRTemp op2addr)
5553{
5554 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5555
5556 return "lgf";
5557}
5558
florian55085f82012-11-21 00:36:55 +00005559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005560s390_irgen_LGFI(UChar r1, UInt i2)
5561{
5562 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5563
5564 return "lgfi";
5565}
5566
florian55085f82012-11-21 00:36:55 +00005567static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005568s390_irgen_LRL(UChar r1, UInt i2)
5569{
5570 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5571 i2 << 1))));
5572
5573 return "lrl";
5574}
5575
florian55085f82012-11-21 00:36:55 +00005576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005577s390_irgen_LGRL(UChar r1, UInt i2)
5578{
5579 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5580 i2 << 1))));
5581
5582 return "lgrl";
5583}
5584
florian55085f82012-11-21 00:36:55 +00005585static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005586s390_irgen_LGFRL(UChar r1, UInt i2)
5587{
5588 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5589 ((ULong)(Long)(Int)i2 << 1)))));
5590
5591 return "lgfrl";
5592}
5593
florian55085f82012-11-21 00:36:55 +00005594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005595s390_irgen_LA(UChar r1, IRTemp op2addr)
5596{
5597 put_gpr_dw0(r1, mkexpr(op2addr));
5598
5599 return "la";
5600}
5601
florian55085f82012-11-21 00:36:55 +00005602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005603s390_irgen_LAY(UChar r1, IRTemp op2addr)
5604{
5605 put_gpr_dw0(r1, mkexpr(op2addr));
5606
5607 return "lay";
5608}
5609
florian55085f82012-11-21 00:36:55 +00005610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005611s390_irgen_LAE(UChar r1, IRTemp op2addr)
5612{
5613 put_gpr_dw0(r1, mkexpr(op2addr));
5614
5615 return "lae";
5616}
5617
florian55085f82012-11-21 00:36:55 +00005618static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005619s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5620{
5621 put_gpr_dw0(r1, mkexpr(op2addr));
5622
5623 return "laey";
5624}
5625
florian55085f82012-11-21 00:36:55 +00005626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005627s390_irgen_LARL(UChar r1, UInt i2)
5628{
5629 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5630
5631 return "larl";
5632}
5633
floriana265ee72012-12-02 20:58:17 +00005634/* The IR representation of LAA and friends is an approximation of what
5635 happens natively. Essentially a loop containing a compare-and-swap is
5636 constructed which will iterate until the CAS succeeds. As a consequence,
5637 instrumenters may see more memory accesses than happen natively. See also
5638 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005639static void
5640s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005641{
floriana265ee72012-12-02 20:58:17 +00005642 IRCAS *cas;
5643 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005644 IRTemp op2 = newTemp(Ity_I32);
5645 IRTemp op3 = newTemp(Ity_I32);
5646 IRTemp result = newTemp(Ity_I32);
5647
5648 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5649 assign(op3, get_gpr_w1(r3));
5650 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005651
5652 /* Place the addition of second operand and third operand at the
5653 second-operand location everytime */
5654 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5655 Iend_BE, mkexpr(op2addr),
5656 NULL, mkexpr(op2), /* expected value */
5657 NULL, mkexpr(result) /* new value */);
5658 stmt(IRStmt_CAS(cas));
5659
florianffc94012012-12-02 21:31:15 +00005660 /* Set CC according to 32-bit addition */
5661 if (is_signed) {
5662 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5663 } else {
5664 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5665 }
floriana265ee72012-12-02 20:58:17 +00005666
5667 /* If old_mem contains the expected value, then the CAS succeeded.
5668 Otherwise, it did not */
5669 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5670 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005671}
5672
5673static void
5674s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5675{
5676 IRCAS *cas;
5677 IRTemp old_mem = newTemp(Ity_I64);
5678 IRTemp op2 = newTemp(Ity_I64);
5679 IRTemp op3 = newTemp(Ity_I64);
5680 IRTemp result = newTemp(Ity_I64);
5681
5682 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5683 assign(op3, get_gpr_dw0(r3));
5684 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5685
5686 /* Place the addition of second operand and third operand at the
5687 second-operand location everytime */
5688 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5689 Iend_BE, mkexpr(op2addr),
5690 NULL, mkexpr(op2), /* expected value */
5691 NULL, mkexpr(result) /* new value */);
5692 stmt(IRStmt_CAS(cas));
5693
5694 /* Set CC according to 64-bit addition */
5695 if (is_signed) {
5696 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5697 } else {
5698 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5699 }
5700
5701 /* If old_mem contains the expected value, then the CAS succeeded.
5702 Otherwise, it did not */
5703 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5704 put_gpr_dw0(r1, mkexpr(old_mem));
5705}
5706
5707static void
5708s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5709{
5710 IRCAS *cas;
5711 IRTemp old_mem = newTemp(Ity_I32);
5712 IRTemp op2 = newTemp(Ity_I32);
5713 IRTemp op3 = newTemp(Ity_I32);
5714 IRTemp result = newTemp(Ity_I32);
5715
5716 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5717 assign(op3, get_gpr_w1(r3));
5718 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5719
5720 /* Place the addition of second operand and third operand at the
5721 second-operand location everytime */
5722 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5723 Iend_BE, mkexpr(op2addr),
5724 NULL, mkexpr(op2), /* expected value */
5725 NULL, mkexpr(result) /* new value */);
5726 stmt(IRStmt_CAS(cas));
5727
5728 /* Set CC according to bitwise operation */
5729 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5730
5731 /* If old_mem contains the expected value, then the CAS succeeded.
5732 Otherwise, it did not */
5733 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5734 put_gpr_w1(r1, mkexpr(old_mem));
5735}
5736
5737static void
5738s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5739{
5740 IRCAS *cas;
5741 IRTemp old_mem = newTemp(Ity_I64);
5742 IRTemp op2 = newTemp(Ity_I64);
5743 IRTemp op3 = newTemp(Ity_I64);
5744 IRTemp result = newTemp(Ity_I64);
5745
5746 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5747 assign(op3, get_gpr_dw0(r3));
5748 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5749
5750 /* Place the addition of second operand and third operand at the
5751 second-operand location everytime */
5752 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5753 Iend_BE, mkexpr(op2addr),
5754 NULL, mkexpr(op2), /* expected value */
5755 NULL, mkexpr(result) /* new value */);
5756 stmt(IRStmt_CAS(cas));
5757
5758 /* Set CC according to bitwise operation */
5759 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5760
5761 /* If old_mem contains the expected value, then the CAS succeeded.
5762 Otherwise, it did not */
5763 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5764 put_gpr_dw0(r1, mkexpr(old_mem));
5765}
5766
5767static const HChar *
5768s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5769{
5770 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005771
5772 return "laa";
5773}
5774
florian55085f82012-11-21 00:36:55 +00005775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005776s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5777{
florianffc94012012-12-02 21:31:15 +00005778 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005779
5780 return "laag";
5781}
5782
florian55085f82012-11-21 00:36:55 +00005783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005784s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5785{
florianffc94012012-12-02 21:31:15 +00005786 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005787
5788 return "laal";
5789}
5790
florian55085f82012-11-21 00:36:55 +00005791static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005792s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5793{
florianffc94012012-12-02 21:31:15 +00005794 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005795
5796 return "laalg";
5797}
5798
florian55085f82012-11-21 00:36:55 +00005799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005800s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5801{
florianffc94012012-12-02 21:31:15 +00005802 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005803
5804 return "lan";
5805}
5806
florian55085f82012-11-21 00:36:55 +00005807static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005808s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5809{
florianffc94012012-12-02 21:31:15 +00005810 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005811
5812 return "lang";
5813}
5814
florian55085f82012-11-21 00:36:55 +00005815static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005816s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5817{
florianffc94012012-12-02 21:31:15 +00005818 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005819
5820 return "lax";
5821}
5822
florian55085f82012-11-21 00:36:55 +00005823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005824s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5825{
florianffc94012012-12-02 21:31:15 +00005826 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005827
5828 return "laxg";
5829}
5830
florian55085f82012-11-21 00:36:55 +00005831static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005832s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5833{
florianffc94012012-12-02 21:31:15 +00005834 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005835
5836 return "lao";
5837}
5838
florian55085f82012-11-21 00:36:55 +00005839static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005840s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5841{
florianffc94012012-12-02 21:31:15 +00005842 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005843
5844 return "laog";
5845}
5846
florian55085f82012-11-21 00:36:55 +00005847static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005848s390_irgen_LTR(UChar r1, UChar r2)
5849{
5850 IRTemp op2 = newTemp(Ity_I32);
5851
5852 assign(op2, get_gpr_w1(r2));
5853 put_gpr_w1(r1, mkexpr(op2));
5854 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5855
5856 return "ltr";
5857}
5858
florian55085f82012-11-21 00:36:55 +00005859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005860s390_irgen_LTGR(UChar r1, UChar r2)
5861{
5862 IRTemp op2 = newTemp(Ity_I64);
5863
5864 assign(op2, get_gpr_dw0(r2));
5865 put_gpr_dw0(r1, mkexpr(op2));
5866 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5867
5868 return "ltgr";
5869}
5870
florian55085f82012-11-21 00:36:55 +00005871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005872s390_irgen_LTGFR(UChar r1, UChar r2)
5873{
5874 IRTemp op2 = newTemp(Ity_I64);
5875
5876 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5877 put_gpr_dw0(r1, mkexpr(op2));
5878 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5879
5880 return "ltgfr";
5881}
5882
florian55085f82012-11-21 00:36:55 +00005883static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005884s390_irgen_LT(UChar r1, IRTemp op2addr)
5885{
5886 IRTemp op2 = newTemp(Ity_I32);
5887
5888 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5889 put_gpr_w1(r1, mkexpr(op2));
5890 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5891
5892 return "lt";
5893}
5894
florian55085f82012-11-21 00:36:55 +00005895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005896s390_irgen_LTG(UChar r1, IRTemp op2addr)
5897{
5898 IRTemp op2 = newTemp(Ity_I64);
5899
5900 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5901 put_gpr_dw0(r1, mkexpr(op2));
5902 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5903
5904 return "ltg";
5905}
5906
florian55085f82012-11-21 00:36:55 +00005907static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005908s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5909{
5910 IRTemp op2 = newTemp(Ity_I64);
5911
5912 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5913 put_gpr_dw0(r1, mkexpr(op2));
5914 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5915
5916 return "ltgf";
5917}
5918
florian55085f82012-11-21 00:36:55 +00005919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005920s390_irgen_LBR(UChar r1, UChar r2)
5921{
5922 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5923
5924 return "lbr";
5925}
5926
florian55085f82012-11-21 00:36:55 +00005927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005928s390_irgen_LGBR(UChar r1, UChar r2)
5929{
5930 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5931
5932 return "lgbr";
5933}
5934
florian55085f82012-11-21 00:36:55 +00005935static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005936s390_irgen_LB(UChar r1, IRTemp op2addr)
5937{
5938 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5939
5940 return "lb";
5941}
5942
florian55085f82012-11-21 00:36:55 +00005943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005944s390_irgen_LGB(UChar r1, IRTemp op2addr)
5945{
5946 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5947
5948 return "lgb";
5949}
5950
florian55085f82012-11-21 00:36:55 +00005951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005952s390_irgen_LBH(UChar r1, IRTemp op2addr)
5953{
5954 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5955
5956 return "lbh";
5957}
5958
florian55085f82012-11-21 00:36:55 +00005959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005960s390_irgen_LCR(UChar r1, UChar r2)
5961{
5962 Int op1;
5963 IRTemp op2 = newTemp(Ity_I32);
5964 IRTemp result = newTemp(Ity_I32);
5965
5966 op1 = 0;
5967 assign(op2, get_gpr_w1(r2));
5968 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5969 put_gpr_w1(r1, mkexpr(result));
5970 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5971 op1)), op2);
5972
5973 return "lcr";
5974}
5975
florian55085f82012-11-21 00:36:55 +00005976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005977s390_irgen_LCGR(UChar r1, UChar r2)
5978{
5979 Long op1;
5980 IRTemp op2 = newTemp(Ity_I64);
5981 IRTemp result = newTemp(Ity_I64);
5982
5983 op1 = 0ULL;
5984 assign(op2, get_gpr_dw0(r2));
5985 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5986 put_gpr_dw0(r1, mkexpr(result));
5987 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5988 op1)), op2);
5989
5990 return "lcgr";
5991}
5992
florian55085f82012-11-21 00:36:55 +00005993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005994s390_irgen_LCGFR(UChar r1, UChar r2)
5995{
5996 Long op1;
5997 IRTemp op2 = newTemp(Ity_I64);
5998 IRTemp result = newTemp(Ity_I64);
5999
6000 op1 = 0ULL;
6001 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6002 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6003 put_gpr_dw0(r1, mkexpr(result));
6004 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6005 op1)), op2);
6006
6007 return "lcgfr";
6008}
6009
florian55085f82012-11-21 00:36:55 +00006010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006011s390_irgen_LHR(UChar r1, UChar r2)
6012{
6013 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6014
6015 return "lhr";
6016}
6017
florian55085f82012-11-21 00:36:55 +00006018static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006019s390_irgen_LGHR(UChar r1, UChar r2)
6020{
6021 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6022
6023 return "lghr";
6024}
6025
florian55085f82012-11-21 00:36:55 +00006026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006027s390_irgen_LH(UChar r1, IRTemp op2addr)
6028{
6029 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6030
6031 return "lh";
6032}
6033
florian55085f82012-11-21 00:36:55 +00006034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006035s390_irgen_LHY(UChar r1, IRTemp op2addr)
6036{
6037 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6038
6039 return "lhy";
6040}
6041
florian55085f82012-11-21 00:36:55 +00006042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006043s390_irgen_LGH(UChar r1, IRTemp op2addr)
6044{
6045 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6046
6047 return "lgh";
6048}
6049
florian55085f82012-11-21 00:36:55 +00006050static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006051s390_irgen_LHI(UChar r1, UShort i2)
6052{
6053 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6054
6055 return "lhi";
6056}
6057
florian55085f82012-11-21 00:36:55 +00006058static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006059s390_irgen_LGHI(UChar r1, UShort i2)
6060{
6061 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6062
6063 return "lghi";
6064}
6065
florian55085f82012-11-21 00:36:55 +00006066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006067s390_irgen_LHRL(UChar r1, UInt i2)
6068{
6069 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6070 ((ULong)(Long)(Int)i2 << 1)))));
6071
6072 return "lhrl";
6073}
6074
florian55085f82012-11-21 00:36:55 +00006075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006076s390_irgen_LGHRL(UChar r1, UInt i2)
6077{
6078 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6079 ((ULong)(Long)(Int)i2 << 1)))));
6080
6081 return "lghrl";
6082}
6083
florian55085f82012-11-21 00:36:55 +00006084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006085s390_irgen_LHH(UChar r1, IRTemp op2addr)
6086{
6087 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6088
6089 return "lhh";
6090}
6091
florian55085f82012-11-21 00:36:55 +00006092static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006093s390_irgen_LFH(UChar r1, IRTemp op2addr)
6094{
6095 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6096
6097 return "lfh";
6098}
6099
florian55085f82012-11-21 00:36:55 +00006100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006101s390_irgen_LLGFR(UChar r1, UChar r2)
6102{
6103 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6104
6105 return "llgfr";
6106}
6107
florian55085f82012-11-21 00:36:55 +00006108static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006109s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6110{
6111 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6112
6113 return "llgf";
6114}
6115
florian55085f82012-11-21 00:36:55 +00006116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006117s390_irgen_LLGFRL(UChar r1, UInt i2)
6118{
6119 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6120 ((ULong)(Long)(Int)i2 << 1)))));
6121
6122 return "llgfrl";
6123}
6124
florian55085f82012-11-21 00:36:55 +00006125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006126s390_irgen_LLCR(UChar r1, UChar r2)
6127{
6128 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6129
6130 return "llcr";
6131}
6132
florian55085f82012-11-21 00:36:55 +00006133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006134s390_irgen_LLGCR(UChar r1, UChar r2)
6135{
6136 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6137
6138 return "llgcr";
6139}
6140
florian55085f82012-11-21 00:36:55 +00006141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006142s390_irgen_LLC(UChar r1, IRTemp op2addr)
6143{
6144 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6145
6146 return "llc";
6147}
6148
florian55085f82012-11-21 00:36:55 +00006149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006150s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6151{
6152 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6153
6154 return "llgc";
6155}
6156
florian55085f82012-11-21 00:36:55 +00006157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006158s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6159{
6160 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6161
6162 return "llch";
6163}
6164
florian55085f82012-11-21 00:36:55 +00006165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006166s390_irgen_LLHR(UChar r1, UChar r2)
6167{
6168 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6169
6170 return "llhr";
6171}
6172
florian55085f82012-11-21 00:36:55 +00006173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006174s390_irgen_LLGHR(UChar r1, UChar r2)
6175{
6176 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6177
6178 return "llghr";
6179}
6180
florian55085f82012-11-21 00:36:55 +00006181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006182s390_irgen_LLH(UChar r1, IRTemp op2addr)
6183{
6184 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6185
6186 return "llh";
6187}
6188
florian55085f82012-11-21 00:36:55 +00006189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006190s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6191{
6192 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6193
6194 return "llgh";
6195}
6196
florian55085f82012-11-21 00:36:55 +00006197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006198s390_irgen_LLHRL(UChar r1, UInt i2)
6199{
6200 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6201 ((ULong)(Long)(Int)i2 << 1)))));
6202
6203 return "llhrl";
6204}
6205
florian55085f82012-11-21 00:36:55 +00006206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006207s390_irgen_LLGHRL(UChar r1, UInt i2)
6208{
6209 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6210 ((ULong)(Long)(Int)i2 << 1)))));
6211
6212 return "llghrl";
6213}
6214
florian55085f82012-11-21 00:36:55 +00006215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006216s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6217{
6218 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6219
6220 return "llhh";
6221}
6222
florian55085f82012-11-21 00:36:55 +00006223static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006224s390_irgen_LLIHF(UChar r1, UInt i2)
6225{
6226 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6227
6228 return "llihf";
6229}
6230
florian55085f82012-11-21 00:36:55 +00006231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006232s390_irgen_LLIHH(UChar r1, UShort i2)
6233{
6234 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6235
6236 return "llihh";
6237}
6238
florian55085f82012-11-21 00:36:55 +00006239static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006240s390_irgen_LLIHL(UChar r1, UShort i2)
6241{
6242 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6243
6244 return "llihl";
6245}
6246
florian55085f82012-11-21 00:36:55 +00006247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006248s390_irgen_LLILF(UChar r1, UInt i2)
6249{
6250 put_gpr_dw0(r1, mkU64(i2));
6251
6252 return "llilf";
6253}
6254
florian55085f82012-11-21 00:36:55 +00006255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006256s390_irgen_LLILH(UChar r1, UShort i2)
6257{
6258 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6259
6260 return "llilh";
6261}
6262
florian55085f82012-11-21 00:36:55 +00006263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006264s390_irgen_LLILL(UChar r1, UShort i2)
6265{
6266 put_gpr_dw0(r1, mkU64(i2));
6267
6268 return "llill";
6269}
6270
florian55085f82012-11-21 00:36:55 +00006271static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006272s390_irgen_LLGTR(UChar r1, UChar r2)
6273{
6274 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6275 mkU32(2147483647))));
6276
6277 return "llgtr";
6278}
6279
florian55085f82012-11-21 00:36:55 +00006280static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006281s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6282{
6283 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6284 mkexpr(op2addr)), mkU32(2147483647))));
6285
6286 return "llgt";
6287}
6288
florian55085f82012-11-21 00:36:55 +00006289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006290s390_irgen_LNR(UChar r1, UChar r2)
6291{
6292 IRTemp op2 = newTemp(Ity_I32);
6293 IRTemp result = newTemp(Ity_I32);
6294
6295 assign(op2, get_gpr_w1(r2));
6296 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6297 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6298 put_gpr_w1(r1, mkexpr(result));
6299 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6300
6301 return "lnr";
6302}
6303
florian55085f82012-11-21 00:36:55 +00006304static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006305s390_irgen_LNGR(UChar r1, UChar r2)
6306{
6307 IRTemp op2 = newTemp(Ity_I64);
6308 IRTemp result = newTemp(Ity_I64);
6309
6310 assign(op2, get_gpr_dw0(r2));
6311 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6312 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6313 put_gpr_dw0(r1, mkexpr(result));
6314 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6315
6316 return "lngr";
6317}
6318
florian55085f82012-11-21 00:36:55 +00006319static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006320s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6321{
6322 IRTemp op2 = newTemp(Ity_I64);
6323 IRTemp result = newTemp(Ity_I64);
6324
6325 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6326 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6327 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6328 put_gpr_dw0(r1, mkexpr(result));
6329 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6330
6331 return "lngfr";
6332}
6333
florian55085f82012-11-21 00:36:55 +00006334static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006335s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6336{
florian6820ba52012-07-26 02:01:50 +00006337 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006338 put_gpr_w1(r1, get_gpr_w1(r2));
6339
6340 return "locr";
6341}
6342
florian55085f82012-11-21 00:36:55 +00006343static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006344s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6345{
florian6820ba52012-07-26 02:01:50 +00006346 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006347 put_gpr_dw0(r1, get_gpr_dw0(r2));
6348
6349 return "locgr";
6350}
6351
florian55085f82012-11-21 00:36:55 +00006352static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006353s390_irgen_LOC(UChar r1, IRTemp op2addr)
6354{
6355 /* condition is checked in format handler */
6356 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6357
6358 return "loc";
6359}
6360
florian55085f82012-11-21 00:36:55 +00006361static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006362s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6363{
6364 /* condition is checked in format handler */
6365 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6366
6367 return "locg";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006371s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6372{
6373 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6374 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6375 ));
6376
6377 return "lpq";
6378}
6379
florian55085f82012-11-21 00:36:55 +00006380static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006381s390_irgen_LPR(UChar r1, UChar r2)
6382{
6383 IRTemp op2 = newTemp(Ity_I32);
6384 IRTemp result = newTemp(Ity_I32);
6385
6386 assign(op2, get_gpr_w1(r2));
6387 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6388 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6389 put_gpr_w1(r1, mkexpr(result));
6390 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6391
6392 return "lpr";
6393}
6394
florian55085f82012-11-21 00:36:55 +00006395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006396s390_irgen_LPGR(UChar r1, UChar r2)
6397{
6398 IRTemp op2 = newTemp(Ity_I64);
6399 IRTemp result = newTemp(Ity_I64);
6400
6401 assign(op2, get_gpr_dw0(r2));
6402 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6403 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6404 put_gpr_dw0(r1, mkexpr(result));
6405 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6406
6407 return "lpgr";
6408}
6409
florian55085f82012-11-21 00:36:55 +00006410static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006411s390_irgen_LPGFR(UChar r1, UChar r2)
6412{
6413 IRTemp op2 = newTemp(Ity_I64);
6414 IRTemp result = newTemp(Ity_I64);
6415
6416 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6417 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6418 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6419 put_gpr_dw0(r1, mkexpr(result));
6420 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6421
6422 return "lpgfr";
6423}
6424
florian55085f82012-11-21 00:36:55 +00006425static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006426s390_irgen_LRVR(UChar r1, UChar r2)
6427{
6428 IRTemp b0 = newTemp(Ity_I8);
6429 IRTemp b1 = newTemp(Ity_I8);
6430 IRTemp b2 = newTemp(Ity_I8);
6431 IRTemp b3 = newTemp(Ity_I8);
6432
6433 assign(b3, get_gpr_b7(r2));
6434 assign(b2, get_gpr_b6(r2));
6435 assign(b1, get_gpr_b5(r2));
6436 assign(b0, get_gpr_b4(r2));
6437 put_gpr_b4(r1, mkexpr(b3));
6438 put_gpr_b5(r1, mkexpr(b2));
6439 put_gpr_b6(r1, mkexpr(b1));
6440 put_gpr_b7(r1, mkexpr(b0));
6441
6442 return "lrvr";
6443}
6444
florian55085f82012-11-21 00:36:55 +00006445static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006446s390_irgen_LRVGR(UChar r1, UChar r2)
6447{
6448 IRTemp b0 = newTemp(Ity_I8);
6449 IRTemp b1 = newTemp(Ity_I8);
6450 IRTemp b2 = newTemp(Ity_I8);
6451 IRTemp b3 = newTemp(Ity_I8);
6452 IRTemp b4 = newTemp(Ity_I8);
6453 IRTemp b5 = newTemp(Ity_I8);
6454 IRTemp b6 = newTemp(Ity_I8);
6455 IRTemp b7 = newTemp(Ity_I8);
6456
6457 assign(b7, get_gpr_b7(r2));
6458 assign(b6, get_gpr_b6(r2));
6459 assign(b5, get_gpr_b5(r2));
6460 assign(b4, get_gpr_b4(r2));
6461 assign(b3, get_gpr_b3(r2));
6462 assign(b2, get_gpr_b2(r2));
6463 assign(b1, get_gpr_b1(r2));
6464 assign(b0, get_gpr_b0(r2));
6465 put_gpr_b0(r1, mkexpr(b7));
6466 put_gpr_b1(r1, mkexpr(b6));
6467 put_gpr_b2(r1, mkexpr(b5));
6468 put_gpr_b3(r1, mkexpr(b4));
6469 put_gpr_b4(r1, mkexpr(b3));
6470 put_gpr_b5(r1, mkexpr(b2));
6471 put_gpr_b6(r1, mkexpr(b1));
6472 put_gpr_b7(r1, mkexpr(b0));
6473
6474 return "lrvgr";
6475}
6476
florian55085f82012-11-21 00:36:55 +00006477static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006478s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6479{
6480 IRTemp op2 = newTemp(Ity_I16);
6481
6482 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6483 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6484 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6485
6486 return "lrvh";
6487}
6488
florian55085f82012-11-21 00:36:55 +00006489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006490s390_irgen_LRV(UChar r1, IRTemp op2addr)
6491{
6492 IRTemp op2 = newTemp(Ity_I32);
6493
6494 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6495 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6496 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6497 mkU8(8)), mkU32(255))));
6498 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6499 mkU8(16)), mkU32(255))));
6500 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6501 mkU8(24)), mkU32(255))));
6502
6503 return "lrv";
6504}
6505
florian55085f82012-11-21 00:36:55 +00006506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006507s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6508{
6509 IRTemp op2 = newTemp(Ity_I64);
6510
6511 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6512 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6513 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6514 mkU8(8)), mkU64(255))));
6515 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6516 mkU8(16)), mkU64(255))));
6517 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6518 mkU8(24)), mkU64(255))));
6519 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6520 mkU8(32)), mkU64(255))));
6521 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6522 mkU8(40)), mkU64(255))));
6523 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6524 mkU8(48)), mkU64(255))));
6525 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6526 mkU8(56)), mkU64(255))));
6527
6528 return "lrvg";
6529}
6530
florian55085f82012-11-21 00:36:55 +00006531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006532s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6533{
6534 store(mkexpr(op1addr), mkU16(i2));
6535
6536 return "mvhhi";
6537}
6538
florian55085f82012-11-21 00:36:55 +00006539static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006540s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6541{
6542 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6543
6544 return "mvhi";
6545}
6546
florian55085f82012-11-21 00:36:55 +00006547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006548s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6549{
6550 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6551
6552 return "mvghi";
6553}
6554
florian55085f82012-11-21 00:36:55 +00006555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006556s390_irgen_MVI(UChar i2, IRTemp op1addr)
6557{
6558 store(mkexpr(op1addr), mkU8(i2));
6559
6560 return "mvi";
6561}
6562
florian55085f82012-11-21 00:36:55 +00006563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006564s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6565{
6566 store(mkexpr(op1addr), mkU8(i2));
6567
6568 return "mviy";
6569}
6570
florian55085f82012-11-21 00:36:55 +00006571static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006572s390_irgen_MR(UChar r1, UChar r2)
6573{
6574 IRTemp op1 = newTemp(Ity_I32);
6575 IRTemp op2 = newTemp(Ity_I32);
6576 IRTemp result = newTemp(Ity_I64);
6577
6578 assign(op1, get_gpr_w1(r1 + 1));
6579 assign(op2, get_gpr_w1(r2));
6580 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6581 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6582 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6583
6584 return "mr";
6585}
6586
florian55085f82012-11-21 00:36:55 +00006587static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006588s390_irgen_M(UChar r1, IRTemp op2addr)
6589{
6590 IRTemp op1 = newTemp(Ity_I32);
6591 IRTemp op2 = newTemp(Ity_I32);
6592 IRTemp result = newTemp(Ity_I64);
6593
6594 assign(op1, get_gpr_w1(r1 + 1));
6595 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6596 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6597 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6598 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6599
6600 return "m";
6601}
6602
florian55085f82012-11-21 00:36:55 +00006603static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006604s390_irgen_MFY(UChar r1, IRTemp op2addr)
6605{
6606 IRTemp op1 = newTemp(Ity_I32);
6607 IRTemp op2 = newTemp(Ity_I32);
6608 IRTemp result = newTemp(Ity_I64);
6609
6610 assign(op1, get_gpr_w1(r1 + 1));
6611 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6612 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6613 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6614 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6615
6616 return "mfy";
6617}
6618
florian55085f82012-11-21 00:36:55 +00006619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006620s390_irgen_MH(UChar r1, IRTemp op2addr)
6621{
6622 IRTemp op1 = newTemp(Ity_I32);
6623 IRTemp op2 = newTemp(Ity_I16);
6624 IRTemp result = newTemp(Ity_I64);
6625
6626 assign(op1, get_gpr_w1(r1));
6627 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6628 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6629 ));
6630 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6631
6632 return "mh";
6633}
6634
florian55085f82012-11-21 00:36:55 +00006635static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006636s390_irgen_MHY(UChar r1, IRTemp op2addr)
6637{
6638 IRTemp op1 = newTemp(Ity_I32);
6639 IRTemp op2 = newTemp(Ity_I16);
6640 IRTemp result = newTemp(Ity_I64);
6641
6642 assign(op1, get_gpr_w1(r1));
6643 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6644 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6645 ));
6646 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6647
6648 return "mhy";
6649}
6650
florian55085f82012-11-21 00:36:55 +00006651static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006652s390_irgen_MHI(UChar r1, UShort i2)
6653{
6654 IRTemp op1 = newTemp(Ity_I32);
6655 Short op2;
6656 IRTemp result = newTemp(Ity_I64);
6657
6658 assign(op1, get_gpr_w1(r1));
6659 op2 = (Short)i2;
6660 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6661 mkU16((UShort)op2))));
6662 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6663
6664 return "mhi";
6665}
6666
florian55085f82012-11-21 00:36:55 +00006667static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006668s390_irgen_MGHI(UChar r1, UShort i2)
6669{
6670 IRTemp op1 = newTemp(Ity_I64);
6671 Short op2;
6672 IRTemp result = newTemp(Ity_I128);
6673
6674 assign(op1, get_gpr_dw0(r1));
6675 op2 = (Short)i2;
6676 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6677 mkU16((UShort)op2))));
6678 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6679
6680 return "mghi";
6681}
6682
florian55085f82012-11-21 00:36:55 +00006683static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006684s390_irgen_MLR(UChar r1, UChar r2)
6685{
6686 IRTemp op1 = newTemp(Ity_I32);
6687 IRTemp op2 = newTemp(Ity_I32);
6688 IRTemp result = newTemp(Ity_I64);
6689
6690 assign(op1, get_gpr_w1(r1 + 1));
6691 assign(op2, get_gpr_w1(r2));
6692 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6693 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6694 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6695
6696 return "mlr";
6697}
6698
florian55085f82012-11-21 00:36:55 +00006699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006700s390_irgen_MLGR(UChar r1, UChar r2)
6701{
6702 IRTemp op1 = newTemp(Ity_I64);
6703 IRTemp op2 = newTemp(Ity_I64);
6704 IRTemp result = newTemp(Ity_I128);
6705
6706 assign(op1, get_gpr_dw0(r1 + 1));
6707 assign(op2, get_gpr_dw0(r2));
6708 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6709 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6710 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6711
6712 return "mlgr";
6713}
6714
florian55085f82012-11-21 00:36:55 +00006715static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006716s390_irgen_ML(UChar r1, IRTemp op2addr)
6717{
6718 IRTemp op1 = newTemp(Ity_I32);
6719 IRTemp op2 = newTemp(Ity_I32);
6720 IRTemp result = newTemp(Ity_I64);
6721
6722 assign(op1, get_gpr_w1(r1 + 1));
6723 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6724 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6725 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6726 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6727
6728 return "ml";
6729}
6730
florian55085f82012-11-21 00:36:55 +00006731static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006732s390_irgen_MLG(UChar r1, IRTemp op2addr)
6733{
6734 IRTemp op1 = newTemp(Ity_I64);
6735 IRTemp op2 = newTemp(Ity_I64);
6736 IRTemp result = newTemp(Ity_I128);
6737
6738 assign(op1, get_gpr_dw0(r1 + 1));
6739 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6740 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6741 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6742 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6743
6744 return "mlg";
6745}
6746
florian55085f82012-11-21 00:36:55 +00006747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006748s390_irgen_MSR(UChar r1, UChar r2)
6749{
6750 IRTemp op1 = newTemp(Ity_I32);
6751 IRTemp op2 = newTemp(Ity_I32);
6752 IRTemp result = newTemp(Ity_I64);
6753
6754 assign(op1, get_gpr_w1(r1));
6755 assign(op2, get_gpr_w1(r2));
6756 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6757 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6758
6759 return "msr";
6760}
6761
florian55085f82012-11-21 00:36:55 +00006762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006763s390_irgen_MSGR(UChar r1, UChar r2)
6764{
6765 IRTemp op1 = newTemp(Ity_I64);
6766 IRTemp op2 = newTemp(Ity_I64);
6767 IRTemp result = newTemp(Ity_I128);
6768
6769 assign(op1, get_gpr_dw0(r1));
6770 assign(op2, get_gpr_dw0(r2));
6771 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6772 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6773
6774 return "msgr";
6775}
6776
florian55085f82012-11-21 00:36:55 +00006777static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006778s390_irgen_MSGFR(UChar r1, UChar r2)
6779{
6780 IRTemp op1 = newTemp(Ity_I64);
6781 IRTemp op2 = newTemp(Ity_I32);
6782 IRTemp result = newTemp(Ity_I128);
6783
6784 assign(op1, get_gpr_dw0(r1));
6785 assign(op2, get_gpr_w1(r2));
6786 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6787 ));
6788 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6789
6790 return "msgfr";
6791}
6792
florian55085f82012-11-21 00:36:55 +00006793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006794s390_irgen_MS(UChar r1, IRTemp op2addr)
6795{
6796 IRTemp op1 = newTemp(Ity_I32);
6797 IRTemp op2 = newTemp(Ity_I32);
6798 IRTemp result = newTemp(Ity_I64);
6799
6800 assign(op1, get_gpr_w1(r1));
6801 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6802 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6803 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6804
6805 return "ms";
6806}
6807
florian55085f82012-11-21 00:36:55 +00006808static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006809s390_irgen_MSY(UChar r1, IRTemp op2addr)
6810{
6811 IRTemp op1 = newTemp(Ity_I32);
6812 IRTemp op2 = newTemp(Ity_I32);
6813 IRTemp result = newTemp(Ity_I64);
6814
6815 assign(op1, get_gpr_w1(r1));
6816 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6817 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6818 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6819
6820 return "msy";
6821}
6822
florian55085f82012-11-21 00:36:55 +00006823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006824s390_irgen_MSG(UChar r1, IRTemp op2addr)
6825{
6826 IRTemp op1 = newTemp(Ity_I64);
6827 IRTemp op2 = newTemp(Ity_I64);
6828 IRTemp result = newTemp(Ity_I128);
6829
6830 assign(op1, get_gpr_dw0(r1));
6831 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6832 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6833 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6834
6835 return "msg";
6836}
6837
florian55085f82012-11-21 00:36:55 +00006838static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006839s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6840{
6841 IRTemp op1 = newTemp(Ity_I64);
6842 IRTemp op2 = newTemp(Ity_I32);
6843 IRTemp result = newTemp(Ity_I128);
6844
6845 assign(op1, get_gpr_dw0(r1));
6846 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6847 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6848 ));
6849 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6850
6851 return "msgf";
6852}
6853
florian55085f82012-11-21 00:36:55 +00006854static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006855s390_irgen_MSFI(UChar r1, UInt i2)
6856{
6857 IRTemp op1 = newTemp(Ity_I32);
6858 Int op2;
6859 IRTemp result = newTemp(Ity_I64);
6860
6861 assign(op1, get_gpr_w1(r1));
6862 op2 = (Int)i2;
6863 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6864 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6865
6866 return "msfi";
6867}
6868
florian55085f82012-11-21 00:36:55 +00006869static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006870s390_irgen_MSGFI(UChar r1, UInt i2)
6871{
6872 IRTemp op1 = newTemp(Ity_I64);
6873 Int op2;
6874 IRTemp result = newTemp(Ity_I128);
6875
6876 assign(op1, get_gpr_dw0(r1));
6877 op2 = (Int)i2;
6878 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6879 op2))));
6880 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6881
6882 return "msgfi";
6883}
6884
florian55085f82012-11-21 00:36:55 +00006885static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006886s390_irgen_OR(UChar r1, UChar r2)
6887{
6888 IRTemp op1 = newTemp(Ity_I32);
6889 IRTemp op2 = newTemp(Ity_I32);
6890 IRTemp result = newTemp(Ity_I32);
6891
6892 assign(op1, get_gpr_w1(r1));
6893 assign(op2, get_gpr_w1(r2));
6894 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6895 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6896 put_gpr_w1(r1, mkexpr(result));
6897
6898 return "or";
6899}
6900
florian55085f82012-11-21 00:36:55 +00006901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006902s390_irgen_OGR(UChar r1, UChar r2)
6903{
6904 IRTemp op1 = newTemp(Ity_I64);
6905 IRTemp op2 = newTemp(Ity_I64);
6906 IRTemp result = newTemp(Ity_I64);
6907
6908 assign(op1, get_gpr_dw0(r1));
6909 assign(op2, get_gpr_dw0(r2));
6910 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6911 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6912 put_gpr_dw0(r1, mkexpr(result));
6913
6914 return "ogr";
6915}
6916
florian55085f82012-11-21 00:36:55 +00006917static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006918s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6919{
6920 IRTemp op2 = newTemp(Ity_I32);
6921 IRTemp op3 = newTemp(Ity_I32);
6922 IRTemp result = newTemp(Ity_I32);
6923
6924 assign(op2, get_gpr_w1(r2));
6925 assign(op3, get_gpr_w1(r3));
6926 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6927 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6928 put_gpr_w1(r1, mkexpr(result));
6929
6930 return "ork";
6931}
6932
florian55085f82012-11-21 00:36:55 +00006933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006934s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6935{
6936 IRTemp op2 = newTemp(Ity_I64);
6937 IRTemp op3 = newTemp(Ity_I64);
6938 IRTemp result = newTemp(Ity_I64);
6939
6940 assign(op2, get_gpr_dw0(r2));
6941 assign(op3, get_gpr_dw0(r3));
6942 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6943 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6944 put_gpr_dw0(r1, mkexpr(result));
6945
6946 return "ogrk";
6947}
6948
florian55085f82012-11-21 00:36:55 +00006949static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006950s390_irgen_O(UChar r1, IRTemp op2addr)
6951{
6952 IRTemp op1 = newTemp(Ity_I32);
6953 IRTemp op2 = newTemp(Ity_I32);
6954 IRTemp result = newTemp(Ity_I32);
6955
6956 assign(op1, get_gpr_w1(r1));
6957 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6958 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6959 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6960 put_gpr_w1(r1, mkexpr(result));
6961
6962 return "o";
6963}
6964
florian55085f82012-11-21 00:36:55 +00006965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006966s390_irgen_OY(UChar r1, IRTemp op2addr)
6967{
6968 IRTemp op1 = newTemp(Ity_I32);
6969 IRTemp op2 = newTemp(Ity_I32);
6970 IRTemp result = newTemp(Ity_I32);
6971
6972 assign(op1, get_gpr_w1(r1));
6973 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6974 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6975 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6976 put_gpr_w1(r1, mkexpr(result));
6977
6978 return "oy";
6979}
6980
florian55085f82012-11-21 00:36:55 +00006981static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006982s390_irgen_OG(UChar r1, IRTemp op2addr)
6983{
6984 IRTemp op1 = newTemp(Ity_I64);
6985 IRTemp op2 = newTemp(Ity_I64);
6986 IRTemp result = newTemp(Ity_I64);
6987
6988 assign(op1, get_gpr_dw0(r1));
6989 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6990 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6991 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6992 put_gpr_dw0(r1, mkexpr(result));
6993
6994 return "og";
6995}
6996
florian55085f82012-11-21 00:36:55 +00006997static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006998s390_irgen_OI(UChar i2, IRTemp op1addr)
6999{
7000 IRTemp op1 = newTemp(Ity_I8);
7001 UChar op2;
7002 IRTemp result = newTemp(Ity_I8);
7003
7004 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7005 op2 = i2;
7006 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7007 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7008 store(mkexpr(op1addr), mkexpr(result));
7009
7010 return "oi";
7011}
7012
florian55085f82012-11-21 00:36:55 +00007013static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007014s390_irgen_OIY(UChar i2, IRTemp op1addr)
7015{
7016 IRTemp op1 = newTemp(Ity_I8);
7017 UChar op2;
7018 IRTemp result = newTemp(Ity_I8);
7019
7020 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7021 op2 = i2;
7022 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7023 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7024 store(mkexpr(op1addr), mkexpr(result));
7025
7026 return "oiy";
7027}
7028
florian55085f82012-11-21 00:36:55 +00007029static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007030s390_irgen_OIHF(UChar r1, UInt i2)
7031{
7032 IRTemp op1 = newTemp(Ity_I32);
7033 UInt op2;
7034 IRTemp result = newTemp(Ity_I32);
7035
7036 assign(op1, get_gpr_w0(r1));
7037 op2 = i2;
7038 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7039 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7040 put_gpr_w0(r1, mkexpr(result));
7041
7042 return "oihf";
7043}
7044
florian55085f82012-11-21 00:36:55 +00007045static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007046s390_irgen_OIHH(UChar r1, UShort i2)
7047{
7048 IRTemp op1 = newTemp(Ity_I16);
7049 UShort op2;
7050 IRTemp result = newTemp(Ity_I16);
7051
7052 assign(op1, get_gpr_hw0(r1));
7053 op2 = i2;
7054 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7055 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7056 put_gpr_hw0(r1, mkexpr(result));
7057
7058 return "oihh";
7059}
7060
florian55085f82012-11-21 00:36:55 +00007061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007062s390_irgen_OIHL(UChar r1, UShort i2)
7063{
7064 IRTemp op1 = newTemp(Ity_I16);
7065 UShort op2;
7066 IRTemp result = newTemp(Ity_I16);
7067
7068 assign(op1, get_gpr_hw1(r1));
7069 op2 = i2;
7070 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7071 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7072 put_gpr_hw1(r1, mkexpr(result));
7073
7074 return "oihl";
7075}
7076
florian55085f82012-11-21 00:36:55 +00007077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007078s390_irgen_OILF(UChar r1, UInt i2)
7079{
7080 IRTemp op1 = newTemp(Ity_I32);
7081 UInt op2;
7082 IRTemp result = newTemp(Ity_I32);
7083
7084 assign(op1, get_gpr_w1(r1));
7085 op2 = i2;
7086 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7087 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7088 put_gpr_w1(r1, mkexpr(result));
7089
7090 return "oilf";
7091}
7092
florian55085f82012-11-21 00:36:55 +00007093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007094s390_irgen_OILH(UChar r1, UShort i2)
7095{
7096 IRTemp op1 = newTemp(Ity_I16);
7097 UShort op2;
7098 IRTemp result = newTemp(Ity_I16);
7099
7100 assign(op1, get_gpr_hw2(r1));
7101 op2 = i2;
7102 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7103 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7104 put_gpr_hw2(r1, mkexpr(result));
7105
7106 return "oilh";
7107}
7108
florian55085f82012-11-21 00:36:55 +00007109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007110s390_irgen_OILL(UChar r1, UShort i2)
7111{
7112 IRTemp op1 = newTemp(Ity_I16);
7113 UShort op2;
7114 IRTemp result = newTemp(Ity_I16);
7115
7116 assign(op1, get_gpr_hw3(r1));
7117 op2 = i2;
7118 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7119 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7120 put_gpr_hw3(r1, mkexpr(result));
7121
7122 return "oill";
7123}
7124
florian55085f82012-11-21 00:36:55 +00007125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007126s390_irgen_PFD(void)
7127{
7128
7129 return "pfd";
7130}
7131
florian55085f82012-11-21 00:36:55 +00007132static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007133s390_irgen_PFDRL(void)
7134{
7135
7136 return "pfdrl";
7137}
7138
florian78d5ef72013-05-11 15:02:58 +00007139static IRExpr *
7140get_rounding_mode_from_gr0(void)
7141{
7142 IRTemp rm_bits = newTemp(Ity_I32);
7143 IRExpr *s390rm;
7144 IRExpr *irrm;
7145
7146 vassert(s390_host_has_pfpo);
7147 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7148 when PFPO insn is called. So, extract the bits at [60:63] */
7149 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7150 s390rm = mkexpr(rm_bits);
7151 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7152 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7153 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7154 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7155 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7156 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7157 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7158 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7159 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7160 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7161 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7162 mkexpr(encode_dfp_rounding_mode(
7163 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7164 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7165 mkexpr(encode_dfp_rounding_mode(
7166 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7167 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7168 mkexpr(encode_dfp_rounding_mode(
7169 S390_DFP_ROUND_AWAY_0)),
7170 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7171 mkexpr(encode_dfp_rounding_mode(
7172 S390_DFP_ROUND_PREPARE_SHORT_15)),
7173 /* if rounding mode is 0 or invalid (2-7)
7174 set S390_DFP_ROUND_PER_FPC_0 */
7175 mkexpr(encode_dfp_rounding_mode(
7176 S390_DFP_ROUND_PER_FPC_0)))))))))));
7177
7178 return irrm;
7179}
7180
7181static IRExpr *
7182s390_call_pfpo_helper(IRExpr *gr0)
7183{
7184 IRExpr **args, *call;
7185
7186 args = mkIRExprVec_1(gr0);
7187 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7188 "s390_do_pfpo", &s390_do_pfpo, args);
7189 /* Nothing is excluded from definedness checking. */
7190 call->Iex.CCall.cee->mcx_mask = 0;
7191
7192 return call;
7193}
7194
7195static const HChar *
7196s390_irgen_PFPO(void)
7197{
7198 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
7199 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7200 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
7201 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
7202 IRTemp src1 = newTemp(Ity_F64);
7203 IRTemp dst1 = newTemp(Ity_D64);
7204 IRTemp src2 = newTemp(Ity_D64);
7205 IRTemp dst2 = newTemp(Ity_F64);
7206 IRTemp src3 = newTemp(Ity_F64);
7207 IRTemp dst3 = newTemp(Ity_D128);
7208 IRTemp src4 = newTemp(Ity_D128);
7209 IRTemp dst4 = newTemp(Ity_F64);
7210 IRTemp src5 = newTemp(Ity_F128);
7211 IRTemp dst5 = newTemp(Ity_D128);
7212 IRTemp src6 = newTemp(Ity_D128);
7213 IRTemp dst6 = newTemp(Ity_F128);
7214 IRExpr *irrm;
7215
7216 vassert(s390_host_has_pfpo);
7217
7218 assign(gr0, get_gpr_w1(0));
7219 /* get function code */
7220 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7221 mkU32(0x7fffff)));
7222 /* get validity test bit */
7223 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7224 mkU32(0x1)));
7225 irrm = get_rounding_mode_from_gr0();
7226
7227 /* test_bit is 1 */
7228 assign(src1, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7229 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7230
7231 /* Return code set in GR1 is usually 0. Non-zero value is set only
7232 when exceptions are raised. See Programming Notes point 5 in the
7233 instrcution description of pfpo in POP. Since valgrind does not
7234 model exception, it might be safe to just set 0 to GR 1. */
7235 put_gpr_w1(1, mkU32(0x0));
7236 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7237
7238 /* Check validity of function code in GR 0 */
7239 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
7240
7241 /* fixs390: Function emulation_failure can be used if it takes argument as
7242 IRExpr * instead of VexEmNote. */
7243 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkexpr(ef)));
7244 dis_res->whatNext = Dis_StopHere;
7245 dis_res->jk_StopHere = Ijk_EmFail;
7246
7247 stmt(
7248 IRStmt_Exit(
7249 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7250 Ijk_EmFail,
7251 IRConst_U64(guest_IA_next_instr),
7252 S390X_GUEST_OFFSET(guest_IA)
7253 )
7254 );
7255
7256 /* F64 -> D64 */
7257 /* get source from FPR 4,6 - already set in src1 */
7258 assign(dst1, binop(Iop_F64toD64, irrm, mkexpr(src1)));
7259 put_dpr_dw0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
7260 put_gpr_w1(1, mkU32(0x0));
7261 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7262 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7263
7264 /* D64 -> F64 */
7265 assign(src2, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7266 assign(dst2, binop(Iop_D64toF64, irrm, mkexpr(src2)));
7267 put_fpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
7268 put_gpr_w1(1, mkU32(0x0));
7269 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src2, gr0);
7270 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7271
7272 /* F64 -> D128 */
7273 assign(src3, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7274 assign(dst3, binop(Iop_F64toD128, irrm, mkexpr(src3)));
7275 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7276 put_gpr_w1(1, mkU32(0x0));
7277 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src3, gr0);
7278 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7279
7280 /* D128 -> F64 */
7281 assign(src4, get_dpr_pair(4)); /* get source from FPR 4,6 */
7282 assign(dst4, binop(Iop_D128toF64, irrm, mkexpr(src4)));
7283 put_fpr_dw0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7284 put_gpr_w1(1, mkU32(0x0));
7285 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src4, gr0);
7286 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7287
7288 /* F128 -> D128 */
7289 assign(src5, get_fpr_pair(4)); /* get source from FPR 4,6 */
7290 assign(dst5, binop(Iop_F128toD128, irrm, mkexpr(src5)));
7291 put_dpr_pair(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7292 put_gpr_w1(1, mkU32(0x0));
7293 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src5, gr0);
7294 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7295
7296 /* D128 -> F128 */
7297 assign(src6, get_dpr_pair(4)); /* get source from FPR 4,6 */
7298 assign(dst6, binop(Iop_D128toF128, irrm, mkexpr(src6)));
7299 put_fpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7300 put_gpr_w1(1, mkU32(0x0));
7301 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src6, gr0);
7302 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7303
7304 return "pfpo";
7305}
7306
florian55085f82012-11-21 00:36:55 +00007307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007308s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7309{
7310 IRTemp amount = newTemp(Ity_I64);
7311 IRTemp op = newTemp(Ity_I32);
7312
7313 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7314 assign(op, get_gpr_w1(r3));
7315 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7316 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7317 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7318
7319 return "rll";
7320}
7321
florian55085f82012-11-21 00:36:55 +00007322static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007323s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7324{
7325 IRTemp amount = newTemp(Ity_I64);
7326 IRTemp op = newTemp(Ity_I64);
7327
7328 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7329 assign(op, get_gpr_dw0(r3));
7330 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7331 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7332 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7333
7334 return "rllg";
7335}
7336
florian55085f82012-11-21 00:36:55 +00007337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007338s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7339{
7340 UChar from;
7341 UChar to;
7342 UChar rot;
7343 UChar t_bit;
7344 ULong mask;
7345 ULong maskc;
7346 IRTemp result = newTemp(Ity_I64);
7347 IRTemp op2 = newTemp(Ity_I64);
7348
7349 from = i3 & 63;
7350 to = i4 & 63;
7351 rot = i5 & 63;
7352 t_bit = i3 & 128;
7353 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7354 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7355 mkU8(64 - rot))));
7356 if (from <= to) {
7357 mask = ~0ULL;
7358 mask = (mask >> from) & (mask << (63 - to));
7359 maskc = ~mask;
7360 } else {
7361 maskc = ~0ULL;
7362 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7363 mask = ~maskc;
7364 }
7365 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7366 ), mkU64(mask)));
7367 if (t_bit == 0) {
7368 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7369 mkU64(maskc)), mkexpr(result)));
7370 }
7371 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7372
7373 return "rnsbg";
7374}
7375
florian55085f82012-11-21 00:36:55 +00007376static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007377s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7378{
7379 UChar from;
7380 UChar to;
7381 UChar rot;
7382 UChar t_bit;
7383 ULong mask;
7384 ULong maskc;
7385 IRTemp result = newTemp(Ity_I64);
7386 IRTemp op2 = newTemp(Ity_I64);
7387
7388 from = i3 & 63;
7389 to = i4 & 63;
7390 rot = i5 & 63;
7391 t_bit = i3 & 128;
7392 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7393 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7394 mkU8(64 - rot))));
7395 if (from <= to) {
7396 mask = ~0ULL;
7397 mask = (mask >> from) & (mask << (63 - to));
7398 maskc = ~mask;
7399 } else {
7400 maskc = ~0ULL;
7401 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7402 mask = ~maskc;
7403 }
7404 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7405 ), mkU64(mask)));
7406 if (t_bit == 0) {
7407 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7408 mkU64(maskc)), mkexpr(result)));
7409 }
7410 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7411
7412 return "rxsbg";
7413}
7414
florian55085f82012-11-21 00:36:55 +00007415static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007416s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7417{
7418 UChar from;
7419 UChar to;
7420 UChar rot;
7421 UChar t_bit;
7422 ULong mask;
7423 ULong maskc;
7424 IRTemp result = newTemp(Ity_I64);
7425 IRTemp op2 = newTemp(Ity_I64);
7426
7427 from = i3 & 63;
7428 to = i4 & 63;
7429 rot = i5 & 63;
7430 t_bit = i3 & 128;
7431 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7432 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7433 mkU8(64 - rot))));
7434 if (from <= to) {
7435 mask = ~0ULL;
7436 mask = (mask >> from) & (mask << (63 - to));
7437 maskc = ~mask;
7438 } else {
7439 maskc = ~0ULL;
7440 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7441 mask = ~maskc;
7442 }
7443 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7444 ), mkU64(mask)));
7445 if (t_bit == 0) {
7446 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7447 mkU64(maskc)), mkexpr(result)));
7448 }
7449 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7450
7451 return "rosbg";
7452}
7453
florian55085f82012-11-21 00:36:55 +00007454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007455s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7456{
7457 UChar from;
7458 UChar to;
7459 UChar rot;
7460 UChar z_bit;
7461 ULong mask;
7462 ULong maskc;
7463 IRTemp op2 = newTemp(Ity_I64);
7464 IRTemp result = newTemp(Ity_I64);
7465
7466 from = i3 & 63;
7467 to = i4 & 63;
7468 rot = i5 & 63;
7469 z_bit = i4 & 128;
7470 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7471 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7472 mkU8(64 - rot))));
7473 if (from <= to) {
7474 mask = ~0ULL;
7475 mask = (mask >> from) & (mask << (63 - to));
7476 maskc = ~mask;
7477 } else {
7478 maskc = ~0ULL;
7479 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7480 mask = ~maskc;
7481 }
7482 if (z_bit == 0) {
7483 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7484 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7485 } else {
7486 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7487 }
7488 assign(result, get_gpr_dw0(r1));
7489 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7490
7491 return "risbg";
7492}
7493
florian55085f82012-11-21 00:36:55 +00007494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007495s390_irgen_SAR(UChar r1, UChar r2)
7496{
7497 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007498 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007499 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7500
7501 return "sar";
7502}
7503
florian55085f82012-11-21 00:36:55 +00007504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007505s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7506{
7507 IRTemp p1 = newTemp(Ity_I64);
7508 IRTemp p2 = newTemp(Ity_I64);
7509 IRTemp op = newTemp(Ity_I64);
7510 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007511 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007512 IRTemp shift_amount = newTemp(Ity_I64);
7513
7514 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7515 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7516 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7517 ));
7518 sign_mask = 1ULL << 63;
7519 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7520 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007521 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7522 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007523 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7524 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7525 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7526
7527 return "slda";
7528}
7529
florian55085f82012-11-21 00:36:55 +00007530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007531s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7532{
7533 IRTemp p1 = newTemp(Ity_I64);
7534 IRTemp p2 = newTemp(Ity_I64);
7535 IRTemp result = newTemp(Ity_I64);
7536
7537 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7538 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7539 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7540 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7541 mkexpr(op2addr), mkU64(63)))));
7542 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7543 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7544
7545 return "sldl";
7546}
7547
florian55085f82012-11-21 00:36:55 +00007548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007549s390_irgen_SLA(UChar r1, IRTemp op2addr)
7550{
7551 IRTemp uop = newTemp(Ity_I32);
7552 IRTemp result = newTemp(Ity_I32);
7553 UInt sign_mask;
7554 IRTemp shift_amount = newTemp(Ity_I64);
7555 IRTemp op = newTemp(Ity_I32);
7556
7557 assign(op, get_gpr_w1(r1));
7558 assign(uop, get_gpr_w1(r1));
7559 sign_mask = 2147483648U;
7560 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7561 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7562 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7563 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7564 put_gpr_w1(r1, mkexpr(result));
7565 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7566
7567 return "sla";
7568}
7569
florian55085f82012-11-21 00:36:55 +00007570static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007571s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7572{
7573 IRTemp uop = newTemp(Ity_I32);
7574 IRTemp result = newTemp(Ity_I32);
7575 UInt sign_mask;
7576 IRTemp shift_amount = newTemp(Ity_I64);
7577 IRTemp op = newTemp(Ity_I32);
7578
7579 assign(op, get_gpr_w1(r3));
7580 assign(uop, get_gpr_w1(r3));
7581 sign_mask = 2147483648U;
7582 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7583 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7584 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7585 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7586 put_gpr_w1(r1, mkexpr(result));
7587 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7588
7589 return "slak";
7590}
7591
florian55085f82012-11-21 00:36:55 +00007592static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007593s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7594{
7595 IRTemp uop = newTemp(Ity_I64);
7596 IRTemp result = newTemp(Ity_I64);
7597 ULong sign_mask;
7598 IRTemp shift_amount = newTemp(Ity_I64);
7599 IRTemp op = newTemp(Ity_I64);
7600
7601 assign(op, get_gpr_dw0(r3));
7602 assign(uop, get_gpr_dw0(r3));
7603 sign_mask = 9223372036854775808ULL;
7604 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7605 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7606 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7607 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7608 put_gpr_dw0(r1, mkexpr(result));
7609 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7610
7611 return "slag";
7612}
7613
florian55085f82012-11-21 00:36:55 +00007614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007615s390_irgen_SLL(UChar r1, IRTemp op2addr)
7616{
7617 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7618 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7619
7620 return "sll";
7621}
7622
florian55085f82012-11-21 00:36:55 +00007623static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007624s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7625{
7626 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7627 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7628
7629 return "sllk";
7630}
7631
florian55085f82012-11-21 00:36:55 +00007632static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007633s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7634{
7635 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7636 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7637
7638 return "sllg";
7639}
7640
florian55085f82012-11-21 00:36:55 +00007641static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007642s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7643{
7644 IRTemp p1 = newTemp(Ity_I64);
7645 IRTemp p2 = newTemp(Ity_I64);
7646 IRTemp result = newTemp(Ity_I64);
7647
7648 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7649 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7650 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7651 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7652 mkexpr(op2addr), mkU64(63)))));
7653 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7654 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7655 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7656
7657 return "srda";
7658}
7659
florian55085f82012-11-21 00:36:55 +00007660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007661s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7662{
7663 IRTemp p1 = newTemp(Ity_I64);
7664 IRTemp p2 = newTemp(Ity_I64);
7665 IRTemp result = newTemp(Ity_I64);
7666
7667 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7668 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7669 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7670 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7671 mkexpr(op2addr), mkU64(63)))));
7672 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7673 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7674
7675 return "srdl";
7676}
7677
florian55085f82012-11-21 00:36:55 +00007678static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007679s390_irgen_SRA(UChar r1, IRTemp op2addr)
7680{
7681 IRTemp result = newTemp(Ity_I32);
7682 IRTemp op = newTemp(Ity_I32);
7683
7684 assign(op, get_gpr_w1(r1));
7685 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7686 mkexpr(op2addr), mkU64(63)))));
7687 put_gpr_w1(r1, mkexpr(result));
7688 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7689
7690 return "sra";
7691}
7692
florian55085f82012-11-21 00:36:55 +00007693static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007694s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7695{
7696 IRTemp result = newTemp(Ity_I32);
7697 IRTemp op = newTemp(Ity_I32);
7698
7699 assign(op, get_gpr_w1(r3));
7700 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7701 mkexpr(op2addr), mkU64(63)))));
7702 put_gpr_w1(r1, mkexpr(result));
7703 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7704
7705 return "srak";
7706}
7707
florian55085f82012-11-21 00:36:55 +00007708static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007709s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7710{
7711 IRTemp result = newTemp(Ity_I64);
7712 IRTemp op = newTemp(Ity_I64);
7713
7714 assign(op, get_gpr_dw0(r3));
7715 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7716 mkexpr(op2addr), mkU64(63)))));
7717 put_gpr_dw0(r1, mkexpr(result));
7718 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7719
7720 return "srag";
7721}
7722
florian55085f82012-11-21 00:36:55 +00007723static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007724s390_irgen_SRL(UChar r1, IRTemp op2addr)
7725{
7726 IRTemp op = newTemp(Ity_I32);
7727
7728 assign(op, get_gpr_w1(r1));
7729 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7730 mkexpr(op2addr), mkU64(63)))));
7731
7732 return "srl";
7733}
7734
florian55085f82012-11-21 00:36:55 +00007735static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007736s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7737{
7738 IRTemp op = newTemp(Ity_I32);
7739
7740 assign(op, get_gpr_w1(r3));
7741 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7742 mkexpr(op2addr), mkU64(63)))));
7743
7744 return "srlk";
7745}
7746
florian55085f82012-11-21 00:36:55 +00007747static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007748s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7749{
7750 IRTemp op = newTemp(Ity_I64);
7751
7752 assign(op, get_gpr_dw0(r3));
7753 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7754 mkexpr(op2addr), mkU64(63)))));
7755
7756 return "srlg";
7757}
7758
florian55085f82012-11-21 00:36:55 +00007759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007760s390_irgen_ST(UChar r1, IRTemp op2addr)
7761{
7762 store(mkexpr(op2addr), get_gpr_w1(r1));
7763
7764 return "st";
7765}
7766
florian55085f82012-11-21 00:36:55 +00007767static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007768s390_irgen_STY(UChar r1, IRTemp op2addr)
7769{
7770 store(mkexpr(op2addr), get_gpr_w1(r1));
7771
7772 return "sty";
7773}
7774
florian55085f82012-11-21 00:36:55 +00007775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007776s390_irgen_STG(UChar r1, IRTemp op2addr)
7777{
7778 store(mkexpr(op2addr), get_gpr_dw0(r1));
7779
7780 return "stg";
7781}
7782
florian55085f82012-11-21 00:36:55 +00007783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007784s390_irgen_STRL(UChar r1, UInt i2)
7785{
7786 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7787 get_gpr_w1(r1));
7788
7789 return "strl";
7790}
7791
florian55085f82012-11-21 00:36:55 +00007792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007793s390_irgen_STGRL(UChar r1, UInt i2)
7794{
7795 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7796 get_gpr_dw0(r1));
7797
7798 return "stgrl";
7799}
7800
florian55085f82012-11-21 00:36:55 +00007801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007802s390_irgen_STC(UChar r1, IRTemp op2addr)
7803{
7804 store(mkexpr(op2addr), get_gpr_b7(r1));
7805
7806 return "stc";
7807}
7808
florian55085f82012-11-21 00:36:55 +00007809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007810s390_irgen_STCY(UChar r1, IRTemp op2addr)
7811{
7812 store(mkexpr(op2addr), get_gpr_b7(r1));
7813
7814 return "stcy";
7815}
7816
florian55085f82012-11-21 00:36:55 +00007817static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007818s390_irgen_STCH(UChar r1, IRTemp op2addr)
7819{
7820 store(mkexpr(op2addr), get_gpr_b3(r1));
7821
7822 return "stch";
7823}
7824
florian55085f82012-11-21 00:36:55 +00007825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007826s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7827{
7828 UChar mask;
7829 UChar n;
7830
7831 mask = (UChar)r3;
7832 n = 0;
7833 if ((mask & 8) != 0) {
7834 store(mkexpr(op2addr), get_gpr_b4(r1));
7835 n = n + 1;
7836 }
7837 if ((mask & 4) != 0) {
7838 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7839 n = n + 1;
7840 }
7841 if ((mask & 2) != 0) {
7842 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7843 n = n + 1;
7844 }
7845 if ((mask & 1) != 0) {
7846 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7847 }
7848
7849 return "stcm";
7850}
7851
florian55085f82012-11-21 00:36:55 +00007852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007853s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7854{
7855 UChar mask;
7856 UChar n;
7857
7858 mask = (UChar)r3;
7859 n = 0;
7860 if ((mask & 8) != 0) {
7861 store(mkexpr(op2addr), get_gpr_b4(r1));
7862 n = n + 1;
7863 }
7864 if ((mask & 4) != 0) {
7865 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7866 n = n + 1;
7867 }
7868 if ((mask & 2) != 0) {
7869 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7870 n = n + 1;
7871 }
7872 if ((mask & 1) != 0) {
7873 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7874 }
7875
7876 return "stcmy";
7877}
7878
florian55085f82012-11-21 00:36:55 +00007879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007880s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7881{
7882 UChar mask;
7883 UChar n;
7884
7885 mask = (UChar)r3;
7886 n = 0;
7887 if ((mask & 8) != 0) {
7888 store(mkexpr(op2addr), get_gpr_b0(r1));
7889 n = n + 1;
7890 }
7891 if ((mask & 4) != 0) {
7892 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7893 n = n + 1;
7894 }
7895 if ((mask & 2) != 0) {
7896 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7897 n = n + 1;
7898 }
7899 if ((mask & 1) != 0) {
7900 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7901 }
7902
7903 return "stcmh";
7904}
7905
florian55085f82012-11-21 00:36:55 +00007906static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007907s390_irgen_STH(UChar r1, IRTemp op2addr)
7908{
7909 store(mkexpr(op2addr), get_gpr_hw3(r1));
7910
7911 return "sth";
7912}
7913
florian55085f82012-11-21 00:36:55 +00007914static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007915s390_irgen_STHY(UChar r1, IRTemp op2addr)
7916{
7917 store(mkexpr(op2addr), get_gpr_hw3(r1));
7918
7919 return "sthy";
7920}
7921
florian55085f82012-11-21 00:36:55 +00007922static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007923s390_irgen_STHRL(UChar r1, UInt i2)
7924{
7925 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7926 get_gpr_hw3(r1));
7927
7928 return "sthrl";
7929}
7930
florian55085f82012-11-21 00:36:55 +00007931static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007932s390_irgen_STHH(UChar r1, IRTemp op2addr)
7933{
7934 store(mkexpr(op2addr), get_gpr_hw1(r1));
7935
7936 return "sthh";
7937}
7938
florian55085f82012-11-21 00:36:55 +00007939static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007940s390_irgen_STFH(UChar r1, IRTemp op2addr)
7941{
7942 store(mkexpr(op2addr), get_gpr_w0(r1));
7943
7944 return "stfh";
7945}
7946
florian55085f82012-11-21 00:36:55 +00007947static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007948s390_irgen_STOC(UChar r1, IRTemp op2addr)
7949{
7950 /* condition is checked in format handler */
7951 store(mkexpr(op2addr), get_gpr_w1(r1));
7952
7953 return "stoc";
7954}
7955
florian55085f82012-11-21 00:36:55 +00007956static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007957s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7958{
7959 /* condition is checked in format handler */
7960 store(mkexpr(op2addr), get_gpr_dw0(r1));
7961
7962 return "stocg";
7963}
7964
florian55085f82012-11-21 00:36:55 +00007965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007966s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7967{
7968 store(mkexpr(op2addr), get_gpr_dw0(r1));
7969 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7970
7971 return "stpq";
7972}
7973
florian55085f82012-11-21 00:36:55 +00007974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007975s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7976{
7977 store(mkexpr(op2addr), get_gpr_b7(r1));
7978 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7979
7980 return "strvh";
7981}
7982
florian55085f82012-11-21 00:36:55 +00007983static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007984s390_irgen_STRV(UChar r1, IRTemp op2addr)
7985{
7986 store(mkexpr(op2addr), get_gpr_b7(r1));
7987 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7988 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7989 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7990
7991 return "strv";
7992}
7993
florian55085f82012-11-21 00:36:55 +00007994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007995s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7996{
7997 store(mkexpr(op2addr), get_gpr_b7(r1));
7998 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7999 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8000 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8001 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8002 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8003 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8004 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8005
8006 return "strvg";
8007}
8008
florian55085f82012-11-21 00:36:55 +00008009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008010s390_irgen_SR(UChar r1, UChar r2)
8011{
8012 IRTemp op1 = newTemp(Ity_I32);
8013 IRTemp op2 = newTemp(Ity_I32);
8014 IRTemp result = newTemp(Ity_I32);
8015
8016 assign(op1, get_gpr_w1(r1));
8017 assign(op2, get_gpr_w1(r2));
8018 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8019 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8020 put_gpr_w1(r1, mkexpr(result));
8021
8022 return "sr";
8023}
8024
florian55085f82012-11-21 00:36:55 +00008025static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008026s390_irgen_SGR(UChar r1, UChar r2)
8027{
8028 IRTemp op1 = newTemp(Ity_I64);
8029 IRTemp op2 = newTemp(Ity_I64);
8030 IRTemp result = newTemp(Ity_I64);
8031
8032 assign(op1, get_gpr_dw0(r1));
8033 assign(op2, get_gpr_dw0(r2));
8034 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8035 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8036 put_gpr_dw0(r1, mkexpr(result));
8037
8038 return "sgr";
8039}
8040
florian55085f82012-11-21 00:36:55 +00008041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008042s390_irgen_SGFR(UChar r1, UChar r2)
8043{
8044 IRTemp op1 = newTemp(Ity_I64);
8045 IRTemp op2 = newTemp(Ity_I64);
8046 IRTemp result = newTemp(Ity_I64);
8047
8048 assign(op1, get_gpr_dw0(r1));
8049 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8050 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8051 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8052 put_gpr_dw0(r1, mkexpr(result));
8053
8054 return "sgfr";
8055}
8056
florian55085f82012-11-21 00:36:55 +00008057static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008058s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8059{
8060 IRTemp op2 = newTemp(Ity_I32);
8061 IRTemp op3 = newTemp(Ity_I32);
8062 IRTemp result = newTemp(Ity_I32);
8063
8064 assign(op2, get_gpr_w1(r2));
8065 assign(op3, get_gpr_w1(r3));
8066 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8067 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8068 put_gpr_w1(r1, mkexpr(result));
8069
8070 return "srk";
8071}
8072
florian55085f82012-11-21 00:36:55 +00008073static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008074s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8075{
8076 IRTemp op2 = newTemp(Ity_I64);
8077 IRTemp op3 = newTemp(Ity_I64);
8078 IRTemp result = newTemp(Ity_I64);
8079
8080 assign(op2, get_gpr_dw0(r2));
8081 assign(op3, get_gpr_dw0(r3));
8082 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8083 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8084 put_gpr_dw0(r1, mkexpr(result));
8085
8086 return "sgrk";
8087}
8088
florian55085f82012-11-21 00:36:55 +00008089static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008090s390_irgen_S(UChar r1, IRTemp op2addr)
8091{
8092 IRTemp op1 = newTemp(Ity_I32);
8093 IRTemp op2 = newTemp(Ity_I32);
8094 IRTemp result = newTemp(Ity_I32);
8095
8096 assign(op1, get_gpr_w1(r1));
8097 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8098 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8099 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8100 put_gpr_w1(r1, mkexpr(result));
8101
8102 return "s";
8103}
8104
florian55085f82012-11-21 00:36:55 +00008105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008106s390_irgen_SY(UChar r1, IRTemp op2addr)
8107{
8108 IRTemp op1 = newTemp(Ity_I32);
8109 IRTemp op2 = newTemp(Ity_I32);
8110 IRTemp result = newTemp(Ity_I32);
8111
8112 assign(op1, get_gpr_w1(r1));
8113 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8114 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8115 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8116 put_gpr_w1(r1, mkexpr(result));
8117
8118 return "sy";
8119}
8120
florian55085f82012-11-21 00:36:55 +00008121static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008122s390_irgen_SG(UChar r1, IRTemp op2addr)
8123{
8124 IRTemp op1 = newTemp(Ity_I64);
8125 IRTemp op2 = newTemp(Ity_I64);
8126 IRTemp result = newTemp(Ity_I64);
8127
8128 assign(op1, get_gpr_dw0(r1));
8129 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8130 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8131 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8132 put_gpr_dw0(r1, mkexpr(result));
8133
8134 return "sg";
8135}
8136
florian55085f82012-11-21 00:36:55 +00008137static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008138s390_irgen_SGF(UChar r1, IRTemp op2addr)
8139{
8140 IRTemp op1 = newTemp(Ity_I64);
8141 IRTemp op2 = newTemp(Ity_I64);
8142 IRTemp result = newTemp(Ity_I64);
8143
8144 assign(op1, get_gpr_dw0(r1));
8145 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8146 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8147 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8148 put_gpr_dw0(r1, mkexpr(result));
8149
8150 return "sgf";
8151}
8152
florian55085f82012-11-21 00:36:55 +00008153static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008154s390_irgen_SH(UChar r1, IRTemp op2addr)
8155{
8156 IRTemp op1 = newTemp(Ity_I32);
8157 IRTemp op2 = newTemp(Ity_I32);
8158 IRTemp result = newTemp(Ity_I32);
8159
8160 assign(op1, get_gpr_w1(r1));
8161 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8162 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8163 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8164 put_gpr_w1(r1, mkexpr(result));
8165
8166 return "sh";
8167}
8168
florian55085f82012-11-21 00:36:55 +00008169static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008170s390_irgen_SHY(UChar r1, IRTemp op2addr)
8171{
8172 IRTemp op1 = newTemp(Ity_I32);
8173 IRTemp op2 = newTemp(Ity_I32);
8174 IRTemp result = newTemp(Ity_I32);
8175
8176 assign(op1, get_gpr_w1(r1));
8177 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8178 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8179 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8180 put_gpr_w1(r1, mkexpr(result));
8181
8182 return "shy";
8183}
8184
florian55085f82012-11-21 00:36:55 +00008185static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008186s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8187{
8188 IRTemp op2 = newTemp(Ity_I32);
8189 IRTemp op3 = newTemp(Ity_I32);
8190 IRTemp result = newTemp(Ity_I32);
8191
8192 assign(op2, get_gpr_w0(r1));
8193 assign(op3, get_gpr_w0(r2));
8194 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8195 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8196 put_gpr_w0(r1, mkexpr(result));
8197
8198 return "shhhr";
8199}
8200
florian55085f82012-11-21 00:36:55 +00008201static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008202s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8203{
8204 IRTemp op2 = newTemp(Ity_I32);
8205 IRTemp op3 = newTemp(Ity_I32);
8206 IRTemp result = newTemp(Ity_I32);
8207
8208 assign(op2, get_gpr_w0(r1));
8209 assign(op3, get_gpr_w1(r2));
8210 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8211 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8212 put_gpr_w0(r1, mkexpr(result));
8213
8214 return "shhlr";
8215}
8216
florian55085f82012-11-21 00:36:55 +00008217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008218s390_irgen_SLR(UChar r1, UChar r2)
8219{
8220 IRTemp op1 = newTemp(Ity_I32);
8221 IRTemp op2 = newTemp(Ity_I32);
8222 IRTemp result = newTemp(Ity_I32);
8223
8224 assign(op1, get_gpr_w1(r1));
8225 assign(op2, get_gpr_w1(r2));
8226 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8227 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8228 put_gpr_w1(r1, mkexpr(result));
8229
8230 return "slr";
8231}
8232
florian55085f82012-11-21 00:36:55 +00008233static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008234s390_irgen_SLGR(UChar r1, UChar r2)
8235{
8236 IRTemp op1 = newTemp(Ity_I64);
8237 IRTemp op2 = newTemp(Ity_I64);
8238 IRTemp result = newTemp(Ity_I64);
8239
8240 assign(op1, get_gpr_dw0(r1));
8241 assign(op2, get_gpr_dw0(r2));
8242 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8243 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8244 put_gpr_dw0(r1, mkexpr(result));
8245
8246 return "slgr";
8247}
8248
florian55085f82012-11-21 00:36:55 +00008249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008250s390_irgen_SLGFR(UChar r1, UChar r2)
8251{
8252 IRTemp op1 = newTemp(Ity_I64);
8253 IRTemp op2 = newTemp(Ity_I64);
8254 IRTemp result = newTemp(Ity_I64);
8255
8256 assign(op1, get_gpr_dw0(r1));
8257 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8258 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8259 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8260 put_gpr_dw0(r1, mkexpr(result));
8261
8262 return "slgfr";
8263}
8264
florian55085f82012-11-21 00:36:55 +00008265static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008266s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8267{
8268 IRTemp op2 = newTemp(Ity_I32);
8269 IRTemp op3 = newTemp(Ity_I32);
8270 IRTemp result = newTemp(Ity_I32);
8271
8272 assign(op2, get_gpr_w1(r2));
8273 assign(op3, get_gpr_w1(r3));
8274 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8275 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8276 put_gpr_w1(r1, mkexpr(result));
8277
8278 return "slrk";
8279}
8280
florian55085f82012-11-21 00:36:55 +00008281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008282s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8283{
8284 IRTemp op2 = newTemp(Ity_I64);
8285 IRTemp op3 = newTemp(Ity_I64);
8286 IRTemp result = newTemp(Ity_I64);
8287
8288 assign(op2, get_gpr_dw0(r2));
8289 assign(op3, get_gpr_dw0(r3));
8290 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8291 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8292 put_gpr_dw0(r1, mkexpr(result));
8293
8294 return "slgrk";
8295}
8296
florian55085f82012-11-21 00:36:55 +00008297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008298s390_irgen_SL(UChar r1, IRTemp op2addr)
8299{
8300 IRTemp op1 = newTemp(Ity_I32);
8301 IRTemp op2 = newTemp(Ity_I32);
8302 IRTemp result = newTemp(Ity_I32);
8303
8304 assign(op1, get_gpr_w1(r1));
8305 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8306 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8307 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8308 put_gpr_w1(r1, mkexpr(result));
8309
8310 return "sl";
8311}
8312
florian55085f82012-11-21 00:36:55 +00008313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008314s390_irgen_SLY(UChar r1, IRTemp op2addr)
8315{
8316 IRTemp op1 = newTemp(Ity_I32);
8317 IRTemp op2 = newTemp(Ity_I32);
8318 IRTemp result = newTemp(Ity_I32);
8319
8320 assign(op1, get_gpr_w1(r1));
8321 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8322 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8323 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8324 put_gpr_w1(r1, mkexpr(result));
8325
8326 return "sly";
8327}
8328
florian55085f82012-11-21 00:36:55 +00008329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008330s390_irgen_SLG(UChar r1, IRTemp op2addr)
8331{
8332 IRTemp op1 = newTemp(Ity_I64);
8333 IRTemp op2 = newTemp(Ity_I64);
8334 IRTemp result = newTemp(Ity_I64);
8335
8336 assign(op1, get_gpr_dw0(r1));
8337 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8338 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8339 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8340 put_gpr_dw0(r1, mkexpr(result));
8341
8342 return "slg";
8343}
8344
florian55085f82012-11-21 00:36:55 +00008345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008346s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8347{
8348 IRTemp op1 = newTemp(Ity_I64);
8349 IRTemp op2 = newTemp(Ity_I64);
8350 IRTemp result = newTemp(Ity_I64);
8351
8352 assign(op1, get_gpr_dw0(r1));
8353 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8354 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8355 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8356 put_gpr_dw0(r1, mkexpr(result));
8357
8358 return "slgf";
8359}
8360
florian55085f82012-11-21 00:36:55 +00008361static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008362s390_irgen_SLFI(UChar r1, UInt i2)
8363{
8364 IRTemp op1 = newTemp(Ity_I32);
8365 UInt op2;
8366 IRTemp result = newTemp(Ity_I32);
8367
8368 assign(op1, get_gpr_w1(r1));
8369 op2 = i2;
8370 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8371 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8372 mkU32(op2)));
8373 put_gpr_w1(r1, mkexpr(result));
8374
8375 return "slfi";
8376}
8377
florian55085f82012-11-21 00:36:55 +00008378static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008379s390_irgen_SLGFI(UChar r1, UInt i2)
8380{
8381 IRTemp op1 = newTemp(Ity_I64);
8382 ULong op2;
8383 IRTemp result = newTemp(Ity_I64);
8384
8385 assign(op1, get_gpr_dw0(r1));
8386 op2 = (ULong)i2;
8387 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8388 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8389 mkU64(op2)));
8390 put_gpr_dw0(r1, mkexpr(result));
8391
8392 return "slgfi";
8393}
8394
florian55085f82012-11-21 00:36:55 +00008395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008396s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8397{
8398 IRTemp op2 = newTemp(Ity_I32);
8399 IRTemp op3 = newTemp(Ity_I32);
8400 IRTemp result = newTemp(Ity_I32);
8401
8402 assign(op2, get_gpr_w0(r1));
8403 assign(op3, get_gpr_w0(r2));
8404 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8405 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8406 put_gpr_w0(r1, mkexpr(result));
8407
8408 return "slhhhr";
8409}
8410
florian55085f82012-11-21 00:36:55 +00008411static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008412s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8413{
8414 IRTemp op2 = newTemp(Ity_I32);
8415 IRTemp op3 = newTemp(Ity_I32);
8416 IRTemp result = newTemp(Ity_I32);
8417
8418 assign(op2, get_gpr_w0(r1));
8419 assign(op3, get_gpr_w1(r2));
8420 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8421 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8422 put_gpr_w0(r1, mkexpr(result));
8423
8424 return "slhhlr";
8425}
8426
florian55085f82012-11-21 00:36:55 +00008427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008428s390_irgen_SLBR(UChar r1, UChar r2)
8429{
8430 IRTemp op1 = newTemp(Ity_I32);
8431 IRTemp op2 = newTemp(Ity_I32);
8432 IRTemp result = newTemp(Ity_I32);
8433 IRTemp borrow_in = newTemp(Ity_I32);
8434
8435 assign(op1, get_gpr_w1(r1));
8436 assign(op2, get_gpr_w1(r2));
8437 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8438 s390_call_calculate_cc(), mkU8(1))));
8439 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8440 mkexpr(borrow_in)));
8441 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8442 put_gpr_w1(r1, mkexpr(result));
8443
8444 return "slbr";
8445}
8446
florian55085f82012-11-21 00:36:55 +00008447static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008448s390_irgen_SLBGR(UChar r1, UChar r2)
8449{
8450 IRTemp op1 = newTemp(Ity_I64);
8451 IRTemp op2 = newTemp(Ity_I64);
8452 IRTemp result = newTemp(Ity_I64);
8453 IRTemp borrow_in = newTemp(Ity_I64);
8454
8455 assign(op1, get_gpr_dw0(r1));
8456 assign(op2, get_gpr_dw0(r2));
8457 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8458 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8459 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8460 mkexpr(borrow_in)));
8461 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8462 put_gpr_dw0(r1, mkexpr(result));
8463
8464 return "slbgr";
8465}
8466
florian55085f82012-11-21 00:36:55 +00008467static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008468s390_irgen_SLB(UChar r1, IRTemp op2addr)
8469{
8470 IRTemp op1 = newTemp(Ity_I32);
8471 IRTemp op2 = newTemp(Ity_I32);
8472 IRTemp result = newTemp(Ity_I32);
8473 IRTemp borrow_in = newTemp(Ity_I32);
8474
8475 assign(op1, get_gpr_w1(r1));
8476 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8477 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8478 s390_call_calculate_cc(), mkU8(1))));
8479 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8480 mkexpr(borrow_in)));
8481 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8482 put_gpr_w1(r1, mkexpr(result));
8483
8484 return "slb";
8485}
8486
florian55085f82012-11-21 00:36:55 +00008487static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008488s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8489{
8490 IRTemp op1 = newTemp(Ity_I64);
8491 IRTemp op2 = newTemp(Ity_I64);
8492 IRTemp result = newTemp(Ity_I64);
8493 IRTemp borrow_in = newTemp(Ity_I64);
8494
8495 assign(op1, get_gpr_dw0(r1));
8496 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8497 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8498 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8499 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8500 mkexpr(borrow_in)));
8501 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8502 put_gpr_dw0(r1, mkexpr(result));
8503
8504 return "slbg";
8505}
8506
florian55085f82012-11-21 00:36:55 +00008507static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008508s390_irgen_SVC(UChar i)
8509{
8510 IRTemp sysno = newTemp(Ity_I64);
8511
8512 if (i != 0) {
8513 assign(sysno, mkU64(i));
8514 } else {
8515 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8516 }
8517 system_call(mkexpr(sysno));
8518
8519 return "svc";
8520}
8521
florian55085f82012-11-21 00:36:55 +00008522static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008523s390_irgen_TM(UChar i2, IRTemp op1addr)
8524{
8525 UChar mask;
8526 IRTemp value = newTemp(Ity_I8);
8527
8528 mask = i2;
8529 assign(value, load(Ity_I8, mkexpr(op1addr)));
8530 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8531 mkU8(mask)));
8532
8533 return "tm";
8534}
8535
florian55085f82012-11-21 00:36:55 +00008536static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008537s390_irgen_TMY(UChar i2, IRTemp op1addr)
8538{
8539 UChar mask;
8540 IRTemp value = newTemp(Ity_I8);
8541
8542 mask = i2;
8543 assign(value, load(Ity_I8, mkexpr(op1addr)));
8544 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8545 mkU8(mask)));
8546
8547 return "tmy";
8548}
8549
florian55085f82012-11-21 00:36:55 +00008550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008551s390_irgen_TMHH(UChar r1, UShort i2)
8552{
8553 UShort mask;
8554 IRTemp value = newTemp(Ity_I16);
8555
8556 mask = i2;
8557 assign(value, get_gpr_hw0(r1));
8558 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8559 mkU16(mask)));
8560
8561 return "tmhh";
8562}
8563
florian55085f82012-11-21 00:36:55 +00008564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008565s390_irgen_TMHL(UChar r1, UShort i2)
8566{
8567 UShort mask;
8568 IRTemp value = newTemp(Ity_I16);
8569
8570 mask = i2;
8571 assign(value, get_gpr_hw1(r1));
8572 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8573 mkU16(mask)));
8574
8575 return "tmhl";
8576}
8577
florian55085f82012-11-21 00:36:55 +00008578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008579s390_irgen_TMLH(UChar r1, UShort i2)
8580{
8581 UShort mask;
8582 IRTemp value = newTemp(Ity_I16);
8583
8584 mask = i2;
8585 assign(value, get_gpr_hw2(r1));
8586 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8587 mkU16(mask)));
8588
8589 return "tmlh";
8590}
8591
florian55085f82012-11-21 00:36:55 +00008592static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008593s390_irgen_TMLL(UChar r1, UShort i2)
8594{
8595 UShort mask;
8596 IRTemp value = newTemp(Ity_I16);
8597
8598 mask = i2;
8599 assign(value, get_gpr_hw3(r1));
8600 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8601 mkU16(mask)));
8602
8603 return "tmll";
8604}
8605
florian55085f82012-11-21 00:36:55 +00008606static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008607s390_irgen_EFPC(UChar r1)
8608{
8609 put_gpr_w1(r1, get_fpc_w0());
8610
8611 return "efpc";
8612}
8613
florian55085f82012-11-21 00:36:55 +00008614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008615s390_irgen_LER(UChar r1, UChar r2)
8616{
8617 put_fpr_w0(r1, get_fpr_w0(r2));
8618
8619 return "ler";
8620}
8621
florian55085f82012-11-21 00:36:55 +00008622static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008623s390_irgen_LDR(UChar r1, UChar r2)
8624{
8625 put_fpr_dw0(r1, get_fpr_dw0(r2));
8626
8627 return "ldr";
8628}
8629
florian55085f82012-11-21 00:36:55 +00008630static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008631s390_irgen_LXR(UChar r1, UChar r2)
8632{
8633 put_fpr_dw0(r1, get_fpr_dw0(r2));
8634 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8635
8636 return "lxr";
8637}
8638
florian55085f82012-11-21 00:36:55 +00008639static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008640s390_irgen_LE(UChar r1, IRTemp op2addr)
8641{
8642 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8643
8644 return "le";
8645}
8646
florian55085f82012-11-21 00:36:55 +00008647static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008648s390_irgen_LD(UChar r1, IRTemp op2addr)
8649{
8650 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8651
8652 return "ld";
8653}
8654
florian55085f82012-11-21 00:36:55 +00008655static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008656s390_irgen_LEY(UChar r1, IRTemp op2addr)
8657{
8658 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8659
8660 return "ley";
8661}
8662
florian55085f82012-11-21 00:36:55 +00008663static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008664s390_irgen_LDY(UChar r1, IRTemp op2addr)
8665{
8666 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8667
8668 return "ldy";
8669}
8670
florian55085f82012-11-21 00:36:55 +00008671static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008672s390_irgen_LFPC(IRTemp op2addr)
8673{
8674 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8675
8676 return "lfpc";
8677}
8678
florian55085f82012-11-21 00:36:55 +00008679static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008680s390_irgen_LZER(UChar r1)
8681{
8682 put_fpr_w0(r1, mkF32i(0x0));
8683
8684 return "lzer";
8685}
8686
florian55085f82012-11-21 00:36:55 +00008687static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008688s390_irgen_LZDR(UChar r1)
8689{
8690 put_fpr_dw0(r1, mkF64i(0x0));
8691
8692 return "lzdr";
8693}
8694
florian55085f82012-11-21 00:36:55 +00008695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008696s390_irgen_LZXR(UChar r1)
8697{
8698 put_fpr_dw0(r1, mkF64i(0x0));
8699 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8700
8701 return "lzxr";
8702}
8703
florian55085f82012-11-21 00:36:55 +00008704static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008705s390_irgen_SRNM(IRTemp op2addr)
8706{
florianf0fa1be2012-09-18 20:24:38 +00008707 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008708
florianf0fa1be2012-09-18 20:24:38 +00008709 input_mask = 3;
8710 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008711
florianf0fa1be2012-09-18 20:24:38 +00008712 put_fpc_w0(binop(Iop_Or32,
8713 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8714 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8715 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008716 return "srnm";
8717}
8718
florian55085f82012-11-21 00:36:55 +00008719static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008720s390_irgen_SRNMB(IRTemp op2addr)
8721{
8722 UInt input_mask, fpc_mask;
8723
8724 input_mask = 7;
8725 fpc_mask = 7;
8726
8727 put_fpc_w0(binop(Iop_Or32,
8728 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8729 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8730 mkU32(input_mask))));
8731 return "srnmb";
8732}
8733
florian81a4bfe2012-09-20 01:25:28 +00008734static void
florianf0fa1be2012-09-18 20:24:38 +00008735s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8736{
8737 if (b2 == 0) { /* This is the typical case */
8738 if (d2 > 3) {
8739 if (s390_host_has_fpext && d2 == 7) {
8740 /* ok */
8741 } else {
8742 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008743 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008744 }
8745 }
8746 }
8747
8748 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8749}
8750
florian82cdba62013-03-12 01:31:24 +00008751/* Wrapper to validate the parameter as in SRNMB is not required, as all
8752 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8753static const HChar *
8754s390_irgen_SRNMT(IRTemp op2addr)
8755{
8756 UInt input_mask, fpc_mask;
8757
8758 input_mask = 7;
8759 fpc_mask = 0x70;
8760
8761 /* fpc[25:27] <- op2addr[61:63]
8762 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8763 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8764 binop(Iop_Shl32, binop(Iop_And32,
8765 unop(Iop_64to32, mkexpr(op2addr)),
8766 mkU32(input_mask)), mkU8(4))));
8767 return "srnmt";
8768}
8769
florianf0fa1be2012-09-18 20:24:38 +00008770
florian55085f82012-11-21 00:36:55 +00008771static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008772s390_irgen_SFPC(UChar r1)
8773{
8774 put_fpc_w0(get_gpr_w1(r1));
8775
8776 return "sfpc";
8777}
8778
florian55085f82012-11-21 00:36:55 +00008779static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008780s390_irgen_STE(UChar r1, IRTemp op2addr)
8781{
8782 store(mkexpr(op2addr), get_fpr_w0(r1));
8783
8784 return "ste";
8785}
8786
florian55085f82012-11-21 00:36:55 +00008787static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008788s390_irgen_STD(UChar r1, IRTemp op2addr)
8789{
8790 store(mkexpr(op2addr), get_fpr_dw0(r1));
8791
8792 return "std";
8793}
8794
florian55085f82012-11-21 00:36:55 +00008795static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008796s390_irgen_STEY(UChar r1, IRTemp op2addr)
8797{
8798 store(mkexpr(op2addr), get_fpr_w0(r1));
8799
8800 return "stey";
8801}
8802
florian55085f82012-11-21 00:36:55 +00008803static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008804s390_irgen_STDY(UChar r1, IRTemp op2addr)
8805{
8806 store(mkexpr(op2addr), get_fpr_dw0(r1));
8807
8808 return "stdy";
8809}
8810
florian55085f82012-11-21 00:36:55 +00008811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008812s390_irgen_STFPC(IRTemp op2addr)
8813{
8814 store(mkexpr(op2addr), get_fpc_w0());
8815
8816 return "stfpc";
8817}
8818
florian55085f82012-11-21 00:36:55 +00008819static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008820s390_irgen_AEBR(UChar r1, UChar r2)
8821{
8822 IRTemp op1 = newTemp(Ity_F32);
8823 IRTemp op2 = newTemp(Ity_F32);
8824 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008825 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008826
8827 assign(op1, get_fpr_w0(r1));
8828 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008829 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008830 mkexpr(op2)));
8831 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8832 put_fpr_w0(r1, mkexpr(result));
8833
8834 return "aebr";
8835}
8836
florian55085f82012-11-21 00:36:55 +00008837static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008838s390_irgen_ADBR(UChar r1, UChar r2)
8839{
8840 IRTemp op1 = newTemp(Ity_F64);
8841 IRTemp op2 = newTemp(Ity_F64);
8842 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008843 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008844
8845 assign(op1, get_fpr_dw0(r1));
8846 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008847 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008848 mkexpr(op2)));
8849 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8850 put_fpr_dw0(r1, mkexpr(result));
8851
8852 return "adbr";
8853}
8854
florian55085f82012-11-21 00:36:55 +00008855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008856s390_irgen_AEB(UChar r1, IRTemp op2addr)
8857{
8858 IRTemp op1 = newTemp(Ity_F32);
8859 IRTemp op2 = newTemp(Ity_F32);
8860 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008861 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008862
8863 assign(op1, get_fpr_w0(r1));
8864 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008865 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008866 mkexpr(op2)));
8867 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8868 put_fpr_w0(r1, mkexpr(result));
8869
8870 return "aeb";
8871}
8872
florian55085f82012-11-21 00:36:55 +00008873static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008874s390_irgen_ADB(UChar r1, IRTemp op2addr)
8875{
8876 IRTemp op1 = newTemp(Ity_F64);
8877 IRTemp op2 = newTemp(Ity_F64);
8878 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008879 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008880
8881 assign(op1, get_fpr_dw0(r1));
8882 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008883 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008884 mkexpr(op2)));
8885 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8886 put_fpr_dw0(r1, mkexpr(result));
8887
8888 return "adb";
8889}
8890
florian55085f82012-11-21 00:36:55 +00008891static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008892s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8893 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008894{
florian125e20d2012-10-07 15:42:37 +00008895 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008896 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008897 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008898 }
sewardj2019a972011-03-07 16:04:07 +00008899 IRTemp op2 = newTemp(Ity_I32);
8900
8901 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008902 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008903 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008904
8905 return "cefbr";
8906}
8907
florian55085f82012-11-21 00:36:55 +00008908static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008909s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8910 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008911{
8912 IRTemp op2 = newTemp(Ity_I32);
8913
8914 assign(op2, get_gpr_w1(r2));
8915 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8916
8917 return "cdfbr";
8918}
8919
florian55085f82012-11-21 00:36:55 +00008920static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008921s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8922 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008923{
florian125e20d2012-10-07 15:42:37 +00008924 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008925 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008926 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008927 }
sewardj2019a972011-03-07 16:04:07 +00008928 IRTemp op2 = newTemp(Ity_I64);
8929
8930 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008931 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008932 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008933
8934 return "cegbr";
8935}
8936
florian55085f82012-11-21 00:36:55 +00008937static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008938s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8939 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008940{
florian125e20d2012-10-07 15:42:37 +00008941 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008942 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008943 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008944 }
sewardj2019a972011-03-07 16:04:07 +00008945 IRTemp op2 = newTemp(Ity_I64);
8946
8947 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008948 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008949 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008950
8951 return "cdgbr";
8952}
8953
florian55085f82012-11-21 00:36:55 +00008954static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008955s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8956 UChar r1, UChar r2)
8957{
floriane75dafa2012-09-01 17:54:09 +00008958 if (! s390_host_has_fpext) {
8959 emulation_failure(EmFail_S390X_fpext);
8960 } else {
8961 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008962
floriane75dafa2012-09-01 17:54:09 +00008963 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008964 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008965 mkexpr(op2)));
8966 }
florian1c8f7ff2012-09-01 00:12:11 +00008967 return "celfbr";
8968}
8969
florian55085f82012-11-21 00:36:55 +00008970static const HChar *
floriand2129202012-09-01 20:01:39 +00008971s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8972 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008973{
floriane75dafa2012-09-01 17:54:09 +00008974 if (! s390_host_has_fpext) {
8975 emulation_failure(EmFail_S390X_fpext);
8976 } else {
8977 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008978
floriane75dafa2012-09-01 17:54:09 +00008979 assign(op2, get_gpr_w1(r2));
8980 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8981 }
florian1c8f7ff2012-09-01 00:12:11 +00008982 return "cdlfbr";
8983}
8984
florian55085f82012-11-21 00:36:55 +00008985static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008986s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8987 UChar r1, UChar r2)
8988{
floriane75dafa2012-09-01 17:54:09 +00008989 if (! s390_host_has_fpext) {
8990 emulation_failure(EmFail_S390X_fpext);
8991 } else {
8992 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008993
floriane75dafa2012-09-01 17:54:09 +00008994 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008995 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008996 mkexpr(op2)));
8997 }
florian1c8f7ff2012-09-01 00:12:11 +00008998 return "celgbr";
8999}
9000
florian55085f82012-11-21 00:36:55 +00009001static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009002s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9003 UChar r1, UChar r2)
9004{
floriane75dafa2012-09-01 17:54:09 +00009005 if (! s390_host_has_fpext) {
9006 emulation_failure(EmFail_S390X_fpext);
9007 } else {
9008 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009009
floriane75dafa2012-09-01 17:54:09 +00009010 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009011 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9012 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009013 mkexpr(op2)));
9014 }
florian1c8f7ff2012-09-01 00:12:11 +00009015 return "cdlgbr";
9016}
9017
florian55085f82012-11-21 00:36:55 +00009018static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009019s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9020 UChar r1, UChar r2)
9021{
floriane75dafa2012-09-01 17:54:09 +00009022 if (! s390_host_has_fpext) {
9023 emulation_failure(EmFail_S390X_fpext);
9024 } else {
9025 IRTemp op = newTemp(Ity_F32);
9026 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009027 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009028
floriane75dafa2012-09-01 17:54:09 +00009029 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009030 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009031 mkexpr(op)));
9032 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009033 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009034 }
florian1c8f7ff2012-09-01 00:12:11 +00009035 return "clfebr";
9036}
9037
florian55085f82012-11-21 00:36:55 +00009038static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009039s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9040 UChar r1, UChar r2)
9041{
floriane75dafa2012-09-01 17:54:09 +00009042 if (! s390_host_has_fpext) {
9043 emulation_failure(EmFail_S390X_fpext);
9044 } else {
9045 IRTemp op = newTemp(Ity_F64);
9046 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009047 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009048
floriane75dafa2012-09-01 17:54:09 +00009049 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009050 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009051 mkexpr(op)));
9052 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009053 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009054 }
florian1c8f7ff2012-09-01 00:12:11 +00009055 return "clfdbr";
9056}
9057
florian55085f82012-11-21 00:36:55 +00009058static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009059s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9060 UChar r1, UChar r2)
9061{
floriane75dafa2012-09-01 17:54:09 +00009062 if (! s390_host_has_fpext) {
9063 emulation_failure(EmFail_S390X_fpext);
9064 } else {
9065 IRTemp op = newTemp(Ity_F32);
9066 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009067 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009068
floriane75dafa2012-09-01 17:54:09 +00009069 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009070 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009071 mkexpr(op)));
9072 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009073 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009074 }
florian1c8f7ff2012-09-01 00:12:11 +00009075 return "clgebr";
9076}
9077
florian55085f82012-11-21 00:36:55 +00009078static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009079s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9080 UChar r1, UChar r2)
9081{
floriane75dafa2012-09-01 17:54:09 +00009082 if (! s390_host_has_fpext) {
9083 emulation_failure(EmFail_S390X_fpext);
9084 } else {
9085 IRTemp op = newTemp(Ity_F64);
9086 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009087 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009088
floriane75dafa2012-09-01 17:54:09 +00009089 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009090 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009091 mkexpr(op)));
9092 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009093 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009094 }
florian1c8f7ff2012-09-01 00:12:11 +00009095 return "clgdbr";
9096}
9097
florian55085f82012-11-21 00:36:55 +00009098static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009099s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9100 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009101{
9102 IRTemp op = newTemp(Ity_F32);
9103 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009104 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009105
9106 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009107 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009108 mkexpr(op)));
9109 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009110 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009111
9112 return "cfebr";
9113}
9114
florian55085f82012-11-21 00:36:55 +00009115static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009116s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9117 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009118{
9119 IRTemp op = newTemp(Ity_F64);
9120 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009121 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009122
9123 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009124 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009125 mkexpr(op)));
9126 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009127 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009128
9129 return "cfdbr";
9130}
9131
florian55085f82012-11-21 00:36:55 +00009132static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009133s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9134 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009135{
9136 IRTemp op = newTemp(Ity_F32);
9137 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009138 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009139
9140 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009141 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009142 mkexpr(op)));
9143 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009144 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009145
9146 return "cgebr";
9147}
9148
florian55085f82012-11-21 00:36:55 +00009149static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009150s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9151 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009152{
9153 IRTemp op = newTemp(Ity_F64);
9154 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009155 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009156
9157 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009158 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009159 mkexpr(op)));
9160 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009161 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009162
9163 return "cgdbr";
9164}
9165
florian55085f82012-11-21 00:36:55 +00009166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009167s390_irgen_DEBR(UChar r1, UChar r2)
9168{
9169 IRTemp op1 = newTemp(Ity_F32);
9170 IRTemp op2 = newTemp(Ity_F32);
9171 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009172 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009173
9174 assign(op1, get_fpr_w0(r1));
9175 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009176 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009177 mkexpr(op2)));
9178 put_fpr_w0(r1, mkexpr(result));
9179
9180 return "debr";
9181}
9182
florian55085f82012-11-21 00:36:55 +00009183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009184s390_irgen_DDBR(UChar r1, UChar r2)
9185{
9186 IRTemp op1 = newTemp(Ity_F64);
9187 IRTemp op2 = newTemp(Ity_F64);
9188 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009189 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009190
9191 assign(op1, get_fpr_dw0(r1));
9192 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009193 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009194 mkexpr(op2)));
9195 put_fpr_dw0(r1, mkexpr(result));
9196
9197 return "ddbr";
9198}
9199
florian55085f82012-11-21 00:36:55 +00009200static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009201s390_irgen_DEB(UChar r1, IRTemp op2addr)
9202{
9203 IRTemp op1 = newTemp(Ity_F32);
9204 IRTemp op2 = newTemp(Ity_F32);
9205 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009206 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009207
9208 assign(op1, get_fpr_w0(r1));
9209 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009210 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009211 mkexpr(op2)));
9212 put_fpr_w0(r1, mkexpr(result));
9213
9214 return "deb";
9215}
9216
florian55085f82012-11-21 00:36:55 +00009217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009218s390_irgen_DDB(UChar r1, IRTemp op2addr)
9219{
9220 IRTemp op1 = newTemp(Ity_F64);
9221 IRTemp op2 = newTemp(Ity_F64);
9222 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009223 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009224
9225 assign(op1, get_fpr_dw0(r1));
9226 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009227 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009228 mkexpr(op2)));
9229 put_fpr_dw0(r1, mkexpr(result));
9230
9231 return "ddb";
9232}
9233
florian55085f82012-11-21 00:36:55 +00009234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009235s390_irgen_LTEBR(UChar r1, UChar r2)
9236{
9237 IRTemp result = newTemp(Ity_F32);
9238
9239 assign(result, get_fpr_w0(r2));
9240 put_fpr_w0(r1, mkexpr(result));
9241 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9242
9243 return "ltebr";
9244}
9245
florian55085f82012-11-21 00:36:55 +00009246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009247s390_irgen_LTDBR(UChar r1, UChar r2)
9248{
9249 IRTemp result = newTemp(Ity_F64);
9250
9251 assign(result, get_fpr_dw0(r2));
9252 put_fpr_dw0(r1, mkexpr(result));
9253 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9254
9255 return "ltdbr";
9256}
9257
florian55085f82012-11-21 00:36:55 +00009258static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009259s390_irgen_LCEBR(UChar r1, UChar r2)
9260{
9261 IRTemp result = newTemp(Ity_F32);
9262
9263 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9264 put_fpr_w0(r1, mkexpr(result));
9265 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9266
9267 return "lcebr";
9268}
9269
florian55085f82012-11-21 00:36:55 +00009270static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009271s390_irgen_LCDBR(UChar r1, UChar r2)
9272{
9273 IRTemp result = newTemp(Ity_F64);
9274
9275 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9276 put_fpr_dw0(r1, mkexpr(result));
9277 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9278
9279 return "lcdbr";
9280}
9281
florian55085f82012-11-21 00:36:55 +00009282static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009283s390_irgen_LDEBR(UChar r1, UChar r2)
9284{
9285 IRTemp op = newTemp(Ity_F32);
9286
9287 assign(op, get_fpr_w0(r2));
9288 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9289
9290 return "ldebr";
9291}
9292
florian55085f82012-11-21 00:36:55 +00009293static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009294s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9295{
9296 IRTemp op = newTemp(Ity_F32);
9297
9298 assign(op, load(Ity_F32, mkexpr(op2addr)));
9299 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9300
9301 return "ldeb";
9302}
9303
florian55085f82012-11-21 00:36:55 +00009304static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009305s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9306 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009307{
florian125e20d2012-10-07 15:42:37 +00009308 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009309 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009310 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009311 }
sewardj2019a972011-03-07 16:04:07 +00009312 IRTemp op = newTemp(Ity_F64);
9313
9314 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009315 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009316 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009317
9318 return "ledbr";
9319}
9320
florian55085f82012-11-21 00:36:55 +00009321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009322s390_irgen_MEEBR(UChar r1, UChar r2)
9323{
9324 IRTemp op1 = newTemp(Ity_F32);
9325 IRTemp op2 = newTemp(Ity_F32);
9326 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009327 IRRoundingMode rounding_mode =
9328 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009329
9330 assign(op1, get_fpr_w0(r1));
9331 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009332 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009333 mkexpr(op2)));
9334 put_fpr_w0(r1, mkexpr(result));
9335
9336 return "meebr";
9337}
9338
florian55085f82012-11-21 00:36:55 +00009339static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009340s390_irgen_MDBR(UChar r1, UChar r2)
9341{
9342 IRTemp op1 = newTemp(Ity_F64);
9343 IRTemp op2 = newTemp(Ity_F64);
9344 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009345 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009346
9347 assign(op1, get_fpr_dw0(r1));
9348 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009349 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009350 mkexpr(op2)));
9351 put_fpr_dw0(r1, mkexpr(result));
9352
9353 return "mdbr";
9354}
9355
florian55085f82012-11-21 00:36:55 +00009356static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009357s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9358{
9359 IRTemp op1 = newTemp(Ity_F32);
9360 IRTemp op2 = newTemp(Ity_F32);
9361 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009362 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009363
9364 assign(op1, get_fpr_w0(r1));
9365 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009366 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009367 mkexpr(op2)));
9368 put_fpr_w0(r1, mkexpr(result));
9369
9370 return "meeb";
9371}
9372
florian55085f82012-11-21 00:36:55 +00009373static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009374s390_irgen_MDB(UChar r1, IRTemp op2addr)
9375{
9376 IRTemp op1 = newTemp(Ity_F64);
9377 IRTemp op2 = newTemp(Ity_F64);
9378 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009379 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009380
9381 assign(op1, get_fpr_dw0(r1));
9382 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009383 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009384 mkexpr(op2)));
9385 put_fpr_dw0(r1, mkexpr(result));
9386
9387 return "mdb";
9388}
9389
florian55085f82012-11-21 00:36:55 +00009390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009391s390_irgen_SEBR(UChar r1, UChar r2)
9392{
9393 IRTemp op1 = newTemp(Ity_F32);
9394 IRTemp op2 = newTemp(Ity_F32);
9395 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009396 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009397
9398 assign(op1, get_fpr_w0(r1));
9399 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009400 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009401 mkexpr(op2)));
9402 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9403 put_fpr_w0(r1, mkexpr(result));
9404
9405 return "sebr";
9406}
9407
florian55085f82012-11-21 00:36:55 +00009408static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009409s390_irgen_SDBR(UChar r1, UChar r2)
9410{
9411 IRTemp op1 = newTemp(Ity_F64);
9412 IRTemp op2 = newTemp(Ity_F64);
9413 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009414 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009415
9416 assign(op1, get_fpr_dw0(r1));
9417 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009418 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009419 mkexpr(op2)));
9420 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9421 put_fpr_dw0(r1, mkexpr(result));
9422
9423 return "sdbr";
9424}
9425
florian55085f82012-11-21 00:36:55 +00009426static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009427s390_irgen_SEB(UChar r1, IRTemp op2addr)
9428{
9429 IRTemp op1 = newTemp(Ity_F32);
9430 IRTemp op2 = newTemp(Ity_F32);
9431 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009432 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009433
9434 assign(op1, get_fpr_w0(r1));
9435 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009436 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009437 mkexpr(op2)));
9438 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9439 put_fpr_w0(r1, mkexpr(result));
9440
9441 return "seb";
9442}
9443
florian55085f82012-11-21 00:36:55 +00009444static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009445s390_irgen_SDB(UChar r1, IRTemp op2addr)
9446{
9447 IRTemp op1 = newTemp(Ity_F64);
9448 IRTemp op2 = newTemp(Ity_F64);
9449 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009450 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009451
9452 assign(op1, get_fpr_dw0(r1));
9453 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009454 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009455 mkexpr(op2)));
9456 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9457 put_fpr_dw0(r1, mkexpr(result));
9458
9459 return "sdb";
9460}
9461
florian55085f82012-11-21 00:36:55 +00009462static const HChar *
florian12390202012-11-10 22:34:14 +00009463s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9464{
9465 IRTemp op1 = newTemp(Ity_D64);
9466 IRTemp op2 = newTemp(Ity_D64);
9467 IRTemp result = newTemp(Ity_D64);
9468 IRTemp rounding_mode;
9469
9470 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009471
9472 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9473 emulation_warning(EmWarn_S390X_fpext_rounding);
9474 m4 = S390_DFP_ROUND_PER_FPC_0;
9475 }
9476
florian12390202012-11-10 22:34:14 +00009477 rounding_mode = encode_dfp_rounding_mode(m4);
9478 assign(op1, get_dpr_dw0(r2));
9479 assign(op2, get_dpr_dw0(r3));
9480 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9481 mkexpr(op2)));
9482 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9483 put_dpr_dw0(r1, mkexpr(result));
9484
9485 return (m4 == 0) ? "adtr" : "adtra";
9486}
9487
florian55085f82012-11-21 00:36:55 +00009488static const HChar *
floriane38f6412012-12-21 17:32:12 +00009489s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9490{
9491 IRTemp op1 = newTemp(Ity_D128);
9492 IRTemp op2 = newTemp(Ity_D128);
9493 IRTemp result = newTemp(Ity_D128);
9494 IRTemp rounding_mode;
9495
9496 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009497
9498 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9499 emulation_warning(EmWarn_S390X_fpext_rounding);
9500 m4 = S390_DFP_ROUND_PER_FPC_0;
9501 }
9502
floriane38f6412012-12-21 17:32:12 +00009503 rounding_mode = encode_dfp_rounding_mode(m4);
9504 assign(op1, get_dpr_pair(r2));
9505 assign(op2, get_dpr_pair(r3));
9506 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9507 mkexpr(op2)));
9508 put_dpr_pair(r1, mkexpr(result));
9509
9510 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9511
9512 return (m4 == 0) ? "axtr" : "axtra";
9513}
9514
9515static const HChar *
9516s390_irgen_CDTR(UChar r1, UChar r2)
9517{
9518 IRTemp op1 = newTemp(Ity_D64);
9519 IRTemp op2 = newTemp(Ity_D64);
9520 IRTemp cc_vex = newTemp(Ity_I32);
9521 IRTemp cc_s390 = newTemp(Ity_I32);
9522
9523 assign(op1, get_dpr_dw0(r1));
9524 assign(op2, get_dpr_dw0(r2));
9525 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9526
florian2d3d87f2012-12-21 21:05:17 +00009527 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009528 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9529
9530 return "cdtr";
9531}
9532
9533static const HChar *
9534s390_irgen_CXTR(UChar r1, UChar r2)
9535{
9536 IRTemp op1 = newTemp(Ity_D128);
9537 IRTemp op2 = newTemp(Ity_D128);
9538 IRTemp cc_vex = newTemp(Ity_I32);
9539 IRTemp cc_s390 = newTemp(Ity_I32);
9540
9541 assign(op1, get_dpr_pair(r1));
9542 assign(op2, get_dpr_pair(r2));
9543 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9544
florian2d3d87f2012-12-21 21:05:17 +00009545 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009546 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9547
9548 return "cxtr";
9549}
9550
9551static const HChar *
florian5f034622013-01-13 02:29:05 +00009552s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9553 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9554{
9555 vassert(s390_host_has_dfp);
9556
9557 if (! s390_host_has_fpext) {
9558 emulation_failure(EmFail_S390X_fpext);
9559 } else {
9560 IRTemp op2 = newTemp(Ity_I32);
9561
9562 assign(op2, get_gpr_w1(r2));
9563 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9564 }
9565 return "cdftr";
9566}
9567
9568static const HChar *
9569s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9570 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9571{
9572 vassert(s390_host_has_dfp);
9573
9574 if (! s390_host_has_fpext) {
9575 emulation_failure(EmFail_S390X_fpext);
9576 } else {
9577 IRTemp op2 = newTemp(Ity_I32);
9578
9579 assign(op2, get_gpr_w1(r2));
9580 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9581 }
9582 return "cxftr";
9583}
9584
9585static const HChar *
floriana887acd2013-02-08 23:32:54 +00009586s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9587 UChar r1, UChar r2)
9588{
9589 IRTemp op2 = newTemp(Ity_I64);
9590
9591 vassert(s390_host_has_dfp);
9592 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9593 emulation_warning(EmWarn_S390X_fpext_rounding);
9594 m3 = S390_DFP_ROUND_PER_FPC_0;
9595 }
9596
9597 assign(op2, get_gpr_dw0(r2));
9598 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9599 mkexpr(op2)));
9600
9601 return (m3 == 0) ? "cdgtr" : "cdgtra";
9602}
9603
9604static const HChar *
9605s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9606 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9607{
9608 IRTemp op2 = newTemp(Ity_I64);
9609
9610 vassert(s390_host_has_dfp);
9611
florian1bb7f6f2013-02-11 00:03:27 +00009612 /* No emulation warning here about an non-zero m3 on hosts without
9613 floating point extension facility. No rounding is performed */
9614
floriana887acd2013-02-08 23:32:54 +00009615 assign(op2, get_gpr_dw0(r2));
9616 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9617
9618 return "cxgtr";
9619}
9620
9621static const HChar *
florian5f034622013-01-13 02:29:05 +00009622s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9623 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9624{
9625 vassert(s390_host_has_dfp);
9626
9627 if (! s390_host_has_fpext) {
9628 emulation_failure(EmFail_S390X_fpext);
9629 } else {
9630 IRTemp op2 = newTemp(Ity_I32);
9631
9632 assign(op2, get_gpr_w1(r2));
9633 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9634 }
9635 return "cdlftr";
9636}
9637
9638static const HChar *
9639s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9640 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9641{
9642 vassert(s390_host_has_dfp);
9643
9644 if (! s390_host_has_fpext) {
9645 emulation_failure(EmFail_S390X_fpext);
9646 } else {
9647 IRTemp op2 = newTemp(Ity_I32);
9648
9649 assign(op2, get_gpr_w1(r2));
9650 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9651 }
9652 return "cxlftr";
9653}
9654
9655static const HChar *
9656s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9657 UChar r1, UChar r2)
9658{
9659 vassert(s390_host_has_dfp);
9660
9661 if (! s390_host_has_fpext) {
9662 emulation_failure(EmFail_S390X_fpext);
9663 } else {
9664 IRTemp op2 = newTemp(Ity_I64);
9665
9666 assign(op2, get_gpr_dw0(r2));
9667 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9668 mkexpr(encode_dfp_rounding_mode(m3)),
9669 mkexpr(op2)));
9670 }
9671 return "cdlgtr";
9672}
9673
9674static const HChar *
9675s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9676 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9677{
9678 vassert(s390_host_has_dfp);
9679
9680 if (! s390_host_has_fpext) {
9681 emulation_failure(EmFail_S390X_fpext);
9682 } else {
9683 IRTemp op2 = newTemp(Ity_I64);
9684
9685 assign(op2, get_gpr_dw0(r2));
9686 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9687 }
9688 return "cxlgtr";
9689}
9690
9691static const HChar *
9692s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9693 UChar r1, UChar r2)
9694{
9695 vassert(s390_host_has_dfp);
9696
9697 if (! s390_host_has_fpext) {
9698 emulation_failure(EmFail_S390X_fpext);
9699 } else {
9700 IRTemp op = newTemp(Ity_D64);
9701 IRTemp result = newTemp(Ity_I32);
9702 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9703
9704 assign(op, get_dpr_dw0(r2));
9705 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9706 mkexpr(op)));
9707 put_gpr_w1(r1, mkexpr(result));
9708 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9709 }
9710 return "cfdtr";
9711}
9712
9713static const HChar *
9714s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9715 UChar r1, UChar r2)
9716{
9717 vassert(s390_host_has_dfp);
9718
9719 if (! s390_host_has_fpext) {
9720 emulation_failure(EmFail_S390X_fpext);
9721 } else {
9722 IRTemp op = newTemp(Ity_D128);
9723 IRTemp result = newTemp(Ity_I32);
9724 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9725
9726 assign(op, get_dpr_pair(r2));
9727 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9728 mkexpr(op)));
9729 put_gpr_w1(r1, mkexpr(result));
9730 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9731 }
9732 return "cfxtr";
9733}
9734
9735static const HChar *
floriana887acd2013-02-08 23:32:54 +00009736s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9737 UChar r1, UChar r2)
9738{
9739 IRTemp op = newTemp(Ity_D64);
9740 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9741
9742 vassert(s390_host_has_dfp);
9743
9744 /* If fpext is not installed and m3 is in 1:7,
9745 rounding mode performed is unpredictable */
9746 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9747 emulation_warning(EmWarn_S390X_fpext_rounding);
9748 m3 = S390_DFP_ROUND_PER_FPC_0;
9749 }
9750
9751 assign(op, get_dpr_dw0(r2));
9752 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9753 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9754
9755 return "cgdtr";
9756}
9757
9758static const HChar *
9759s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9760 UChar r1, UChar r2)
9761{
9762 IRTemp op = newTemp(Ity_D128);
9763 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9764
9765 vassert(s390_host_has_dfp);
9766
9767 /* If fpext is not installed and m3 is in 1:7,
9768 rounding mode performed is unpredictable */
9769 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9770 emulation_warning(EmWarn_S390X_fpext_rounding);
9771 m3 = S390_DFP_ROUND_PER_FPC_0;
9772 }
9773 assign(op, get_dpr_pair(r2));
9774 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9775 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9776
9777 return "cgxtr";
9778}
9779
9780static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009781s390_irgen_CEDTR(UChar r1, UChar r2)
9782{
9783 IRTemp op1 = newTemp(Ity_D64);
9784 IRTemp op2 = newTemp(Ity_D64);
9785 IRTemp cc_vex = newTemp(Ity_I32);
9786 IRTemp cc_s390 = newTemp(Ity_I32);
9787
9788 vassert(s390_host_has_dfp);
9789 assign(op1, get_dpr_dw0(r1));
9790 assign(op2, get_dpr_dw0(r2));
9791 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9792
9793 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9794 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9795
9796 return "cedtr";
9797}
9798
9799static const HChar *
9800s390_irgen_CEXTR(UChar r1, UChar r2)
9801{
9802 IRTemp op1 = newTemp(Ity_D128);
9803 IRTemp op2 = newTemp(Ity_D128);
9804 IRTemp cc_vex = newTemp(Ity_I32);
9805 IRTemp cc_s390 = newTemp(Ity_I32);
9806
9807 vassert(s390_host_has_dfp);
9808 assign(op1, get_dpr_pair(r1));
9809 assign(op2, get_dpr_pair(r2));
9810 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9811
9812 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9813 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9814
9815 return "cextr";
9816}
9817
9818static const HChar *
florian5f034622013-01-13 02:29:05 +00009819s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9820 UChar r1, UChar r2)
9821{
9822 vassert(s390_host_has_dfp);
9823
9824 if (! s390_host_has_fpext) {
9825 emulation_failure(EmFail_S390X_fpext);
9826 } else {
9827 IRTemp op = newTemp(Ity_D64);
9828 IRTemp result = newTemp(Ity_I32);
9829 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9830
9831 assign(op, get_dpr_dw0(r2));
9832 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9833 mkexpr(op)));
9834 put_gpr_w1(r1, mkexpr(result));
9835 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9836 }
9837 return "clfdtr";
9838}
9839
9840static const HChar *
9841s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9842 UChar r1, UChar r2)
9843{
9844 vassert(s390_host_has_dfp);
9845
9846 if (! s390_host_has_fpext) {
9847 emulation_failure(EmFail_S390X_fpext);
9848 } else {
9849 IRTemp op = newTemp(Ity_D128);
9850 IRTemp result = newTemp(Ity_I32);
9851 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9852
9853 assign(op, get_dpr_pair(r2));
9854 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9855 mkexpr(op)));
9856 put_gpr_w1(r1, mkexpr(result));
9857 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9858 }
9859 return "clfxtr";
9860}
9861
9862static const HChar *
9863s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9864 UChar r1, UChar r2)
9865{
9866 vassert(s390_host_has_dfp);
9867
9868 if (! s390_host_has_fpext) {
9869 emulation_failure(EmFail_S390X_fpext);
9870 } else {
9871 IRTemp op = newTemp(Ity_D64);
9872 IRTemp result = newTemp(Ity_I64);
9873 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9874
9875 assign(op, get_dpr_dw0(r2));
9876 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
9877 mkexpr(op)));
9878 put_gpr_dw0(r1, mkexpr(result));
9879 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
9880 }
9881 return "clgdtr";
9882}
9883
9884static const HChar *
9885s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
9886 UChar r1, UChar r2)
9887{
9888 vassert(s390_host_has_dfp);
9889
9890 if (! s390_host_has_fpext) {
9891 emulation_failure(EmFail_S390X_fpext);
9892 } else {
9893 IRTemp op = newTemp(Ity_D128);
9894 IRTemp result = newTemp(Ity_I64);
9895 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9896
9897 assign(op, get_dpr_pair(r2));
9898 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
9899 mkexpr(op)));
9900 put_gpr_dw0(r1, mkexpr(result));
9901 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
9902 rounding_mode);
9903 }
9904 return "clgxtr";
9905}
9906
9907static const HChar *
florian12390202012-11-10 22:34:14 +00009908s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9909{
9910 IRTemp op1 = newTemp(Ity_D64);
9911 IRTemp op2 = newTemp(Ity_D64);
9912 IRTemp result = newTemp(Ity_D64);
9913 IRTemp rounding_mode;
9914
9915 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009916
9917 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9918 emulation_warning(EmWarn_S390X_fpext_rounding);
9919 m4 = S390_DFP_ROUND_PER_FPC_0;
9920 }
9921
florian12390202012-11-10 22:34:14 +00009922 rounding_mode = encode_dfp_rounding_mode(m4);
9923 assign(op1, get_dpr_dw0(r2));
9924 assign(op2, get_dpr_dw0(r3));
9925 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9926 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009927 put_dpr_dw0(r1, mkexpr(result));
9928
9929 return (m4 == 0) ? "ddtr" : "ddtra";
9930}
9931
florian55085f82012-11-21 00:36:55 +00009932static const HChar *
floriane38f6412012-12-21 17:32:12 +00009933s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9934{
9935 IRTemp op1 = newTemp(Ity_D128);
9936 IRTemp op2 = newTemp(Ity_D128);
9937 IRTemp result = newTemp(Ity_D128);
9938 IRTemp rounding_mode;
9939
9940 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009941
9942 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9943 emulation_warning(EmWarn_S390X_fpext_rounding);
9944 m4 = S390_DFP_ROUND_PER_FPC_0;
9945 }
9946
floriane38f6412012-12-21 17:32:12 +00009947 rounding_mode = encode_dfp_rounding_mode(m4);
9948 assign(op1, get_dpr_pair(r2));
9949 assign(op2, get_dpr_pair(r3));
9950 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9951 mkexpr(op2)));
9952 put_dpr_pair(r1, mkexpr(result));
9953
9954 return (m4 == 0) ? "dxtr" : "dxtra";
9955}
9956
9957static const HChar *
florian5c539732013-02-14 14:27:12 +00009958s390_irgen_EEDTR(UChar r1, UChar r2)
9959{
9960 vassert(s390_host_has_dfp);
9961
9962 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
9963 return "eedtr";
9964}
9965
9966static const HChar *
9967s390_irgen_EEXTR(UChar r1, UChar r2)
9968{
9969 vassert(s390_host_has_dfp);
9970
9971 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
9972 return "eextr";
9973}
9974
9975static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009976s390_irgen_ESDTR(UChar r1, UChar r2)
9977{
9978 vassert(s390_host_has_dfp);
9979 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
9980 return "esdtr";
9981}
9982
9983static const HChar *
9984s390_irgen_ESXTR(UChar r1, UChar r2)
9985{
9986 vassert(s390_host_has_dfp);
9987 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
9988 return "esxtr";
9989}
9990
9991static const HChar *
florian5c539732013-02-14 14:27:12 +00009992s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
9993{
9994 IRTemp op1 = newTemp(Ity_I64);
9995 IRTemp op2 = newTemp(Ity_D64);
9996 IRTemp result = newTemp(Ity_D64);
9997
9998 vassert(s390_host_has_dfp);
9999
10000 assign(op1, get_gpr_dw0(r2));
10001 assign(op2, get_dpr_dw0(r3));
10002 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10003 put_dpr_dw0(r1, mkexpr(result));
10004
10005 return "iedtr";
10006}
10007
10008static const HChar *
10009s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10010{
10011 IRTemp op1 = newTemp(Ity_I64);
10012 IRTemp op2 = newTemp(Ity_D128);
10013 IRTemp result = newTemp(Ity_D128);
10014
10015 vassert(s390_host_has_dfp);
10016
10017 assign(op1, get_gpr_dw0(r2));
10018 assign(op2, get_dpr_pair(r3));
10019 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10020 put_dpr_pair(r1, mkexpr(result));
10021
10022 return "iextr";
10023}
10024
10025static const HChar *
floriane38f6412012-12-21 17:32:12 +000010026s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10027{
10028 IRTemp op = newTemp(Ity_D32);
10029
10030 vassert(s390_host_has_dfp);
10031
10032 assign(op, get_dpr_w0(r2));
10033 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10034
10035 return "ldetr";
10036}
10037
10038static const HChar *
10039s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10040{
10041 IRTemp op = newTemp(Ity_D64);
10042
10043 assign(op, get_dpr_dw0(r2));
10044 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10045
10046 return "lxdtr";
10047}
10048
10049static const HChar *
10050s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10051 UChar r1, UChar r2)
10052{
10053 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010054
10055 /* If fpext is not installed and m3 is in 1:7,
10056 rounding mode performed is unpredictable */
10057 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010058 emulation_warning(EmWarn_S390X_fpext_rounding);
10059 m3 = S390_DFP_ROUND_PER_FPC_0;
10060 }
10061 IRTemp result = newTemp(Ity_D64);
10062
10063 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10064 get_dpr_pair(r2)));
10065 put_dpr_dw0(r1, mkexpr(result));
10066
10067 return "ldxtr";
10068}
10069
10070static const HChar *
10071s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10072 UChar r1, UChar r2)
10073{
10074 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010075
10076 /* If fpext is not installed and m3 is in 1:7,
10077 rounding mode performed is unpredictable */
10078 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010079 emulation_warning(EmWarn_S390X_fpext_rounding);
10080 m3 = S390_DFP_ROUND_PER_FPC_0;
10081 }
10082 IRTemp op = newTemp(Ity_D64);
10083
10084 assign(op, get_dpr_dw0(r2));
10085 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10086 mkexpr(op)));
10087
10088 return "ledtr";
10089}
10090
10091static const HChar *
10092s390_irgen_LTDTR(UChar r1, UChar r2)
10093{
10094 IRTemp result = newTemp(Ity_D64);
10095
10096 assign(result, get_dpr_dw0(r2));
10097 put_dpr_dw0(r1, mkexpr(result));
10098 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10099
10100 return "ltdtr";
10101}
10102
10103static const HChar *
10104s390_irgen_LTXTR(UChar r1, UChar r2)
10105{
10106 IRTemp result = newTemp(Ity_D128);
10107
10108 assign(result, get_dpr_pair(r2));
10109 put_dpr_pair(r1, mkexpr(result));
10110 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10111
10112 return "ltxtr";
10113}
10114
10115static const HChar *
florian12390202012-11-10 22:34:14 +000010116s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10117{
10118 IRTemp op1 = newTemp(Ity_D64);
10119 IRTemp op2 = newTemp(Ity_D64);
10120 IRTemp result = newTemp(Ity_D64);
10121 IRTemp rounding_mode;
10122
10123 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010124
10125 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10126 emulation_warning(EmWarn_S390X_fpext_rounding);
10127 m4 = S390_DFP_ROUND_PER_FPC_0;
10128 }
10129
florian12390202012-11-10 22:34:14 +000010130 rounding_mode = encode_dfp_rounding_mode(m4);
10131 assign(op1, get_dpr_dw0(r2));
10132 assign(op2, get_dpr_dw0(r3));
10133 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10134 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010135 put_dpr_dw0(r1, mkexpr(result));
10136
10137 return (m4 == 0) ? "mdtr" : "mdtra";
10138}
10139
florian55085f82012-11-21 00:36:55 +000010140static const HChar *
floriane38f6412012-12-21 17:32:12 +000010141s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10142{
10143 IRTemp op1 = newTemp(Ity_D128);
10144 IRTemp op2 = newTemp(Ity_D128);
10145 IRTemp result = newTemp(Ity_D128);
10146 IRTemp rounding_mode;
10147
10148 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010149
10150 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10151 emulation_warning(EmWarn_S390X_fpext_rounding);
10152 m4 = S390_DFP_ROUND_PER_FPC_0;
10153 }
10154
floriane38f6412012-12-21 17:32:12 +000010155 rounding_mode = encode_dfp_rounding_mode(m4);
10156 assign(op1, get_dpr_pair(r2));
10157 assign(op2, get_dpr_pair(r3));
10158 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10159 mkexpr(op2)));
10160 put_dpr_pair(r1, mkexpr(result));
10161
10162 return (m4 == 0) ? "mxtr" : "mxtra";
10163}
10164
10165static const HChar *
florian5c539732013-02-14 14:27:12 +000010166s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10167{
10168 IRTemp op1 = newTemp(Ity_D64);
10169 IRTemp op2 = newTemp(Ity_D64);
10170 IRTemp result = newTemp(Ity_D64);
10171 IRTemp rounding_mode;
10172
10173 vassert(s390_host_has_dfp);
10174 /* If fpext is not installed and m4 is in 1:7,
10175 rounding mode performed is unpredictable */
10176 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10177 emulation_warning(EmWarn_S390X_fpext_rounding);
10178 m4 = S390_DFP_ROUND_PER_FPC_0;
10179 }
10180
10181 rounding_mode = encode_dfp_rounding_mode(m4);
10182 assign(op1, get_dpr_dw0(r2));
10183 assign(op2, get_dpr_dw0(r3));
10184 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10185 mkexpr(op2)));
10186 put_dpr_dw0(r1, mkexpr(result));
10187
10188 return "qadtr";
10189}
10190
10191static const HChar *
10192s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10193{
10194 IRTemp op1 = newTemp(Ity_D128);
10195 IRTemp op2 = newTemp(Ity_D128);
10196 IRTemp result = newTemp(Ity_D128);
10197 IRTemp rounding_mode;
10198
10199 vassert(s390_host_has_dfp);
10200 /* If fpext is not installed and m4 is in 1:7,
10201 rounding mode performed is unpredictable */
10202 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10203 emulation_warning(EmWarn_S390X_fpext_rounding);
10204 m4 = S390_DFP_ROUND_PER_FPC_0;
10205 }
10206
10207 rounding_mode = encode_dfp_rounding_mode(m4);
10208 assign(op1, get_dpr_pair(r2));
10209 assign(op2, get_dpr_pair(r3));
10210 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10211 mkexpr(op2)));
10212 put_dpr_pair(r1, mkexpr(result));
10213
10214 return "qaxtr";
10215}
10216
10217static const HChar *
10218s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10219{
10220 IRTemp op1 = newTemp(Ity_I8);
10221 IRTemp op2 = newTemp(Ity_D64);
10222 IRTemp result = newTemp(Ity_D64);
10223 IRTemp rounding_mode;
10224
10225 vassert(s390_host_has_dfp);
10226 /* If fpext is not installed and m4 is in 1:7,
10227 rounding mode performed is unpredictable */
10228 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10229 emulation_warning(EmWarn_S390X_fpext_rounding);
10230 m4 = S390_DFP_ROUND_PER_FPC_0;
10231 }
10232
10233 rounding_mode = encode_dfp_rounding_mode(m4);
10234 assign(op1, get_gpr_b7(r2));
10235 assign(op2, get_dpr_dw0(r3));
10236 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10237 mkexpr(op1), mkexpr(op2)));
10238 put_dpr_dw0(r1, mkexpr(result));
10239
10240 return "rrdtr";
10241}
10242
10243static const HChar *
10244s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10245{
10246 IRTemp op1 = newTemp(Ity_I8);
10247 IRTemp op2 = newTemp(Ity_D128);
10248 IRTemp result = newTemp(Ity_D128);
10249 IRTemp rounding_mode;
10250
10251 vassert(s390_host_has_dfp);
10252 /* If fpext is not installed and m4 is in 1:7,
10253 rounding mode performed is unpredictable */
10254 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10255 emulation_warning(EmWarn_S390X_fpext_rounding);
10256 m4 = S390_DFP_ROUND_PER_FPC_0;
10257 }
10258
10259 rounding_mode = encode_dfp_rounding_mode(m4);
10260 assign(op1, get_gpr_b7(r2));
10261 assign(op2, get_dpr_pair(r3));
10262 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10263 mkexpr(op1), mkexpr(op2)));
10264 put_dpr_pair(r1, mkexpr(result));
10265
10266 return "rrxtr";
10267}
10268
10269static const HChar *
florian12390202012-11-10 22:34:14 +000010270s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10271{
10272 IRTemp op1 = newTemp(Ity_D64);
10273 IRTemp op2 = newTemp(Ity_D64);
10274 IRTemp result = newTemp(Ity_D64);
10275 IRTemp rounding_mode;
10276
10277 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010278
10279 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10280 emulation_warning(EmWarn_S390X_fpext_rounding);
10281 m4 = S390_DFP_ROUND_PER_FPC_0;
10282 }
10283
florian12390202012-11-10 22:34:14 +000010284 rounding_mode = encode_dfp_rounding_mode(m4);
10285 assign(op1, get_dpr_dw0(r2));
10286 assign(op2, get_dpr_dw0(r3));
10287 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10288 mkexpr(op2)));
10289 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10290 put_dpr_dw0(r1, mkexpr(result));
10291
10292 return (m4 == 0) ? "sdtr" : "sdtra";
10293}
10294
floriane38f6412012-12-21 17:32:12 +000010295static const HChar *
10296s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10297{
10298 IRTemp op1 = newTemp(Ity_D128);
10299 IRTemp op2 = newTemp(Ity_D128);
10300 IRTemp result = newTemp(Ity_D128);
10301 IRTemp rounding_mode;
10302
10303 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010304
10305 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10306 emulation_warning(EmWarn_S390X_fpext_rounding);
10307 m4 = S390_DFP_ROUND_PER_FPC_0;
10308 }
10309
floriane38f6412012-12-21 17:32:12 +000010310 rounding_mode = encode_dfp_rounding_mode(m4);
10311 assign(op1, get_dpr_pair(r2));
10312 assign(op2, get_dpr_pair(r3));
10313 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10314 mkexpr(op2)));
10315 put_dpr_pair(r1, mkexpr(result));
10316
10317 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10318
10319 return (m4 == 0) ? "sxtr" : "sxtra";
10320}
sewardj2019a972011-03-07 16:04:07 +000010321
florian55085f82012-11-21 00:36:55 +000010322static const HChar *
florian1b901d42013-01-01 22:19:24 +000010323s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10324{
10325 IRTemp op = newTemp(Ity_D64);
10326
10327 vassert(s390_host_has_dfp);
10328
10329 assign(op, get_dpr_dw0(r3));
10330 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
10331 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10332
10333 return "sldt";
10334}
10335
10336static const HChar *
10337s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10338{
10339 IRTemp op = newTemp(Ity_D128);
10340
10341 vassert(s390_host_has_dfp);
10342
10343 assign(op, get_dpr_pair(r3));
10344 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
10345 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10346
10347 return "slxt";
10348}
10349
10350static const HChar *
10351s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10352{
10353 IRTemp op = newTemp(Ity_D64);
10354
10355 vassert(s390_host_has_dfp);
10356
10357 assign(op, get_dpr_dw0(r3));
10358 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
10359 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10360
10361 return "srdt";
10362}
10363
10364static const HChar *
10365s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10366{
10367 IRTemp op = newTemp(Ity_D128);
10368
10369 vassert(s390_host_has_dfp);
10370
10371 assign(op, get_dpr_pair(r3));
10372 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
10373 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10374
10375 return "srxt";
10376}
10377
10378static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010379s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10380{
10381 IRTemp value = newTemp(Ity_D32);
10382
10383 vassert(s390_host_has_dfp);
10384 assign(value, get_dpr_w0(r1));
10385
10386 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10387
10388 return "tdcet";
10389}
10390
10391static const HChar *
10392s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10393{
10394 IRTemp value = newTemp(Ity_D64);
10395
10396 vassert(s390_host_has_dfp);
10397 assign(value, get_dpr_dw0(r1));
10398
10399 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10400
10401 return "tdcdt";
10402}
10403
10404static const HChar *
10405s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10406{
10407 IRTemp value = newTemp(Ity_D128);
10408
10409 vassert(s390_host_has_dfp);
10410 assign(value, get_dpr_pair(r1));
10411
10412 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10413
10414 return "tdcxt";
10415}
10416
10417static const HChar *
10418s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10419{
10420 IRTemp value = newTemp(Ity_D32);
10421
10422 vassert(s390_host_has_dfp);
10423 assign(value, get_dpr_w0(r1));
10424
10425 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10426
10427 return "tdget";
10428}
10429
10430static const HChar *
10431s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10432{
10433 IRTemp value = newTemp(Ity_D64);
10434
10435 vassert(s390_host_has_dfp);
10436 assign(value, get_dpr_dw0(r1));
10437
10438 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10439
10440 return "tdgdt";
10441}
10442
10443static const HChar *
10444s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10445{
10446 IRTemp value = newTemp(Ity_D128);
10447
10448 vassert(s390_host_has_dfp);
10449 assign(value, get_dpr_pair(r1));
10450
10451 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10452
10453 return "tdgxt";
10454}
10455
10456static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010457s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10458{
florian79e839e2012-05-05 02:20:30 +000010459 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010460
florian79e839e2012-05-05 02:20:30 +000010461 assign(len, mkU64(length));
10462 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010463
10464 return "clc";
10465}
10466
florian55085f82012-11-21 00:36:55 +000010467static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010468s390_irgen_CLCL(UChar r1, UChar r2)
10469{
10470 IRTemp addr1 = newTemp(Ity_I64);
10471 IRTemp addr2 = newTemp(Ity_I64);
10472 IRTemp addr1_load = newTemp(Ity_I64);
10473 IRTemp addr2_load = newTemp(Ity_I64);
10474 IRTemp len1 = newTemp(Ity_I32);
10475 IRTemp len2 = newTemp(Ity_I32);
10476 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10477 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10478 IRTemp single1 = newTemp(Ity_I8);
10479 IRTemp single2 = newTemp(Ity_I8);
10480 IRTemp pad = newTemp(Ity_I8);
10481
10482 assign(addr1, get_gpr_dw0(r1));
10483 assign(r1p1, get_gpr_w1(r1 + 1));
10484 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10485 assign(addr2, get_gpr_dw0(r2));
10486 assign(r2p1, get_gpr_w1(r2 + 1));
10487 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10488 assign(pad, get_gpr_b4(r2 + 1));
10489
10490 /* len1 == 0 and len2 == 0? Exit */
10491 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010492 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10493 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010494
10495 /* Because mkite evaluates both the then-clause and the else-clause
10496 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10497 may be NULL and loading from there would segfault. So we provide a
10498 valid dummy address in that case. Loading from there does no harm and
10499 the value will be discarded at runtime. */
10500 assign(addr1_load,
10501 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10502 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10503 assign(single1,
10504 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10505 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10506
10507 assign(addr2_load,
10508 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10509 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10510 assign(single2,
10511 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10512 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10513
10514 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10515 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010516 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010517
10518 /* Update len1 and addr1, unless len1 == 0. */
10519 put_gpr_dw0(r1,
10520 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10521 mkexpr(addr1),
10522 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10523
10524 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10525 put_gpr_w1(r1 + 1,
10526 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10527 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10528 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10529
10530 /* Update len2 and addr2, unless len2 == 0. */
10531 put_gpr_dw0(r2,
10532 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10533 mkexpr(addr2),
10534 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10535
10536 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10537 put_gpr_w1(r2 + 1,
10538 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10539 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10540 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10541
florian6820ba52012-07-26 02:01:50 +000010542 iterate();
florianb0c9a132011-09-08 15:37:39 +000010543
10544 return "clcl";
10545}
10546
florian55085f82012-11-21 00:36:55 +000010547static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010548s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10549{
10550 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10551
10552 addr1 = newTemp(Ity_I64);
10553 addr3 = newTemp(Ity_I64);
10554 addr1_load = newTemp(Ity_I64);
10555 addr3_load = newTemp(Ity_I64);
10556 len1 = newTemp(Ity_I64);
10557 len3 = newTemp(Ity_I64);
10558 single1 = newTemp(Ity_I8);
10559 single3 = newTemp(Ity_I8);
10560
10561 assign(addr1, get_gpr_dw0(r1));
10562 assign(len1, get_gpr_dw0(r1 + 1));
10563 assign(addr3, get_gpr_dw0(r3));
10564 assign(len3, get_gpr_dw0(r3 + 1));
10565
10566 /* len1 == 0 and len3 == 0? Exit */
10567 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010568 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10569 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010570
10571 /* A mux requires both ways to be possible. This is a way to prevent clcle
10572 from reading from addr1 if it should read from the pad. Since the pad
10573 has no address, just read from the instruction, we discard that anyway */
10574 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010575 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10576 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010577
10578 /* same for addr3 */
10579 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010580 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10581 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010582
10583 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010584 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10585 unop(Iop_64to8, mkexpr(pad2)),
10586 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010587
10588 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010589 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10590 unop(Iop_64to8, mkexpr(pad2)),
10591 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010592
10593 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10594 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010595 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010596
10597 /* If a length in 0 we must not change this length and the address */
10598 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010599 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10600 mkexpr(addr1),
10601 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010602
10603 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010604 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10605 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010606
10607 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010608 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10609 mkexpr(addr3),
10610 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010611
10612 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010613 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10614 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010615
florian6820ba52012-07-26 02:01:50 +000010616 iterate();
sewardj2019a972011-03-07 16:04:07 +000010617
10618 return "clcle";
10619}
floriana64c2432011-07-16 02:11:50 +000010620
florianb0bf6602012-05-05 00:01:16 +000010621
sewardj2019a972011-03-07 16:04:07 +000010622static void
10623s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10624{
florianb0bf6602012-05-05 00:01:16 +000010625 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10626}
sewardj2019a972011-03-07 16:04:07 +000010627
sewardj2019a972011-03-07 16:04:07 +000010628
florianb0bf6602012-05-05 00:01:16 +000010629static void
10630s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10631{
10632 s390_irgen_xonc(Iop_And8, length, start1, start2);
10633}
sewardj2019a972011-03-07 16:04:07 +000010634
sewardj2019a972011-03-07 16:04:07 +000010635
florianb0bf6602012-05-05 00:01:16 +000010636static void
10637s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10638{
10639 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010640}
10641
10642
10643static void
10644s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10645{
10646 IRTemp current1 = newTemp(Ity_I8);
10647 IRTemp current2 = newTemp(Ity_I8);
10648 IRTemp counter = newTemp(Ity_I64);
10649
10650 assign(counter, get_counter_dw0());
10651 put_counter_dw0(mkU64(0));
10652
10653 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10654 mkexpr(counter))));
10655 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10656 mkexpr(counter))));
10657 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10658 False);
10659
10660 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010661 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010662
10663 /* Check for end of field */
10664 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010665 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010666 put_counter_dw0(mkU64(0));
10667}
10668
10669static void
10670s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10671{
10672 IRTemp counter = newTemp(Ity_I64);
10673
10674 assign(counter, get_counter_dw0());
10675
10676 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10677 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10678
10679 /* Check for end of field */
10680 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010681 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010682 put_counter_dw0(mkU64(0));
10683}
10684
florianf87d4fb2012-05-05 02:55:24 +000010685static void
10686s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10687{
10688 IRTemp op = newTemp(Ity_I8);
10689 IRTemp op1 = newTemp(Ity_I8);
10690 IRTemp result = newTemp(Ity_I64);
10691 IRTemp counter = newTemp(Ity_I64);
10692
10693 assign(counter, get_counter_dw0());
10694
10695 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10696
10697 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10698
10699 assign(op1, load(Ity_I8, mkexpr(result)));
10700 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10701
10702 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010703 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010704 put_counter_dw0(mkU64(0));
10705}
sewardj2019a972011-03-07 16:04:07 +000010706
10707
10708static void
10709s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010710 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010711 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010712{
10713 struct SS {
10714 unsigned int op : 8;
10715 unsigned int l : 8;
10716 unsigned int b1 : 4;
10717 unsigned int d1 : 12;
10718 unsigned int b2 : 4;
10719 unsigned int d2 : 12;
10720 };
10721 union {
10722 struct SS dec;
10723 unsigned long bytes;
10724 } ss;
10725 IRTemp cond;
10726 IRDirty *d;
10727 IRTemp torun;
10728
10729 IRTemp start1 = newTemp(Ity_I64);
10730 IRTemp start2 = newTemp(Ity_I64);
10731 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10732 cond = newTemp(Ity_I1);
10733 torun = newTemp(Ity_I64);
10734
10735 assign(torun, load(Ity_I64, mkexpr(addr2)));
10736 /* Start with a check that the saved code is still correct */
10737 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10738 /* If not, save the new value */
10739 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10740 mkIRExprVec_1(mkexpr(torun)));
10741 d->guard = mkexpr(cond);
10742 stmt(IRStmt_Dirty(d));
10743
10744 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010745 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10746 mkU64(guest_IA_curr_instr)));
10747 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010748 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010749
10750 ss.bytes = last_execute_target;
10751 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10752 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10753 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10754 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10755 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10756 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10757 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010758
sewardj2019a972011-03-07 16:04:07 +000010759 last_execute_target = 0;
10760}
10761
florian55085f82012-11-21 00:36:55 +000010762static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010763s390_irgen_EX(UChar r1, IRTemp addr2)
10764{
10765 switch(last_execute_target & 0xff00000000000000ULL) {
10766 case 0:
10767 {
10768 /* no code information yet */
10769 IRDirty *d;
10770
10771 /* so safe the code... */
10772 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10773 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10774 stmt(IRStmt_Dirty(d));
10775 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010776 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10777 mkU64(guest_IA_curr_instr)));
10778 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010779 restart_if(IRExpr_Const(IRConst_U1(True)));
10780
sewardj2019a972011-03-07 16:04:07 +000010781 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010782 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010783 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000010784 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000010785 break;
10786 }
10787
10788 case 0xd200000000000000ULL:
10789 /* special case MVC */
10790 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010791 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010792
10793 case 0xd500000000000000ULL:
10794 /* special case CLC */
10795 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010796 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010797
10798 case 0xd700000000000000ULL:
10799 /* special case XC */
10800 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010801 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010802
florianb0bf6602012-05-05 00:01:16 +000010803 case 0xd600000000000000ULL:
10804 /* special case OC */
10805 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010806 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010807
10808 case 0xd400000000000000ULL:
10809 /* special case NC */
10810 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010811 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010812
florianf87d4fb2012-05-05 02:55:24 +000010813 case 0xdc00000000000000ULL:
10814 /* special case TR */
10815 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010816 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010817
sewardj2019a972011-03-07 16:04:07 +000010818 default:
10819 {
10820 /* everything else will get a self checking prefix that also checks the
10821 register content */
10822 IRDirty *d;
10823 UChar *bytes;
10824 IRTemp cond;
10825 IRTemp orperand;
10826 IRTemp torun;
10827
10828 cond = newTemp(Ity_I1);
10829 orperand = newTemp(Ity_I64);
10830 torun = newTemp(Ity_I64);
10831
10832 if (r1 == 0)
10833 assign(orperand, mkU64(0));
10834 else
10835 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10836 /* This code is going to be translated */
10837 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10838 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10839
10840 /* Start with a check that saved code is still correct */
10841 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10842 mkU64(last_execute_target)));
10843 /* If not, save the new value */
10844 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10845 mkIRExprVec_1(mkexpr(torun)));
10846 d->guard = mkexpr(cond);
10847 stmt(IRStmt_Dirty(d));
10848
10849 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010850 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10851 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010852 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010853
10854 /* Now comes the actual translation */
10855 bytes = (UChar *) &last_execute_target;
10856 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10857 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010858 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010859 vex_printf(" which was executed by\n");
10860 /* dont make useless translations in the next execute */
10861 last_execute_target = 0;
10862 }
10863 }
10864 return "ex";
10865}
10866
florian55085f82012-11-21 00:36:55 +000010867static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010868s390_irgen_EXRL(UChar r1, UInt offset)
10869{
10870 IRTemp addr = newTemp(Ity_I64);
10871 /* we might save one round trip because we know the target */
10872 if (!last_execute_target)
10873 last_execute_target = *(ULong *)(HWord)
10874 (guest_IA_curr_instr + offset * 2UL);
10875 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10876 s390_irgen_EX(r1, addr);
10877 return "exrl";
10878}
10879
florian55085f82012-11-21 00:36:55 +000010880static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010881s390_irgen_IPM(UChar r1)
10882{
10883 // As long as we dont support SPM, lets just assume 0 as program mask
10884 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
10885 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
10886
10887 return "ipm";
10888}
10889
10890
florian55085f82012-11-21 00:36:55 +000010891static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010892s390_irgen_SRST(UChar r1, UChar r2)
10893{
10894 IRTemp address = newTemp(Ity_I64);
10895 IRTemp next = newTemp(Ity_I64);
10896 IRTemp delim = newTemp(Ity_I8);
10897 IRTemp counter = newTemp(Ity_I64);
10898 IRTemp byte = newTemp(Ity_I8);
10899
10900 assign(address, get_gpr_dw0(r2));
10901 assign(next, get_gpr_dw0(r1));
10902
10903 assign(counter, get_counter_dw0());
10904 put_counter_dw0(mkU64(0));
10905
10906 // start = next? CC=2 and out r1 and r2 unchanged
10907 s390_cc_set(2);
10908 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010909 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000010910
10911 assign(byte, load(Ity_I8, mkexpr(address)));
10912 assign(delim, get_gpr_b7(0));
10913
10914 // byte = delim? CC=1, R1=address
10915 s390_cc_set(1);
10916 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000010917 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010918
10919 // else: all equal, no end yet, loop
10920 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10921 put_gpr_dw0(r1, mkexpr(next));
10922 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010923
florian6820ba52012-07-26 02:01:50 +000010924 iterate();
sewardj2019a972011-03-07 16:04:07 +000010925
10926 return "srst";
10927}
10928
florian55085f82012-11-21 00:36:55 +000010929static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010930s390_irgen_CLST(UChar r1, UChar r2)
10931{
10932 IRTemp address1 = newTemp(Ity_I64);
10933 IRTemp address2 = newTemp(Ity_I64);
10934 IRTemp end = newTemp(Ity_I8);
10935 IRTemp counter = newTemp(Ity_I64);
10936 IRTemp byte1 = newTemp(Ity_I8);
10937 IRTemp byte2 = newTemp(Ity_I8);
10938
10939 assign(address1, get_gpr_dw0(r1));
10940 assign(address2, get_gpr_dw0(r2));
10941 assign(end, get_gpr_b7(0));
10942 assign(counter, get_counter_dw0());
10943 put_counter_dw0(mkU64(0));
10944 assign(byte1, load(Ity_I8, mkexpr(address1)));
10945 assign(byte2, load(Ity_I8, mkexpr(address2)));
10946
10947 // end in both? all equal, reset r1 and r2 to start values
10948 s390_cc_set(0);
10949 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
10950 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010951 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10952 binop(Iop_Or8,
10953 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10954 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010955
10956 put_gpr_dw0(r1, mkexpr(address1));
10957 put_gpr_dw0(r2, mkexpr(address2));
10958
10959 // End found in string1
10960 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010961 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010962
10963 // End found in string2
10964 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010965 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010966
10967 // string1 < string2
10968 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010969 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10970 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010971
10972 // string2 < string1
10973 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010974 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10975 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010976
10977 // else: all equal, no end yet, loop
10978 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10979 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10980 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010981
florian6820ba52012-07-26 02:01:50 +000010982 iterate();
sewardj2019a972011-03-07 16:04:07 +000010983
10984 return "clst";
10985}
10986
10987static void
10988s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10989{
10990 UChar reg;
10991 IRTemp addr = newTemp(Ity_I64);
10992
10993 assign(addr, mkexpr(op2addr));
10994 reg = r1;
10995 do {
10996 IRTemp old = addr;
10997
10998 reg %= 16;
10999 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11000 addr = newTemp(Ity_I64);
11001 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11002 reg++;
11003 } while (reg != (r3 + 1));
11004}
11005
florian55085f82012-11-21 00:36:55 +000011006static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011007s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11008{
11009 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11010
11011 return "lm";
11012}
11013
florian55085f82012-11-21 00:36:55 +000011014static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011015s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11016{
11017 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11018
11019 return "lmy";
11020}
11021
florian55085f82012-11-21 00:36:55 +000011022static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011023s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11024{
11025 UChar reg;
11026 IRTemp addr = newTemp(Ity_I64);
11027
11028 assign(addr, mkexpr(op2addr));
11029 reg = r1;
11030 do {
11031 IRTemp old = addr;
11032
11033 reg %= 16;
11034 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11035 addr = newTemp(Ity_I64);
11036 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11037 reg++;
11038 } while (reg != (r3 + 1));
11039
11040 return "lmh";
11041}
11042
florian55085f82012-11-21 00:36:55 +000011043static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011044s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11045{
11046 UChar reg;
11047 IRTemp addr = newTemp(Ity_I64);
11048
11049 assign(addr, mkexpr(op2addr));
11050 reg = r1;
11051 do {
11052 IRTemp old = addr;
11053
11054 reg %= 16;
11055 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11056 addr = newTemp(Ity_I64);
11057 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11058 reg++;
11059 } while (reg != (r3 + 1));
11060
11061 return "lmg";
11062}
11063
11064static void
11065s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11066{
11067 UChar reg;
11068 IRTemp addr = newTemp(Ity_I64);
11069
11070 assign(addr, mkexpr(op2addr));
11071 reg = r1;
11072 do {
11073 IRTemp old = addr;
11074
11075 reg %= 16;
11076 store(mkexpr(addr), get_gpr_w1(reg));
11077 addr = newTemp(Ity_I64);
11078 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11079 reg++;
11080 } while( reg != (r3 + 1));
11081}
11082
florian55085f82012-11-21 00:36:55 +000011083static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011084s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11085{
11086 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11087
11088 return "stm";
11089}
11090
florian55085f82012-11-21 00:36:55 +000011091static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011092s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11093{
11094 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11095
11096 return "stmy";
11097}
11098
florian55085f82012-11-21 00:36:55 +000011099static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011100s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11101{
11102 UChar reg;
11103 IRTemp addr = newTemp(Ity_I64);
11104
11105 assign(addr, mkexpr(op2addr));
11106 reg = r1;
11107 do {
11108 IRTemp old = addr;
11109
11110 reg %= 16;
11111 store(mkexpr(addr), get_gpr_w0(reg));
11112 addr = newTemp(Ity_I64);
11113 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11114 reg++;
11115 } while( reg != (r3 + 1));
11116
11117 return "stmh";
11118}
11119
florian55085f82012-11-21 00:36:55 +000011120static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011121s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11122{
11123 UChar reg;
11124 IRTemp addr = newTemp(Ity_I64);
11125
11126 assign(addr, mkexpr(op2addr));
11127 reg = r1;
11128 do {
11129 IRTemp old = addr;
11130
11131 reg %= 16;
11132 store(mkexpr(addr), get_gpr_dw0(reg));
11133 addr = newTemp(Ity_I64);
11134 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11135 reg++;
11136 } while( reg != (r3 + 1));
11137
11138 return "stmg";
11139}
11140
11141static void
florianb0bf6602012-05-05 00:01:16 +000011142s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000011143{
11144 IRTemp old1 = newTemp(Ity_I8);
11145 IRTemp old2 = newTemp(Ity_I8);
11146 IRTemp new1 = newTemp(Ity_I8);
11147 IRTemp counter = newTemp(Ity_I32);
11148 IRTemp addr1 = newTemp(Ity_I64);
11149
11150 assign(counter, get_counter_w0());
11151
11152 assign(addr1, binop(Iop_Add64, mkexpr(start1),
11153 unop(Iop_32Uto64, mkexpr(counter))));
11154
11155 assign(old1, load(Ity_I8, mkexpr(addr1)));
11156 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11157 unop(Iop_32Uto64,mkexpr(counter)))));
11158 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11159
11160 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000011161 if (op == Iop_Xor8) {
11162 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000011163 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11164 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000011165 } else
11166 store(mkexpr(addr1), mkexpr(new1));
11167 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11168 get_counter_w1()));
11169
11170 /* Check for end of field */
11171 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011172 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000011173 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11174 False);
11175 put_counter_dw0(mkU64(0));
11176}
11177
florian55085f82012-11-21 00:36:55 +000011178static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011179s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11180{
florianb0bf6602012-05-05 00:01:16 +000011181 IRTemp len = newTemp(Ity_I32);
11182
11183 assign(len, mkU32(length));
11184 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011185
11186 return "xc";
11187}
11188
sewardjb63967e2011-03-24 08:50:04 +000011189static void
11190s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11191{
11192 IRTemp counter = newTemp(Ity_I32);
11193 IRTemp start = newTemp(Ity_I64);
11194 IRTemp addr = newTemp(Ity_I64);
11195
11196 assign(start,
11197 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11198
11199 if (length < 8) {
11200 UInt i;
11201
11202 for (i = 0; i <= length; ++i) {
11203 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11204 }
11205 } else {
11206 assign(counter, get_counter_w0());
11207
11208 assign(addr, binop(Iop_Add64, mkexpr(start),
11209 unop(Iop_32Uto64, mkexpr(counter))));
11210
11211 store(mkexpr(addr), mkU8(0));
11212
11213 /* Check for end of field */
11214 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011215 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011216
11217 /* Reset counter */
11218 put_counter_dw0(mkU64(0));
11219 }
11220
11221 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11222
sewardj7ee97522011-05-09 21:45:04 +000011223 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011224 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11225}
11226
florian55085f82012-11-21 00:36:55 +000011227static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011228s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11229{
florianb0bf6602012-05-05 00:01:16 +000011230 IRTemp len = newTemp(Ity_I32);
11231
11232 assign(len, mkU32(length));
11233 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011234
11235 return "nc";
11236}
11237
florian55085f82012-11-21 00:36:55 +000011238static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011239s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11240{
florianb0bf6602012-05-05 00:01:16 +000011241 IRTemp len = newTemp(Ity_I32);
11242
11243 assign(len, mkU32(length));
11244 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011245
11246 return "oc";
11247}
11248
11249
florian55085f82012-11-21 00:36:55 +000011250static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011251s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11252{
florian79e839e2012-05-05 02:20:30 +000011253 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011254
florian79e839e2012-05-05 02:20:30 +000011255 assign(len, mkU64(length));
11256 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011257
11258 return "mvc";
11259}
11260
florian55085f82012-11-21 00:36:55 +000011261static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011262s390_irgen_MVCL(UChar r1, UChar r2)
11263{
11264 IRTemp addr1 = newTemp(Ity_I64);
11265 IRTemp addr2 = newTemp(Ity_I64);
11266 IRTemp addr2_load = newTemp(Ity_I64);
11267 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11268 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11269 IRTemp len1 = newTemp(Ity_I32);
11270 IRTemp len2 = newTemp(Ity_I32);
11271 IRTemp pad = newTemp(Ity_I8);
11272 IRTemp single = newTemp(Ity_I8);
11273
11274 assign(addr1, get_gpr_dw0(r1));
11275 assign(r1p1, get_gpr_w1(r1 + 1));
11276 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11277 assign(addr2, get_gpr_dw0(r2));
11278 assign(r2p1, get_gpr_w1(r2 + 1));
11279 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11280 assign(pad, get_gpr_b4(r2 + 1));
11281
11282 /* len1 == 0 ? */
11283 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011284 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011285
11286 /* Check for destructive overlap:
11287 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11288 s390_cc_set(3);
11289 IRTemp cond1 = newTemp(Ity_I32);
11290 assign(cond1, unop(Iop_1Uto32,
11291 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11292 IRTemp cond2 = newTemp(Ity_I32);
11293 assign(cond2, unop(Iop_1Uto32,
11294 binop(Iop_CmpLT64U, mkexpr(addr1),
11295 binop(Iop_Add64, mkexpr(addr2),
11296 unop(Iop_32Uto64, mkexpr(len1))))));
11297 IRTemp cond3 = newTemp(Ity_I32);
11298 assign(cond3, unop(Iop_1Uto32,
11299 binop(Iop_CmpLT64U,
11300 mkexpr(addr1),
11301 binop(Iop_Add64, mkexpr(addr2),
11302 unop(Iop_32Uto64, mkexpr(len2))))));
11303
florian6820ba52012-07-26 02:01:50 +000011304 next_insn_if(binop(Iop_CmpEQ32,
11305 binop(Iop_And32,
11306 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11307 mkexpr(cond3)),
11308 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011309
11310 /* See s390_irgen_CLCL for explanation why we cannot load directly
11311 and need two steps. */
11312 assign(addr2_load,
11313 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11314 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11315 assign(single,
11316 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11317 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11318
11319 store(mkexpr(addr1), mkexpr(single));
11320
11321 /* Update addr1 and len1 */
11322 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11323 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11324
11325 /* Update addr2 and len2 */
11326 put_gpr_dw0(r2,
11327 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11328 mkexpr(addr2),
11329 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11330
11331 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11332 put_gpr_w1(r2 + 1,
11333 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11334 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11335 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11336
11337 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011338 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011339
11340 return "mvcl";
11341}
11342
11343
florian55085f82012-11-21 00:36:55 +000011344static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011345s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11346{
11347 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11348
11349 addr1 = newTemp(Ity_I64);
11350 addr3 = newTemp(Ity_I64);
11351 addr3_load = newTemp(Ity_I64);
11352 len1 = newTemp(Ity_I64);
11353 len3 = newTemp(Ity_I64);
11354 single = newTemp(Ity_I8);
11355
11356 assign(addr1, get_gpr_dw0(r1));
11357 assign(len1, get_gpr_dw0(r1 + 1));
11358 assign(addr3, get_gpr_dw0(r3));
11359 assign(len3, get_gpr_dw0(r3 + 1));
11360
11361 // len1 == 0 ?
11362 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011363 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011364
11365 /* This is a hack to prevent mvcle from reading from addr3 if it
11366 should read from the pad. Since the pad has no address, just
11367 read from the instruction, we discard that anyway */
11368 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011369 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11370 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011371
11372 assign(single,
florian6ad49522011-09-09 02:38:55 +000011373 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11374 unop(Iop_64to8, mkexpr(pad2)),
11375 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011376 store(mkexpr(addr1), mkexpr(single));
11377
11378 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11379
11380 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11381
11382 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011383 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11384 mkexpr(addr3),
11385 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011386
11387 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011388 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11389 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011390
sewardj2019a972011-03-07 16:04:07 +000011391 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011392 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011393
11394 return "mvcle";
11395}
11396
florian55085f82012-11-21 00:36:55 +000011397static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011398s390_irgen_MVST(UChar r1, UChar r2)
11399{
11400 IRTemp addr1 = newTemp(Ity_I64);
11401 IRTemp addr2 = newTemp(Ity_I64);
11402 IRTemp end = newTemp(Ity_I8);
11403 IRTemp byte = newTemp(Ity_I8);
11404 IRTemp counter = newTemp(Ity_I64);
11405
11406 assign(addr1, get_gpr_dw0(r1));
11407 assign(addr2, get_gpr_dw0(r2));
11408 assign(counter, get_counter_dw0());
11409 assign(end, get_gpr_b7(0));
11410 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11411 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11412
11413 // We use unlimited as cpu-determined number
11414 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011415 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011416
11417 // and always set cc=1 at the end + update r1
11418 s390_cc_set(1);
11419 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11420 put_counter_dw0(mkU64(0));
11421
11422 return "mvst";
11423}
11424
11425static void
11426s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11427{
11428 IRTemp op1 = newTemp(Ity_I64);
11429 IRTemp result = newTemp(Ity_I64);
11430
11431 assign(op1, binop(Iop_32HLto64,
11432 get_gpr_w1(r1), // high 32 bits
11433 get_gpr_w1(r1 + 1))); // low 32 bits
11434 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11435 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11436 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11437}
11438
11439static void
11440s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11441{
11442 IRTemp op1 = newTemp(Ity_I128);
11443 IRTemp result = newTemp(Ity_I128);
11444
11445 assign(op1, binop(Iop_64HLto128,
11446 get_gpr_dw0(r1), // high 64 bits
11447 get_gpr_dw0(r1 + 1))); // low 64 bits
11448 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11449 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11450 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11451}
11452
11453static void
11454s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11455{
11456 IRTemp op1 = newTemp(Ity_I64);
11457 IRTemp result = newTemp(Ity_I128);
11458
11459 assign(op1, get_gpr_dw0(r1 + 1));
11460 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11461 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11462 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11463}
11464
florian55085f82012-11-21 00:36:55 +000011465static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011466s390_irgen_DR(UChar r1, UChar r2)
11467{
11468 IRTemp op2 = newTemp(Ity_I32);
11469
11470 assign(op2, get_gpr_w1(r2));
11471
11472 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11473
11474 return "dr";
11475}
11476
florian55085f82012-11-21 00:36:55 +000011477static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011478s390_irgen_D(UChar r1, IRTemp op2addr)
11479{
11480 IRTemp op2 = newTemp(Ity_I32);
11481
11482 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11483
11484 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11485
11486 return "d";
11487}
11488
florian55085f82012-11-21 00:36:55 +000011489static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011490s390_irgen_DLR(UChar r1, UChar r2)
11491{
11492 IRTemp op2 = newTemp(Ity_I32);
11493
11494 assign(op2, get_gpr_w1(r2));
11495
11496 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11497
florian7cd1cde2012-08-16 23:57:43 +000011498 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011499}
11500
florian55085f82012-11-21 00:36:55 +000011501static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011502s390_irgen_DL(UChar r1, IRTemp op2addr)
11503{
11504 IRTemp op2 = newTemp(Ity_I32);
11505
11506 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11507
11508 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11509
11510 return "dl";
11511}
11512
florian55085f82012-11-21 00:36:55 +000011513static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011514s390_irgen_DLG(UChar r1, IRTemp op2addr)
11515{
11516 IRTemp op2 = newTemp(Ity_I64);
11517
11518 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11519
11520 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11521
11522 return "dlg";
11523}
11524
florian55085f82012-11-21 00:36:55 +000011525static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011526s390_irgen_DLGR(UChar r1, UChar r2)
11527{
11528 IRTemp op2 = newTemp(Ity_I64);
11529
11530 assign(op2, get_gpr_dw0(r2));
11531
11532 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11533
11534 return "dlgr";
11535}
11536
florian55085f82012-11-21 00:36:55 +000011537static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011538s390_irgen_DSGR(UChar r1, UChar r2)
11539{
11540 IRTemp op2 = newTemp(Ity_I64);
11541
11542 assign(op2, get_gpr_dw0(r2));
11543
11544 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11545
11546 return "dsgr";
11547}
11548
florian55085f82012-11-21 00:36:55 +000011549static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011550s390_irgen_DSG(UChar r1, IRTemp op2addr)
11551{
11552 IRTemp op2 = newTemp(Ity_I64);
11553
11554 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11555
11556 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11557
11558 return "dsg";
11559}
11560
florian55085f82012-11-21 00:36:55 +000011561static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011562s390_irgen_DSGFR(UChar r1, UChar r2)
11563{
11564 IRTemp op2 = newTemp(Ity_I64);
11565
11566 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11567
11568 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11569
11570 return "dsgfr";
11571}
11572
florian55085f82012-11-21 00:36:55 +000011573static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011574s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11575{
11576 IRTemp op2 = newTemp(Ity_I64);
11577
11578 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11579
11580 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11581
11582 return "dsgf";
11583}
11584
11585static void
11586s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11587{
11588 UChar reg;
11589 IRTemp addr = newTemp(Ity_I64);
11590
11591 assign(addr, mkexpr(op2addr));
11592 reg = r1;
11593 do {
11594 IRTemp old = addr;
11595
11596 reg %= 16;
11597 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11598 addr = newTemp(Ity_I64);
11599 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11600 reg++;
11601 } while (reg != (r3 + 1));
11602}
11603
florian55085f82012-11-21 00:36:55 +000011604static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011605s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11606{
11607 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11608
11609 return "lam";
11610}
11611
florian55085f82012-11-21 00:36:55 +000011612static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011613s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11614{
11615 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11616
11617 return "lamy";
11618}
11619
11620static void
11621s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11622{
11623 UChar reg;
11624 IRTemp addr = newTemp(Ity_I64);
11625
11626 assign(addr, mkexpr(op2addr));
11627 reg = r1;
11628 do {
11629 IRTemp old = addr;
11630
11631 reg %= 16;
11632 store(mkexpr(addr), get_ar_w0(reg));
11633 addr = newTemp(Ity_I64);
11634 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11635 reg++;
11636 } while (reg != (r3 + 1));
11637}
11638
florian55085f82012-11-21 00:36:55 +000011639static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011640s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11641{
11642 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11643
11644 return "stam";
11645}
11646
florian55085f82012-11-21 00:36:55 +000011647static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011648s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11649{
11650 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11651
11652 return "stamy";
11653}
11654
11655
11656/* Implementation for 32-bit compare-and-swap */
11657static void
11658s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11659{
11660 IRCAS *cas;
11661 IRTemp op1 = newTemp(Ity_I32);
11662 IRTemp old_mem = newTemp(Ity_I32);
11663 IRTemp op3 = newTemp(Ity_I32);
11664 IRTemp result = newTemp(Ity_I32);
11665 IRTemp nequal = newTemp(Ity_I1);
11666
11667 assign(op1, get_gpr_w1(r1));
11668 assign(op3, get_gpr_w1(r3));
11669
11670 /* The first and second operands are compared. If they are equal,
11671 the third operand is stored at the second- operand location. */
11672 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11673 Iend_BE, mkexpr(op2addr),
11674 NULL, mkexpr(op1), /* expected value */
11675 NULL, mkexpr(op3) /* new value */);
11676 stmt(IRStmt_CAS(cas));
11677
11678 /* Set CC. Operands compared equal -> 0, else 1. */
11679 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11680 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11681
11682 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11683 Otherwise, store the old_value from memory in r1 and yield. */
11684 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11685 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011686 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011687}
11688
florian55085f82012-11-21 00:36:55 +000011689static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011690s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11691{
11692 s390_irgen_cas_32(r1, r3, op2addr);
11693
11694 return "cs";
11695}
11696
florian55085f82012-11-21 00:36:55 +000011697static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011698s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11699{
11700 s390_irgen_cas_32(r1, r3, op2addr);
11701
11702 return "csy";
11703}
11704
florian55085f82012-11-21 00:36:55 +000011705static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011706s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11707{
11708 IRCAS *cas;
11709 IRTemp op1 = newTemp(Ity_I64);
11710 IRTemp old_mem = newTemp(Ity_I64);
11711 IRTemp op3 = newTemp(Ity_I64);
11712 IRTemp result = newTemp(Ity_I64);
11713 IRTemp nequal = newTemp(Ity_I1);
11714
11715 assign(op1, get_gpr_dw0(r1));
11716 assign(op3, get_gpr_dw0(r3));
11717
11718 /* The first and second operands are compared. If they are equal,
11719 the third operand is stored at the second- operand location. */
11720 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11721 Iend_BE, mkexpr(op2addr),
11722 NULL, mkexpr(op1), /* expected value */
11723 NULL, mkexpr(op3) /* new value */);
11724 stmt(IRStmt_CAS(cas));
11725
11726 /* Set CC. Operands compared equal -> 0, else 1. */
11727 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11728 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11729
11730 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11731 Otherwise, store the old_value from memory in r1 and yield. */
11732 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11733 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011734 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011735
11736 return "csg";
11737}
11738
florian448cbba2012-06-06 02:26:01 +000011739/* Implementation for 32-bit compare-double-and-swap */
11740static void
11741s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11742{
11743 IRCAS *cas;
11744 IRTemp op1_high = newTemp(Ity_I32);
11745 IRTemp op1_low = newTemp(Ity_I32);
11746 IRTemp old_mem_high = newTemp(Ity_I32);
11747 IRTemp old_mem_low = newTemp(Ity_I32);
11748 IRTemp op3_high = newTemp(Ity_I32);
11749 IRTemp op3_low = newTemp(Ity_I32);
11750 IRTemp result = newTemp(Ity_I32);
11751 IRTemp nequal = newTemp(Ity_I1);
11752
11753 assign(op1_high, get_gpr_w1(r1));
11754 assign(op1_low, get_gpr_w1(r1+1));
11755 assign(op3_high, get_gpr_w1(r3));
11756 assign(op3_low, get_gpr_w1(r3+1));
11757
11758 /* The first and second operands are compared. If they are equal,
11759 the third operand is stored at the second-operand location. */
11760 cas = mkIRCAS(old_mem_high, old_mem_low,
11761 Iend_BE, mkexpr(op2addr),
11762 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11763 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11764 stmt(IRStmt_CAS(cas));
11765
11766 /* Set CC. Operands compared equal -> 0, else 1. */
11767 assign(result, unop(Iop_1Uto32,
11768 binop(Iop_CmpNE32,
11769 binop(Iop_Or32,
11770 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11771 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11772 mkU32(0))));
11773
11774 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11775
11776 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11777 Otherwise, store the old_value from memory in r1 and yield. */
11778 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11779 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11780 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011781 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011782}
11783
florian55085f82012-11-21 00:36:55 +000011784static const HChar *
florian448cbba2012-06-06 02:26:01 +000011785s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11786{
11787 s390_irgen_cdas_32(r1, r3, op2addr);
11788
11789 return "cds";
11790}
11791
florian55085f82012-11-21 00:36:55 +000011792static const HChar *
florian448cbba2012-06-06 02:26:01 +000011793s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11794{
11795 s390_irgen_cdas_32(r1, r3, op2addr);
11796
11797 return "cdsy";
11798}
11799
florian55085f82012-11-21 00:36:55 +000011800static const HChar *
florian448cbba2012-06-06 02:26:01 +000011801s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11802{
11803 IRCAS *cas;
11804 IRTemp op1_high = newTemp(Ity_I64);
11805 IRTemp op1_low = newTemp(Ity_I64);
11806 IRTemp old_mem_high = newTemp(Ity_I64);
11807 IRTemp old_mem_low = newTemp(Ity_I64);
11808 IRTemp op3_high = newTemp(Ity_I64);
11809 IRTemp op3_low = newTemp(Ity_I64);
11810 IRTemp result = newTemp(Ity_I64);
11811 IRTemp nequal = newTemp(Ity_I1);
11812
11813 assign(op1_high, get_gpr_dw0(r1));
11814 assign(op1_low, get_gpr_dw0(r1+1));
11815 assign(op3_high, get_gpr_dw0(r3));
11816 assign(op3_low, get_gpr_dw0(r3+1));
11817
11818 /* The first and second operands are compared. If they are equal,
11819 the third operand is stored at the second-operand location. */
11820 cas = mkIRCAS(old_mem_high, old_mem_low,
11821 Iend_BE, mkexpr(op2addr),
11822 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11823 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11824 stmt(IRStmt_CAS(cas));
11825
11826 /* Set CC. Operands compared equal -> 0, else 1. */
11827 assign(result, unop(Iop_1Uto64,
11828 binop(Iop_CmpNE64,
11829 binop(Iop_Or64,
11830 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11831 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11832 mkU64(0))));
11833
11834 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11835
11836 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11837 Otherwise, store the old_value from memory in r1 and yield. */
11838 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11839 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11840 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011841 yield_if(mkexpr(nequal));
11842
florian448cbba2012-06-06 02:26:01 +000011843 return "cdsg";
11844}
11845
sewardj2019a972011-03-07 16:04:07 +000011846
11847/* Binary floating point */
11848
florian55085f82012-11-21 00:36:55 +000011849static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011850s390_irgen_AXBR(UChar r1, UChar r2)
11851{
11852 IRTemp op1 = newTemp(Ity_F128);
11853 IRTemp op2 = newTemp(Ity_F128);
11854 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011855 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011856
11857 assign(op1, get_fpr_pair(r1));
11858 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011859 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011860 mkexpr(op2)));
11861 put_fpr_pair(r1, mkexpr(result));
11862
11863 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11864
11865 return "axbr";
11866}
11867
florian55085f82012-11-21 00:36:55 +000011868static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011869s390_irgen_CEBR(UChar r1, UChar r2)
11870{
11871 IRTemp op1 = newTemp(Ity_F32);
11872 IRTemp op2 = newTemp(Ity_F32);
11873 IRTemp cc_vex = newTemp(Ity_I32);
11874 IRTemp cc_s390 = newTemp(Ity_I32);
11875
11876 assign(op1, get_fpr_w0(r1));
11877 assign(op2, get_fpr_w0(r2));
11878 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11879
florian2d3d87f2012-12-21 21:05:17 +000011880 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011881 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11882
11883 return "cebr";
11884}
11885
florian55085f82012-11-21 00:36:55 +000011886static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011887s390_irgen_CDBR(UChar r1, UChar r2)
11888{
11889 IRTemp op1 = newTemp(Ity_F64);
11890 IRTemp op2 = newTemp(Ity_F64);
11891 IRTemp cc_vex = newTemp(Ity_I32);
11892 IRTemp cc_s390 = newTemp(Ity_I32);
11893
11894 assign(op1, get_fpr_dw0(r1));
11895 assign(op2, get_fpr_dw0(r2));
11896 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11897
florian2d3d87f2012-12-21 21:05:17 +000011898 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011899 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11900
11901 return "cdbr";
11902}
11903
florian55085f82012-11-21 00:36:55 +000011904static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011905s390_irgen_CXBR(UChar r1, UChar r2)
11906{
11907 IRTemp op1 = newTemp(Ity_F128);
11908 IRTemp op2 = newTemp(Ity_F128);
11909 IRTemp cc_vex = newTemp(Ity_I32);
11910 IRTemp cc_s390 = newTemp(Ity_I32);
11911
11912 assign(op1, get_fpr_pair(r1));
11913 assign(op2, get_fpr_pair(r2));
11914 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
11915
florian2d3d87f2012-12-21 21:05:17 +000011916 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011917 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11918
11919 return "cxbr";
11920}
11921
florian55085f82012-11-21 00:36:55 +000011922static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011923s390_irgen_CEB(UChar r1, IRTemp op2addr)
11924{
11925 IRTemp op1 = newTemp(Ity_F32);
11926 IRTemp op2 = newTemp(Ity_F32);
11927 IRTemp cc_vex = newTemp(Ity_I32);
11928 IRTemp cc_s390 = newTemp(Ity_I32);
11929
11930 assign(op1, get_fpr_w0(r1));
11931 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11932 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11933
florian2d3d87f2012-12-21 21:05:17 +000011934 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011935 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11936
11937 return "ceb";
11938}
11939
florian55085f82012-11-21 00:36:55 +000011940static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011941s390_irgen_CDB(UChar r1, IRTemp op2addr)
11942{
11943 IRTemp op1 = newTemp(Ity_F64);
11944 IRTemp op2 = newTemp(Ity_F64);
11945 IRTemp cc_vex = newTemp(Ity_I32);
11946 IRTemp cc_s390 = newTemp(Ity_I32);
11947
11948 assign(op1, get_fpr_dw0(r1));
11949 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11950 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11951
florian2d3d87f2012-12-21 21:05:17 +000011952 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011953 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11954
11955 return "cdb";
11956}
11957
florian55085f82012-11-21 00:36:55 +000011958static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011959s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11960 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011961{
11962 IRTemp op2 = newTemp(Ity_I32);
11963
11964 assign(op2, get_gpr_w1(r2));
11965 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11966
11967 return "cxfbr";
11968}
11969
florian55085f82012-11-21 00:36:55 +000011970static const HChar *
floriand2129202012-09-01 20:01:39 +000011971s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11972 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011973{
floriane75dafa2012-09-01 17:54:09 +000011974 if (! s390_host_has_fpext) {
11975 emulation_failure(EmFail_S390X_fpext);
11976 } else {
11977 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011978
floriane75dafa2012-09-01 17:54:09 +000011979 assign(op2, get_gpr_w1(r2));
11980 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11981 }
florian1c8f7ff2012-09-01 00:12:11 +000011982 return "cxlfbr";
11983}
11984
11985
florian55085f82012-11-21 00:36:55 +000011986static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011987s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11988 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011989{
11990 IRTemp op2 = newTemp(Ity_I64);
11991
11992 assign(op2, get_gpr_dw0(r2));
11993 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11994
11995 return "cxgbr";
11996}
11997
florian55085f82012-11-21 00:36:55 +000011998static const HChar *
floriand2129202012-09-01 20:01:39 +000011999s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12000 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012001{
floriane75dafa2012-09-01 17:54:09 +000012002 if (! s390_host_has_fpext) {
12003 emulation_failure(EmFail_S390X_fpext);
12004 } else {
12005 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000012006
floriane75dafa2012-09-01 17:54:09 +000012007 assign(op2, get_gpr_dw0(r2));
12008 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12009 }
florian1c8f7ff2012-09-01 00:12:11 +000012010 return "cxlgbr";
12011}
12012
florian55085f82012-11-21 00:36:55 +000012013static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012014s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12015 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012016{
12017 IRTemp op = newTemp(Ity_F128);
12018 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012019 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012020
12021 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012022 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012023 mkexpr(op)));
12024 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012025 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012026
12027 return "cfxbr";
12028}
12029
florian55085f82012-11-21 00:36:55 +000012030static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012031s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12032 UChar r1, UChar r2)
12033{
floriane75dafa2012-09-01 17:54:09 +000012034 if (! s390_host_has_fpext) {
12035 emulation_failure(EmFail_S390X_fpext);
12036 } else {
12037 IRTemp op = newTemp(Ity_F128);
12038 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012039 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012040
floriane75dafa2012-09-01 17:54:09 +000012041 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012042 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012043 mkexpr(op)));
12044 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012045 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012046 }
florian1c8f7ff2012-09-01 00:12:11 +000012047 return "clfxbr";
12048}
12049
12050
florian55085f82012-11-21 00:36:55 +000012051static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012052s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12053 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012054{
12055 IRTemp op = newTemp(Ity_F128);
12056 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012057 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012058
12059 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012060 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012061 mkexpr(op)));
12062 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012063 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012064
12065 return "cgxbr";
12066}
12067
florian55085f82012-11-21 00:36:55 +000012068static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012069s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12070 UChar r1, UChar r2)
12071{
floriane75dafa2012-09-01 17:54:09 +000012072 if (! s390_host_has_fpext) {
12073 emulation_failure(EmFail_S390X_fpext);
12074 } else {
12075 IRTemp op = newTemp(Ity_F128);
12076 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012077 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012078
floriane75dafa2012-09-01 17:54:09 +000012079 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012080 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012081 mkexpr(op)));
12082 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012083 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12084 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012085 }
florian1c8f7ff2012-09-01 00:12:11 +000012086 return "clgxbr";
12087}
12088
florian55085f82012-11-21 00:36:55 +000012089static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012090s390_irgen_DXBR(UChar r1, UChar r2)
12091{
12092 IRTemp op1 = newTemp(Ity_F128);
12093 IRTemp op2 = newTemp(Ity_F128);
12094 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012095 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012096
12097 assign(op1, get_fpr_pair(r1));
12098 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012099 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012100 mkexpr(op2)));
12101 put_fpr_pair(r1, mkexpr(result));
12102
12103 return "dxbr";
12104}
12105
florian55085f82012-11-21 00:36:55 +000012106static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012107s390_irgen_LTXBR(UChar r1, UChar r2)
12108{
12109 IRTemp result = newTemp(Ity_F128);
12110
12111 assign(result, get_fpr_pair(r2));
12112 put_fpr_pair(r1, mkexpr(result));
12113 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12114
12115 return "ltxbr";
12116}
12117
florian55085f82012-11-21 00:36:55 +000012118static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012119s390_irgen_LCXBR(UChar r1, UChar r2)
12120{
12121 IRTemp result = newTemp(Ity_F128);
12122
12123 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12124 put_fpr_pair(r1, mkexpr(result));
12125 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12126
12127 return "lcxbr";
12128}
12129
florian55085f82012-11-21 00:36:55 +000012130static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012131s390_irgen_LXDBR(UChar r1, UChar r2)
12132{
12133 IRTemp op = newTemp(Ity_F64);
12134
12135 assign(op, get_fpr_dw0(r2));
12136 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12137
12138 return "lxdbr";
12139}
12140
florian55085f82012-11-21 00:36:55 +000012141static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012142s390_irgen_LXEBR(UChar r1, UChar r2)
12143{
12144 IRTemp op = newTemp(Ity_F32);
12145
12146 assign(op, get_fpr_w0(r2));
12147 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12148
12149 return "lxebr";
12150}
12151
florian55085f82012-11-21 00:36:55 +000012152static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012153s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12154{
12155 IRTemp op = newTemp(Ity_F64);
12156
12157 assign(op, load(Ity_F64, mkexpr(op2addr)));
12158 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12159
12160 return "lxdb";
12161}
12162
florian55085f82012-11-21 00:36:55 +000012163static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012164s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12165{
12166 IRTemp op = newTemp(Ity_F32);
12167
12168 assign(op, load(Ity_F32, mkexpr(op2addr)));
12169 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12170
12171 return "lxeb";
12172}
12173
florian55085f82012-11-21 00:36:55 +000012174static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012175s390_irgen_LNEBR(UChar r1, UChar r2)
12176{
12177 IRTemp result = newTemp(Ity_F32);
12178
12179 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12180 put_fpr_w0(r1, mkexpr(result));
12181 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12182
12183 return "lnebr";
12184}
12185
florian55085f82012-11-21 00:36:55 +000012186static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012187s390_irgen_LNDBR(UChar r1, UChar r2)
12188{
12189 IRTemp result = newTemp(Ity_F64);
12190
12191 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12192 put_fpr_dw0(r1, mkexpr(result));
12193 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12194
12195 return "lndbr";
12196}
12197
florian55085f82012-11-21 00:36:55 +000012198static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012199s390_irgen_LNXBR(UChar r1, UChar r2)
12200{
12201 IRTemp result = newTemp(Ity_F128);
12202
12203 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12204 put_fpr_pair(r1, mkexpr(result));
12205 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12206
12207 return "lnxbr";
12208}
12209
florian55085f82012-11-21 00:36:55 +000012210static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012211s390_irgen_LPEBR(UChar r1, UChar r2)
12212{
12213 IRTemp result = newTemp(Ity_F32);
12214
12215 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12216 put_fpr_w0(r1, mkexpr(result));
12217 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12218
12219 return "lpebr";
12220}
12221
florian55085f82012-11-21 00:36:55 +000012222static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012223s390_irgen_LPDBR(UChar r1, UChar r2)
12224{
12225 IRTemp result = newTemp(Ity_F64);
12226
12227 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12228 put_fpr_dw0(r1, mkexpr(result));
12229 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12230
12231 return "lpdbr";
12232}
12233
florian55085f82012-11-21 00:36:55 +000012234static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012235s390_irgen_LPXBR(UChar r1, UChar r2)
12236{
12237 IRTemp result = newTemp(Ity_F128);
12238
12239 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12240 put_fpr_pair(r1, mkexpr(result));
12241 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12242
12243 return "lpxbr";
12244}
12245
florian55085f82012-11-21 00:36:55 +000012246static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012247s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12248 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012249{
florian125e20d2012-10-07 15:42:37 +000012250 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012251 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012252 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012253 }
sewardj2019a972011-03-07 16:04:07 +000012254 IRTemp result = newTemp(Ity_F64);
12255
floriandb4fcaa2012-09-05 19:54:08 +000012256 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012257 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012258 put_fpr_dw0(r1, mkexpr(result));
12259
12260 return "ldxbr";
12261}
12262
florian55085f82012-11-21 00:36:55 +000012263static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012264s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12265 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012266{
florian125e20d2012-10-07 15:42:37 +000012267 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012268 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012269 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012270 }
sewardj2019a972011-03-07 16:04:07 +000012271 IRTemp result = newTemp(Ity_F32);
12272
floriandb4fcaa2012-09-05 19:54:08 +000012273 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012274 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012275 put_fpr_w0(r1, mkexpr(result));
12276
12277 return "lexbr";
12278}
12279
florian55085f82012-11-21 00:36:55 +000012280static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012281s390_irgen_MXBR(UChar r1, UChar r2)
12282{
12283 IRTemp op1 = newTemp(Ity_F128);
12284 IRTemp op2 = newTemp(Ity_F128);
12285 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012286 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012287
12288 assign(op1, get_fpr_pair(r1));
12289 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012290 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012291 mkexpr(op2)));
12292 put_fpr_pair(r1, mkexpr(result));
12293
12294 return "mxbr";
12295}
12296
florian55085f82012-11-21 00:36:55 +000012297static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012298s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12299{
florian125e20d2012-10-07 15:42:37 +000012300 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012301
floriandb4fcaa2012-09-05 19:54:08 +000012302 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012303 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012304
12305 return "maebr";
12306}
12307
florian55085f82012-11-21 00:36:55 +000012308static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012309s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12310{
florian125e20d2012-10-07 15:42:37 +000012311 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012312
floriandb4fcaa2012-09-05 19:54:08 +000012313 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012314 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012315
12316 return "madbr";
12317}
12318
florian55085f82012-11-21 00:36:55 +000012319static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012320s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12321{
12322 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012323 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012324
floriandb4fcaa2012-09-05 19:54:08 +000012325 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012326 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012327
12328 return "maeb";
12329}
12330
florian55085f82012-11-21 00:36:55 +000012331static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012332s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12333{
12334 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012335 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012336
floriandb4fcaa2012-09-05 19:54:08 +000012337 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012338 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012339
12340 return "madb";
12341}
12342
florian55085f82012-11-21 00:36:55 +000012343static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012344s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12345{
florian125e20d2012-10-07 15:42:37 +000012346 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012347
floriandb4fcaa2012-09-05 19:54:08 +000012348 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012349 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012350
12351 return "msebr";
12352}
12353
florian55085f82012-11-21 00:36:55 +000012354static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012355s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12356{
florian125e20d2012-10-07 15:42:37 +000012357 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012358
floriandb4fcaa2012-09-05 19:54:08 +000012359 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012360 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012361
12362 return "msdbr";
12363}
12364
florian55085f82012-11-21 00:36:55 +000012365static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012366s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12367{
12368 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012369 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012370
floriandb4fcaa2012-09-05 19:54:08 +000012371 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012372 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012373
12374 return "mseb";
12375}
12376
florian55085f82012-11-21 00:36:55 +000012377static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012378s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12379{
12380 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012381 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012382
floriandb4fcaa2012-09-05 19:54:08 +000012383 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012384 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012385
12386 return "msdb";
12387}
12388
florian55085f82012-11-21 00:36:55 +000012389static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012390s390_irgen_SQEBR(UChar r1, UChar r2)
12391{
12392 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012393 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012394
floriandb4fcaa2012-09-05 19:54:08 +000012395 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012396 put_fpr_w0(r1, mkexpr(result));
12397
12398 return "sqebr";
12399}
12400
florian55085f82012-11-21 00:36:55 +000012401static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012402s390_irgen_SQDBR(UChar r1, UChar r2)
12403{
12404 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012405 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012406
floriandb4fcaa2012-09-05 19:54:08 +000012407 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012408 put_fpr_dw0(r1, mkexpr(result));
12409
12410 return "sqdbr";
12411}
12412
florian55085f82012-11-21 00:36:55 +000012413static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012414s390_irgen_SQXBR(UChar r1, UChar r2)
12415{
12416 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012417 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012418
floriandb4fcaa2012-09-05 19:54:08 +000012419 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12420 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012421 put_fpr_pair(r1, mkexpr(result));
12422
12423 return "sqxbr";
12424}
12425
florian55085f82012-11-21 00:36:55 +000012426static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012427s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12428{
12429 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012430 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012431
12432 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012433 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012434
12435 return "sqeb";
12436}
12437
florian55085f82012-11-21 00:36:55 +000012438static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012439s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12440{
12441 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012442 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012443
12444 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012445 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012446
12447 return "sqdb";
12448}
12449
florian55085f82012-11-21 00:36:55 +000012450static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012451s390_irgen_SXBR(UChar r1, UChar r2)
12452{
12453 IRTemp op1 = newTemp(Ity_F128);
12454 IRTemp op2 = newTemp(Ity_F128);
12455 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012456 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012457
12458 assign(op1, get_fpr_pair(r1));
12459 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012460 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012461 mkexpr(op2)));
12462 put_fpr_pair(r1, mkexpr(result));
12463 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12464
12465 return "sxbr";
12466}
12467
florian55085f82012-11-21 00:36:55 +000012468static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012469s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12470{
12471 IRTemp value = newTemp(Ity_F32);
12472
12473 assign(value, get_fpr_w0(r1));
12474
12475 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12476
12477 return "tceb";
12478}
12479
florian55085f82012-11-21 00:36:55 +000012480static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012481s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12482{
12483 IRTemp value = newTemp(Ity_F64);
12484
12485 assign(value, get_fpr_dw0(r1));
12486
12487 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12488
12489 return "tcdb";
12490}
12491
florian55085f82012-11-21 00:36:55 +000012492static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012493s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12494{
12495 IRTemp value = newTemp(Ity_F128);
12496
12497 assign(value, get_fpr_pair(r1));
12498
12499 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12500
12501 return "tcxb";
12502}
12503
florian55085f82012-11-21 00:36:55 +000012504static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012505s390_irgen_LCDFR(UChar r1, UChar r2)
12506{
12507 IRTemp result = newTemp(Ity_F64);
12508
12509 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12510 put_fpr_dw0(r1, mkexpr(result));
12511
12512 return "lcdfr";
12513}
12514
florian55085f82012-11-21 00:36:55 +000012515static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012516s390_irgen_LNDFR(UChar r1, UChar r2)
12517{
12518 IRTemp result = newTemp(Ity_F64);
12519
12520 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12521 put_fpr_dw0(r1, mkexpr(result));
12522
12523 return "lndfr";
12524}
12525
florian55085f82012-11-21 00:36:55 +000012526static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012527s390_irgen_LPDFR(UChar r1, UChar r2)
12528{
12529 IRTemp result = newTemp(Ity_F64);
12530
12531 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12532 put_fpr_dw0(r1, mkexpr(result));
12533
12534 return "lpdfr";
12535}
12536
florian55085f82012-11-21 00:36:55 +000012537static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012538s390_irgen_LDGR(UChar r1, UChar r2)
12539{
12540 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12541
12542 return "ldgr";
12543}
12544
florian55085f82012-11-21 00:36:55 +000012545static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012546s390_irgen_LGDR(UChar r1, UChar r2)
12547{
12548 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12549
12550 return "lgdr";
12551}
12552
12553
florian55085f82012-11-21 00:36:55 +000012554static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012555s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12556{
12557 IRTemp sign = newTemp(Ity_I64);
12558 IRTemp value = newTemp(Ity_I64);
12559
12560 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12561 mkU64(1ULL << 63)));
12562 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12563 mkU64((1ULL << 63) - 1)));
12564 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12565 mkexpr(sign))));
12566
12567 return "cpsdr";
12568}
12569
12570
sewardj2019a972011-03-07 16:04:07 +000012571static IRExpr *
12572s390_call_cvb(IRExpr *in)
12573{
12574 IRExpr **args, *call;
12575
12576 args = mkIRExprVec_1(in);
12577 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12578 "s390_do_cvb", &s390_do_cvb, args);
12579
12580 /* Nothing is excluded from definedness checking. */
12581 call->Iex.CCall.cee->mcx_mask = 0;
12582
12583 return call;
12584}
12585
florian55085f82012-11-21 00:36:55 +000012586static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012587s390_irgen_CVB(UChar r1, IRTemp op2addr)
12588{
12589 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12590
12591 return "cvb";
12592}
12593
florian55085f82012-11-21 00:36:55 +000012594static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012595s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12596{
12597 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12598
12599 return "cvby";
12600}
12601
12602
sewardj2019a972011-03-07 16:04:07 +000012603static IRExpr *
12604s390_call_cvd(IRExpr *in)
12605{
12606 IRExpr **args, *call;
12607
12608 args = mkIRExprVec_1(in);
12609 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12610 "s390_do_cvd", &s390_do_cvd, args);
12611
12612 /* Nothing is excluded from definedness checking. */
12613 call->Iex.CCall.cee->mcx_mask = 0;
12614
12615 return call;
12616}
12617
florian55085f82012-11-21 00:36:55 +000012618static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012619s390_irgen_CVD(UChar r1, IRTemp op2addr)
12620{
florian11b8ee82012-08-06 13:35:33 +000012621 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012622
12623 return "cvd";
12624}
12625
florian55085f82012-11-21 00:36:55 +000012626static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012627s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12628{
12629 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12630
12631 return "cvdy";
12632}
12633
florian55085f82012-11-21 00:36:55 +000012634static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012635s390_irgen_FLOGR(UChar r1, UChar r2)
12636{
12637 IRTemp input = newTemp(Ity_I64);
12638 IRTemp not_zero = newTemp(Ity_I64);
12639 IRTemp tmpnum = newTemp(Ity_I64);
12640 IRTemp num = newTemp(Ity_I64);
12641 IRTemp shift_amount = newTemp(Ity_I8);
12642
12643 /* We use the "count leading zeroes" operator because the number of
12644 leading zeroes is identical with the bit position of the first '1' bit.
12645 However, that operator does not work when the input value is zero.
12646 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12647 the modified value. If input == 0, then the result is 64. Otherwise,
12648 the result of Clz64 is what we want. */
12649
12650 assign(input, get_gpr_dw0(r2));
12651 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12652 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12653
12654 /* num = (input == 0) ? 64 : tmpnum */
12655 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12656 /* == 0 */ mkU64(64),
12657 /* != 0 */ mkexpr(tmpnum)));
12658
12659 put_gpr_dw0(r1, mkexpr(num));
12660
12661 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12662 is to first shift the input value by NUM + 1 bits to the left which
12663 causes the leftmost '1' bit to disappear. Then we shift logically to
12664 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12665 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12666 the width of the value-to-be-shifted, we need to special case
12667 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12668 For both such INPUT values the result will be 0. */
12669
12670 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12671 mkU64(1))));
12672
12673 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012674 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12675 /* == 0 || == 1*/ mkU64(0),
12676 /* otherwise */
12677 binop(Iop_Shr64,
12678 binop(Iop_Shl64, mkexpr(input),
12679 mkexpr(shift_amount)),
12680 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012681
12682 /* Compare the original value as an unsigned integer with 0. */
12683 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12684 mktemp(Ity_I64, mkU64(0)), False);
12685
12686 return "flogr";
12687}
12688
florian55085f82012-11-21 00:36:55 +000012689static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012690s390_irgen_STCK(IRTemp op2addr)
12691{
12692 IRDirty *d;
12693 IRTemp cc = newTemp(Ity_I64);
12694
12695 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12696 &s390x_dirtyhelper_STCK,
12697 mkIRExprVec_1(mkexpr(op2addr)));
12698 d->mFx = Ifx_Write;
12699 d->mAddr = mkexpr(op2addr);
12700 d->mSize = 8;
12701 stmt(IRStmt_Dirty(d));
12702 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12703 mkexpr(cc), mkU64(0), mkU64(0));
12704 return "stck";
12705}
12706
florian55085f82012-11-21 00:36:55 +000012707static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012708s390_irgen_STCKF(IRTemp op2addr)
12709{
florianc5c669b2012-08-26 14:32:28 +000012710 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012711 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012712 } else {
12713 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012714
florianc5c669b2012-08-26 14:32:28 +000012715 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12716 &s390x_dirtyhelper_STCKF,
12717 mkIRExprVec_1(mkexpr(op2addr)));
12718 d->mFx = Ifx_Write;
12719 d->mAddr = mkexpr(op2addr);
12720 d->mSize = 8;
12721 stmt(IRStmt_Dirty(d));
12722 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12723 mkexpr(cc), mkU64(0), mkU64(0));
12724 }
sewardj1e5fea62011-05-17 16:18:36 +000012725 return "stckf";
12726}
12727
florian55085f82012-11-21 00:36:55 +000012728static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012729s390_irgen_STCKE(IRTemp op2addr)
12730{
12731 IRDirty *d;
12732 IRTemp cc = newTemp(Ity_I64);
12733
12734 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12735 &s390x_dirtyhelper_STCKE,
12736 mkIRExprVec_1(mkexpr(op2addr)));
12737 d->mFx = Ifx_Write;
12738 d->mAddr = mkexpr(op2addr);
12739 d->mSize = 16;
12740 stmt(IRStmt_Dirty(d));
12741 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12742 mkexpr(cc), mkU64(0), mkU64(0));
12743 return "stcke";
12744}
12745
florian55085f82012-11-21 00:36:55 +000012746static const HChar *
florian933065d2011-07-11 01:48:02 +000012747s390_irgen_STFLE(IRTemp op2addr)
12748{
florian4e0083e2012-08-26 03:41:56 +000012749 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012750 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012751 return "stfle";
12752 }
12753
florian933065d2011-07-11 01:48:02 +000012754 IRDirty *d;
12755 IRTemp cc = newTemp(Ity_I64);
12756
12757 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12758 &s390x_dirtyhelper_STFLE,
12759 mkIRExprVec_1(mkexpr(op2addr)));
12760
12761 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
12762
sewardjc9069f22012-06-01 16:09:50 +000012763 d->nFxState = 1;
12764 vex_bzero(&d->fxState, sizeof(d->fxState));
12765
florian933065d2011-07-11 01:48:02 +000012766 d->fxState[0].fx = Ifx_Modify; /* read then write */
12767 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12768 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012769
12770 d->mAddr = mkexpr(op2addr);
12771 /* Pretend all double words are written */
12772 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12773 d->mFx = Ifx_Write;
12774
12775 stmt(IRStmt_Dirty(d));
12776
12777 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12778
12779 return "stfle";
12780}
12781
florian55085f82012-11-21 00:36:55 +000012782static const HChar *
floriana4384a32011-08-11 16:58:45 +000012783s390_irgen_CKSM(UChar r1,UChar r2)
12784{
12785 IRTemp addr = newTemp(Ity_I64);
12786 IRTemp op = newTemp(Ity_I32);
12787 IRTemp len = newTemp(Ity_I64);
12788 IRTemp oldval = newTemp(Ity_I32);
12789 IRTemp mask = newTemp(Ity_I32);
12790 IRTemp newop = newTemp(Ity_I32);
12791 IRTemp result = newTemp(Ity_I32);
12792 IRTemp result1 = newTemp(Ity_I32);
12793 IRTemp inc = newTemp(Ity_I64);
12794
12795 assign(oldval, get_gpr_w1(r1));
12796 assign(addr, get_gpr_dw0(r2));
12797 assign(len, get_gpr_dw0(r2+1));
12798
12799 /* Condition code is always zero. */
12800 s390_cc_set(0);
12801
12802 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012803 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012804
12805 /* Assiging the increment variable to adjust address and length
12806 later on. */
12807 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12808 mkexpr(len), mkU64(4)));
12809
12810 /* If length < 4 the final 4-byte 2nd operand value is computed by
12811 appending the remaining bytes to the right with 0. This is done
12812 by AND'ing the 4 bytes loaded from memory with an appropriate
12813 mask. If length >= 4, that mask is simply 0xffffffff. */
12814
12815 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12816 /* Mask computation when len < 4:
12817 0xffffffff << (32 - (len % 4)*8) */
12818 binop(Iop_Shl32, mkU32(0xffffffff),
12819 unop(Iop_32to8,
12820 binop(Iop_Sub32, mkU32(32),
12821 binop(Iop_Shl32,
12822 unop(Iop_64to32,
12823 binop(Iop_And64,
12824 mkexpr(len), mkU64(3))),
12825 mkU8(3))))),
12826 mkU32(0xffffffff)));
12827
12828 assign(op, load(Ity_I32, mkexpr(addr)));
12829 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12830 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12831
12832 /* Checking for carry */
12833 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12834 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12835 mkexpr(result)));
12836
12837 put_gpr_w1(r1, mkexpr(result1));
12838 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12839 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12840
florian6820ba52012-07-26 02:01:50 +000012841 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012842
12843 return "cksm";
12844}
12845
florian55085f82012-11-21 00:36:55 +000012846static const HChar *
florian9af37692012-01-15 21:01:16 +000012847s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12848{
12849 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12850 src_addr = newTemp(Ity_I64);
12851 des_addr = newTemp(Ity_I64);
12852 tab_addr = newTemp(Ity_I64);
12853 test_byte = newTemp(Ity_I8);
12854 src_len = newTemp(Ity_I64);
12855
12856 assign(src_addr, get_gpr_dw0(r2));
12857 assign(des_addr, get_gpr_dw0(r1));
12858 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012859 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012860 assign(test_byte, get_gpr_b7(0));
12861
12862 IRTemp op = newTemp(Ity_I8);
12863 IRTemp op1 = newTemp(Ity_I8);
12864 IRTemp result = newTemp(Ity_I64);
12865
12866 /* End of source string? We're done; proceed to next insn */
12867 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012868 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012869
12870 /* Load character from source string, index translation table and
12871 store translated character in op1. */
12872 assign(op, load(Ity_I8, mkexpr(src_addr)));
12873
12874 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12875 mkexpr(tab_addr)));
12876 assign(op1, load(Ity_I8, mkexpr(result)));
12877
12878 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12879 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012880 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000012881 }
12882 store(get_gpr_dw0(r1), mkexpr(op1));
12883
12884 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12885 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12886 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12887
florian6820ba52012-07-26 02:01:50 +000012888 iterate();
florian9af37692012-01-15 21:01:16 +000012889
12890 return "troo";
12891}
12892
florian55085f82012-11-21 00:36:55 +000012893static const HChar *
florian730448f2012-02-04 17:07:07 +000012894s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
12895{
12896 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12897 src_addr = newTemp(Ity_I64);
12898 des_addr = newTemp(Ity_I64);
12899 tab_addr = newTemp(Ity_I64);
12900 test_byte = newTemp(Ity_I8);
12901 src_len = newTemp(Ity_I64);
12902
12903 assign(src_addr, get_gpr_dw0(r2));
12904 assign(des_addr, get_gpr_dw0(r1));
12905 assign(tab_addr, get_gpr_dw0(1));
12906 assign(src_len, get_gpr_dw0(r1+1));
12907 assign(test_byte, get_gpr_b7(0));
12908
12909 IRTemp op = newTemp(Ity_I16);
12910 IRTemp op1 = newTemp(Ity_I8);
12911 IRTemp result = newTemp(Ity_I64);
12912
12913 /* End of source string? We're done; proceed to next insn */
12914 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012915 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012916
12917 /* Load character from source string, index translation table and
12918 store translated character in op1. */
12919 assign(op, load(Ity_I16, mkexpr(src_addr)));
12920
12921 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12922 mkexpr(tab_addr)));
12923
12924 assign(op1, load(Ity_I8, mkexpr(result)));
12925
12926 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12927 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012928 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012929 }
12930 store(get_gpr_dw0(r1), mkexpr(op1));
12931
12932 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12933 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12934 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12935
florian6820ba52012-07-26 02:01:50 +000012936 iterate();
florian730448f2012-02-04 17:07:07 +000012937
12938 return "trto";
12939}
12940
florian55085f82012-11-21 00:36:55 +000012941static const HChar *
florian730448f2012-02-04 17:07:07 +000012942s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
12943{
12944 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12945 src_addr = newTemp(Ity_I64);
12946 des_addr = newTemp(Ity_I64);
12947 tab_addr = newTemp(Ity_I64);
12948 test_byte = newTemp(Ity_I16);
12949 src_len = newTemp(Ity_I64);
12950
12951 assign(src_addr, get_gpr_dw0(r2));
12952 assign(des_addr, get_gpr_dw0(r1));
12953 assign(tab_addr, get_gpr_dw0(1));
12954 assign(src_len, get_gpr_dw0(r1+1));
12955 assign(test_byte, get_gpr_hw3(0));
12956
12957 IRTemp op = newTemp(Ity_I8);
12958 IRTemp op1 = newTemp(Ity_I16);
12959 IRTemp result = newTemp(Ity_I64);
12960
12961 /* End of source string? We're done; proceed to next insn */
12962 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012963 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012964
12965 /* Load character from source string, index translation table and
12966 store translated character in op1. */
12967 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12968
12969 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12970 mkexpr(tab_addr)));
12971 assign(op1, load(Ity_I16, mkexpr(result)));
12972
12973 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12974 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012975 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012976 }
12977 store(get_gpr_dw0(r1), mkexpr(op1));
12978
12979 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12980 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12981 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12982
florian6820ba52012-07-26 02:01:50 +000012983 iterate();
florian730448f2012-02-04 17:07:07 +000012984
12985 return "trot";
12986}
12987
florian55085f82012-11-21 00:36:55 +000012988static const HChar *
florian730448f2012-02-04 17:07:07 +000012989s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12990{
12991 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12992 src_addr = newTemp(Ity_I64);
12993 des_addr = newTemp(Ity_I64);
12994 tab_addr = newTemp(Ity_I64);
12995 test_byte = newTemp(Ity_I16);
12996 src_len = newTemp(Ity_I64);
12997
12998 assign(src_addr, get_gpr_dw0(r2));
12999 assign(des_addr, get_gpr_dw0(r1));
13000 assign(tab_addr, get_gpr_dw0(1));
13001 assign(src_len, get_gpr_dw0(r1+1));
13002 assign(test_byte, get_gpr_hw3(0));
13003
13004 IRTemp op = newTemp(Ity_I16);
13005 IRTemp op1 = newTemp(Ity_I16);
13006 IRTemp result = newTemp(Ity_I64);
13007
13008 /* End of source string? We're done; proceed to next insn */
13009 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013010 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013011
13012 /* Load character from source string, index translation table and
13013 store translated character in op1. */
13014 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13015
13016 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13017 mkexpr(tab_addr)));
13018 assign(op1, load(Ity_I16, mkexpr(result)));
13019
13020 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13021 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013022 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013023 }
13024
13025 store(get_gpr_dw0(r1), mkexpr(op1));
13026
13027 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13028 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13029 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13030
florian6820ba52012-07-26 02:01:50 +000013031 iterate();
florian730448f2012-02-04 17:07:07 +000013032
13033 return "trtt";
13034}
13035
florian55085f82012-11-21 00:36:55 +000013036static const HChar *
florian730448f2012-02-04 17:07:07 +000013037s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13038{
florianf87d4fb2012-05-05 02:55:24 +000013039 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000013040
florianf87d4fb2012-05-05 02:55:24 +000013041 assign(len, mkU64(length));
13042 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000013043
13044 return "tr";
13045}
13046
florian55085f82012-11-21 00:36:55 +000013047static const HChar *
florian730448f2012-02-04 17:07:07 +000013048s390_irgen_TRE(UChar r1,UChar r2)
13049{
13050 IRTemp src_addr, tab_addr, src_len, test_byte;
13051 src_addr = newTemp(Ity_I64);
13052 tab_addr = newTemp(Ity_I64);
13053 src_len = newTemp(Ity_I64);
13054 test_byte = newTemp(Ity_I8);
13055
13056 assign(src_addr, get_gpr_dw0(r1));
13057 assign(src_len, get_gpr_dw0(r1+1));
13058 assign(tab_addr, get_gpr_dw0(r2));
13059 assign(test_byte, get_gpr_b7(0));
13060
13061 IRTemp op = newTemp(Ity_I8);
13062 IRTemp op1 = newTemp(Ity_I8);
13063 IRTemp result = newTemp(Ity_I64);
13064
13065 /* End of source string? We're done; proceed to next insn */
13066 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013067 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013068
13069 /* Load character from source string and compare with test byte */
13070 assign(op, load(Ity_I8, mkexpr(src_addr)));
13071
13072 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013073 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013074
13075 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13076 mkexpr(tab_addr)));
13077
13078 assign(op1, load(Ity_I8, mkexpr(result)));
13079
13080 store(get_gpr_dw0(r1), mkexpr(op1));
13081 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13082 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13083
florian6820ba52012-07-26 02:01:50 +000013084 iterate();
florian730448f2012-02-04 17:07:07 +000013085
13086 return "tre";
13087}
13088
floriana0100c92012-07-20 00:06:35 +000013089static IRExpr *
13090s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13091{
13092 IRExpr **args, *call;
13093 args = mkIRExprVec_2(srcval, low_surrogate);
13094 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13095 "s390_do_cu21", &s390_do_cu21, args);
13096
13097 /* Nothing is excluded from definedness checking. */
13098 call->Iex.CCall.cee->mcx_mask = 0;
13099
13100 return call;
13101}
13102
florian55085f82012-11-21 00:36:55 +000013103static const HChar *
floriana0100c92012-07-20 00:06:35 +000013104s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13105{
13106 IRTemp addr1 = newTemp(Ity_I64);
13107 IRTemp addr2 = newTemp(Ity_I64);
13108 IRTemp len1 = newTemp(Ity_I64);
13109 IRTemp len2 = newTemp(Ity_I64);
13110
13111 assign(addr1, get_gpr_dw0(r1));
13112 assign(addr2, get_gpr_dw0(r2));
13113 assign(len1, get_gpr_dw0(r1 + 1));
13114 assign(len2, get_gpr_dw0(r2 + 1));
13115
13116 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13117 there are less than 2 bytes left, then the 2nd operand is exhausted
13118 and we're done here. cc = 0 */
13119 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013120 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000013121
13122 /* There are at least two bytes there. Read them. */
13123 IRTemp srcval = newTemp(Ity_I32);
13124 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13125
13126 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13127 inside the interval [0xd800 - 0xdbff] */
13128 IRTemp is_high_surrogate = newTemp(Ity_I32);
13129 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13130 mkU32(1), mkU32(0));
13131 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13132 mkU32(1), mkU32(0));
13133 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13134
13135 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13136 then the 2nd operand is exhausted and we're done here. cc = 0 */
13137 IRExpr *not_enough_bytes =
13138 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13139
florian6820ba52012-07-26 02:01:50 +000013140 next_insn_if(binop(Iop_CmpEQ32,
13141 binop(Iop_And32, mkexpr(is_high_surrogate),
13142 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000013143
13144 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13145 surrogate, read the next two bytes (low surrogate). */
13146 IRTemp low_surrogate = newTemp(Ity_I32);
13147 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13148
13149 assign(low_surrogate,
13150 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13151 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13152 mkU32(0))); // any value is fine; it will not be used
13153
13154 /* Call the helper */
13155 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013156 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13157 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000013158
13159 /* Before we can test whether the 1st operand is exhausted we need to
13160 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13161 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13162 IRExpr *invalid_low_surrogate =
13163 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13164
13165 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013166 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000013167 }
13168
13169 /* Now test whether the 1st operand is exhausted */
13170 IRTemp num_bytes = newTemp(Ity_I64);
13171 assign(num_bytes, binop(Iop_And64,
13172 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13173 mkU64(0xff)));
13174 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013175 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000013176
13177 /* Extract the bytes to be stored at addr1 */
13178 IRTemp data = newTemp(Ity_I64);
13179 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13180
13181 /* To store the bytes construct 4 dirty helper calls. The helper calls
13182 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13183 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013184 UInt i;
floriana0100c92012-07-20 00:06:35 +000013185 for (i = 1; i <= 4; ++i) {
13186 IRDirty *d;
13187
13188 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13189 &s390x_dirtyhelper_CUxy,
13190 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13191 mkexpr(num_bytes)));
13192 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13193 d->mFx = Ifx_Write;
13194 d->mAddr = mkexpr(addr1);
13195 d->mSize = i;
13196 stmt(IRStmt_Dirty(d));
13197 }
13198
13199 /* Update source address and length */
13200 IRTemp num_src_bytes = newTemp(Ity_I64);
13201 assign(num_src_bytes,
13202 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13203 mkU64(4), mkU64(2)));
13204 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13205 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13206
13207 /* Update destination address and length */
13208 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13209 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13210
florian6820ba52012-07-26 02:01:50 +000013211 iterate();
floriana0100c92012-07-20 00:06:35 +000013212
13213 return "cu21";
13214}
13215
florian2a415a12012-07-21 17:41:36 +000013216static IRExpr *
13217s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13218{
13219 IRExpr **args, *call;
13220 args = mkIRExprVec_2(srcval, low_surrogate);
13221 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13222 "s390_do_cu24", &s390_do_cu24, args);
13223
13224 /* Nothing is excluded from definedness checking. */
13225 call->Iex.CCall.cee->mcx_mask = 0;
13226
13227 return call;
13228}
13229
florian55085f82012-11-21 00:36:55 +000013230static const HChar *
florian2a415a12012-07-21 17:41:36 +000013231s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13232{
13233 IRTemp addr1 = newTemp(Ity_I64);
13234 IRTemp addr2 = newTemp(Ity_I64);
13235 IRTemp len1 = newTemp(Ity_I64);
13236 IRTemp len2 = newTemp(Ity_I64);
13237
13238 assign(addr1, get_gpr_dw0(r1));
13239 assign(addr2, get_gpr_dw0(r2));
13240 assign(len1, get_gpr_dw0(r1 + 1));
13241 assign(len2, get_gpr_dw0(r2 + 1));
13242
13243 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13244 there are less than 2 bytes left, then the 2nd operand is exhausted
13245 and we're done here. cc = 0 */
13246 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013247 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013248
13249 /* There are at least two bytes there. Read them. */
13250 IRTemp srcval = newTemp(Ity_I32);
13251 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13252
13253 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13254 inside the interval [0xd800 - 0xdbff] */
13255 IRTemp is_high_surrogate = newTemp(Ity_I32);
13256 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13257 mkU32(1), mkU32(0));
13258 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13259 mkU32(1), mkU32(0));
13260 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13261
13262 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13263 then the 2nd operand is exhausted and we're done here. cc = 0 */
13264 IRExpr *not_enough_bytes =
13265 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13266
florian6820ba52012-07-26 02:01:50 +000013267 next_insn_if(binop(Iop_CmpEQ32,
13268 binop(Iop_And32, mkexpr(is_high_surrogate),
13269 not_enough_bytes),
13270 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013271
13272 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13273 surrogate, read the next two bytes (low surrogate). */
13274 IRTemp low_surrogate = newTemp(Ity_I32);
13275 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13276
13277 assign(low_surrogate,
13278 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13279 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13280 mkU32(0))); // any value is fine; it will not be used
13281
13282 /* Call the helper */
13283 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013284 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13285 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013286
13287 /* Before we can test whether the 1st operand is exhausted we need to
13288 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13289 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13290 IRExpr *invalid_low_surrogate =
13291 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13292
13293 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013294 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013295 }
13296
13297 /* Now test whether the 1st operand is exhausted */
13298 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013299 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013300
13301 /* Extract the bytes to be stored at addr1 */
13302 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13303
13304 store(mkexpr(addr1), data);
13305
13306 /* Update source address and length */
13307 IRTemp num_src_bytes = newTemp(Ity_I64);
13308 assign(num_src_bytes,
13309 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13310 mkU64(4), mkU64(2)));
13311 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13312 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13313
13314 /* Update destination address and length */
13315 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13316 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13317
florian6820ba52012-07-26 02:01:50 +000013318 iterate();
florian2a415a12012-07-21 17:41:36 +000013319
13320 return "cu24";
13321}
floriana4384a32011-08-11 16:58:45 +000013322
florian956194b2012-07-28 22:18:32 +000013323static IRExpr *
13324s390_call_cu42(IRExpr *srcval)
13325{
13326 IRExpr **args, *call;
13327 args = mkIRExprVec_1(srcval);
13328 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13329 "s390_do_cu42", &s390_do_cu42, args);
13330
13331 /* Nothing is excluded from definedness checking. */
13332 call->Iex.CCall.cee->mcx_mask = 0;
13333
13334 return call;
13335}
13336
florian55085f82012-11-21 00:36:55 +000013337static const HChar *
florian956194b2012-07-28 22:18:32 +000013338s390_irgen_CU42(UChar r1, UChar r2)
13339{
13340 IRTemp addr1 = newTemp(Ity_I64);
13341 IRTemp addr2 = newTemp(Ity_I64);
13342 IRTemp len1 = newTemp(Ity_I64);
13343 IRTemp len2 = newTemp(Ity_I64);
13344
13345 assign(addr1, get_gpr_dw0(r1));
13346 assign(addr2, get_gpr_dw0(r2));
13347 assign(len1, get_gpr_dw0(r1 + 1));
13348 assign(len2, get_gpr_dw0(r2 + 1));
13349
13350 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13351 there are less than 4 bytes left, then the 2nd operand is exhausted
13352 and we're done here. cc = 0 */
13353 s390_cc_set(0);
13354 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13355
13356 /* Read the 2nd operand. */
13357 IRTemp srcval = newTemp(Ity_I32);
13358 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13359
13360 /* Call the helper */
13361 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013362 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013363
13364 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13365 cc=2 outranks cc=1 (1st operand exhausted) */
13366 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13367
13368 s390_cc_set(2);
13369 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13370
13371 /* Now test whether the 1st operand is exhausted */
13372 IRTemp num_bytes = newTemp(Ity_I64);
13373 assign(num_bytes, binop(Iop_And64,
13374 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13375 mkU64(0xff)));
13376 s390_cc_set(1);
13377 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13378
13379 /* Extract the bytes to be stored at addr1 */
13380 IRTemp data = newTemp(Ity_I64);
13381 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13382
13383 /* To store the bytes construct 2 dirty helper calls. The helper calls
13384 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13385 that only one of them will be called at runtime. */
13386
13387 Int i;
13388 for (i = 2; i <= 4; ++i) {
13389 IRDirty *d;
13390
13391 if (i == 3) continue; // skip this one
13392
13393 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13394 &s390x_dirtyhelper_CUxy,
13395 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13396 mkexpr(num_bytes)));
13397 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13398 d->mFx = Ifx_Write;
13399 d->mAddr = mkexpr(addr1);
13400 d->mSize = i;
13401 stmt(IRStmt_Dirty(d));
13402 }
13403
13404 /* Update source address and length */
13405 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13406 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13407
13408 /* Update destination address and length */
13409 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13410 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13411
13412 iterate();
13413
13414 return "cu42";
13415}
13416
florian6d9b9b22012-08-03 18:35:39 +000013417static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013418s390_call_cu41(IRExpr *srcval)
13419{
13420 IRExpr **args, *call;
13421 args = mkIRExprVec_1(srcval);
13422 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13423 "s390_do_cu41", &s390_do_cu41, args);
13424
13425 /* Nothing is excluded from definedness checking. */
13426 call->Iex.CCall.cee->mcx_mask = 0;
13427
13428 return call;
13429}
13430
florian55085f82012-11-21 00:36:55 +000013431static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013432s390_irgen_CU41(UChar r1, UChar r2)
13433{
13434 IRTemp addr1 = newTemp(Ity_I64);
13435 IRTemp addr2 = newTemp(Ity_I64);
13436 IRTemp len1 = newTemp(Ity_I64);
13437 IRTemp len2 = newTemp(Ity_I64);
13438
13439 assign(addr1, get_gpr_dw0(r1));
13440 assign(addr2, get_gpr_dw0(r2));
13441 assign(len1, get_gpr_dw0(r1 + 1));
13442 assign(len2, get_gpr_dw0(r2 + 1));
13443
13444 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13445 there are less than 4 bytes left, then the 2nd operand is exhausted
13446 and we're done here. cc = 0 */
13447 s390_cc_set(0);
13448 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13449
13450 /* Read the 2nd operand. */
13451 IRTemp srcval = newTemp(Ity_I32);
13452 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13453
13454 /* Call the helper */
13455 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013456 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013457
13458 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13459 cc=2 outranks cc=1 (1st operand exhausted) */
13460 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13461
13462 s390_cc_set(2);
13463 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13464
13465 /* Now test whether the 1st operand is exhausted */
13466 IRTemp num_bytes = newTemp(Ity_I64);
13467 assign(num_bytes, binop(Iop_And64,
13468 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13469 mkU64(0xff)));
13470 s390_cc_set(1);
13471 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13472
13473 /* Extract the bytes to be stored at addr1 */
13474 IRTemp data = newTemp(Ity_I64);
13475 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13476
13477 /* To store the bytes construct 4 dirty helper calls. The helper calls
13478 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13479 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013480 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013481 for (i = 1; i <= 4; ++i) {
13482 IRDirty *d;
13483
13484 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13485 &s390x_dirtyhelper_CUxy,
13486 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13487 mkexpr(num_bytes)));
13488 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13489 d->mFx = Ifx_Write;
13490 d->mAddr = mkexpr(addr1);
13491 d->mSize = i;
13492 stmt(IRStmt_Dirty(d));
13493 }
13494
13495 /* Update source address and length */
13496 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13497 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13498
13499 /* Update destination address and length */
13500 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13501 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13502
13503 iterate();
13504
13505 return "cu41";
13506}
13507
13508static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013509s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013510{
13511 IRExpr **args, *call;
13512 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013513 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13514 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013515
13516 /* Nothing is excluded from definedness checking. */
13517 call->Iex.CCall.cee->mcx_mask = 0;
13518
13519 return call;
13520}
13521
13522static IRExpr *
13523s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13524 IRExpr *byte4, IRExpr *stuff)
13525{
13526 IRExpr **args, *call;
13527 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13528 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13529 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13530
13531 /* Nothing is excluded from definedness checking. */
13532 call->Iex.CCall.cee->mcx_mask = 0;
13533
13534 return call;
13535}
13536
florian3f8a96a2012-08-05 02:59:55 +000013537static IRExpr *
13538s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13539 IRExpr *byte4, IRExpr *stuff)
13540{
13541 IRExpr **args, *call;
13542 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13543 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13544 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13545
13546 /* Nothing is excluded from definedness checking. */
13547 call->Iex.CCall.cee->mcx_mask = 0;
13548
13549 return call;
13550}
13551
13552static void
13553s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013554{
13555 IRTemp addr1 = newTemp(Ity_I64);
13556 IRTemp addr2 = newTemp(Ity_I64);
13557 IRTemp len1 = newTemp(Ity_I64);
13558 IRTemp len2 = newTemp(Ity_I64);
13559
13560 assign(addr1, get_gpr_dw0(r1));
13561 assign(addr2, get_gpr_dw0(r2));
13562 assign(len1, get_gpr_dw0(r1 + 1));
13563 assign(len2, get_gpr_dw0(r2 + 1));
13564
13565 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13566
13567 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13568 there is less than 1 byte left, then the 2nd operand is exhausted
13569 and we're done here. cc = 0 */
13570 s390_cc_set(0);
13571 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13572
13573 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013574 IRTemp byte1 = newTemp(Ity_I64);
13575 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013576
13577 /* Call the helper to get number of bytes and invalid byte indicator */
13578 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013579 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013580 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013581
13582 /* Check for invalid 1st byte */
13583 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13584 s390_cc_set(2);
13585 next_insn_if(is_invalid);
13586
13587 /* How many bytes do we have to read? */
13588 IRTemp num_src_bytes = newTemp(Ity_I64);
13589 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13590
13591 /* Now test whether the 2nd operand is exhausted */
13592 s390_cc_set(0);
13593 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13594
13595 /* Read the remaining bytes */
13596 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13597
13598 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13599 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013600 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013601 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13602 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013603 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013604 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13605 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013606 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013607
13608 /* Call the helper to get the converted value and invalid byte indicator.
13609 We can pass at most 5 arguments; therefore some encoding is needed
13610 here */
13611 IRExpr *stuff = binop(Iop_Or64,
13612 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13613 mkU64(extended_checking));
13614 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013615
13616 if (is_cu12) {
13617 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13618 byte4, stuff));
13619 } else {
13620 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13621 byte4, stuff));
13622 }
florian6d9b9b22012-08-03 18:35:39 +000013623
13624 /* Check for invalid character */
13625 s390_cc_set(2);
13626 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13627 next_insn_if(is_invalid);
13628
13629 /* Now test whether the 1st operand is exhausted */
13630 IRTemp num_bytes = newTemp(Ity_I64);
13631 assign(num_bytes, binop(Iop_And64,
13632 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13633 mkU64(0xff)));
13634 s390_cc_set(1);
13635 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13636
13637 /* Extract the bytes to be stored at addr1 */
13638 IRTemp data = newTemp(Ity_I64);
13639 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13640
florian3f8a96a2012-08-05 02:59:55 +000013641 if (is_cu12) {
13642 /* To store the bytes construct 2 dirty helper calls. The helper calls
13643 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13644 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013645
florian3f8a96a2012-08-05 02:59:55 +000013646 Int i;
13647 for (i = 2; i <= 4; ++i) {
13648 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013649
florian3f8a96a2012-08-05 02:59:55 +000013650 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013651
florian3f8a96a2012-08-05 02:59:55 +000013652 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13653 &s390x_dirtyhelper_CUxy,
13654 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13655 mkexpr(num_bytes)));
13656 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13657 d->mFx = Ifx_Write;
13658 d->mAddr = mkexpr(addr1);
13659 d->mSize = i;
13660 stmt(IRStmt_Dirty(d));
13661 }
13662 } else {
13663 // cu14
13664 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013665 }
13666
13667 /* Update source address and length */
13668 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13669 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13670
13671 /* Update destination address and length */
13672 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13673 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13674
13675 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013676}
13677
florian55085f82012-11-21 00:36:55 +000013678static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013679s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13680{
13681 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013682
13683 return "cu12";
13684}
13685
florian55085f82012-11-21 00:36:55 +000013686static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013687s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13688{
13689 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13690
13691 return "cu14";
13692}
13693
florian8c88cb62012-08-26 18:58:13 +000013694static IRExpr *
13695s390_call_ecag(IRExpr *op2addr)
13696{
13697 IRExpr **args, *call;
13698
13699 args = mkIRExprVec_1(op2addr);
13700 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13701 "s390_do_ecag", &s390_do_ecag, args);
13702
13703 /* Nothing is excluded from definedness checking. */
13704 call->Iex.CCall.cee->mcx_mask = 0;
13705
13706 return call;
13707}
13708
florian55085f82012-11-21 00:36:55 +000013709static const HChar *
floriand2129202012-09-01 20:01:39 +000013710s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013711{
13712 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013713 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013714 } else {
13715 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13716 }
13717
13718 return "ecag";
13719}
13720
13721
florianb7def222012-12-04 04:45:32 +000013722/* New insns are added here.
13723 If an insn is contingent on a facility being installed also
13724 check whether the list of supported facilities in function
13725 s390x_dirtyhelper_STFLE needs updating */
13726
sewardj2019a972011-03-07 16:04:07 +000013727/*------------------------------------------------------------*/
13728/*--- Build IR for special instructions ---*/
13729/*------------------------------------------------------------*/
13730
florianb4df7682011-07-05 02:09:01 +000013731static void
sewardj2019a972011-03-07 16:04:07 +000013732s390_irgen_client_request(void)
13733{
13734 if (0)
13735 vex_printf("%%R3 = client_request ( %%R2 )\n");
13736
florianf9e1ed72012-04-17 02:41:56 +000013737 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13738 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013739
florianf9e1ed72012-04-17 02:41:56 +000013740 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013741 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013742
13743 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013744}
13745
florianb4df7682011-07-05 02:09:01 +000013746static void
sewardj2019a972011-03-07 16:04:07 +000013747s390_irgen_guest_NRADDR(void)
13748{
13749 if (0)
13750 vex_printf("%%R3 = guest_NRADDR\n");
13751
floriane88b3c92011-07-05 02:48:39 +000013752 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013753}
13754
florianb4df7682011-07-05 02:09:01 +000013755static void
sewardj2019a972011-03-07 16:04:07 +000013756s390_irgen_call_noredir(void)
13757{
florianf9e1ed72012-04-17 02:41:56 +000013758 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13759 + S390_SPECIAL_OP_SIZE;
13760
sewardj2019a972011-03-07 16:04:07 +000013761 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013762 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013763
13764 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013765 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013766
13767 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013768 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013769}
13770
13771/* Force proper alignment for the structures below. */
13772#pragma pack(1)
13773
13774
13775static s390_decode_t
13776s390_decode_2byte_and_irgen(UChar *bytes)
13777{
13778 typedef union {
13779 struct {
13780 unsigned int op : 16;
13781 } E;
13782 struct {
13783 unsigned int op : 8;
13784 unsigned int i : 8;
13785 } I;
13786 struct {
13787 unsigned int op : 8;
13788 unsigned int r1 : 4;
13789 unsigned int r2 : 4;
13790 } RR;
13791 } formats;
13792 union {
13793 formats fmt;
13794 UShort value;
13795 } ovl;
13796
13797 vassert(sizeof(formats) == 2);
13798
florianffbd84d2012-12-09 02:06:29 +000013799 ((UChar *)(&ovl.value))[0] = bytes[0];
13800 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013801
13802 switch (ovl.value & 0xffff) {
13803 case 0x0101: /* PR */ goto unimplemented;
13804 case 0x0102: /* UPT */ goto unimplemented;
13805 case 0x0104: /* PTFF */ goto unimplemented;
13806 case 0x0107: /* SCKPF */ goto unimplemented;
florian78d5ef72013-05-11 15:02:58 +000013807 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013808 case 0x010b: /* TAM */ goto unimplemented;
13809 case 0x010c: /* SAM24 */ goto unimplemented;
13810 case 0x010d: /* SAM31 */ goto unimplemented;
13811 case 0x010e: /* SAM64 */ goto unimplemented;
13812 case 0x01ff: /* TRAP2 */ goto unimplemented;
13813 }
13814
13815 switch ((ovl.value & 0xff00) >> 8) {
13816 case 0x04: /* SPM */ goto unimplemented;
13817 case 0x05: /* BALR */ goto unimplemented;
13818 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13819 goto ok;
13820 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13821 goto ok;
13822 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13823 case 0x0b: /* BSM */ goto unimplemented;
13824 case 0x0c: /* BASSM */ goto unimplemented;
13825 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13826 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013827 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13828 goto ok;
13829 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13830 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013831 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13832 goto ok;
13833 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13834 goto ok;
13835 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13836 goto ok;
13837 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13838 goto ok;
13839 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13840 goto ok;
13841 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13842 goto ok;
13843 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13844 goto ok;
13845 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13846 goto ok;
13847 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13848 goto ok;
13849 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13850 goto ok;
13851 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13852 goto ok;
13853 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13854 goto ok;
13855 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13856 goto ok;
13857 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13858 goto ok;
13859 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13860 goto ok;
13861 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13862 goto ok;
13863 case 0x20: /* LPDR */ goto unimplemented;
13864 case 0x21: /* LNDR */ goto unimplemented;
13865 case 0x22: /* LTDR */ goto unimplemented;
13866 case 0x23: /* LCDR */ goto unimplemented;
13867 case 0x24: /* HDR */ goto unimplemented;
13868 case 0x25: /* LDXR */ goto unimplemented;
13869 case 0x26: /* MXR */ goto unimplemented;
13870 case 0x27: /* MXDR */ goto unimplemented;
13871 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13872 goto ok;
13873 case 0x29: /* CDR */ goto unimplemented;
13874 case 0x2a: /* ADR */ goto unimplemented;
13875 case 0x2b: /* SDR */ goto unimplemented;
13876 case 0x2c: /* MDR */ goto unimplemented;
13877 case 0x2d: /* DDR */ goto unimplemented;
13878 case 0x2e: /* AWR */ goto unimplemented;
13879 case 0x2f: /* SWR */ goto unimplemented;
13880 case 0x30: /* LPER */ goto unimplemented;
13881 case 0x31: /* LNER */ goto unimplemented;
13882 case 0x32: /* LTER */ goto unimplemented;
13883 case 0x33: /* LCER */ goto unimplemented;
13884 case 0x34: /* HER */ goto unimplemented;
13885 case 0x35: /* LEDR */ goto unimplemented;
13886 case 0x36: /* AXR */ goto unimplemented;
13887 case 0x37: /* SXR */ goto unimplemented;
13888 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13889 goto ok;
13890 case 0x39: /* CER */ goto unimplemented;
13891 case 0x3a: /* AER */ goto unimplemented;
13892 case 0x3b: /* SER */ goto unimplemented;
13893 case 0x3c: /* MDER */ goto unimplemented;
13894 case 0x3d: /* DER */ goto unimplemented;
13895 case 0x3e: /* AUR */ goto unimplemented;
13896 case 0x3f: /* SUR */ goto unimplemented;
13897 }
13898
13899 return S390_DECODE_UNKNOWN_INSN;
13900
13901ok:
13902 return S390_DECODE_OK;
13903
13904unimplemented:
13905 return S390_DECODE_UNIMPLEMENTED_INSN;
13906}
13907
13908static s390_decode_t
13909s390_decode_4byte_and_irgen(UChar *bytes)
13910{
13911 typedef union {
13912 struct {
13913 unsigned int op1 : 8;
13914 unsigned int r1 : 4;
13915 unsigned int op2 : 4;
13916 unsigned int i2 : 16;
13917 } RI;
13918 struct {
13919 unsigned int op : 16;
13920 unsigned int : 8;
13921 unsigned int r1 : 4;
13922 unsigned int r2 : 4;
13923 } RRE;
13924 struct {
13925 unsigned int op : 16;
13926 unsigned int r1 : 4;
13927 unsigned int : 4;
13928 unsigned int r3 : 4;
13929 unsigned int r2 : 4;
13930 } RRF;
13931 struct {
13932 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000013933 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000013934 unsigned int m4 : 4;
13935 unsigned int r1 : 4;
13936 unsigned int r2 : 4;
13937 } RRF2;
13938 struct {
13939 unsigned int op : 16;
13940 unsigned int r3 : 4;
13941 unsigned int : 4;
13942 unsigned int r1 : 4;
13943 unsigned int r2 : 4;
13944 } RRF3;
13945 struct {
13946 unsigned int op : 16;
13947 unsigned int r3 : 4;
13948 unsigned int : 4;
13949 unsigned int r1 : 4;
13950 unsigned int r2 : 4;
13951 } RRR;
13952 struct {
13953 unsigned int op : 16;
13954 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013955 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013956 unsigned int r1 : 4;
13957 unsigned int r2 : 4;
13958 } RRF4;
13959 struct {
floriane38f6412012-12-21 17:32:12 +000013960 unsigned int op : 16;
13961 unsigned int : 4;
13962 unsigned int m4 : 4;
13963 unsigned int r1 : 4;
13964 unsigned int r2 : 4;
13965 } RRF5;
13966 struct {
sewardj2019a972011-03-07 16:04:07 +000013967 unsigned int op : 8;
13968 unsigned int r1 : 4;
13969 unsigned int r3 : 4;
13970 unsigned int b2 : 4;
13971 unsigned int d2 : 12;
13972 } RS;
13973 struct {
13974 unsigned int op : 8;
13975 unsigned int r1 : 4;
13976 unsigned int r3 : 4;
13977 unsigned int i2 : 16;
13978 } RSI;
13979 struct {
13980 unsigned int op : 8;
13981 unsigned int r1 : 4;
13982 unsigned int x2 : 4;
13983 unsigned int b2 : 4;
13984 unsigned int d2 : 12;
13985 } RX;
13986 struct {
13987 unsigned int op : 16;
13988 unsigned int b2 : 4;
13989 unsigned int d2 : 12;
13990 } S;
13991 struct {
13992 unsigned int op : 8;
13993 unsigned int i2 : 8;
13994 unsigned int b1 : 4;
13995 unsigned int d1 : 12;
13996 } SI;
13997 } formats;
13998 union {
13999 formats fmt;
14000 UInt value;
14001 } ovl;
14002
14003 vassert(sizeof(formats) == 4);
14004
florianffbd84d2012-12-09 02:06:29 +000014005 ((UChar *)(&ovl.value))[0] = bytes[0];
14006 ((UChar *)(&ovl.value))[1] = bytes[1];
14007 ((UChar *)(&ovl.value))[2] = bytes[2];
14008 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000014009
14010 switch ((ovl.value & 0xff0f0000) >> 16) {
14011 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14012 ovl.fmt.RI.i2); goto ok;
14013 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14014 ovl.fmt.RI.i2); goto ok;
14015 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14016 ovl.fmt.RI.i2); goto ok;
14017 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14018 ovl.fmt.RI.i2); goto ok;
14019 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14020 ovl.fmt.RI.i2); goto ok;
14021 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14022 ovl.fmt.RI.i2); goto ok;
14023 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14024 ovl.fmt.RI.i2); goto ok;
14025 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14026 ovl.fmt.RI.i2); goto ok;
14027 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14028 ovl.fmt.RI.i2); goto ok;
14029 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14030 ovl.fmt.RI.i2); goto ok;
14031 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14032 ovl.fmt.RI.i2); goto ok;
14033 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14034 ovl.fmt.RI.i2); goto ok;
14035 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14036 ovl.fmt.RI.i2); goto ok;
14037 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14038 ovl.fmt.RI.i2); goto ok;
14039 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14040 ovl.fmt.RI.i2); goto ok;
14041 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14042 ovl.fmt.RI.i2); goto ok;
14043 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14044 ovl.fmt.RI.i2); goto ok;
14045 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14046 ovl.fmt.RI.i2); goto ok;
14047 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14048 ovl.fmt.RI.i2); goto ok;
14049 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14050 ovl.fmt.RI.i2); goto ok;
14051 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14052 goto ok;
14053 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14054 ovl.fmt.RI.i2); goto ok;
14055 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14056 ovl.fmt.RI.i2); goto ok;
14057 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14058 ovl.fmt.RI.i2); goto ok;
14059 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14060 goto ok;
14061 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14062 ovl.fmt.RI.i2); goto ok;
14063 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14064 goto ok;
14065 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14066 ovl.fmt.RI.i2); goto ok;
14067 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14068 goto ok;
14069 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14070 ovl.fmt.RI.i2); goto ok;
14071 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14072 goto ok;
14073 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14074 ovl.fmt.RI.i2); goto ok;
14075 }
14076
14077 switch ((ovl.value & 0xffff0000) >> 16) {
14078 case 0x8000: /* SSM */ goto unimplemented;
14079 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014080 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014081 case 0xb202: /* STIDP */ goto unimplemented;
14082 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014083 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14084 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014085 case 0xb206: /* SCKC */ goto unimplemented;
14086 case 0xb207: /* STCKC */ goto unimplemented;
14087 case 0xb208: /* SPT */ goto unimplemented;
14088 case 0xb209: /* STPT */ goto unimplemented;
14089 case 0xb20a: /* SPKA */ goto unimplemented;
14090 case 0xb20b: /* IPK */ goto unimplemented;
14091 case 0xb20d: /* PTLB */ goto unimplemented;
14092 case 0xb210: /* SPX */ goto unimplemented;
14093 case 0xb211: /* STPX */ goto unimplemented;
14094 case 0xb212: /* STAP */ goto unimplemented;
14095 case 0xb214: /* SIE */ goto unimplemented;
14096 case 0xb218: /* PC */ goto unimplemented;
14097 case 0xb219: /* SAC */ goto unimplemented;
14098 case 0xb21a: /* CFC */ goto unimplemented;
14099 case 0xb221: /* IPTE */ goto unimplemented;
14100 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
14101 case 0xb223: /* IVSK */ goto unimplemented;
14102 case 0xb224: /* IAC */ goto unimplemented;
14103 case 0xb225: /* SSAR */ goto unimplemented;
14104 case 0xb226: /* EPAR */ goto unimplemented;
14105 case 0xb227: /* ESAR */ goto unimplemented;
14106 case 0xb228: /* PT */ goto unimplemented;
14107 case 0xb229: /* ISKE */ goto unimplemented;
14108 case 0xb22a: /* RRBE */ goto unimplemented;
14109 case 0xb22b: /* SSKE */ goto unimplemented;
14110 case 0xb22c: /* TB */ goto unimplemented;
14111 case 0xb22d: /* DXR */ goto unimplemented;
14112 case 0xb22e: /* PGIN */ goto unimplemented;
14113 case 0xb22f: /* PGOUT */ goto unimplemented;
14114 case 0xb230: /* CSCH */ goto unimplemented;
14115 case 0xb231: /* HSCH */ goto unimplemented;
14116 case 0xb232: /* MSCH */ goto unimplemented;
14117 case 0xb233: /* SSCH */ goto unimplemented;
14118 case 0xb234: /* STSCH */ goto unimplemented;
14119 case 0xb235: /* TSCH */ goto unimplemented;
14120 case 0xb236: /* TPI */ goto unimplemented;
14121 case 0xb237: /* SAL */ goto unimplemented;
14122 case 0xb238: /* RSCH */ goto unimplemented;
14123 case 0xb239: /* STCRW */ goto unimplemented;
14124 case 0xb23a: /* STCPS */ goto unimplemented;
14125 case 0xb23b: /* RCHP */ goto unimplemented;
14126 case 0xb23c: /* SCHM */ goto unimplemented;
14127 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000014128 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14129 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014130 case 0xb244: /* SQDR */ goto unimplemented;
14131 case 0xb245: /* SQER */ goto unimplemented;
14132 case 0xb246: /* STURA */ goto unimplemented;
14133 case 0xb247: /* MSTA */ goto unimplemented;
14134 case 0xb248: /* PALB */ goto unimplemented;
14135 case 0xb249: /* EREG */ goto unimplemented;
14136 case 0xb24a: /* ESTA */ goto unimplemented;
14137 case 0xb24b: /* LURA */ goto unimplemented;
14138 case 0xb24c: /* TAR */ goto unimplemented;
14139 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14140 ovl.fmt.RRE.r2); goto ok;
14141 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14142 goto ok;
14143 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14144 goto ok;
14145 case 0xb250: /* CSP */ goto unimplemented;
14146 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14147 ovl.fmt.RRE.r2); goto ok;
14148 case 0xb254: /* MVPG */ goto unimplemented;
14149 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14150 ovl.fmt.RRE.r2); goto ok;
14151 case 0xb257: /* CUSE */ goto unimplemented;
14152 case 0xb258: /* BSG */ goto unimplemented;
14153 case 0xb25a: /* BSA */ goto unimplemented;
14154 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14155 ovl.fmt.RRE.r2); goto ok;
14156 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14157 ovl.fmt.RRE.r2); goto ok;
14158 case 0xb263: /* CMPSC */ goto unimplemented;
14159 case 0xb274: /* SIGA */ goto unimplemented;
14160 case 0xb276: /* XSCH */ goto unimplemented;
14161 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014162 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 +000014163 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014164 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 +000014165 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014166 case 0xb280: /* LPP */ goto unimplemented;
14167 case 0xb284: /* LCCTL */ goto unimplemented;
14168 case 0xb285: /* LPCTL */ goto unimplemented;
14169 case 0xb286: /* QSI */ goto unimplemented;
14170 case 0xb287: /* LSCTL */ goto unimplemented;
14171 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014172 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14173 goto ok;
14174 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14175 goto ok;
14176 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14177 goto ok;
florian730448f2012-02-04 17:07:07 +000014178 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 +000014179 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14180 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14181 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000014182 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14183 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14184 goto ok;
florian933065d2011-07-11 01:48:02 +000014185 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14186 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014187 case 0xb2b1: /* STFL */ goto unimplemented;
14188 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000014189 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14190 goto ok;
florian82cdba62013-03-12 01:31:24 +000014191 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14192 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014193 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014194 case 0xb2e0: /* SCCTR */ goto unimplemented;
14195 case 0xb2e1: /* SPCTR */ goto unimplemented;
14196 case 0xb2e4: /* ECCTR */ goto unimplemented;
14197 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014198 case 0xb2e8: /* PPA */ goto unimplemented;
14199 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014200 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014201 case 0xb2f8: /* TEND */ goto unimplemented;
14202 case 0xb2fa: /* NIAI */ goto unimplemented;
14203 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014204 case 0xb2ff: /* TRAP4 */ goto unimplemented;
14205 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14206 ovl.fmt.RRE.r2); goto ok;
14207 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14208 ovl.fmt.RRE.r2); goto ok;
14209 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14210 ovl.fmt.RRE.r2); goto ok;
14211 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14212 ovl.fmt.RRE.r2); goto ok;
14213 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14214 ovl.fmt.RRE.r2); goto ok;
14215 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14216 ovl.fmt.RRE.r2); goto ok;
14217 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14218 ovl.fmt.RRE.r2); goto ok;
14219 case 0xb307: /* MXDBR */ goto unimplemented;
14220 case 0xb308: /* KEBR */ goto unimplemented;
14221 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14222 ovl.fmt.RRE.r2); goto ok;
14223 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14224 ovl.fmt.RRE.r2); goto ok;
14225 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14226 ovl.fmt.RRE.r2); goto ok;
14227 case 0xb30c: /* MDEBR */ goto unimplemented;
14228 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14229 ovl.fmt.RRE.r2); goto ok;
14230 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14231 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14232 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14233 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14234 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14235 ovl.fmt.RRE.r2); goto ok;
14236 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14237 ovl.fmt.RRE.r2); goto ok;
14238 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14239 ovl.fmt.RRE.r2); goto ok;
14240 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14241 ovl.fmt.RRE.r2); goto ok;
14242 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14243 ovl.fmt.RRE.r2); goto ok;
14244 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14245 ovl.fmt.RRE.r2); goto ok;
14246 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14247 ovl.fmt.RRE.r2); goto ok;
14248 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14249 ovl.fmt.RRE.r2); goto ok;
14250 case 0xb318: /* KDBR */ goto unimplemented;
14251 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14252 ovl.fmt.RRE.r2); goto ok;
14253 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14254 ovl.fmt.RRE.r2); goto ok;
14255 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14256 ovl.fmt.RRE.r2); goto ok;
14257 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14258 ovl.fmt.RRE.r2); goto ok;
14259 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14260 ovl.fmt.RRE.r2); goto ok;
14261 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14262 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14263 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14264 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14265 case 0xb324: /* LDER */ goto unimplemented;
14266 case 0xb325: /* LXDR */ goto unimplemented;
14267 case 0xb326: /* LXER */ goto unimplemented;
14268 case 0xb32e: /* MAER */ goto unimplemented;
14269 case 0xb32f: /* MSER */ goto unimplemented;
14270 case 0xb336: /* SQXR */ goto unimplemented;
14271 case 0xb337: /* MEER */ goto unimplemented;
14272 case 0xb338: /* MAYLR */ goto unimplemented;
14273 case 0xb339: /* MYLR */ goto unimplemented;
14274 case 0xb33a: /* MAYR */ goto unimplemented;
14275 case 0xb33b: /* MYR */ goto unimplemented;
14276 case 0xb33c: /* MAYHR */ goto unimplemented;
14277 case 0xb33d: /* MYHR */ goto unimplemented;
14278 case 0xb33e: /* MADR */ goto unimplemented;
14279 case 0xb33f: /* MSDR */ goto unimplemented;
14280 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14281 ovl.fmt.RRE.r2); goto ok;
14282 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14283 ovl.fmt.RRE.r2); goto ok;
14284 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14285 ovl.fmt.RRE.r2); goto ok;
14286 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14287 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014288 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14289 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14290 ovl.fmt.RRF2.r2); goto ok;
14291 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14292 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14293 ovl.fmt.RRF2.r2); goto ok;
14294 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14295 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14296 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014297 case 0xb347: /* FIXBR */ goto unimplemented;
14298 case 0xb348: /* KXBR */ goto unimplemented;
14299 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14300 ovl.fmt.RRE.r2); goto ok;
14301 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14302 ovl.fmt.RRE.r2); goto ok;
14303 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14304 ovl.fmt.RRE.r2); goto ok;
14305 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14306 ovl.fmt.RRE.r2); goto ok;
14307 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14308 ovl.fmt.RRE.r2); goto ok;
14309 case 0xb350: /* TBEDR */ goto unimplemented;
14310 case 0xb351: /* TBDR */ goto unimplemented;
14311 case 0xb353: /* DIEBR */ goto unimplemented;
14312 case 0xb357: /* FIEBR */ goto unimplemented;
14313 case 0xb358: /* THDER */ goto unimplemented;
14314 case 0xb359: /* THDR */ goto unimplemented;
14315 case 0xb35b: /* DIDBR */ goto unimplemented;
14316 case 0xb35f: /* FIDBR */ goto unimplemented;
14317 case 0xb360: /* LPXR */ goto unimplemented;
14318 case 0xb361: /* LNXR */ goto unimplemented;
14319 case 0xb362: /* LTXR */ goto unimplemented;
14320 case 0xb363: /* LCXR */ goto unimplemented;
14321 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14322 ovl.fmt.RRE.r2); goto ok;
14323 case 0xb366: /* LEXR */ goto unimplemented;
14324 case 0xb367: /* FIXR */ goto unimplemented;
14325 case 0xb369: /* CXR */ goto unimplemented;
14326 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14327 ovl.fmt.RRE.r2); goto ok;
14328 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14329 ovl.fmt.RRE.r2); goto ok;
14330 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14331 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14332 goto ok;
14333 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14334 ovl.fmt.RRE.r2); goto ok;
14335 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14336 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14337 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14338 case 0xb377: /* FIER */ goto unimplemented;
14339 case 0xb37f: /* FIDR */ goto unimplemented;
14340 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14341 case 0xb385: /* SFASR */ goto unimplemented;
14342 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014343 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14344 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14345 ovl.fmt.RRF2.r2); goto ok;
14346 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14347 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14348 ovl.fmt.RRF2.r2); goto ok;
14349 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14350 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14351 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014352 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14353 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14354 ovl.fmt.RRF2.r2); goto ok;
14355 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14356 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14357 ovl.fmt.RRF2.r2); goto ok;
14358 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14359 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14360 ovl.fmt.RRF2.r2); goto ok;
14361 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14362 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14363 ovl.fmt.RRF2.r2); goto ok;
14364 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14365 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14366 ovl.fmt.RRF2.r2); goto ok;
14367 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14368 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14369 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014370 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14371 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14372 ovl.fmt.RRF2.r2); goto ok;
14373 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14374 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14375 ovl.fmt.RRF2.r2); goto ok;
14376 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14377 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14378 ovl.fmt.RRF2.r2); goto ok;
14379 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14380 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14381 ovl.fmt.RRF2.r2); goto ok;
14382 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14383 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14384 ovl.fmt.RRF2.r2); goto ok;
14385 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14386 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14387 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014388 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14389 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14390 ovl.fmt.RRF2.r2); goto ok;
14391 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14392 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14393 ovl.fmt.RRF2.r2); goto ok;
14394 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14395 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14396 ovl.fmt.RRF2.r2); goto ok;
14397 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14398 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14399 ovl.fmt.RRF2.r2); goto ok;
14400 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14401 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14402 ovl.fmt.RRF2.r2); goto ok;
14403 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14404 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14405 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014406 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14407 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14408 ovl.fmt.RRF2.r2); goto ok;
14409 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14410 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14411 ovl.fmt.RRF2.r2); goto ok;
14412 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14413 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14414 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014415 case 0xb3b4: /* CEFR */ goto unimplemented;
14416 case 0xb3b5: /* CDFR */ goto unimplemented;
14417 case 0xb3b6: /* CXFR */ goto unimplemented;
14418 case 0xb3b8: /* CFER */ goto unimplemented;
14419 case 0xb3b9: /* CFDR */ goto unimplemented;
14420 case 0xb3ba: /* CFXR */ goto unimplemented;
14421 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14422 ovl.fmt.RRE.r2); goto ok;
14423 case 0xb3c4: /* CEGR */ goto unimplemented;
14424 case 0xb3c5: /* CDGR */ goto unimplemented;
14425 case 0xb3c6: /* CXGR */ goto unimplemented;
14426 case 0xb3c8: /* CGER */ goto unimplemented;
14427 case 0xb3c9: /* CGDR */ goto unimplemented;
14428 case 0xb3ca: /* CGXR */ goto unimplemented;
14429 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14430 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014431 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14432 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14433 ovl.fmt.RRF4.r2); goto ok;
14434 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14435 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14436 ovl.fmt.RRF4.r2); goto ok;
14437 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14438 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14439 ovl.fmt.RRF4.r2); goto ok;
14440 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14441 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14442 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014443 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14444 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14445 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14446 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14447 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014448 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14449 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014450 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014451 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14452 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14453 ovl.fmt.RRF4.r2); goto ok;
14454 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14455 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14456 ovl.fmt.RRF4.r2); goto ok;
14457 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14458 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14459 ovl.fmt.RRF4.r2); goto ok;
14460 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14461 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14462 ovl.fmt.RRF4.r2); goto ok;
14463 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14464 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14465 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14466 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14467 ovl.fmt.RRF2.r2); goto ok;
14468 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14469 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014470 case 0xb3df: /* FIXTR */ goto unimplemented;
14471 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014472 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14473 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14474 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014475 case 0xb3e2: /* CUDTR */ goto unimplemented;
14476 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014477 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14478 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014479 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14480 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014481 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14482 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014483 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014484 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14485 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14486 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014487 case 0xb3ea: /* CUXTR */ goto unimplemented;
14488 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014489 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14490 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014491 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14492 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014493 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14494 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014495 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14496 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14497 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014498 case 0xb3f2: /* CDUTR */ goto unimplemented;
14499 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014500 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14501 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014502 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14503 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14504 ovl.fmt.RRF4.r2); goto ok;
14505 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14506 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14507 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14508 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14509 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014510 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14511 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14512 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014513 case 0xb3fa: /* CXUTR */ goto unimplemented;
14514 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014515 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14516 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014517 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14518 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14519 ovl.fmt.RRF4.r2); goto ok;
14520 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14521 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14522 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14523 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14524 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014525 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14526 ovl.fmt.RRE.r2); goto ok;
14527 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14528 ovl.fmt.RRE.r2); goto ok;
14529 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14530 ovl.fmt.RRE.r2); goto ok;
14531 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14532 ovl.fmt.RRE.r2); goto ok;
14533 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14534 ovl.fmt.RRE.r2); goto ok;
14535 case 0xb905: /* LURAG */ goto unimplemented;
14536 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14537 ovl.fmt.RRE.r2); goto ok;
14538 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14539 ovl.fmt.RRE.r2); goto ok;
14540 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14541 ovl.fmt.RRE.r2); goto ok;
14542 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14543 ovl.fmt.RRE.r2); goto ok;
14544 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14545 ovl.fmt.RRE.r2); goto ok;
14546 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14547 ovl.fmt.RRE.r2); goto ok;
14548 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14549 ovl.fmt.RRE.r2); goto ok;
14550 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14551 ovl.fmt.RRE.r2); goto ok;
14552 case 0xb90e: /* EREGG */ goto unimplemented;
14553 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14554 ovl.fmt.RRE.r2); goto ok;
14555 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14556 ovl.fmt.RRE.r2); goto ok;
14557 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14558 ovl.fmt.RRE.r2); goto ok;
14559 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14560 ovl.fmt.RRE.r2); goto ok;
14561 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14562 ovl.fmt.RRE.r2); goto ok;
14563 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14564 ovl.fmt.RRE.r2); goto ok;
14565 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14566 ovl.fmt.RRE.r2); goto ok;
14567 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14568 ovl.fmt.RRE.r2); goto ok;
14569 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14570 ovl.fmt.RRE.r2); goto ok;
14571 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14572 ovl.fmt.RRE.r2); goto ok;
14573 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14574 ovl.fmt.RRE.r2); goto ok;
14575 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14576 ovl.fmt.RRE.r2); goto ok;
14577 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14578 ovl.fmt.RRE.r2); goto ok;
14579 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14580 ovl.fmt.RRE.r2); goto ok;
14581 case 0xb91e: /* KMAC */ goto unimplemented;
14582 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14583 ovl.fmt.RRE.r2); goto ok;
14584 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14585 ovl.fmt.RRE.r2); goto ok;
14586 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14587 ovl.fmt.RRE.r2); goto ok;
14588 case 0xb925: /* STURG */ goto unimplemented;
14589 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14590 ovl.fmt.RRE.r2); goto ok;
14591 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14592 ovl.fmt.RRE.r2); goto ok;
14593 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014594 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014595 case 0xb92b: /* KMO */ goto unimplemented;
14596 case 0xb92c: /* PCC */ goto unimplemented;
14597 case 0xb92d: /* KMCTR */ goto unimplemented;
14598 case 0xb92e: /* KM */ goto unimplemented;
14599 case 0xb92f: /* KMC */ goto unimplemented;
14600 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14601 ovl.fmt.RRE.r2); goto ok;
14602 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14603 ovl.fmt.RRE.r2); goto ok;
14604 case 0xb93e: /* KIMD */ goto unimplemented;
14605 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014606 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14607 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14608 ovl.fmt.RRF2.r2); goto ok;
14609 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14610 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14611 ovl.fmt.RRF2.r2); goto ok;
14612 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14613 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14614 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014615 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14616 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014617 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14618 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14619 ovl.fmt.RRF2.r2); goto ok;
14620 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14621 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14622 ovl.fmt.RRF2.r2); goto ok;
14623 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14624 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14625 ovl.fmt.RRF2.r2); goto ok;
14626 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14627 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14628 ovl.fmt.RRF2.r2); goto ok;
14629 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14630 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14631 ovl.fmt.RRF2.r2); goto ok;
14632 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14633 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14634 ovl.fmt.RRF2.r2); goto ok;
14635 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14636 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14637 ovl.fmt.RRF2.r2); goto ok;
14638 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14639 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14640 ovl.fmt.RRF2.r2); goto ok;
14641 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14642 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14643 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014644 case 0xb960: /* CGRT */ goto unimplemented;
14645 case 0xb961: /* CLGRT */ goto unimplemented;
14646 case 0xb972: /* CRT */ goto unimplemented;
14647 case 0xb973: /* CLRT */ goto unimplemented;
14648 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14649 ovl.fmt.RRE.r2); goto ok;
14650 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14651 ovl.fmt.RRE.r2); goto ok;
14652 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14653 ovl.fmt.RRE.r2); goto ok;
14654 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14655 ovl.fmt.RRE.r2); goto ok;
14656 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14657 ovl.fmt.RRE.r2); goto ok;
14658 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14659 ovl.fmt.RRE.r2); goto ok;
14660 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14661 ovl.fmt.RRE.r2); goto ok;
14662 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14663 ovl.fmt.RRE.r2); goto ok;
14664 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14665 ovl.fmt.RRE.r2); goto ok;
14666 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14667 ovl.fmt.RRE.r2); goto ok;
14668 case 0xb98a: /* CSPG */ goto unimplemented;
14669 case 0xb98d: /* EPSW */ goto unimplemented;
14670 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014671 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014672 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14673 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14674 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14675 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14676 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14677 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014678 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14679 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014680 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14681 ovl.fmt.RRE.r2); goto ok;
14682 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14683 ovl.fmt.RRE.r2); goto ok;
14684 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14685 ovl.fmt.RRE.r2); goto ok;
14686 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14687 ovl.fmt.RRE.r2); goto ok;
14688 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14689 ovl.fmt.RRE.r2); goto ok;
14690 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14691 ovl.fmt.RRE.r2); goto ok;
14692 case 0xb99a: /* EPAIR */ goto unimplemented;
14693 case 0xb99b: /* ESAIR */ goto unimplemented;
14694 case 0xb99d: /* ESEA */ goto unimplemented;
14695 case 0xb99e: /* PTI */ goto unimplemented;
14696 case 0xb99f: /* SSAIR */ goto unimplemented;
14697 case 0xb9a2: /* PTF */ goto unimplemented;
14698 case 0xb9aa: /* LPTEA */ goto unimplemented;
14699 case 0xb9ae: /* RRBM */ goto unimplemented;
14700 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014701 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14702 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14703 goto ok;
florian2a415a12012-07-21 17:41:36 +000014704 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14705 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14706 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014707 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14708 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014709 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14710 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014711 case 0xb9bd: /* TRTRE */ goto unimplemented;
14712 case 0xb9be: /* SRSTU */ goto unimplemented;
14713 case 0xb9bf: /* TRTE */ goto unimplemented;
14714 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14715 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14716 goto ok;
14717 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14718 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14719 goto ok;
14720 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14721 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14722 goto ok;
14723 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14724 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14725 goto ok;
14726 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14727 ovl.fmt.RRE.r2); goto ok;
14728 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14729 ovl.fmt.RRE.r2); goto ok;
14730 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14731 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14732 goto ok;
14733 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14734 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14735 goto ok;
14736 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14737 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14738 goto ok;
14739 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14740 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14741 goto ok;
14742 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14743 ovl.fmt.RRE.r2); goto ok;
14744 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14745 ovl.fmt.RRE.r2); goto ok;
14746 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014747 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14748 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14749 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014750 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14751 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14752 goto ok;
14753 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14754 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14755 goto ok;
14756 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14757 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14758 goto ok;
14759 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14760 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14761 goto ok;
14762 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14763 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14764 goto ok;
14765 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14766 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14767 goto ok;
14768 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14769 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14770 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014771 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14772 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14773 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014774 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14775 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14776 goto ok;
14777 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14778 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14779 goto ok;
14780 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14781 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14782 goto ok;
14783 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14784 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14785 goto ok;
14786 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14787 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14788 goto ok;
14789 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14790 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14791 goto ok;
14792 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14793 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14794 goto ok;
14795 }
14796
14797 switch ((ovl.value & 0xff000000) >> 24) {
14798 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14799 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14800 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14801 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14802 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14803 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14804 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14805 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14806 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14807 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14808 case 0x45: /* BAL */ goto unimplemented;
14809 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14810 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14811 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14812 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14813 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14814 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14815 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14816 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14817 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14818 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14819 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14820 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14821 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14822 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14823 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14824 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14825 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14826 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14827 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14828 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14829 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14830 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14831 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14832 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14833 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14834 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14835 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14836 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14837 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14838 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14839 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14840 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14841 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14842 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14843 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14844 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14845 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14846 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14847 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14848 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14849 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14850 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14851 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14852 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14853 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14854 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14855 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14856 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14857 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14858 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14859 case 0x67: /* MXD */ goto unimplemented;
14860 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14861 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14862 case 0x69: /* CD */ goto unimplemented;
14863 case 0x6a: /* AD */ goto unimplemented;
14864 case 0x6b: /* SD */ goto unimplemented;
14865 case 0x6c: /* MD */ goto unimplemented;
14866 case 0x6d: /* DD */ goto unimplemented;
14867 case 0x6e: /* AW */ goto unimplemented;
14868 case 0x6f: /* SW */ goto unimplemented;
14869 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14870 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14871 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14872 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14873 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14874 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14875 case 0x79: /* CE */ goto unimplemented;
14876 case 0x7a: /* AE */ goto unimplemented;
14877 case 0x7b: /* SE */ goto unimplemented;
14878 case 0x7c: /* MDE */ goto unimplemented;
14879 case 0x7d: /* DE */ goto unimplemented;
14880 case 0x7e: /* AU */ goto unimplemented;
14881 case 0x7f: /* SU */ goto unimplemented;
14882 case 0x83: /* DIAG */ goto unimplemented;
14883 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
14884 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14885 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
14886 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14887 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14888 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14889 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14890 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14891 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14892 ovl.fmt.RS.d2); goto ok;
14893 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14894 ovl.fmt.RS.d2); goto ok;
14895 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14896 ovl.fmt.RS.d2); goto ok;
14897 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14898 ovl.fmt.RS.d2); goto ok;
14899 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14900 ovl.fmt.RS.d2); goto ok;
14901 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14902 ovl.fmt.RS.d2); goto ok;
14903 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14904 ovl.fmt.RS.d2); goto ok;
14905 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14906 ovl.fmt.RS.d2); goto ok;
14907 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14908 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14909 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14910 ovl.fmt.SI.d1); goto ok;
14911 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14912 ovl.fmt.SI.d1); goto ok;
14913 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14914 ovl.fmt.SI.d1); goto ok;
14915 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14916 ovl.fmt.SI.d1); goto ok;
14917 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14918 ovl.fmt.SI.d1); goto ok;
14919 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14920 ovl.fmt.SI.d1); goto ok;
14921 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14922 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14923 case 0x99: /* TRACE */ goto unimplemented;
14924 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14925 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14926 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14927 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14928 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
14929 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14930 goto ok;
14931 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
14932 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14933 goto ok;
14934 case 0xac: /* STNSM */ goto unimplemented;
14935 case 0xad: /* STOSM */ goto unimplemented;
14936 case 0xae: /* SIGP */ goto unimplemented;
14937 case 0xaf: /* MC */ goto unimplemented;
14938 case 0xb1: /* LRA */ goto unimplemented;
14939 case 0xb6: /* STCTL */ goto unimplemented;
14940 case 0xb7: /* LCTL */ goto unimplemented;
14941 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14942 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014943 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14944 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014945 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14946 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14947 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14948 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14949 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14950 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14951 }
14952
14953 return S390_DECODE_UNKNOWN_INSN;
14954
14955ok:
14956 return S390_DECODE_OK;
14957
14958unimplemented:
14959 return S390_DECODE_UNIMPLEMENTED_INSN;
14960}
14961
14962static s390_decode_t
14963s390_decode_6byte_and_irgen(UChar *bytes)
14964{
14965 typedef union {
14966 struct {
14967 unsigned int op1 : 8;
14968 unsigned int r1 : 4;
14969 unsigned int r3 : 4;
14970 unsigned int i2 : 16;
14971 unsigned int : 8;
14972 unsigned int op2 : 8;
14973 } RIE;
14974 struct {
14975 unsigned int op1 : 8;
14976 unsigned int r1 : 4;
14977 unsigned int r2 : 4;
14978 unsigned int i3 : 8;
14979 unsigned int i4 : 8;
14980 unsigned int i5 : 8;
14981 unsigned int op2 : 8;
14982 } RIE_RRUUU;
14983 struct {
14984 unsigned int op1 : 8;
14985 unsigned int r1 : 4;
14986 unsigned int : 4;
14987 unsigned int i2 : 16;
14988 unsigned int m3 : 4;
14989 unsigned int : 4;
14990 unsigned int op2 : 8;
14991 } RIEv1;
14992 struct {
14993 unsigned int op1 : 8;
14994 unsigned int r1 : 4;
14995 unsigned int r2 : 4;
14996 unsigned int i4 : 16;
14997 unsigned int m3 : 4;
14998 unsigned int : 4;
14999 unsigned int op2 : 8;
15000 } RIE_RRPU;
15001 struct {
15002 unsigned int op1 : 8;
15003 unsigned int r1 : 4;
15004 unsigned int m3 : 4;
15005 unsigned int i4 : 16;
15006 unsigned int i2 : 8;
15007 unsigned int op2 : 8;
15008 } RIEv3;
15009 struct {
15010 unsigned int op1 : 8;
15011 unsigned int r1 : 4;
15012 unsigned int op2 : 4;
15013 unsigned int i2 : 32;
15014 } RIL;
15015 struct {
15016 unsigned int op1 : 8;
15017 unsigned int r1 : 4;
15018 unsigned int m3 : 4;
15019 unsigned int b4 : 4;
15020 unsigned int d4 : 12;
15021 unsigned int i2 : 8;
15022 unsigned int op2 : 8;
15023 } RIS;
15024 struct {
15025 unsigned int op1 : 8;
15026 unsigned int r1 : 4;
15027 unsigned int r2 : 4;
15028 unsigned int b4 : 4;
15029 unsigned int d4 : 12;
15030 unsigned int m3 : 4;
15031 unsigned int : 4;
15032 unsigned int op2 : 8;
15033 } RRS;
15034 struct {
15035 unsigned int op1 : 8;
15036 unsigned int l1 : 4;
15037 unsigned int : 4;
15038 unsigned int b1 : 4;
15039 unsigned int d1 : 12;
15040 unsigned int : 8;
15041 unsigned int op2 : 8;
15042 } RSL;
15043 struct {
15044 unsigned int op1 : 8;
15045 unsigned int r1 : 4;
15046 unsigned int r3 : 4;
15047 unsigned int b2 : 4;
15048 unsigned int dl2 : 12;
15049 unsigned int dh2 : 8;
15050 unsigned int op2 : 8;
15051 } RSY;
15052 struct {
15053 unsigned int op1 : 8;
15054 unsigned int r1 : 4;
15055 unsigned int x2 : 4;
15056 unsigned int b2 : 4;
15057 unsigned int d2 : 12;
15058 unsigned int : 8;
15059 unsigned int op2 : 8;
15060 } RXE;
15061 struct {
15062 unsigned int op1 : 8;
15063 unsigned int r3 : 4;
15064 unsigned int x2 : 4;
15065 unsigned int b2 : 4;
15066 unsigned int d2 : 12;
15067 unsigned int r1 : 4;
15068 unsigned int : 4;
15069 unsigned int op2 : 8;
15070 } RXF;
15071 struct {
15072 unsigned int op1 : 8;
15073 unsigned int r1 : 4;
15074 unsigned int x2 : 4;
15075 unsigned int b2 : 4;
15076 unsigned int dl2 : 12;
15077 unsigned int dh2 : 8;
15078 unsigned int op2 : 8;
15079 } RXY;
15080 struct {
15081 unsigned int op1 : 8;
15082 unsigned int i2 : 8;
15083 unsigned int b1 : 4;
15084 unsigned int dl1 : 12;
15085 unsigned int dh1 : 8;
15086 unsigned int op2 : 8;
15087 } SIY;
15088 struct {
15089 unsigned int op : 8;
15090 unsigned int l : 8;
15091 unsigned int b1 : 4;
15092 unsigned int d1 : 12;
15093 unsigned int b2 : 4;
15094 unsigned int d2 : 12;
15095 } SS;
15096 struct {
15097 unsigned int op : 8;
15098 unsigned int l1 : 4;
15099 unsigned int l2 : 4;
15100 unsigned int b1 : 4;
15101 unsigned int d1 : 12;
15102 unsigned int b2 : 4;
15103 unsigned int d2 : 12;
15104 } SS_LLRDRD;
15105 struct {
15106 unsigned int op : 8;
15107 unsigned int r1 : 4;
15108 unsigned int r3 : 4;
15109 unsigned int b2 : 4;
15110 unsigned int d2 : 12;
15111 unsigned int b4 : 4;
15112 unsigned int d4 : 12;
15113 } SS_RRRDRD2;
15114 struct {
15115 unsigned int op : 16;
15116 unsigned int b1 : 4;
15117 unsigned int d1 : 12;
15118 unsigned int b2 : 4;
15119 unsigned int d2 : 12;
15120 } SSE;
15121 struct {
15122 unsigned int op1 : 8;
15123 unsigned int r3 : 4;
15124 unsigned int op2 : 4;
15125 unsigned int b1 : 4;
15126 unsigned int d1 : 12;
15127 unsigned int b2 : 4;
15128 unsigned int d2 : 12;
15129 } SSF;
15130 struct {
15131 unsigned int op : 16;
15132 unsigned int b1 : 4;
15133 unsigned int d1 : 12;
15134 unsigned int i2 : 16;
15135 } SIL;
15136 } formats;
15137 union {
15138 formats fmt;
15139 ULong value;
15140 } ovl;
15141
15142 vassert(sizeof(formats) == 6);
15143
florianffbd84d2012-12-09 02:06:29 +000015144 ((UChar *)(&ovl.value))[0] = bytes[0];
15145 ((UChar *)(&ovl.value))[1] = bytes[1];
15146 ((UChar *)(&ovl.value))[2] = bytes[2];
15147 ((UChar *)(&ovl.value))[3] = bytes[3];
15148 ((UChar *)(&ovl.value))[4] = bytes[4];
15149 ((UChar *)(&ovl.value))[5] = bytes[5];
15150 ((UChar *)(&ovl.value))[6] = 0x0;
15151 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000015152
15153 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15154 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15155 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15156 ovl.fmt.RXY.dl2,
15157 ovl.fmt.RXY.dh2); goto ok;
15158 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15159 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15160 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15161 ovl.fmt.RXY.dl2,
15162 ovl.fmt.RXY.dh2); goto ok;
15163 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15164 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15165 ovl.fmt.RXY.dl2,
15166 ovl.fmt.RXY.dh2); goto ok;
15167 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15168 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15169 ovl.fmt.RXY.dl2,
15170 ovl.fmt.RXY.dh2); goto ok;
15171 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15172 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15173 ovl.fmt.RXY.dl2,
15174 ovl.fmt.RXY.dh2); goto ok;
15175 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15176 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15177 ovl.fmt.RXY.dl2,
15178 ovl.fmt.RXY.dh2); goto ok;
15179 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15180 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15181 ovl.fmt.RXY.dl2,
15182 ovl.fmt.RXY.dh2); goto ok;
15183 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15184 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15185 ovl.fmt.RXY.dl2,
15186 ovl.fmt.RXY.dh2); goto ok;
15187 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15188 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15189 ovl.fmt.RXY.dl2,
15190 ovl.fmt.RXY.dh2); goto ok;
15191 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15192 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15193 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15194 ovl.fmt.RXY.dl2,
15195 ovl.fmt.RXY.dh2); goto ok;
15196 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15197 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15198 ovl.fmt.RXY.dl2,
15199 ovl.fmt.RXY.dh2); goto ok;
15200 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15201 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15202 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15203 ovl.fmt.RXY.dl2,
15204 ovl.fmt.RXY.dh2); goto ok;
15205 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15206 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15207 ovl.fmt.RXY.dl2,
15208 ovl.fmt.RXY.dh2); goto ok;
15209 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15210 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15211 ovl.fmt.RXY.dl2,
15212 ovl.fmt.RXY.dh2); goto ok;
15213 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15214 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15215 ovl.fmt.RXY.dl2,
15216 ovl.fmt.RXY.dh2); goto ok;
15217 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15218 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15219 ovl.fmt.RXY.dl2,
15220 ovl.fmt.RXY.dh2); goto ok;
15221 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15222 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15223 ovl.fmt.RXY.dl2,
15224 ovl.fmt.RXY.dh2); goto ok;
15225 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15226 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15227 ovl.fmt.RXY.dl2,
15228 ovl.fmt.RXY.dh2); goto ok;
15229 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15230 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15231 ovl.fmt.RXY.dl2,
15232 ovl.fmt.RXY.dh2); goto ok;
15233 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15234 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15235 ovl.fmt.RXY.dl2,
15236 ovl.fmt.RXY.dh2); goto ok;
15237 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15238 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15239 ovl.fmt.RXY.dl2,
15240 ovl.fmt.RXY.dh2); goto ok;
15241 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15242 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15243 ovl.fmt.RXY.dl2,
15244 ovl.fmt.RXY.dh2); goto ok;
15245 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15246 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15247 ovl.fmt.RXY.dl2,
15248 ovl.fmt.RXY.dh2); goto ok;
15249 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15250 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15251 ovl.fmt.RXY.dl2,
15252 ovl.fmt.RXY.dh2); goto ok;
15253 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15254 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15255 ovl.fmt.RXY.dl2,
15256 ovl.fmt.RXY.dh2); goto ok;
15257 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15258 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15259 ovl.fmt.RXY.dl2,
15260 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015261 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015262 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15263 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15264 ovl.fmt.RXY.dl2,
15265 ovl.fmt.RXY.dh2); goto ok;
15266 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15267 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15268 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15269 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15270 ovl.fmt.RXY.dh2); goto ok;
15271 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15272 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15273 ovl.fmt.RXY.dl2,
15274 ovl.fmt.RXY.dh2); goto ok;
15275 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15276 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15277 ovl.fmt.RXY.dl2,
15278 ovl.fmt.RXY.dh2); goto ok;
15279 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15280 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15281 ovl.fmt.RXY.dl2,
15282 ovl.fmt.RXY.dh2); goto ok;
15283 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15284 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15285 ovl.fmt.RXY.dl2,
15286 ovl.fmt.RXY.dh2); goto ok;
15287 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15288 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15289 ovl.fmt.RXY.dl2,
15290 ovl.fmt.RXY.dh2); goto ok;
15291 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15292 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15293 ovl.fmt.RXY.dl2,
15294 ovl.fmt.RXY.dh2); goto ok;
15295 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15296 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15297 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15298 ovl.fmt.RXY.dh2); goto ok;
15299 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15300 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15301 ovl.fmt.RXY.dl2,
15302 ovl.fmt.RXY.dh2); goto ok;
15303 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15304 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15305 ovl.fmt.RXY.dl2,
15306 ovl.fmt.RXY.dh2); goto ok;
15307 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15308 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15309 ovl.fmt.RXY.dl2,
15310 ovl.fmt.RXY.dh2); goto ok;
15311 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, 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 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, 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 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15320 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15321 ovl.fmt.RXY.dl2,
15322 ovl.fmt.RXY.dh2); goto ok;
15323 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15324 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15325 ovl.fmt.RXY.dl2,
15326 ovl.fmt.RXY.dh2); goto ok;
15327 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15328 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15329 ovl.fmt.RXY.dl2,
15330 ovl.fmt.RXY.dh2); goto ok;
15331 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15332 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15333 ovl.fmt.RXY.dl2,
15334 ovl.fmt.RXY.dh2); goto ok;
15335 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15336 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15337 ovl.fmt.RXY.dl2,
15338 ovl.fmt.RXY.dh2); goto ok;
15339 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15340 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15341 ovl.fmt.RXY.dl2,
15342 ovl.fmt.RXY.dh2); goto ok;
15343 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15344 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15345 ovl.fmt.RXY.dl2,
15346 ovl.fmt.RXY.dh2); goto ok;
15347 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15348 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15349 ovl.fmt.RXY.dl2,
15350 ovl.fmt.RXY.dh2); goto ok;
15351 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15352 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15353 ovl.fmt.RXY.dl2,
15354 ovl.fmt.RXY.dh2); goto ok;
15355 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15356 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15357 ovl.fmt.RXY.dl2,
15358 ovl.fmt.RXY.dh2); goto ok;
15359 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15360 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15361 ovl.fmt.RXY.dl2,
15362 ovl.fmt.RXY.dh2); goto ok;
15363 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15364 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15365 ovl.fmt.RXY.dl2,
15366 ovl.fmt.RXY.dh2); goto ok;
15367 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15368 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15369 ovl.fmt.RXY.dl2,
15370 ovl.fmt.RXY.dh2); goto ok;
15371 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15372 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15373 ovl.fmt.RXY.dl2,
15374 ovl.fmt.RXY.dh2); goto ok;
15375 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15376 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15377 ovl.fmt.RXY.dl2,
15378 ovl.fmt.RXY.dh2); goto ok;
15379 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15380 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15381 ovl.fmt.RXY.dl2,
15382 ovl.fmt.RXY.dh2); goto ok;
15383 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15384 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15385 ovl.fmt.RXY.dl2,
15386 ovl.fmt.RXY.dh2); goto ok;
15387 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15388 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15389 ovl.fmt.RXY.dl2,
15390 ovl.fmt.RXY.dh2); goto ok;
15391 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15392 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15393 ovl.fmt.RXY.dl2,
15394 ovl.fmt.RXY.dh2); goto ok;
15395 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15396 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15397 ovl.fmt.RXY.dl2,
15398 ovl.fmt.RXY.dh2); goto ok;
15399 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15400 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15401 ovl.fmt.RXY.dl2,
15402 ovl.fmt.RXY.dh2); goto ok;
15403 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15404 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15405 ovl.fmt.RXY.dl2,
15406 ovl.fmt.RXY.dh2); goto ok;
15407 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15408 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15409 ovl.fmt.RXY.dl2,
15410 ovl.fmt.RXY.dh2); goto ok;
15411 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15412 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15413 ovl.fmt.RXY.dl2,
15414 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015415 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015416 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15417 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15418 ovl.fmt.RXY.dl2,
15419 ovl.fmt.RXY.dh2); goto ok;
15420 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15421 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15422 ovl.fmt.RXY.dl2,
15423 ovl.fmt.RXY.dh2); goto ok;
15424 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15425 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15426 ovl.fmt.RXY.dl2,
15427 ovl.fmt.RXY.dh2); goto ok;
15428 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15429 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15430 ovl.fmt.RXY.dl2,
15431 ovl.fmt.RXY.dh2); goto ok;
15432 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15433 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15434 ovl.fmt.RXY.dl2,
15435 ovl.fmt.RXY.dh2); goto ok;
15436 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15437 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15438 ovl.fmt.RXY.dl2,
15439 ovl.fmt.RXY.dh2); goto ok;
15440 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15441 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15442 ovl.fmt.RXY.dl2,
15443 ovl.fmt.RXY.dh2); goto ok;
15444 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15445 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15446 ovl.fmt.RXY.dl2,
15447 ovl.fmt.RXY.dh2); goto ok;
15448 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15449 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15450 ovl.fmt.RXY.dl2,
15451 ovl.fmt.RXY.dh2); goto ok;
15452 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15453 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15454 ovl.fmt.RXY.dl2,
15455 ovl.fmt.RXY.dh2); goto ok;
15456 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15457 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15458 ovl.fmt.RXY.dl2,
15459 ovl.fmt.RXY.dh2); goto ok;
15460 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15461 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15462 ovl.fmt.RXY.dl2,
15463 ovl.fmt.RXY.dh2); goto ok;
15464 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15465 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15466 ovl.fmt.RXY.dl2,
15467 ovl.fmt.RXY.dh2); goto ok;
15468 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15469 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15470 ovl.fmt.RXY.dl2,
15471 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015472 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15473 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15474 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015475 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15476 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15477 ovl.fmt.RXY.dl2,
15478 ovl.fmt.RXY.dh2); goto ok;
15479 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15480 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15481 ovl.fmt.RXY.dl2,
15482 ovl.fmt.RXY.dh2); goto ok;
15483 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15484 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15485 ovl.fmt.RXY.dl2,
15486 ovl.fmt.RXY.dh2); goto ok;
15487 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15488 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15489 ovl.fmt.RXY.dl2,
15490 ovl.fmt.RXY.dh2); goto ok;
15491 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15492 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15493 ovl.fmt.RXY.dl2,
15494 ovl.fmt.RXY.dh2); goto ok;
15495 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15496 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15497 ovl.fmt.RXY.dl2,
15498 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015499 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015500 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15501 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15502 ovl.fmt.RXY.dl2,
15503 ovl.fmt.RXY.dh2); goto ok;
15504 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15505 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15506 ovl.fmt.RXY.dl2,
15507 ovl.fmt.RXY.dh2); goto ok;
15508 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15509 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15510 ovl.fmt.RXY.dl2,
15511 ovl.fmt.RXY.dh2); goto ok;
15512 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15513 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15514 ovl.fmt.RXY.dl2,
15515 ovl.fmt.RXY.dh2); goto ok;
15516 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15517 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15518 ovl.fmt.RSY.dl2,
15519 ovl.fmt.RSY.dh2); goto ok;
15520 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15521 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15522 ovl.fmt.RSY.dl2,
15523 ovl.fmt.RSY.dh2); goto ok;
15524 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15525 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15526 ovl.fmt.RSY.dl2,
15527 ovl.fmt.RSY.dh2); goto ok;
15528 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15529 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15530 ovl.fmt.RSY.dl2,
15531 ovl.fmt.RSY.dh2); goto ok;
15532 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15533 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15534 ovl.fmt.RSY.dl2,
15535 ovl.fmt.RSY.dh2); goto ok;
15536 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15537 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15538 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15539 ovl.fmt.RSY.dl2,
15540 ovl.fmt.RSY.dh2); goto ok;
15541 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15542 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15543 ovl.fmt.RSY.dl2,
15544 ovl.fmt.RSY.dh2); goto ok;
15545 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15546 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15547 ovl.fmt.RSY.dl2,
15548 ovl.fmt.RSY.dh2); goto ok;
15549 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15550 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15551 ovl.fmt.RSY.dl2,
15552 ovl.fmt.RSY.dh2); goto ok;
15553 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15554 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15555 ovl.fmt.RSY.dl2,
15556 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015557 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015558 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15559 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15560 ovl.fmt.RSY.dl2,
15561 ovl.fmt.RSY.dh2); goto ok;
15562 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15563 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15564 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15565 ovl.fmt.RSY.dl2,
15566 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015567 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015568 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15569 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15570 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15571 ovl.fmt.RSY.dh2); goto ok;
15572 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15573 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15574 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15575 ovl.fmt.RSY.dh2); goto ok;
15576 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15577 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15578 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15579 ovl.fmt.RSY.dl2,
15580 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015581 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15582 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15583 ovl.fmt.RSY.dl2,
15584 ovl.fmt.RSY.dh2); goto ok;
15585 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15586 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15587 ovl.fmt.RSY.dl2,
15588 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015589 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15590 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15591 ovl.fmt.RSY.dl2,
15592 ovl.fmt.RSY.dh2); goto ok;
15593 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15594 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15595 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15596 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015597 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15598 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15599 ovl.fmt.RSY.dl2,
15600 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015601 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15602 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15603 ovl.fmt.SIY.dh1); goto ok;
15604 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15605 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15606 ovl.fmt.SIY.dh1); goto ok;
15607 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15608 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15609 ovl.fmt.SIY.dh1); goto ok;
15610 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15611 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15612 ovl.fmt.SIY.dh1); goto ok;
15613 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15614 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15615 ovl.fmt.SIY.dh1); goto ok;
15616 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15617 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15618 ovl.fmt.SIY.dh1); goto ok;
15619 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15620 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15621 ovl.fmt.SIY.dh1); goto ok;
15622 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15623 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15624 ovl.fmt.SIY.dh1); goto ok;
15625 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15626 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15627 ovl.fmt.SIY.dh1); goto ok;
15628 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15629 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15630 ovl.fmt.SIY.dh1); goto ok;
15631 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15632 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15633 ovl.fmt.RSY.dl2,
15634 ovl.fmt.RSY.dh2); goto ok;
15635 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, 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 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15640 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15641 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15642 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15643 ovl.fmt.RSY.dl2,
15644 ovl.fmt.RSY.dh2); goto ok;
15645 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15646 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15647 ovl.fmt.RSY.dl2,
15648 ovl.fmt.RSY.dh2); goto ok;
15649 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15650 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15651 ovl.fmt.RSY.dl2,
15652 ovl.fmt.RSY.dh2); goto ok;
15653 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15654 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15655 ovl.fmt.RSY.dl2,
15656 ovl.fmt.RSY.dh2); goto ok;
15657 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15658 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15659 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15660 ovl.fmt.RSY.dh2); goto ok;
15661 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15662 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15663 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15664 ovl.fmt.RSY.dl2,
15665 ovl.fmt.RSY.dh2); goto ok;
15666 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15667 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15668 ovl.fmt.RSY.dl2,
15669 ovl.fmt.RSY.dh2); goto ok;
15670 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15671 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15672 ovl.fmt.RSY.dl2,
15673 ovl.fmt.RSY.dh2); goto ok;
15674 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15675 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15676 ovl.fmt.RSY.dl2,
15677 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015678 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15679 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15680 ovl.fmt.RSY.dl2,
15681 ovl.fmt.RSY.dh2,
15682 S390_XMNM_LOCG); goto ok;
15683 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15684 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15685 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15686 ovl.fmt.RSY.dh2,
15687 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015688 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15689 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15690 ovl.fmt.RSY.dl2,
15691 ovl.fmt.RSY.dh2); goto ok;
15692 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15693 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15694 ovl.fmt.RSY.dl2,
15695 ovl.fmt.RSY.dh2); goto ok;
15696 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, 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;
15700 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, 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 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15705 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15706 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15707 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015708 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15709 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15710 ovl.fmt.RSY.dl2,
15711 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15712 goto ok;
15713 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15714 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15715 ovl.fmt.RSY.dl2,
15716 ovl.fmt.RSY.dh2,
15717 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015718 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15719 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15720 ovl.fmt.RSY.dl2,
15721 ovl.fmt.RSY.dh2); goto ok;
15722 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15723 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15724 ovl.fmt.RSY.dl2,
15725 ovl.fmt.RSY.dh2); goto ok;
15726 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15727 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15728 ovl.fmt.RSY.dl2,
15729 ovl.fmt.RSY.dh2); goto ok;
15730 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15731 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15732 ovl.fmt.RSY.dl2,
15733 ovl.fmt.RSY.dh2); goto ok;
15734 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15735 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15736 ovl.fmt.RSY.dl2,
15737 ovl.fmt.RSY.dh2); goto ok;
15738 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15739 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15740 goto ok;
15741 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15742 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15743 goto ok;
15744 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15745 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15746 ovl.fmt.RIE_RRUUU.r1,
15747 ovl.fmt.RIE_RRUUU.r2,
15748 ovl.fmt.RIE_RRUUU.i3,
15749 ovl.fmt.RIE_RRUUU.i4,
15750 ovl.fmt.RIE_RRUUU.i5);
15751 goto ok;
15752 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15753 ovl.fmt.RIE_RRUUU.r1,
15754 ovl.fmt.RIE_RRUUU.r2,
15755 ovl.fmt.RIE_RRUUU.i3,
15756 ovl.fmt.RIE_RRUUU.i4,
15757 ovl.fmt.RIE_RRUUU.i5);
15758 goto ok;
15759 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15760 ovl.fmt.RIE_RRUUU.r1,
15761 ovl.fmt.RIE_RRUUU.r2,
15762 ovl.fmt.RIE_RRUUU.i3,
15763 ovl.fmt.RIE_RRUUU.i4,
15764 ovl.fmt.RIE_RRUUU.i5);
15765 goto ok;
15766 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15767 ovl.fmt.RIE_RRUUU.r1,
15768 ovl.fmt.RIE_RRUUU.r2,
15769 ovl.fmt.RIE_RRUUU.i3,
15770 ovl.fmt.RIE_RRUUU.i4,
15771 ovl.fmt.RIE_RRUUU.i5);
15772 goto ok;
florian2289cd42012-12-05 04:23:42 +000015773 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015774 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15775 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15776 ovl.fmt.RIE_RRPU.r1,
15777 ovl.fmt.RIE_RRPU.r2,
15778 ovl.fmt.RIE_RRPU.i4,
15779 ovl.fmt.RIE_RRPU.m3); goto ok;
15780 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15781 ovl.fmt.RIE_RRPU.r1,
15782 ovl.fmt.RIE_RRPU.r2,
15783 ovl.fmt.RIE_RRPU.i4,
15784 ovl.fmt.RIE_RRPU.m3); goto ok;
15785 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15786 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15787 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15788 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15789 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15790 ovl.fmt.RIE_RRPU.r1,
15791 ovl.fmt.RIE_RRPU.r2,
15792 ovl.fmt.RIE_RRPU.i4,
15793 ovl.fmt.RIE_RRPU.m3); goto ok;
15794 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15795 ovl.fmt.RIE_RRPU.r1,
15796 ovl.fmt.RIE_RRPU.r2,
15797 ovl.fmt.RIE_RRPU.i4,
15798 ovl.fmt.RIE_RRPU.m3); goto ok;
15799 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15800 ovl.fmt.RIEv3.r1,
15801 ovl.fmt.RIEv3.m3,
15802 ovl.fmt.RIEv3.i4,
15803 ovl.fmt.RIEv3.i2); goto ok;
15804 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15805 ovl.fmt.RIEv3.r1,
15806 ovl.fmt.RIEv3.m3,
15807 ovl.fmt.RIEv3.i4,
15808 ovl.fmt.RIEv3.i2); goto ok;
15809 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15810 ovl.fmt.RIEv3.r1,
15811 ovl.fmt.RIEv3.m3,
15812 ovl.fmt.RIEv3.i4,
15813 ovl.fmt.RIEv3.i2); goto ok;
15814 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15815 ovl.fmt.RIEv3.r1,
15816 ovl.fmt.RIEv3.m3,
15817 ovl.fmt.RIEv3.i4,
15818 ovl.fmt.RIEv3.i2); goto ok;
15819 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15820 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15821 goto ok;
15822 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15823 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15824 ovl.fmt.RIE.i2); goto ok;
15825 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15826 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15827 ovl.fmt.RIE.i2); goto ok;
15828 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15829 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15830 ovl.fmt.RIE.i2); goto ok;
15831 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15832 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15833 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15834 goto ok;
15835 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15836 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15837 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15838 goto ok;
15839 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15840 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15841 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15842 goto ok;
15843 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15844 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15845 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15846 goto ok;
15847 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15848 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15849 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15850 ovl.fmt.RIS.i2); goto ok;
15851 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15852 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15853 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15854 ovl.fmt.RIS.i2); goto ok;
15855 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15856 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15857 ovl.fmt.RIS.d4,
15858 ovl.fmt.RIS.i2); goto ok;
15859 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15860 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15861 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15862 ovl.fmt.RIS.i2); goto ok;
15863 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15864 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15865 ovl.fmt.RXE.d2); goto ok;
15866 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15867 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15868 ovl.fmt.RXE.d2); goto ok;
15869 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15870 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15871 ovl.fmt.RXE.d2); goto ok;
15872 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15873 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15874 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15875 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15876 ovl.fmt.RXE.d2); goto ok;
15877 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15878 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15879 ovl.fmt.RXE.d2); goto ok;
15880 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
15881 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15882 ovl.fmt.RXE.d2); goto ok;
15883 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
15884 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
15885 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15886 ovl.fmt.RXE.d2); goto ok;
15887 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
15888 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15889 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15890 ovl.fmt.RXF.r1); goto ok;
15891 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
15892 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15893 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15894 ovl.fmt.RXF.r1); goto ok;
15895 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
15896 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15897 ovl.fmt.RXE.d2); goto ok;
15898 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
15899 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15900 ovl.fmt.RXE.d2); goto ok;
15901 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
15902 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15903 ovl.fmt.RXE.d2); goto ok;
15904 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
15905 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15906 ovl.fmt.RXE.d2); goto ok;
15907 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
15908 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15909 ovl.fmt.RXE.d2); goto ok;
15910 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
15911 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15912 ovl.fmt.RXE.d2); goto ok;
15913 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
15914 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
15915 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15916 ovl.fmt.RXE.d2); goto ok;
15917 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
15918 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15919 ovl.fmt.RXE.d2); goto ok;
15920 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
15921 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15922 ovl.fmt.RXE.d2); goto ok;
15923 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
15924 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15925 ovl.fmt.RXE.d2); goto ok;
15926 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
15927 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15928 ovl.fmt.RXE.d2); goto ok;
15929 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
15930 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15931 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15932 ovl.fmt.RXF.r1); goto ok;
15933 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
15934 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15935 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15936 ovl.fmt.RXF.r1); goto ok;
15937 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
15938 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
15939 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
15940 case 0xed000000002eULL: /* MAE */ goto unimplemented;
15941 case 0xed000000002fULL: /* MSE */ goto unimplemented;
15942 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
15943 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
15944 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
15945 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
15946 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
15947 case 0xed000000003aULL: /* MAY */ goto unimplemented;
15948 case 0xed000000003bULL: /* MY */ goto unimplemented;
15949 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
15950 case 0xed000000003dULL: /* MYH */ goto unimplemented;
15951 case 0xed000000003eULL: /* MAD */ goto unimplemented;
15952 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000015953 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
15954 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15955 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15956 ovl.fmt.RXF.r1); goto ok;
15957 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
15958 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15959 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15960 ovl.fmt.RXF.r1); goto ok;
15961 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
15962 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15963 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15964 ovl.fmt.RXF.r1); goto ok;
15965 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
15966 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15967 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15968 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000015969 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
15970 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15971 ovl.fmt.RXE.d2); goto ok;
15972 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
15973 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15974 ovl.fmt.RXE.d2); goto ok;
15975 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
15976 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15977 ovl.fmt.RXE.d2); goto ok;
15978 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
15979 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15980 ovl.fmt.RXE.d2); goto ok;
15981 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
15982 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15983 ovl.fmt.RXE.d2); goto ok;
15984 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
15985 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15986 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015987 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
15988 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15989 ovl.fmt.RXY.dl2,
15990 ovl.fmt.RXY.dh2); goto ok;
15991 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
15992 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15993 ovl.fmt.RXY.dl2,
15994 ovl.fmt.RXY.dh2); goto ok;
15995 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
15996 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15997 ovl.fmt.RXY.dl2,
15998 ovl.fmt.RXY.dh2); goto ok;
15999 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16000 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16001 ovl.fmt.RXY.dl2,
16002 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000016003 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16004 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16005 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16006 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016007 }
16008
16009 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16010 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16011 ovl.fmt.RIL.i2); goto ok;
16012 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16013 ovl.fmt.RIL.i2); goto ok;
16014 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16015 ovl.fmt.RIL.i2); goto ok;
16016 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16017 ovl.fmt.RIL.i2); goto ok;
16018 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16019 ovl.fmt.RIL.i2); goto ok;
16020 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16021 ovl.fmt.RIL.i2); goto ok;
16022 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16023 ovl.fmt.RIL.i2); goto ok;
16024 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16025 ovl.fmt.RIL.i2); goto ok;
16026 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16027 ovl.fmt.RIL.i2); goto ok;
16028 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16029 ovl.fmt.RIL.i2); goto ok;
16030 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16031 ovl.fmt.RIL.i2); goto ok;
16032 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16033 ovl.fmt.RIL.i2); goto ok;
16034 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16035 ovl.fmt.RIL.i2); goto ok;
16036 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16037 ovl.fmt.RIL.i2); goto ok;
16038 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16039 ovl.fmt.RIL.i2); goto ok;
16040 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16041 ovl.fmt.RIL.i2); goto ok;
16042 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16043 ovl.fmt.RIL.i2); goto ok;
16044 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16045 ovl.fmt.RIL.i2); goto ok;
16046 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16047 ovl.fmt.RIL.i2); goto ok;
16048 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16049 ovl.fmt.RIL.i2); goto ok;
16050 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16051 ovl.fmt.RIL.i2); goto ok;
16052 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16053 ovl.fmt.RIL.i2); goto ok;
16054 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16055 ovl.fmt.RIL.i2); goto ok;
16056 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16057 ovl.fmt.RIL.i2); goto ok;
16058 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16059 ovl.fmt.RIL.i2); goto ok;
16060 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16061 ovl.fmt.RIL.i2); goto ok;
16062 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16063 ovl.fmt.RIL.i2); goto ok;
16064 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16065 ovl.fmt.RIL.i2); goto ok;
16066 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16067 ovl.fmt.RIL.i2); goto ok;
16068 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16069 ovl.fmt.RIL.i2); goto ok;
16070 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16071 ovl.fmt.RIL.i2); goto ok;
16072 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16073 ovl.fmt.RIL.i2); goto ok;
16074 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16075 ovl.fmt.RIL.i2); goto ok;
16076 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16077 ovl.fmt.RIL.i2); goto ok;
16078 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16079 ovl.fmt.RIL.i2); goto ok;
16080 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16081 ovl.fmt.RIL.i2); goto ok;
16082 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16083 ovl.fmt.RIL.i2); goto ok;
16084 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16085 ovl.fmt.RIL.i2); goto ok;
16086 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16087 ovl.fmt.RIL.i2); goto ok;
16088 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16089 ovl.fmt.RIL.i2); goto ok;
16090 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16091 ovl.fmt.RIL.i2); goto ok;
16092 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16093 ovl.fmt.RIL.i2); goto ok;
16094 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16095 ovl.fmt.RIL.i2); goto ok;
16096 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16097 ovl.fmt.RIL.i2); goto ok;
16098 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16099 ovl.fmt.RIL.i2); goto ok;
16100 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16101 ovl.fmt.RIL.i2); goto ok;
16102 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16103 ovl.fmt.RIL.i2); goto ok;
16104 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16105 ovl.fmt.RIL.i2); goto ok;
16106 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16107 ovl.fmt.RIL.i2); goto ok;
16108 case 0xc800ULL: /* MVCOS */ goto unimplemented;
16109 case 0xc801ULL: /* ECTG */ goto unimplemented;
16110 case 0xc802ULL: /* CSST */ goto unimplemented;
16111 case 0xc804ULL: /* LPD */ goto unimplemented;
16112 case 0xc805ULL: /* LPDG */ goto unimplemented;
16113 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
16114 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16115 ovl.fmt.RIL.i2); goto ok;
16116 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16117 ovl.fmt.RIL.i2); goto ok;
16118 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16119 ovl.fmt.RIL.i2); goto ok;
16120 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16121 ovl.fmt.RIL.i2); goto ok;
16122 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16123 ovl.fmt.RIL.i2); goto ok;
16124 }
16125
16126 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000016127 case 0xc5ULL: /* BPRP */ goto unimplemented;
16128 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016129 case 0xd0ULL: /* TRTR */ goto unimplemented;
16130 case 0xd1ULL: /* MVN */ goto unimplemented;
16131 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16132 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16133 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16134 case 0xd3ULL: /* MVZ */ goto unimplemented;
16135 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16136 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16137 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16138 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16139 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16140 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16141 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16142 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16143 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000016144 case 0xd7ULL:
16145 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16146 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16147 else
16148 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16149 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16150 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16151 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016152 case 0xd9ULL: /* MVCK */ goto unimplemented;
16153 case 0xdaULL: /* MVCP */ goto unimplemented;
16154 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000016155 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16156 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16157 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016158 case 0xddULL: /* TRT */ goto unimplemented;
16159 case 0xdeULL: /* ED */ goto unimplemented;
16160 case 0xdfULL: /* EDMK */ goto unimplemented;
16161 case 0xe1ULL: /* PKU */ goto unimplemented;
16162 case 0xe2ULL: /* UNPKU */ goto unimplemented;
16163 case 0xe8ULL: /* MVCIN */ goto unimplemented;
16164 case 0xe9ULL: /* PKA */ goto unimplemented;
16165 case 0xeaULL: /* UNPKA */ goto unimplemented;
16166 case 0xeeULL: /* PLO */ goto unimplemented;
16167 case 0xefULL: /* LMD */ goto unimplemented;
16168 case 0xf0ULL: /* SRP */ goto unimplemented;
16169 case 0xf1ULL: /* MVO */ goto unimplemented;
16170 case 0xf2ULL: /* PACK */ goto unimplemented;
16171 case 0xf3ULL: /* UNPK */ goto unimplemented;
16172 case 0xf8ULL: /* ZAP */ goto unimplemented;
16173 case 0xf9ULL: /* CP */ goto unimplemented;
16174 case 0xfaULL: /* AP */ goto unimplemented;
16175 case 0xfbULL: /* SP */ goto unimplemented;
16176 case 0xfcULL: /* MP */ goto unimplemented;
16177 case 0xfdULL: /* DP */ goto unimplemented;
16178 }
16179
16180 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16181 case 0xe500ULL: /* LASP */ goto unimplemented;
16182 case 0xe501ULL: /* TPROT */ goto unimplemented;
16183 case 0xe502ULL: /* STRAG */ goto unimplemented;
16184 case 0xe50eULL: /* MVCSK */ goto unimplemented;
16185 case 0xe50fULL: /* MVCDK */ goto unimplemented;
16186 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16187 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16188 goto ok;
16189 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16190 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16191 goto ok;
16192 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16193 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16194 goto ok;
16195 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16196 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16197 goto ok;
16198 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16199 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16200 goto ok;
16201 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16202 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16203 goto ok;
16204 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16205 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16206 goto ok;
16207 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16208 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16209 goto ok;
16210 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16211 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16212 goto ok;
florian2289cd42012-12-05 04:23:42 +000016213 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16214 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016215 }
16216
16217 return S390_DECODE_UNKNOWN_INSN;
16218
16219ok:
16220 return S390_DECODE_OK;
16221
16222unimplemented:
16223 return S390_DECODE_UNIMPLEMENTED_INSN;
16224}
16225
16226/* Handle "special" instructions. */
16227static s390_decode_t
16228s390_decode_special_and_irgen(UChar *bytes)
16229{
16230 s390_decode_t status = S390_DECODE_OK;
16231
16232 /* Got a "Special" instruction preamble. Which one is it? */
16233 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16234 s390_irgen_client_request();
16235 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16236 s390_irgen_guest_NRADDR();
16237 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16238 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016239 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16240 vex_inject_ir(irsb, Iend_BE);
16241
16242 /* Invalidate the current insn. The reason is that the IRop we're
16243 injecting here can change. In which case the translation has to
16244 be redone. For ease of handling, we simply invalidate all the
16245 time. */
16246 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
16247 mkU64(guest_IA_curr_instr)));
16248 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
16249 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16250 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16251 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16252
16253 put_IA(mkaddr_expr(guest_IA_next_instr));
16254 dis_res->whatNext = Dis_StopHere;
16255 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000016256 } else {
16257 /* We don't know what it is. */
16258 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16259 }
16260
16261 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16262
16263 return status;
16264}
16265
16266
16267/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016268static UInt
sewardj2019a972011-03-07 16:04:07 +000016269s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
16270{
16271 s390_decode_t status;
16272
16273 dis_res = dres;
16274
16275 /* Spot the 8-byte preamble: 18ff lr r15,r15
16276 1811 lr r1,r1
16277 1822 lr r2,r2
16278 1833 lr r3,r3 */
16279 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16280 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16281 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16282
16283 /* Handle special instruction that follows that preamble. */
16284 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016285
16286 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16287 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16288
16289 status =
16290 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016291 } else {
16292 /* Handle normal instructions. */
16293 switch (insn_length) {
16294 case 2:
16295 status = s390_decode_2byte_and_irgen(bytes);
16296 break;
16297
16298 case 4:
16299 status = s390_decode_4byte_and_irgen(bytes);
16300 break;
16301
16302 case 6:
16303 status = s390_decode_6byte_and_irgen(bytes);
16304 break;
16305
16306 default:
16307 status = S390_DECODE_ERROR;
16308 break;
16309 }
16310 }
florian5fcbba22011-07-27 20:40:22 +000016311 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016312 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16313 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016314 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016315 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016316 }
16317
16318 if (status == S390_DECODE_OK) return insn_length; /* OK */
16319
16320 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016321 if (sigill_diag) {
16322 vex_printf("vex s390->IR: ");
16323 switch (status) {
16324 case S390_DECODE_UNKNOWN_INSN:
16325 vex_printf("unknown insn: ");
16326 break;
sewardj2019a972011-03-07 16:04:07 +000016327
sewardj442e51a2012-12-06 18:08:04 +000016328 case S390_DECODE_UNIMPLEMENTED_INSN:
16329 vex_printf("unimplemented insn: ");
16330 break;
sewardj2019a972011-03-07 16:04:07 +000016331
sewardj442e51a2012-12-06 18:08:04 +000016332 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16333 vex_printf("unimplemented special insn: ");
16334 break;
sewardj2019a972011-03-07 16:04:07 +000016335
sewardj442e51a2012-12-06 18:08:04 +000016336 default:
16337 case S390_DECODE_ERROR:
16338 vex_printf("decoding error: ");
16339 break;
16340 }
16341
16342 vex_printf("%02x%02x", bytes[0], bytes[1]);
16343 if (insn_length > 2) {
16344 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16345 }
16346 if (insn_length > 4) {
16347 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16348 }
16349 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016350 }
16351
sewardj2019a972011-03-07 16:04:07 +000016352 return 0; /* Failed */
16353}
16354
16355
sewardj2019a972011-03-07 16:04:07 +000016356/* Disassemble a single instruction INSN into IR. */
16357static DisResult
florian420c5012011-07-22 02:12:28 +000016358disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016359{
16360 UChar byte;
16361 UInt insn_length;
16362 DisResult dres;
16363
16364 /* ---------------------------------------------------- */
16365 /* --- Compute instruction length -- */
16366 /* ---------------------------------------------------- */
16367
16368 /* Get the first byte of the insn. */
16369 byte = insn[0];
16370
16371 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16372 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16373 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16374
16375 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16376
16377 /* ---------------------------------------------------- */
16378 /* --- Initialise the DisResult data -- */
16379 /* ---------------------------------------------------- */
16380 dres.whatNext = Dis_Continue;
16381 dres.len = insn_length;
16382 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016383 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000016384
floriana99f20e2011-07-17 14:16:41 +000016385 /* fixs390: consider chasing of conditional jumps */
16386
sewardj2019a972011-03-07 16:04:07 +000016387 /* Normal and special instruction handling starts here. */
16388 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16389 /* All decode failures end up here. The decoder has already issued an
16390 error message.
16391 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016392 not been executed, and (is currently) the next to be executed.
16393 The insn address in the guest state needs to be set to
16394 guest_IA_curr_instr, otherwise the complaint will report an
16395 incorrect address. */
16396 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016397
florian8844a632012-04-13 04:04:06 +000016398 dres.whatNext = Dis_StopHere;
16399 dres.jk_StopHere = Ijk_NoDecode;
16400 dres.continueAt = 0;
16401 dres.len = 0;
16402 } else {
16403 /* Decode success */
16404 switch (dres.whatNext) {
16405 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016406 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016407 break;
16408 case Dis_ResteerU:
16409 case Dis_ResteerC:
16410 put_IA(mkaddr_expr(dres.continueAt));
16411 break;
16412 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016413 if (dres.jk_StopHere == Ijk_EmWarn ||
16414 dres.jk_StopHere == Ijk_EmFail) {
16415 /* We assume here, that emulation warnings are not given for
16416 insns that transfer control. There is no good way to
16417 do that. */
16418 put_IA(mkaddr_expr(guest_IA_next_instr));
16419 }
florian8844a632012-04-13 04:04:06 +000016420 break;
16421 default:
16422 vassert(0);
16423 }
sewardj2019a972011-03-07 16:04:07 +000016424 }
16425
16426 return dres;
16427}
16428
16429
16430/*------------------------------------------------------------*/
16431/*--- Top-level fn ---*/
16432/*------------------------------------------------------------*/
16433
16434/* Disassemble a single instruction into IR. The instruction
16435 is located in host memory at &guest_code[delta]. */
16436
16437DisResult
16438disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000016439 Bool (*resteerOkFn)(void *, Addr64),
16440 Bool resteerCisOk,
16441 void *callback_opaque,
16442 UChar *guest_code,
16443 Long delta,
16444 Addr64 guest_IP,
16445 VexArch guest_arch,
16446 VexArchInfo *archinfo,
16447 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000016448 Bool host_bigendian,
16449 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016450{
16451 vassert(guest_arch == VexArchS390X);
16452
16453 /* The instruction decoder requires a big-endian machine. */
16454 vassert(host_bigendian == True);
16455
16456 /* Set globals (see top of this file) */
16457 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016458 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016459 resteer_fn = resteerOkFn;
16460 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016461 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016462
florian420c5012011-07-22 02:12:28 +000016463 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016464}
16465
16466/*---------------------------------------------------------------*/
16467/*--- end guest_s390_toIR.c ---*/
16468/*---------------------------------------------------------------*/