blob: f90f05da7f138bdc9d90e68209fc927189b53c11 [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
243 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
635 op = mkU64(opc);
636 dep1 = mkexpr(d1);
637 dep2 = mkU64(0);
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, dep1, dep2, ndep);
641}
642
643
644/* Write a floating point value and an integer into the flags thunk. The
645 integer value is zero-extended first. */
646static void
647s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
648{
649 IRExpr *op, *dep1, *dep2, *ndep;
650
651 op = mkU64(opc);
652 dep1 = mkexpr(d1);
653 dep2 = s390_cc_widen(d2, False);
654 ndep = mkU64(0);
655
656 s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a 128-bit floating point value into the flags thunk. This is
661 done by splitting the value into two 64-bits values. */
662static void
663s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
664{
665 IRExpr *op, *hi, *lo, *ndep;
666
667 op = mkU64(opc);
668 hi = unop(Iop_F128HItoF64, mkexpr(d1));
669 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, hi, lo, ndep);
673}
674
675
676/* Write a 128-bit floating point value and an integer into the flags thunk.
677 The integer value is zero-extended first. */
678static void
679s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
680{
681 IRExpr *op, *hi, *lo, *lox, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
686 ndep = s390_cc_widen(nd, False);
687
688 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
689
690 s390_cc_thunk_fill(op, hi, lox, ndep);
691}
692
693
floriane38f6412012-12-21 17:32:12 +0000694/* Write a 128-bit decimal floating point value into the flags thunk.
695 This is done by splitting the value into two 64-bits values. */
696static void
697s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
698{
699 IRExpr *op, *hi, *lo, *ndep;
700
701 op = mkU64(opc);
702 hi = unop(Iop_D128HItoD64, mkexpr(d1));
703 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
704 ndep = mkU64(0);
705
706 s390_cc_thunk_fill(op, hi, lo, ndep);
707}
708
709
sewardj2019a972011-03-07 16:04:07 +0000710static void
711s390_cc_set(UInt val)
712{
713 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
714 mkU64(val), mkU64(0), mkU64(0));
715}
716
717/* Build IR to calculate the condition code from flags thunk.
718 Returns an expression of type Ity_I32 */
719static IRExpr *
720s390_call_calculate_cc(void)
721{
722 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
723
florian428dfdd2012-03-27 03:09:49 +0000724 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
725 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
726 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
727 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000728
729 args = mkIRExprVec_4(op, dep1, dep2, ndep);
730 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
731 "s390_calculate_cc", &s390_calculate_cc, args);
732
733 /* Exclude OP and NDEP from definedness checking. We're only
734 interested in DEP1 and DEP2. */
735 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
736
737 return call;
738}
739
740/* Build IR to calculate the internal condition code for a "compare and branch"
741 insn. Returns an expression of type Ity_I32 */
742static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000743s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000744{
florianff9613f2012-05-12 15:26:44 +0000745 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000746
florianff9613f2012-05-12 15:26:44 +0000747 switch (opc) {
748 case S390_CC_OP_SIGNED_COMPARE:
749 dep1 = s390_cc_widen(op1, True);
750 dep2 = s390_cc_widen(op2, True);
751 break;
752
753 case S390_CC_OP_UNSIGNED_COMPARE:
754 dep1 = s390_cc_widen(op1, False);
755 dep2 = s390_cc_widen(op2, False);
756 break;
757
758 default:
759 vpanic("s390_call_calculate_icc");
760 }
761
762 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000763 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000764
florianff9613f2012-05-12 15:26:44 +0000765 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000766 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000767 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000768
florianff9613f2012-05-12 15:26:44 +0000769 /* Exclude the requested condition, OP and NDEP from definedness
770 checking. We're only interested in DEP1 and DEP2. */
771 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000772
773 return call;
774}
775
776/* Build IR to calculate the condition code from flags thunk.
777 Returns an expression of type Ity_I32 */
778static IRExpr *
779s390_call_calculate_cond(UInt m)
780{
781 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
782
783 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000784 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
785 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
786 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
787 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000788
789 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
790 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
791 "s390_calculate_cond", &s390_calculate_cond, args);
792
793 /* Exclude the requested condition, OP and NDEP from definedness
794 checking. We're only interested in DEP1 and DEP2. */
795 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
796
797 return call;
798}
799
800#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
801#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
802#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
803#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
804#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
805#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
806#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
807 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
808#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
809 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000810
811
sewardj2019a972011-03-07 16:04:07 +0000812
813
814/*------------------------------------------------------------*/
815/*--- Guest register access ---*/
816/*------------------------------------------------------------*/
817
818
819/*------------------------------------------------------------*/
820/*--- ar registers ---*/
821/*------------------------------------------------------------*/
822
823/* Return the guest state offset of a ar register. */
824static UInt
825ar_offset(UInt archreg)
826{
827 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000828 S390X_GUEST_OFFSET(guest_a0),
829 S390X_GUEST_OFFSET(guest_a1),
830 S390X_GUEST_OFFSET(guest_a2),
831 S390X_GUEST_OFFSET(guest_a3),
832 S390X_GUEST_OFFSET(guest_a4),
833 S390X_GUEST_OFFSET(guest_a5),
834 S390X_GUEST_OFFSET(guest_a6),
835 S390X_GUEST_OFFSET(guest_a7),
836 S390X_GUEST_OFFSET(guest_a8),
837 S390X_GUEST_OFFSET(guest_a9),
838 S390X_GUEST_OFFSET(guest_a10),
839 S390X_GUEST_OFFSET(guest_a11),
840 S390X_GUEST_OFFSET(guest_a12),
841 S390X_GUEST_OFFSET(guest_a13),
842 S390X_GUEST_OFFSET(guest_a14),
843 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000844 };
845
846 vassert(archreg < 16);
847
848 return offset[archreg];
849}
850
851
852/* Return the guest state offset of word #0 of a ar register. */
853static __inline__ UInt
854ar_w0_offset(UInt archreg)
855{
856 return ar_offset(archreg) + 0;
857}
858
859/* Write word #0 of a ar to the guest state. */
860static __inline__ void
861put_ar_w0(UInt archreg, IRExpr *expr)
862{
863 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
864
865 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
866}
867
868/* Read word #0 of a ar register. */
869static __inline__ IRExpr *
870get_ar_w0(UInt archreg)
871{
872 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
873}
874
875
876/*------------------------------------------------------------*/
877/*--- fpr registers ---*/
878/*------------------------------------------------------------*/
879
880/* Return the guest state offset of a fpr register. */
881static UInt
882fpr_offset(UInt archreg)
883{
884 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000885 S390X_GUEST_OFFSET(guest_f0),
886 S390X_GUEST_OFFSET(guest_f1),
887 S390X_GUEST_OFFSET(guest_f2),
888 S390X_GUEST_OFFSET(guest_f3),
889 S390X_GUEST_OFFSET(guest_f4),
890 S390X_GUEST_OFFSET(guest_f5),
891 S390X_GUEST_OFFSET(guest_f6),
892 S390X_GUEST_OFFSET(guest_f7),
893 S390X_GUEST_OFFSET(guest_f8),
894 S390X_GUEST_OFFSET(guest_f9),
895 S390X_GUEST_OFFSET(guest_f10),
896 S390X_GUEST_OFFSET(guest_f11),
897 S390X_GUEST_OFFSET(guest_f12),
898 S390X_GUEST_OFFSET(guest_f13),
899 S390X_GUEST_OFFSET(guest_f14),
900 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000901 };
902
903 vassert(archreg < 16);
904
905 return offset[archreg];
906}
907
908
909/* Return the guest state offset of word #0 of a fpr register. */
910static __inline__ UInt
911fpr_w0_offset(UInt archreg)
912{
913 return fpr_offset(archreg) + 0;
914}
915
916/* Write word #0 of a fpr to the guest state. */
917static __inline__ void
918put_fpr_w0(UInt archreg, IRExpr *expr)
919{
920 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
921
922 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
923}
924
925/* Read word #0 of a fpr register. */
926static __inline__ IRExpr *
927get_fpr_w0(UInt archreg)
928{
929 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
930}
931
932/* Return the guest state offset of double word #0 of a fpr register. */
933static __inline__ UInt
934fpr_dw0_offset(UInt archreg)
935{
936 return fpr_offset(archreg) + 0;
937}
938
939/* Write double word #0 of a fpr to the guest state. */
940static __inline__ void
941put_fpr_dw0(UInt archreg, IRExpr *expr)
942{
943 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
944
945 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
946}
947
948/* Read double word #0 of a fpr register. */
949static __inline__ IRExpr *
950get_fpr_dw0(UInt archreg)
951{
952 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
953}
954
floriane38f6412012-12-21 17:32:12 +0000955/* Write word #0 of a dpr to the guest state. */
956static __inline__ void
957put_dpr_w0(UInt archreg, IRExpr *expr)
958{
959 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
960
961 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
962}
963
964/* Read word #0 of a dpr register. */
965static __inline__ IRExpr *
966get_dpr_w0(UInt archreg)
967{
968 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
969}
970
florian12390202012-11-10 22:34:14 +0000971/* Write double word #0 of a fpr containg DFP value to the guest state. */
972static __inline__ void
973put_dpr_dw0(UInt archreg, IRExpr *expr)
974{
975 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
976
977 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
978}
979
980/* Read double word #0 of a fpr register containing DFP value. */
981static __inline__ IRExpr *
982get_dpr_dw0(UInt archreg)
983{
984 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
985}
sewardj2019a972011-03-07 16:04:07 +0000986
987/*------------------------------------------------------------*/
988/*--- gpr registers ---*/
989/*------------------------------------------------------------*/
990
991/* Return the guest state offset of a gpr register. */
992static UInt
993gpr_offset(UInt archreg)
994{
995 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000996 S390X_GUEST_OFFSET(guest_r0),
997 S390X_GUEST_OFFSET(guest_r1),
998 S390X_GUEST_OFFSET(guest_r2),
999 S390X_GUEST_OFFSET(guest_r3),
1000 S390X_GUEST_OFFSET(guest_r4),
1001 S390X_GUEST_OFFSET(guest_r5),
1002 S390X_GUEST_OFFSET(guest_r6),
1003 S390X_GUEST_OFFSET(guest_r7),
1004 S390X_GUEST_OFFSET(guest_r8),
1005 S390X_GUEST_OFFSET(guest_r9),
1006 S390X_GUEST_OFFSET(guest_r10),
1007 S390X_GUEST_OFFSET(guest_r11),
1008 S390X_GUEST_OFFSET(guest_r12),
1009 S390X_GUEST_OFFSET(guest_r13),
1010 S390X_GUEST_OFFSET(guest_r14),
1011 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001012 };
1013
1014 vassert(archreg < 16);
1015
1016 return offset[archreg];
1017}
1018
1019
1020/* Return the guest state offset of word #0 of a gpr register. */
1021static __inline__ UInt
1022gpr_w0_offset(UInt archreg)
1023{
1024 return gpr_offset(archreg) + 0;
1025}
1026
1027/* Write word #0 of a gpr to the guest state. */
1028static __inline__ void
1029put_gpr_w0(UInt archreg, IRExpr *expr)
1030{
1031 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1032
1033 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1034}
1035
1036/* Read word #0 of a gpr register. */
1037static __inline__ IRExpr *
1038get_gpr_w0(UInt archreg)
1039{
1040 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1041}
1042
1043/* Return the guest state offset of double word #0 of a gpr register. */
1044static __inline__ UInt
1045gpr_dw0_offset(UInt archreg)
1046{
1047 return gpr_offset(archreg) + 0;
1048}
1049
1050/* Write double word #0 of a gpr to the guest state. */
1051static __inline__ void
1052put_gpr_dw0(UInt archreg, IRExpr *expr)
1053{
1054 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1055
1056 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1057}
1058
1059/* Read double word #0 of a gpr register. */
1060static __inline__ IRExpr *
1061get_gpr_dw0(UInt archreg)
1062{
1063 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1064}
1065
1066/* Return the guest state offset of half word #1 of a gpr register. */
1067static __inline__ UInt
1068gpr_hw1_offset(UInt archreg)
1069{
1070 return gpr_offset(archreg) + 2;
1071}
1072
1073/* Write half word #1 of a gpr to the guest state. */
1074static __inline__ void
1075put_gpr_hw1(UInt archreg, IRExpr *expr)
1076{
1077 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1078
1079 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1080}
1081
1082/* Read half word #1 of a gpr register. */
1083static __inline__ IRExpr *
1084get_gpr_hw1(UInt archreg)
1085{
1086 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1087}
1088
1089/* Return the guest state offset of byte #6 of a gpr register. */
1090static __inline__ UInt
1091gpr_b6_offset(UInt archreg)
1092{
1093 return gpr_offset(archreg) + 6;
1094}
1095
1096/* Write byte #6 of a gpr to the guest state. */
1097static __inline__ void
1098put_gpr_b6(UInt archreg, IRExpr *expr)
1099{
1100 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1101
1102 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1103}
1104
1105/* Read byte #6 of a gpr register. */
1106static __inline__ IRExpr *
1107get_gpr_b6(UInt archreg)
1108{
1109 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1110}
1111
1112/* Return the guest state offset of byte #3 of a gpr register. */
1113static __inline__ UInt
1114gpr_b3_offset(UInt archreg)
1115{
1116 return gpr_offset(archreg) + 3;
1117}
1118
1119/* Write byte #3 of a gpr to the guest state. */
1120static __inline__ void
1121put_gpr_b3(UInt archreg, IRExpr *expr)
1122{
1123 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1124
1125 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1126}
1127
1128/* Read byte #3 of a gpr register. */
1129static __inline__ IRExpr *
1130get_gpr_b3(UInt archreg)
1131{
1132 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1133}
1134
1135/* Return the guest state offset of byte #0 of a gpr register. */
1136static __inline__ UInt
1137gpr_b0_offset(UInt archreg)
1138{
1139 return gpr_offset(archreg) + 0;
1140}
1141
1142/* Write byte #0 of a gpr to the guest state. */
1143static __inline__ void
1144put_gpr_b0(UInt archreg, IRExpr *expr)
1145{
1146 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1147
1148 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1149}
1150
1151/* Read byte #0 of a gpr register. */
1152static __inline__ IRExpr *
1153get_gpr_b0(UInt archreg)
1154{
1155 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1156}
1157
1158/* Return the guest state offset of word #1 of a gpr register. */
1159static __inline__ UInt
1160gpr_w1_offset(UInt archreg)
1161{
1162 return gpr_offset(archreg) + 4;
1163}
1164
1165/* Write word #1 of a gpr to the guest state. */
1166static __inline__ void
1167put_gpr_w1(UInt archreg, IRExpr *expr)
1168{
1169 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1170
1171 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1172}
1173
1174/* Read word #1 of a gpr register. */
1175static __inline__ IRExpr *
1176get_gpr_w1(UInt archreg)
1177{
1178 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1179}
1180
1181/* Return the guest state offset of half word #3 of a gpr register. */
1182static __inline__ UInt
1183gpr_hw3_offset(UInt archreg)
1184{
1185 return gpr_offset(archreg) + 6;
1186}
1187
1188/* Write half word #3 of a gpr to the guest state. */
1189static __inline__ void
1190put_gpr_hw3(UInt archreg, IRExpr *expr)
1191{
1192 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1193
1194 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1195}
1196
1197/* Read half word #3 of a gpr register. */
1198static __inline__ IRExpr *
1199get_gpr_hw3(UInt archreg)
1200{
1201 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1202}
1203
1204/* Return the guest state offset of byte #7 of a gpr register. */
1205static __inline__ UInt
1206gpr_b7_offset(UInt archreg)
1207{
1208 return gpr_offset(archreg) + 7;
1209}
1210
1211/* Write byte #7 of a gpr to the guest state. */
1212static __inline__ void
1213put_gpr_b7(UInt archreg, IRExpr *expr)
1214{
1215 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1216
1217 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1218}
1219
1220/* Read byte #7 of a gpr register. */
1221static __inline__ IRExpr *
1222get_gpr_b7(UInt archreg)
1223{
1224 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1225}
1226
1227/* Return the guest state offset of half word #0 of a gpr register. */
1228static __inline__ UInt
1229gpr_hw0_offset(UInt archreg)
1230{
1231 return gpr_offset(archreg) + 0;
1232}
1233
1234/* Write half word #0 of a gpr to the guest state. */
1235static __inline__ void
1236put_gpr_hw0(UInt archreg, IRExpr *expr)
1237{
1238 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1239
1240 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1241}
1242
1243/* Read half word #0 of a gpr register. */
1244static __inline__ IRExpr *
1245get_gpr_hw0(UInt archreg)
1246{
1247 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1248}
1249
1250/* Return the guest state offset of byte #4 of a gpr register. */
1251static __inline__ UInt
1252gpr_b4_offset(UInt archreg)
1253{
1254 return gpr_offset(archreg) + 4;
1255}
1256
1257/* Write byte #4 of a gpr to the guest state. */
1258static __inline__ void
1259put_gpr_b4(UInt archreg, IRExpr *expr)
1260{
1261 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1262
1263 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1264}
1265
1266/* Read byte #4 of a gpr register. */
1267static __inline__ IRExpr *
1268get_gpr_b4(UInt archreg)
1269{
1270 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1271}
1272
1273/* Return the guest state offset of byte #1 of a gpr register. */
1274static __inline__ UInt
1275gpr_b1_offset(UInt archreg)
1276{
1277 return gpr_offset(archreg) + 1;
1278}
1279
1280/* Write byte #1 of a gpr to the guest state. */
1281static __inline__ void
1282put_gpr_b1(UInt archreg, IRExpr *expr)
1283{
1284 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1285
1286 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1287}
1288
1289/* Read byte #1 of a gpr register. */
1290static __inline__ IRExpr *
1291get_gpr_b1(UInt archreg)
1292{
1293 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1294}
1295
1296/* Return the guest state offset of half word #2 of a gpr register. */
1297static __inline__ UInt
1298gpr_hw2_offset(UInt archreg)
1299{
1300 return gpr_offset(archreg) + 4;
1301}
1302
1303/* Write half word #2 of a gpr to the guest state. */
1304static __inline__ void
1305put_gpr_hw2(UInt archreg, IRExpr *expr)
1306{
1307 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1308
1309 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1310}
1311
1312/* Read half word #2 of a gpr register. */
1313static __inline__ IRExpr *
1314get_gpr_hw2(UInt archreg)
1315{
1316 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1317}
1318
1319/* Return the guest state offset of byte #5 of a gpr register. */
1320static __inline__ UInt
1321gpr_b5_offset(UInt archreg)
1322{
1323 return gpr_offset(archreg) + 5;
1324}
1325
1326/* Write byte #5 of a gpr to the guest state. */
1327static __inline__ void
1328put_gpr_b5(UInt archreg, IRExpr *expr)
1329{
1330 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1331
1332 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1333}
1334
1335/* Read byte #5 of a gpr register. */
1336static __inline__ IRExpr *
1337get_gpr_b5(UInt archreg)
1338{
1339 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1340}
1341
1342/* Return the guest state offset of byte #2 of a gpr register. */
1343static __inline__ UInt
1344gpr_b2_offset(UInt archreg)
1345{
1346 return gpr_offset(archreg) + 2;
1347}
1348
1349/* Write byte #2 of a gpr to the guest state. */
1350static __inline__ void
1351put_gpr_b2(UInt archreg, IRExpr *expr)
1352{
1353 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1354
1355 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1356}
1357
1358/* Read byte #2 of a gpr register. */
1359static __inline__ IRExpr *
1360get_gpr_b2(UInt archreg)
1361{
1362 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1363}
1364
1365/* Return the guest state offset of the counter register. */
1366static UInt
1367counter_offset(void)
1368{
floriane88b3c92011-07-05 02:48:39 +00001369 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001370}
1371
1372/* Return the guest state offset of double word #0 of the counter register. */
1373static __inline__ UInt
1374counter_dw0_offset(void)
1375{
1376 return counter_offset() + 0;
1377}
1378
1379/* Write double word #0 of the counter to the guest state. */
1380static __inline__ void
1381put_counter_dw0(IRExpr *expr)
1382{
1383 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1384
1385 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1386}
1387
1388/* Read double word #0 of the counter register. */
1389static __inline__ IRExpr *
1390get_counter_dw0(void)
1391{
1392 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1393}
1394
1395/* Return the guest state offset of word #0 of the counter register. */
1396static __inline__ UInt
1397counter_w0_offset(void)
1398{
1399 return counter_offset() + 0;
1400}
1401
1402/* Return the guest state offset of word #1 of the counter register. */
1403static __inline__ UInt
1404counter_w1_offset(void)
1405{
1406 return counter_offset() + 4;
1407}
1408
1409/* Write word #0 of the counter to the guest state. */
1410static __inline__ void
1411put_counter_w0(IRExpr *expr)
1412{
1413 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1414
1415 stmt(IRStmt_Put(counter_w0_offset(), expr));
1416}
1417
1418/* Read word #0 of the counter register. */
1419static __inline__ IRExpr *
1420get_counter_w0(void)
1421{
1422 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1423}
1424
1425/* Write word #1 of the counter to the guest state. */
1426static __inline__ void
1427put_counter_w1(IRExpr *expr)
1428{
1429 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1430
1431 stmt(IRStmt_Put(counter_w1_offset(), expr));
1432}
1433
1434/* Read word #1 of the counter register. */
1435static __inline__ IRExpr *
1436get_counter_w1(void)
1437{
1438 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1439}
1440
1441/* Return the guest state offset of the fpc register. */
1442static UInt
1443fpc_offset(void)
1444{
floriane88b3c92011-07-05 02:48:39 +00001445 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001446}
1447
1448/* Return the guest state offset of word #0 of the fpc register. */
1449static __inline__ UInt
1450fpc_w0_offset(void)
1451{
1452 return fpc_offset() + 0;
1453}
1454
1455/* Write word #0 of the fpc to the guest state. */
1456static __inline__ void
1457put_fpc_w0(IRExpr *expr)
1458{
1459 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1460
1461 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1462}
1463
1464/* Read word #0 of the fpc register. */
1465static __inline__ IRExpr *
1466get_fpc_w0(void)
1467{
1468 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1469}
1470
1471
1472/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001473/*--- Rounding modes ---*/
1474/*------------------------------------------------------------*/
1475
florian125e20d2012-10-07 15:42:37 +00001476/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001477 IRRoundingMode:
1478
1479 rounding mode | s390 | IR
1480 -------------------------
1481 to nearest | 00 | 00
1482 to zero | 01 | 11
1483 to +infinity | 10 | 10
1484 to -infinity | 11 | 01
1485
1486 So: IR = (4 - s390) & 3
1487*/
1488static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001489get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001490{
1491 IRTemp fpc_bits = newTemp(Ity_I32);
1492
1493 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1494 Prior to that bits [30:31] contained the bfp rounding mode with
1495 bit 29 being unused and having a value of 0. So we can always
1496 extract the least significant 3 bits. */
1497 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1498
1499 /* fixs390:
1500
1501
1502 if (! s390_host_has_fpext && rounding_mode > 3) {
1503 emulation warning @ runtime and
1504 set fpc to round nearest
1505 }
1506 */
1507
1508 /* For now silently adjust an unsupported rounding mode to "nearest" */
1509 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1510 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001511 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001512
1513 // rm_IR = (4 - rm_s390) & 3;
1514 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1515}
1516
1517/* Encode the s390 rounding mode as it appears in the m3 field of certain
1518 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1519 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1520 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1521 considers the default rounding mode (4.3.3). */
1522static IRTemp
1523encode_bfp_rounding_mode(UChar mode)
1524{
1525 IRExpr *rm;
1526
1527 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001528 case S390_BFP_ROUND_PER_FPC:
1529 rm = get_bfp_rounding_mode_from_fpc();
1530 break;
1531 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1532 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1533 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1534 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1535 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1536 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001537 default:
1538 vpanic("encode_bfp_rounding_mode");
1539 }
1540
1541 return mktemp(Ity_I32, rm);
1542}
1543
florianc8e4f562012-10-27 16:19:31 +00001544/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1545 IRRoundingMode:
1546
1547 rounding mode | s390 | IR
1548 ------------------------------------------------
1549 to nearest, ties to even | 000 | 000
1550 to zero | 001 | 011
1551 to +infinity | 010 | 010
1552 to -infinity | 011 | 001
1553 to nearest, ties away from 0 | 100 | 100
1554 to nearest, ties toward 0 | 101 | 111
1555 to away from 0 | 110 | 110
1556 to prepare for shorter precision | 111 | 101
1557
1558 So: IR = (s390 ^ ((s390 << 1) & 2))
1559*/
florianc8e4f562012-10-27 16:19:31 +00001560static IRExpr *
1561get_dfp_rounding_mode_from_fpc(void)
1562{
1563 IRTemp fpc_bits = newTemp(Ity_I32);
1564
1565 /* The dfp rounding mode is stored in bits [25:27].
1566 extract the bits at 25:27 and right shift 4 times. */
1567 assign(fpc_bits, binop(Iop_Shr32,
1568 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1569 mkU8(4)));
1570
1571 IRExpr *rm_s390 = mkexpr(fpc_bits);
1572 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1573
1574 return binop(Iop_Xor32, rm_s390,
1575 binop( Iop_And32,
1576 binop(Iop_Shl32, rm_s390, mkU8(1)),
1577 mkU32(2)));
1578}
1579
1580/* Encode the s390 rounding mode as it appears in the m3 field of certain
1581 instructions to VEX's IRRoundingMode. */
1582static IRTemp
1583encode_dfp_rounding_mode(UChar mode)
1584{
1585 IRExpr *rm;
1586
1587 switch (mode) {
1588 case S390_DFP_ROUND_PER_FPC_0:
1589 case S390_DFP_ROUND_PER_FPC_2:
1590 rm = get_dfp_rounding_mode_from_fpc(); break;
1591 case S390_DFP_ROUND_NEAREST_EVEN_4:
1592 case S390_DFP_ROUND_NEAREST_EVEN_8:
1593 rm = mkU32(Irrm_DFP_NEAREST); break;
1594 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1595 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1596 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1597 case S390_DFP_ROUND_PREPARE_SHORT_3:
1598 case S390_DFP_ROUND_PREPARE_SHORT_15:
1599 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1600 case S390_DFP_ROUND_ZERO_5:
1601 case S390_DFP_ROUND_ZERO_9:
1602 rm = mkU32(Irrm_DFP_ZERO ); break;
1603 case S390_DFP_ROUND_POSINF_6:
1604 case S390_DFP_ROUND_POSINF_10:
1605 rm = mkU32(Irrm_DFP_PosINF); break;
1606 case S390_DFP_ROUND_NEGINF_7:
1607 case S390_DFP_ROUND_NEGINF_11:
1608 rm = mkU32(Irrm_DFP_NegINF); break;
1609 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1610 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1611 case S390_DFP_ROUND_AWAY_0:
1612 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1613 default:
1614 vpanic("encode_dfp_rounding_mode");
1615 }
1616
1617 return mktemp(Ity_I32, rm);
1618}
florian12390202012-11-10 22:34:14 +00001619
florianc8e4f562012-10-27 16:19:31 +00001620
florian2c74d242012-09-12 19:38:42 +00001621/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001622/*--- Condition code helpers ---*/
1623/*------------------------------------------------------------*/
1624
1625/* The result of a Iop_CmpFxx operation is a condition code. It is
1626 encoded using the values defined in type IRCmpFxxResult.
1627 Before we can store the condition code into the guest state (or do
1628 anything else with it for that matter) we need to convert it to
1629 the encoding that s390 uses. This is what this function does.
1630
1631 s390 VEX b6 b2 b0 cc.1 cc.0
1632 0 0x40 EQ 1 0 0 0 0
1633 1 0x01 LT 0 0 1 0 1
1634 2 0x00 GT 0 0 0 1 0
1635 3 0x45 Unordered 1 1 1 1 1
1636
1637 The following bits from the VEX encoding are interesting:
1638 b0, b2, b6 with b0 being the LSB. We observe:
1639
1640 cc.0 = b0;
1641 cc.1 = b2 | (~b0 & ~b6)
1642
1643 with cc being the s390 condition code.
1644*/
1645static IRExpr *
1646convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1647{
1648 IRTemp cc0 = newTemp(Ity_I32);
1649 IRTemp cc1 = newTemp(Ity_I32);
1650 IRTemp b0 = newTemp(Ity_I32);
1651 IRTemp b2 = newTemp(Ity_I32);
1652 IRTemp b6 = newTemp(Ity_I32);
1653
1654 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1655 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1656 mkU32(1)));
1657 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1658 mkU32(1)));
1659
1660 assign(cc0, mkexpr(b0));
1661 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1662 binop(Iop_And32,
1663 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1664 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1665 )));
1666
1667 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1668}
1669
1670
1671/* The result of a Iop_CmpDxx operation is a condition code. It is
1672 encoded using the values defined in type IRCmpDxxResult.
1673 Before we can store the condition code into the guest state (or do
1674 anything else with it for that matter) we need to convert it to
1675 the encoding that s390 uses. This is what this function does. */
1676static IRExpr *
1677convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1678{
1679 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1680 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001681 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001682}
1683
1684
1685/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001686/*--- Build IR for formats ---*/
1687/*------------------------------------------------------------*/
1688static void
florian55085f82012-11-21 00:36:55 +00001689s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001690 UChar i)
1691{
florian55085f82012-11-21 00:36:55 +00001692 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001693
sewardj7ee97522011-05-09 21:45:04 +00001694 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001695 s390_disasm(ENC2(MNM, UINT), mnm, i);
1696}
1697
1698static void
florian55085f82012-11-21 00:36:55 +00001699s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001700 UChar r1, UShort i2)
1701{
1702 irgen(r1, i2);
1703}
1704
1705static void
florian55085f82012-11-21 00:36:55 +00001706s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001707 UChar r1, UShort i2)
1708{
florian55085f82012-11-21 00:36:55 +00001709 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001710
sewardj7ee97522011-05-09 21:45:04 +00001711 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001712 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1713}
1714
1715static void
florian55085f82012-11-21 00:36:55 +00001716s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001717 UChar r1, UShort i2)
1718{
florian55085f82012-11-21 00:36:55 +00001719 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001720
sewardj7ee97522011-05-09 21:45:04 +00001721 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001722 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1723}
1724
1725static void
florian55085f82012-11-21 00:36:55 +00001726s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001727 UChar r1, UShort i2)
1728{
florian55085f82012-11-21 00:36:55 +00001729 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001730
sewardj7ee97522011-05-09 21:45:04 +00001731 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001732 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1733}
1734
1735static void
florian55085f82012-11-21 00:36:55 +00001736s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001737 UChar r1, UChar r3, UShort i2)
1738{
florian55085f82012-11-21 00:36:55 +00001739 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001740
sewardj7ee97522011-05-09 21:45:04 +00001741 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001742 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1743}
1744
1745static void
florian55085f82012-11-21 00:36:55 +00001746s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001747 UChar r1, UChar r3, UShort i2)
1748{
florian55085f82012-11-21 00:36:55 +00001749 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001750
sewardj7ee97522011-05-09 21:45:04 +00001751 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001752 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1753}
1754
1755static void
florian55085f82012-11-21 00:36:55 +00001756s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1757 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001758 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1759{
florian55085f82012-11-21 00:36:55 +00001760 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001761
sewardj7ee97522011-05-09 21:45:04 +00001762 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001763 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1764 i5);
1765}
1766
1767static void
florian55085f82012-11-21 00:36:55 +00001768s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1769 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001770 UChar r1, UChar r2, UShort i4, UChar m3)
1771{
florian55085f82012-11-21 00:36:55 +00001772 const HChar *mnm = irgen(r1, r2, i4, m3);
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(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1776 r2, m3, (Int)(Short)i4);
1777}
1778
1779static void
florian55085f82012-11-21 00:36:55 +00001780s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1781 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001782 UChar r1, UChar m3, UShort i4, UChar i2)
1783{
florian55085f82012-11-21 00:36:55 +00001784 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001785
sewardj7ee97522011-05-09 21:45:04 +00001786 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001787 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1788 r1, i2, m3, (Int)(Short)i4);
1789}
1790
1791static void
florian55085f82012-11-21 00:36:55 +00001792s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1793 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001794 UChar r1, UChar m3, UShort i4, UChar i2)
1795{
florian55085f82012-11-21 00:36:55 +00001796 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001797
sewardj7ee97522011-05-09 21:45:04 +00001798 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001799 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1800 (Int)(Char)i2, m3, (Int)(Short)i4);
1801}
1802
1803static void
florian55085f82012-11-21 00:36:55 +00001804s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001805 UChar r1, UInt i2)
1806{
1807 irgen(r1, i2);
1808}
1809
1810static void
florian55085f82012-11-21 00:36:55 +00001811s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001812 UChar r1, UInt i2)
1813{
florian55085f82012-11-21 00:36:55 +00001814 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001815
sewardj7ee97522011-05-09 21:45:04 +00001816 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001817 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1818}
1819
1820static void
florian55085f82012-11-21 00:36:55 +00001821s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001822 UChar r1, UInt i2)
1823{
florian55085f82012-11-21 00:36:55 +00001824 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001825
sewardj7ee97522011-05-09 21:45:04 +00001826 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001827 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1828}
1829
1830static void
florian55085f82012-11-21 00:36:55 +00001831s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001832 UChar r1, UInt i2)
1833{
florian55085f82012-11-21 00:36:55 +00001834 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001835
sewardj7ee97522011-05-09 21:45:04 +00001836 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001837 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1838}
1839
1840static void
florian55085f82012-11-21 00:36:55 +00001841s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001842 UChar r1, UInt i2)
1843{
florian55085f82012-11-21 00:36:55 +00001844 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001845
sewardj7ee97522011-05-09 21:45:04 +00001846 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001847 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1848}
1849
1850static void
florian55085f82012-11-21 00:36:55 +00001851s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001852 IRTemp op4addr),
1853 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1854{
florian55085f82012-11-21 00:36:55 +00001855 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001856 IRTemp op4addr = newTemp(Ity_I64);
1857
1858 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1859 mkU64(0)));
1860
1861 mnm = irgen(r1, m3, i2, op4addr);
1862
sewardj7ee97522011-05-09 21:45:04 +00001863 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001864 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1865 (Int)(Char)i2, m3, d4, 0, b4);
1866}
1867
1868static void
florian55085f82012-11-21 00:36:55 +00001869s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001870 IRTemp op4addr),
1871 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1872{
florian55085f82012-11-21 00:36:55 +00001873 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001874 IRTemp op4addr = newTemp(Ity_I64);
1875
1876 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1877 mkU64(0)));
1878
1879 mnm = irgen(r1, m3, i2, op4addr);
1880
sewardj7ee97522011-05-09 21:45:04 +00001881 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001882 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1883 i2, m3, d4, 0, b4);
1884}
1885
1886static void
florian55085f82012-11-21 00:36:55 +00001887s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001888 UChar r1, UChar r2)
1889{
1890 irgen(r1, r2);
1891}
1892
1893static void
florian55085f82012-11-21 00:36:55 +00001894s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001895 UChar r1, UChar r2)
1896{
florian55085f82012-11-21 00:36:55 +00001897 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001898
sewardj7ee97522011-05-09 21:45:04 +00001899 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001900 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1901}
1902
1903static void
florian55085f82012-11-21 00:36:55 +00001904s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001905 UChar r1, UChar r2)
1906{
florian55085f82012-11-21 00:36:55 +00001907 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001908
sewardj7ee97522011-05-09 21:45:04 +00001909 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001910 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1911}
1912
1913static void
florian55085f82012-11-21 00:36:55 +00001914s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001915 UChar r1, UChar r2)
1916{
1917 irgen(r1, r2);
1918}
1919
1920static void
florian55085f82012-11-21 00:36:55 +00001921s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001922 UChar r1, UChar r2)
1923{
florian55085f82012-11-21 00:36:55 +00001924 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001925
sewardj7ee97522011-05-09 21:45:04 +00001926 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001927 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1928}
1929
1930static void
florian55085f82012-11-21 00:36:55 +00001931s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001932 UChar r1, UChar r2)
1933{
florian55085f82012-11-21 00:36:55 +00001934 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001935
sewardj7ee97522011-05-09 21:45:04 +00001936 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001937 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1938}
1939
1940static void
florian55085f82012-11-21 00:36:55 +00001941s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001942 UChar r1, UChar r2)
1943{
florian55085f82012-11-21 00:36:55 +00001944 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001945
sewardj7ee97522011-05-09 21:45:04 +00001946 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001947 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1948}
1949
1950static void
florian55085f82012-11-21 00:36:55 +00001951s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001952 UChar r1, UChar r2)
1953{
florian55085f82012-11-21 00:36:55 +00001954 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001955
sewardj7ee97522011-05-09 21:45:04 +00001956 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001957 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1958}
1959
1960static void
florian55085f82012-11-21 00:36:55 +00001961s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001962 UChar r1)
1963{
florian55085f82012-11-21 00:36:55 +00001964 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001965
sewardj7ee97522011-05-09 21:45:04 +00001966 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001967 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1968}
1969
1970static void
florian55085f82012-11-21 00:36:55 +00001971s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001972 UChar r1)
1973{
florian55085f82012-11-21 00:36:55 +00001974 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001975
sewardj7ee97522011-05-09 21:45:04 +00001976 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001977 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1978}
1979
1980static void
florian55085f82012-11-21 00:36:55 +00001981s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00001982 UChar m3, UChar r1, UChar r2)
1983{
florian55085f82012-11-21 00:36:55 +00001984 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001985
1986 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001987 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001988}
1989
1990static void
florian55085f82012-11-21 00:36:55 +00001991s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001992 UChar r1, UChar r3, UChar r2)
1993{
florian55085f82012-11-21 00:36:55 +00001994 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00001995
sewardj7ee97522011-05-09 21:45:04 +00001996 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001997 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1998}
1999
2000static void
florian55085f82012-11-21 00:36:55 +00002001s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2002 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002003 UChar m3, UChar m4, UChar r1, UChar r2)
2004{
florian55085f82012-11-21 00:36:55 +00002005 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002006
2007 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2008 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2009}
2010
2011static void
floriane38f6412012-12-21 17:32:12 +00002012s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2013 UChar m4, UChar r1, UChar r2)
2014{
2015 const HChar *mnm = irgen(m4, r1, r2);
2016
2017 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2018 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2019}
2020
2021static void
florian55085f82012-11-21 00:36:55 +00002022s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2023 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002024 UChar m3, UChar m4, UChar r1, UChar r2)
2025{
florian55085f82012-11-21 00:36:55 +00002026 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002027
2028 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2029 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2030}
2031
2032static void
florian55085f82012-11-21 00:36:55 +00002033s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2034 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002035 UChar m3, UChar m4, UChar r1, UChar r2)
2036{
florian55085f82012-11-21 00:36:55 +00002037 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002038
2039 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2040 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2041}
2042
2043
2044static void
florian55085f82012-11-21 00:36:55 +00002045s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002046 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2047{
2048 irgen(m3, r1, r2);
2049
sewardj7ee97522011-05-09 21:45:04 +00002050 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002051 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2052}
2053
2054static void
florian55085f82012-11-21 00:36:55 +00002055s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002056 UChar r3, UChar r1, UChar r2)
2057{
florian55085f82012-11-21 00:36:55 +00002058 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002059
sewardj7ee97522011-05-09 21:45:04 +00002060 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002061 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2062}
2063
2064static void
florian55085f82012-11-21 00:36:55 +00002065s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002066 UChar r3, UChar m4, UChar r1, UChar r2)
2067{
florian55085f82012-11-21 00:36:55 +00002068 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002069
2070 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2071 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2072}
2073
2074static void
florian55085f82012-11-21 00:36:55 +00002075s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002076 UChar r3, UChar r1, UChar r2)
2077{
florian55085f82012-11-21 00:36:55 +00002078 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002079
sewardj7ee97522011-05-09 21:45:04 +00002080 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002081 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2082}
2083
2084static void
florian55085f82012-11-21 00:36:55 +00002085s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2086 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002087 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2088{
florian55085f82012-11-21 00:36:55 +00002089 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002090 IRTemp op4addr = newTemp(Ity_I64);
2091
2092 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2093 mkU64(0)));
2094
2095 mnm = irgen(r1, r2, m3, op4addr);
2096
sewardj7ee97522011-05-09 21:45:04 +00002097 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002098 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2099 r2, m3, d4, 0, b4);
2100}
2101
2102static void
florian55085f82012-11-21 00:36:55 +00002103s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002104 UChar r1, UChar b2, UShort d2)
2105{
florian55085f82012-11-21 00:36:55 +00002106 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002107 IRTemp op2addr = newTemp(Ity_I64);
2108
2109 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2110 mkU64(0)));
2111
2112 mnm = irgen(r1, op2addr);
2113
sewardj7ee97522011-05-09 21:45:04 +00002114 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002115 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2116}
2117
2118static void
florian55085f82012-11-21 00:36:55 +00002119s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002120 UChar r1, UChar r3, UChar b2, UShort d2)
2121{
florian55085f82012-11-21 00:36:55 +00002122 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002123 IRTemp op2addr = newTemp(Ity_I64);
2124
2125 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2126 mkU64(0)));
2127
2128 mnm = irgen(r1, r3, op2addr);
2129
sewardj7ee97522011-05-09 21:45:04 +00002130 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002131 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2132}
2133
2134static void
florian55085f82012-11-21 00:36:55 +00002135s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002136 UChar r1, UChar r3, UChar b2, UShort d2)
2137{
florian55085f82012-11-21 00:36:55 +00002138 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002139 IRTemp op2addr = newTemp(Ity_I64);
2140
2141 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2142 mkU64(0)));
2143
2144 mnm = irgen(r1, r3, op2addr);
2145
sewardj7ee97522011-05-09 21:45:04 +00002146 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002147 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2148}
2149
2150static void
florian55085f82012-11-21 00:36:55 +00002151s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002152 UChar r1, UChar r3, UChar b2, UShort d2)
2153{
florian55085f82012-11-21 00:36:55 +00002154 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002155 IRTemp op2addr = newTemp(Ity_I64);
2156
2157 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2158 mkU64(0)));
2159
2160 mnm = irgen(r1, r3, op2addr);
2161
sewardj7ee97522011-05-09 21:45:04 +00002162 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002163 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2164}
2165
2166static void
florian55085f82012-11-21 00:36:55 +00002167s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002168 UChar r1, UChar r3, UShort i2)
2169{
florian55085f82012-11-21 00:36:55 +00002170 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002171
sewardj7ee97522011-05-09 21:45:04 +00002172 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002173 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2174}
2175
2176static void
florian55085f82012-11-21 00:36:55 +00002177s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002178 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2179{
florian55085f82012-11-21 00:36:55 +00002180 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002181 IRTemp op2addr = newTemp(Ity_I64);
2182 IRTemp d2 = newTemp(Ity_I64);
2183
2184 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2185 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2186 mkU64(0)));
2187
2188 mnm = irgen(r1, r3, op2addr);
2189
sewardj7ee97522011-05-09 21:45:04 +00002190 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002191 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2192}
2193
2194static void
florian55085f82012-11-21 00:36:55 +00002195s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002196 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2197{
florian55085f82012-11-21 00:36:55 +00002198 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002199 IRTemp op2addr = newTemp(Ity_I64);
2200 IRTemp d2 = newTemp(Ity_I64);
2201
2202 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2203 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2204 mkU64(0)));
2205
2206 mnm = irgen(r1, r3, op2addr);
2207
sewardj7ee97522011-05-09 21:45:04 +00002208 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002209 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2210}
2211
2212static void
florian55085f82012-11-21 00:36:55 +00002213s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002214 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2215{
florian55085f82012-11-21 00:36:55 +00002216 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002217 IRTemp op2addr = newTemp(Ity_I64);
2218 IRTemp d2 = newTemp(Ity_I64);
2219
2220 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2221 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2222 mkU64(0)));
2223
2224 mnm = irgen(r1, r3, op2addr);
2225
sewardj7ee97522011-05-09 21:45:04 +00002226 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002227 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2228}
2229
2230static void
florian55085f82012-11-21 00:36:55 +00002231s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002232 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2233 Int xmnm_kind)
2234{
2235 IRTemp op2addr = newTemp(Ity_I64);
2236 IRTemp d2 = newTemp(Ity_I64);
2237
florian6820ba52012-07-26 02:01:50 +00002238 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2239
sewardjd7bde722011-04-05 13:19:33 +00002240 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2241 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2242 mkU64(0)));
2243
2244 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002245
2246 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002247
sewardj7ee97522011-05-09 21:45:04 +00002248 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002249 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2250}
2251
2252static void
florian55085f82012-11-21 00:36:55 +00002253s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002254 IRTemp op2addr),
2255 UChar r1, UChar x2, UChar b2, UShort d2)
2256{
2257 IRTemp op2addr = newTemp(Ity_I64);
2258
2259 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2260 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2261 mkU64(0)));
2262
2263 irgen(r1, x2, b2, d2, op2addr);
2264}
2265
2266static void
florian55085f82012-11-21 00:36:55 +00002267s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002268 UChar r1, UChar x2, UChar b2, UShort d2)
2269{
florian55085f82012-11-21 00:36:55 +00002270 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002271 IRTemp op2addr = newTemp(Ity_I64);
2272
2273 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2274 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2275 mkU64(0)));
2276
2277 mnm = irgen(r1, op2addr);
2278
sewardj7ee97522011-05-09 21:45:04 +00002279 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002280 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2281}
2282
2283static void
florian55085f82012-11-21 00:36:55 +00002284s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002285 UChar r1, UChar x2, UChar b2, UShort d2)
2286{
florian55085f82012-11-21 00:36:55 +00002287 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002288 IRTemp op2addr = newTemp(Ity_I64);
2289
2290 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2291 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2292 mkU64(0)));
2293
2294 mnm = irgen(r1, op2addr);
2295
sewardj7ee97522011-05-09 21:45:04 +00002296 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002297 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2298}
2299
2300static void
florian55085f82012-11-21 00:36:55 +00002301s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002302 UChar r1, UChar x2, UChar b2, UShort d2)
2303{
florian55085f82012-11-21 00:36:55 +00002304 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002305 IRTemp op2addr = newTemp(Ity_I64);
2306
2307 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2308 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2309 mkU64(0)));
2310
2311 mnm = irgen(r1, op2addr);
2312
sewardj7ee97522011-05-09 21:45:04 +00002313 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002314 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2315}
2316
2317static void
florian55085f82012-11-21 00:36:55 +00002318s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002319 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2320{
florian55085f82012-11-21 00:36:55 +00002321 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002322 IRTemp op2addr = newTemp(Ity_I64);
2323
2324 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2325 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2326 mkU64(0)));
2327
2328 mnm = irgen(r3, op2addr, r1);
2329
sewardj7ee97522011-05-09 21:45:04 +00002330 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002331 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2332}
2333
2334static void
florian55085f82012-11-21 00:36:55 +00002335s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002336 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2337{
florian55085f82012-11-21 00:36:55 +00002338 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002339 IRTemp op2addr = newTemp(Ity_I64);
2340 IRTemp d2 = newTemp(Ity_I64);
2341
2342 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2343 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2344 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2345 mkU64(0)));
2346
2347 mnm = irgen(r1, op2addr);
2348
sewardj7ee97522011-05-09 21:45:04 +00002349 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002350 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2351}
2352
2353static void
florian55085f82012-11-21 00:36:55 +00002354s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002355 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2356{
florian55085f82012-11-21 00:36:55 +00002357 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002358 IRTemp op2addr = newTemp(Ity_I64);
2359 IRTemp d2 = newTemp(Ity_I64);
2360
2361 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2362 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2363 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2364 mkU64(0)));
2365
2366 mnm = irgen(r1, op2addr);
2367
sewardj7ee97522011-05-09 21:45:04 +00002368 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002369 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2370}
2371
2372static void
florian55085f82012-11-21 00:36:55 +00002373s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002374 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2375{
florian55085f82012-11-21 00:36:55 +00002376 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002377 IRTemp op2addr = newTemp(Ity_I64);
2378 IRTemp d2 = newTemp(Ity_I64);
2379
2380 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2381 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2382 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2383 mkU64(0)));
2384
2385 mnm = irgen();
2386
sewardj7ee97522011-05-09 21:45:04 +00002387 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002388 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2389}
2390
2391static void
florian55085f82012-11-21 00:36:55 +00002392s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002393 UChar b2, UShort d2)
2394{
florian55085f82012-11-21 00:36:55 +00002395 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002396 IRTemp op2addr = newTemp(Ity_I64);
2397
2398 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2399 mkU64(0)));
2400
2401 mnm = irgen(op2addr);
2402
sewardj7ee97522011-05-09 21:45:04 +00002403 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002404 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2405}
2406
2407static void
florian55085f82012-11-21 00:36:55 +00002408s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002409 UChar i2, UChar b1, UShort d1)
2410{
florian55085f82012-11-21 00:36:55 +00002411 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002412 IRTemp op1addr = newTemp(Ity_I64);
2413
2414 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2415 mkU64(0)));
2416
2417 mnm = irgen(i2, op1addr);
2418
sewardj7ee97522011-05-09 21:45:04 +00002419 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002420 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2421}
2422
2423static void
florian55085f82012-11-21 00:36:55 +00002424s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002425 UChar i2, UChar b1, UShort dl1, UChar dh1)
2426{
florian55085f82012-11-21 00:36:55 +00002427 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002428 IRTemp op1addr = newTemp(Ity_I64);
2429 IRTemp d1 = newTemp(Ity_I64);
2430
2431 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2432 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2433 mkU64(0)));
2434
2435 mnm = irgen(i2, op1addr);
2436
sewardj7ee97522011-05-09 21:45:04 +00002437 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002438 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2439}
2440
2441static void
florian55085f82012-11-21 00:36:55 +00002442s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002443 UChar i2, UChar b1, UShort dl1, UChar dh1)
2444{
florian55085f82012-11-21 00:36:55 +00002445 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002446 IRTemp op1addr = newTemp(Ity_I64);
2447 IRTemp d1 = newTemp(Ity_I64);
2448
2449 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2450 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2451 mkU64(0)));
2452
2453 mnm = irgen(i2, op1addr);
2454
sewardj7ee97522011-05-09 21:45:04 +00002455 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002456 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2457}
2458
2459static void
florian55085f82012-11-21 00:36:55 +00002460s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002461 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2462{
florian55085f82012-11-21 00:36:55 +00002463 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002464 IRTemp op1addr = newTemp(Ity_I64);
2465 IRTemp op2addr = newTemp(Ity_I64);
2466
2467 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2468 mkU64(0)));
2469 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2470 mkU64(0)));
2471
2472 mnm = irgen(l, op1addr, op2addr);
2473
sewardj7ee97522011-05-09 21:45:04 +00002474 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002475 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2476}
2477
2478static void
florian55085f82012-11-21 00:36:55 +00002479s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002480 UChar b1, UShort d1, UShort i2)
2481{
florian55085f82012-11-21 00:36:55 +00002482 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002483 IRTemp op1addr = newTemp(Ity_I64);
2484
2485 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2486 mkU64(0)));
2487
2488 mnm = irgen(i2, op1addr);
2489
sewardj7ee97522011-05-09 21:45:04 +00002490 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002491 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2492}
2493
2494static void
florian55085f82012-11-21 00:36:55 +00002495s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002496 UChar b1, UShort d1, UShort i2)
2497{
florian55085f82012-11-21 00:36:55 +00002498 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002499 IRTemp op1addr = newTemp(Ity_I64);
2500
2501 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2502 mkU64(0)));
2503
2504 mnm = irgen(i2, op1addr);
2505
sewardj7ee97522011-05-09 21:45:04 +00002506 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002507 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2508}
2509
2510
2511
2512/*------------------------------------------------------------*/
2513/*--- Build IR for opcodes ---*/
2514/*------------------------------------------------------------*/
2515
florian55085f82012-11-21 00:36:55 +00002516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002517s390_irgen_AR(UChar r1, UChar r2)
2518{
2519 IRTemp op1 = newTemp(Ity_I32);
2520 IRTemp op2 = newTemp(Ity_I32);
2521 IRTemp result = newTemp(Ity_I32);
2522
2523 assign(op1, get_gpr_w1(r1));
2524 assign(op2, get_gpr_w1(r2));
2525 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2526 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2527 put_gpr_w1(r1, mkexpr(result));
2528
2529 return "ar";
2530}
2531
florian55085f82012-11-21 00:36:55 +00002532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002533s390_irgen_AGR(UChar r1, UChar r2)
2534{
2535 IRTemp op1 = newTemp(Ity_I64);
2536 IRTemp op2 = newTemp(Ity_I64);
2537 IRTemp result = newTemp(Ity_I64);
2538
2539 assign(op1, get_gpr_dw0(r1));
2540 assign(op2, get_gpr_dw0(r2));
2541 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2542 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2543 put_gpr_dw0(r1, mkexpr(result));
2544
2545 return "agr";
2546}
2547
florian55085f82012-11-21 00:36:55 +00002548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002549s390_irgen_AGFR(UChar r1, UChar r2)
2550{
2551 IRTemp op1 = newTemp(Ity_I64);
2552 IRTemp op2 = newTemp(Ity_I64);
2553 IRTemp result = newTemp(Ity_I64);
2554
2555 assign(op1, get_gpr_dw0(r1));
2556 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2557 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2558 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2559 put_gpr_dw0(r1, mkexpr(result));
2560
2561 return "agfr";
2562}
2563
florian55085f82012-11-21 00:36:55 +00002564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002565s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2566{
2567 IRTemp op2 = newTemp(Ity_I32);
2568 IRTemp op3 = newTemp(Ity_I32);
2569 IRTemp result = newTemp(Ity_I32);
2570
2571 assign(op2, get_gpr_w1(r2));
2572 assign(op3, get_gpr_w1(r3));
2573 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2574 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2575 put_gpr_w1(r1, mkexpr(result));
2576
2577 return "ark";
2578}
2579
florian55085f82012-11-21 00:36:55 +00002580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002581s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2582{
2583 IRTemp op2 = newTemp(Ity_I64);
2584 IRTemp op3 = newTemp(Ity_I64);
2585 IRTemp result = newTemp(Ity_I64);
2586
2587 assign(op2, get_gpr_dw0(r2));
2588 assign(op3, get_gpr_dw0(r3));
2589 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2590 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2591 put_gpr_dw0(r1, mkexpr(result));
2592
2593 return "agrk";
2594}
2595
florian55085f82012-11-21 00:36:55 +00002596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002597s390_irgen_A(UChar r1, IRTemp op2addr)
2598{
2599 IRTemp op1 = newTemp(Ity_I32);
2600 IRTemp op2 = newTemp(Ity_I32);
2601 IRTemp result = newTemp(Ity_I32);
2602
2603 assign(op1, get_gpr_w1(r1));
2604 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2605 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2606 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2607 put_gpr_w1(r1, mkexpr(result));
2608
2609 return "a";
2610}
2611
florian55085f82012-11-21 00:36:55 +00002612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002613s390_irgen_AY(UChar r1, IRTemp op2addr)
2614{
2615 IRTemp op1 = newTemp(Ity_I32);
2616 IRTemp op2 = newTemp(Ity_I32);
2617 IRTemp result = newTemp(Ity_I32);
2618
2619 assign(op1, get_gpr_w1(r1));
2620 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2621 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2622 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2623 put_gpr_w1(r1, mkexpr(result));
2624
2625 return "ay";
2626}
2627
florian55085f82012-11-21 00:36:55 +00002628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002629s390_irgen_AG(UChar r1, IRTemp op2addr)
2630{
2631 IRTemp op1 = newTemp(Ity_I64);
2632 IRTemp op2 = newTemp(Ity_I64);
2633 IRTemp result = newTemp(Ity_I64);
2634
2635 assign(op1, get_gpr_dw0(r1));
2636 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2637 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2638 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2639 put_gpr_dw0(r1, mkexpr(result));
2640
2641 return "ag";
2642}
2643
florian55085f82012-11-21 00:36:55 +00002644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002645s390_irgen_AGF(UChar r1, IRTemp op2addr)
2646{
2647 IRTemp op1 = newTemp(Ity_I64);
2648 IRTemp op2 = newTemp(Ity_I64);
2649 IRTemp result = newTemp(Ity_I64);
2650
2651 assign(op1, get_gpr_dw0(r1));
2652 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2653 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2654 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2655 put_gpr_dw0(r1, mkexpr(result));
2656
2657 return "agf";
2658}
2659
florian55085f82012-11-21 00:36:55 +00002660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002661s390_irgen_AFI(UChar r1, UInt i2)
2662{
2663 IRTemp op1 = newTemp(Ity_I32);
2664 Int op2;
2665 IRTemp result = newTemp(Ity_I32);
2666
2667 assign(op1, get_gpr_w1(r1));
2668 op2 = (Int)i2;
2669 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2670 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2671 mkU32((UInt)op2)));
2672 put_gpr_w1(r1, mkexpr(result));
2673
2674 return "afi";
2675}
2676
florian55085f82012-11-21 00:36:55 +00002677static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002678s390_irgen_AGFI(UChar r1, UInt i2)
2679{
2680 IRTemp op1 = newTemp(Ity_I64);
2681 Long op2;
2682 IRTemp result = newTemp(Ity_I64);
2683
2684 assign(op1, get_gpr_dw0(r1));
2685 op2 = (Long)(Int)i2;
2686 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2687 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2688 mkU64((ULong)op2)));
2689 put_gpr_dw0(r1, mkexpr(result));
2690
2691 return "agfi";
2692}
2693
florian55085f82012-11-21 00:36:55 +00002694static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002695s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2696{
2697 Int op2;
2698 IRTemp op3 = newTemp(Ity_I32);
2699 IRTemp result = newTemp(Ity_I32);
2700
2701 op2 = (Int)(Short)i2;
2702 assign(op3, get_gpr_w1(r3));
2703 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2704 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2705 op2)), op3);
2706 put_gpr_w1(r1, mkexpr(result));
2707
2708 return "ahik";
2709}
2710
florian55085f82012-11-21 00:36:55 +00002711static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002712s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2713{
2714 Long op2;
2715 IRTemp op3 = newTemp(Ity_I64);
2716 IRTemp result = newTemp(Ity_I64);
2717
2718 op2 = (Long)(Short)i2;
2719 assign(op3, get_gpr_dw0(r3));
2720 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2721 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2722 op2)), op3);
2723 put_gpr_dw0(r1, mkexpr(result));
2724
2725 return "aghik";
2726}
2727
florian55085f82012-11-21 00:36:55 +00002728static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002729s390_irgen_ASI(UChar i2, IRTemp op1addr)
2730{
2731 IRTemp op1 = newTemp(Ity_I32);
2732 Int op2;
2733 IRTemp result = newTemp(Ity_I32);
2734
2735 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2736 op2 = (Int)(Char)i2;
2737 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2738 store(mkexpr(op1addr), mkexpr(result));
2739 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2740 mkU32((UInt)op2)));
2741
2742 return "asi";
2743}
2744
florian55085f82012-11-21 00:36:55 +00002745static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002746s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2747{
2748 IRTemp op1 = newTemp(Ity_I64);
2749 Long op2;
2750 IRTemp result = newTemp(Ity_I64);
2751
2752 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2753 op2 = (Long)(Char)i2;
2754 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2755 store(mkexpr(op1addr), mkexpr(result));
2756 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2757 mkU64((ULong)op2)));
2758
2759 return "agsi";
2760}
2761
florian55085f82012-11-21 00:36:55 +00002762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002763s390_irgen_AH(UChar r1, IRTemp op2addr)
2764{
2765 IRTemp op1 = newTemp(Ity_I32);
2766 IRTemp op2 = newTemp(Ity_I32);
2767 IRTemp result = newTemp(Ity_I32);
2768
2769 assign(op1, get_gpr_w1(r1));
2770 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2771 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2772 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2773 put_gpr_w1(r1, mkexpr(result));
2774
2775 return "ah";
2776}
2777
florian55085f82012-11-21 00:36:55 +00002778static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002779s390_irgen_AHY(UChar r1, IRTemp op2addr)
2780{
2781 IRTemp op1 = newTemp(Ity_I32);
2782 IRTemp op2 = newTemp(Ity_I32);
2783 IRTemp result = newTemp(Ity_I32);
2784
2785 assign(op1, get_gpr_w1(r1));
2786 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2787 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2788 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2789 put_gpr_w1(r1, mkexpr(result));
2790
2791 return "ahy";
2792}
2793
florian55085f82012-11-21 00:36:55 +00002794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002795s390_irgen_AHI(UChar r1, UShort i2)
2796{
2797 IRTemp op1 = newTemp(Ity_I32);
2798 Int op2;
2799 IRTemp result = newTemp(Ity_I32);
2800
2801 assign(op1, get_gpr_w1(r1));
2802 op2 = (Int)(Short)i2;
2803 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2804 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2805 mkU32((UInt)op2)));
2806 put_gpr_w1(r1, mkexpr(result));
2807
2808 return "ahi";
2809}
2810
florian55085f82012-11-21 00:36:55 +00002811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002812s390_irgen_AGHI(UChar r1, UShort i2)
2813{
2814 IRTemp op1 = newTemp(Ity_I64);
2815 Long op2;
2816 IRTemp result = newTemp(Ity_I64);
2817
2818 assign(op1, get_gpr_dw0(r1));
2819 op2 = (Long)(Short)i2;
2820 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2821 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2822 mkU64((ULong)op2)));
2823 put_gpr_dw0(r1, mkexpr(result));
2824
2825 return "aghi";
2826}
2827
florian55085f82012-11-21 00:36:55 +00002828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002829s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2830{
2831 IRTemp op2 = newTemp(Ity_I32);
2832 IRTemp op3 = newTemp(Ity_I32);
2833 IRTemp result = newTemp(Ity_I32);
2834
2835 assign(op2, get_gpr_w0(r2));
2836 assign(op3, get_gpr_w0(r3));
2837 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2838 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2839 put_gpr_w0(r1, mkexpr(result));
2840
2841 return "ahhhr";
2842}
2843
florian55085f82012-11-21 00:36:55 +00002844static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002845s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2846{
2847 IRTemp op2 = newTemp(Ity_I32);
2848 IRTemp op3 = newTemp(Ity_I32);
2849 IRTemp result = newTemp(Ity_I32);
2850
2851 assign(op2, get_gpr_w0(r2));
2852 assign(op3, get_gpr_w1(r3));
2853 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2854 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2855 put_gpr_w0(r1, mkexpr(result));
2856
2857 return "ahhlr";
2858}
2859
florian55085f82012-11-21 00:36:55 +00002860static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002861s390_irgen_AIH(UChar r1, UInt i2)
2862{
2863 IRTemp op1 = newTemp(Ity_I32);
2864 Int op2;
2865 IRTemp result = newTemp(Ity_I32);
2866
2867 assign(op1, get_gpr_w0(r1));
2868 op2 = (Int)i2;
2869 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2870 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2871 mkU32((UInt)op2)));
2872 put_gpr_w0(r1, mkexpr(result));
2873
2874 return "aih";
2875}
2876
florian55085f82012-11-21 00:36:55 +00002877static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002878s390_irgen_ALR(UChar r1, UChar r2)
2879{
2880 IRTemp op1 = newTemp(Ity_I32);
2881 IRTemp op2 = newTemp(Ity_I32);
2882 IRTemp result = newTemp(Ity_I32);
2883
2884 assign(op1, get_gpr_w1(r1));
2885 assign(op2, get_gpr_w1(r2));
2886 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2887 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2888 put_gpr_w1(r1, mkexpr(result));
2889
2890 return "alr";
2891}
2892
florian55085f82012-11-21 00:36:55 +00002893static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002894s390_irgen_ALGR(UChar r1, UChar r2)
2895{
2896 IRTemp op1 = newTemp(Ity_I64);
2897 IRTemp op2 = newTemp(Ity_I64);
2898 IRTemp result = newTemp(Ity_I64);
2899
2900 assign(op1, get_gpr_dw0(r1));
2901 assign(op2, get_gpr_dw0(r2));
2902 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2903 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2904 put_gpr_dw0(r1, mkexpr(result));
2905
2906 return "algr";
2907}
2908
florian55085f82012-11-21 00:36:55 +00002909static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002910s390_irgen_ALGFR(UChar r1, UChar r2)
2911{
2912 IRTemp op1 = newTemp(Ity_I64);
2913 IRTemp op2 = newTemp(Ity_I64);
2914 IRTemp result = newTemp(Ity_I64);
2915
2916 assign(op1, get_gpr_dw0(r1));
2917 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2918 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2919 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2920 put_gpr_dw0(r1, mkexpr(result));
2921
2922 return "algfr";
2923}
2924
florian55085f82012-11-21 00:36:55 +00002925static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002926s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2927{
2928 IRTemp op2 = newTemp(Ity_I32);
2929 IRTemp op3 = newTemp(Ity_I32);
2930 IRTemp result = newTemp(Ity_I32);
2931
2932 assign(op2, get_gpr_w1(r2));
2933 assign(op3, get_gpr_w1(r3));
2934 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2935 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2936 put_gpr_w1(r1, mkexpr(result));
2937
2938 return "alrk";
2939}
2940
florian55085f82012-11-21 00:36:55 +00002941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002942s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2943{
2944 IRTemp op2 = newTemp(Ity_I64);
2945 IRTemp op3 = newTemp(Ity_I64);
2946 IRTemp result = newTemp(Ity_I64);
2947
2948 assign(op2, get_gpr_dw0(r2));
2949 assign(op3, get_gpr_dw0(r3));
2950 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2951 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2952 put_gpr_dw0(r1, mkexpr(result));
2953
2954 return "algrk";
2955}
2956
florian55085f82012-11-21 00:36:55 +00002957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002958s390_irgen_AL(UChar r1, IRTemp op2addr)
2959{
2960 IRTemp op1 = newTemp(Ity_I32);
2961 IRTemp op2 = newTemp(Ity_I32);
2962 IRTemp result = newTemp(Ity_I32);
2963
2964 assign(op1, get_gpr_w1(r1));
2965 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2966 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2967 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2968 put_gpr_w1(r1, mkexpr(result));
2969
2970 return "al";
2971}
2972
florian55085f82012-11-21 00:36:55 +00002973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002974s390_irgen_ALY(UChar r1, IRTemp op2addr)
2975{
2976 IRTemp op1 = newTemp(Ity_I32);
2977 IRTemp op2 = newTemp(Ity_I32);
2978 IRTemp result = newTemp(Ity_I32);
2979
2980 assign(op1, get_gpr_w1(r1));
2981 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2982 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2983 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2984 put_gpr_w1(r1, mkexpr(result));
2985
2986 return "aly";
2987}
2988
florian55085f82012-11-21 00:36:55 +00002989static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002990s390_irgen_ALG(UChar r1, IRTemp op2addr)
2991{
2992 IRTemp op1 = newTemp(Ity_I64);
2993 IRTemp op2 = newTemp(Ity_I64);
2994 IRTemp result = newTemp(Ity_I64);
2995
2996 assign(op1, get_gpr_dw0(r1));
2997 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2998 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2999 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3000 put_gpr_dw0(r1, mkexpr(result));
3001
3002 return "alg";
3003}
3004
florian55085f82012-11-21 00:36:55 +00003005static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003006s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3007{
3008 IRTemp op1 = newTemp(Ity_I64);
3009 IRTemp op2 = newTemp(Ity_I64);
3010 IRTemp result = newTemp(Ity_I64);
3011
3012 assign(op1, get_gpr_dw0(r1));
3013 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3014 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3015 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3016 put_gpr_dw0(r1, mkexpr(result));
3017
3018 return "algf";
3019}
3020
florian55085f82012-11-21 00:36:55 +00003021static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003022s390_irgen_ALFI(UChar r1, UInt i2)
3023{
3024 IRTemp op1 = newTemp(Ity_I32);
3025 UInt op2;
3026 IRTemp result = newTemp(Ity_I32);
3027
3028 assign(op1, get_gpr_w1(r1));
3029 op2 = i2;
3030 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3031 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3032 mkU32(op2)));
3033 put_gpr_w1(r1, mkexpr(result));
3034
3035 return "alfi";
3036}
3037
florian55085f82012-11-21 00:36:55 +00003038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003039s390_irgen_ALGFI(UChar r1, UInt i2)
3040{
3041 IRTemp op1 = newTemp(Ity_I64);
3042 ULong op2;
3043 IRTemp result = newTemp(Ity_I64);
3044
3045 assign(op1, get_gpr_dw0(r1));
3046 op2 = (ULong)i2;
3047 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3048 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3049 mkU64(op2)));
3050 put_gpr_dw0(r1, mkexpr(result));
3051
3052 return "algfi";
3053}
3054
florian55085f82012-11-21 00:36:55 +00003055static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003056s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3057{
3058 IRTemp op2 = newTemp(Ity_I32);
3059 IRTemp op3 = newTemp(Ity_I32);
3060 IRTemp result = newTemp(Ity_I32);
3061
3062 assign(op2, get_gpr_w0(r2));
3063 assign(op3, get_gpr_w0(r3));
3064 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3065 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3066 put_gpr_w0(r1, mkexpr(result));
3067
3068 return "alhhhr";
3069}
3070
florian55085f82012-11-21 00:36:55 +00003071static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003072s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3073{
3074 IRTemp op2 = newTemp(Ity_I32);
3075 IRTemp op3 = newTemp(Ity_I32);
3076 IRTemp result = newTemp(Ity_I32);
3077
3078 assign(op2, get_gpr_w0(r2));
3079 assign(op3, get_gpr_w1(r3));
3080 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3081 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3082 put_gpr_w0(r1, mkexpr(result));
3083
3084 return "alhhlr";
3085}
3086
florian55085f82012-11-21 00:36:55 +00003087static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003088s390_irgen_ALCR(UChar r1, UChar r2)
3089{
3090 IRTemp op1 = newTemp(Ity_I32);
3091 IRTemp op2 = newTemp(Ity_I32);
3092 IRTemp result = newTemp(Ity_I32);
3093 IRTemp carry_in = newTemp(Ity_I32);
3094
3095 assign(op1, get_gpr_w1(r1));
3096 assign(op2, get_gpr_w1(r2));
3097 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3098 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3099 mkexpr(carry_in)));
3100 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3101 put_gpr_w1(r1, mkexpr(result));
3102
3103 return "alcr";
3104}
3105
florian55085f82012-11-21 00:36:55 +00003106static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003107s390_irgen_ALCGR(UChar r1, UChar r2)
3108{
3109 IRTemp op1 = newTemp(Ity_I64);
3110 IRTemp op2 = newTemp(Ity_I64);
3111 IRTemp result = newTemp(Ity_I64);
3112 IRTemp carry_in = newTemp(Ity_I64);
3113
3114 assign(op1, get_gpr_dw0(r1));
3115 assign(op2, get_gpr_dw0(r2));
3116 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3117 mkU8(1))));
3118 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3119 mkexpr(carry_in)));
3120 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3121 put_gpr_dw0(r1, mkexpr(result));
3122
3123 return "alcgr";
3124}
3125
florian55085f82012-11-21 00:36:55 +00003126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003127s390_irgen_ALC(UChar r1, IRTemp op2addr)
3128{
3129 IRTemp op1 = newTemp(Ity_I32);
3130 IRTemp op2 = newTemp(Ity_I32);
3131 IRTemp result = newTemp(Ity_I32);
3132 IRTemp carry_in = newTemp(Ity_I32);
3133
3134 assign(op1, get_gpr_w1(r1));
3135 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3136 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3137 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3138 mkexpr(carry_in)));
3139 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3140 put_gpr_w1(r1, mkexpr(result));
3141
3142 return "alc";
3143}
3144
florian55085f82012-11-21 00:36:55 +00003145static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003146s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3147{
3148 IRTemp op1 = newTemp(Ity_I64);
3149 IRTemp op2 = newTemp(Ity_I64);
3150 IRTemp result = newTemp(Ity_I64);
3151 IRTemp carry_in = newTemp(Ity_I64);
3152
3153 assign(op1, get_gpr_dw0(r1));
3154 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3155 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3156 mkU8(1))));
3157 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3158 mkexpr(carry_in)));
3159 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3160 put_gpr_dw0(r1, mkexpr(result));
3161
3162 return "alcg";
3163}
3164
florian55085f82012-11-21 00:36:55 +00003165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003166s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3167{
3168 IRTemp op1 = newTemp(Ity_I32);
3169 UInt op2;
3170 IRTemp result = newTemp(Ity_I32);
3171
3172 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3173 op2 = (UInt)(Int)(Char)i2;
3174 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3175 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3176 mkU32(op2)));
3177 store(mkexpr(op1addr), mkexpr(result));
3178
3179 return "alsi";
3180}
3181
florian55085f82012-11-21 00:36:55 +00003182static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003183s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3184{
3185 IRTemp op1 = newTemp(Ity_I64);
3186 ULong op2;
3187 IRTemp result = newTemp(Ity_I64);
3188
3189 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3190 op2 = (ULong)(Long)(Char)i2;
3191 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3192 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3193 mkU64(op2)));
3194 store(mkexpr(op1addr), mkexpr(result));
3195
3196 return "algsi";
3197}
3198
florian55085f82012-11-21 00:36:55 +00003199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003200s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3201{
3202 UInt op2;
3203 IRTemp op3 = newTemp(Ity_I32);
3204 IRTemp result = newTemp(Ity_I32);
3205
3206 op2 = (UInt)(Int)(Short)i2;
3207 assign(op3, get_gpr_w1(r3));
3208 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3209 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3210 op3);
3211 put_gpr_w1(r1, mkexpr(result));
3212
3213 return "alhsik";
3214}
3215
florian55085f82012-11-21 00:36:55 +00003216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003217s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3218{
3219 ULong op2;
3220 IRTemp op3 = newTemp(Ity_I64);
3221 IRTemp result = newTemp(Ity_I64);
3222
3223 op2 = (ULong)(Long)(Short)i2;
3224 assign(op3, get_gpr_dw0(r3));
3225 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3226 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3227 op3);
3228 put_gpr_dw0(r1, mkexpr(result));
3229
3230 return "alghsik";
3231}
3232
florian55085f82012-11-21 00:36:55 +00003233static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003234s390_irgen_ALSIH(UChar r1, UInt i2)
3235{
3236 IRTemp op1 = newTemp(Ity_I32);
3237 UInt op2;
3238 IRTemp result = newTemp(Ity_I32);
3239
3240 assign(op1, get_gpr_w0(r1));
3241 op2 = i2;
3242 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3243 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3244 mkU32(op2)));
3245 put_gpr_w0(r1, mkexpr(result));
3246
3247 return "alsih";
3248}
3249
florian55085f82012-11-21 00:36:55 +00003250static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003251s390_irgen_ALSIHN(UChar r1, UInt i2)
3252{
3253 IRTemp op1 = newTemp(Ity_I32);
3254 UInt op2;
3255 IRTemp result = newTemp(Ity_I32);
3256
3257 assign(op1, get_gpr_w0(r1));
3258 op2 = i2;
3259 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3260 put_gpr_w0(r1, mkexpr(result));
3261
3262 return "alsihn";
3263}
3264
florian55085f82012-11-21 00:36:55 +00003265static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003266s390_irgen_NR(UChar r1, UChar r2)
3267{
3268 IRTemp op1 = newTemp(Ity_I32);
3269 IRTemp op2 = newTemp(Ity_I32);
3270 IRTemp result = newTemp(Ity_I32);
3271
3272 assign(op1, get_gpr_w1(r1));
3273 assign(op2, get_gpr_w1(r2));
3274 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3275 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3276 put_gpr_w1(r1, mkexpr(result));
3277
3278 return "nr";
3279}
3280
florian55085f82012-11-21 00:36:55 +00003281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003282s390_irgen_NGR(UChar r1, UChar r2)
3283{
3284 IRTemp op1 = newTemp(Ity_I64);
3285 IRTemp op2 = newTemp(Ity_I64);
3286 IRTemp result = newTemp(Ity_I64);
3287
3288 assign(op1, get_gpr_dw0(r1));
3289 assign(op2, get_gpr_dw0(r2));
3290 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3291 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3292 put_gpr_dw0(r1, mkexpr(result));
3293
3294 return "ngr";
3295}
3296
florian55085f82012-11-21 00:36:55 +00003297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003298s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3299{
3300 IRTemp op2 = newTemp(Ity_I32);
3301 IRTemp op3 = newTemp(Ity_I32);
3302 IRTemp result = newTemp(Ity_I32);
3303
3304 assign(op2, get_gpr_w1(r2));
3305 assign(op3, get_gpr_w1(r3));
3306 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3307 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3308 put_gpr_w1(r1, mkexpr(result));
3309
3310 return "nrk";
3311}
3312
florian55085f82012-11-21 00:36:55 +00003313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003314s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3315{
3316 IRTemp op2 = newTemp(Ity_I64);
3317 IRTemp op3 = newTemp(Ity_I64);
3318 IRTemp result = newTemp(Ity_I64);
3319
3320 assign(op2, get_gpr_dw0(r2));
3321 assign(op3, get_gpr_dw0(r3));
3322 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3323 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3324 put_gpr_dw0(r1, mkexpr(result));
3325
3326 return "ngrk";
3327}
3328
florian55085f82012-11-21 00:36:55 +00003329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003330s390_irgen_N(UChar r1, IRTemp op2addr)
3331{
3332 IRTemp op1 = newTemp(Ity_I32);
3333 IRTemp op2 = newTemp(Ity_I32);
3334 IRTemp result = newTemp(Ity_I32);
3335
3336 assign(op1, get_gpr_w1(r1));
3337 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3338 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3339 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3340 put_gpr_w1(r1, mkexpr(result));
3341
3342 return "n";
3343}
3344
florian55085f82012-11-21 00:36:55 +00003345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003346s390_irgen_NY(UChar r1, IRTemp op2addr)
3347{
3348 IRTemp op1 = newTemp(Ity_I32);
3349 IRTemp op2 = newTemp(Ity_I32);
3350 IRTemp result = newTemp(Ity_I32);
3351
3352 assign(op1, get_gpr_w1(r1));
3353 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3354 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3355 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3356 put_gpr_w1(r1, mkexpr(result));
3357
3358 return "ny";
3359}
3360
florian55085f82012-11-21 00:36:55 +00003361static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003362s390_irgen_NG(UChar r1, IRTemp op2addr)
3363{
3364 IRTemp op1 = newTemp(Ity_I64);
3365 IRTemp op2 = newTemp(Ity_I64);
3366 IRTemp result = newTemp(Ity_I64);
3367
3368 assign(op1, get_gpr_dw0(r1));
3369 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3370 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3371 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3372 put_gpr_dw0(r1, mkexpr(result));
3373
3374 return "ng";
3375}
3376
florian55085f82012-11-21 00:36:55 +00003377static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003378s390_irgen_NI(UChar i2, IRTemp op1addr)
3379{
3380 IRTemp op1 = newTemp(Ity_I8);
3381 UChar op2;
3382 IRTemp result = newTemp(Ity_I8);
3383
3384 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3385 op2 = i2;
3386 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3387 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3388 store(mkexpr(op1addr), mkexpr(result));
3389
3390 return "ni";
3391}
3392
florian55085f82012-11-21 00:36:55 +00003393static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003394s390_irgen_NIY(UChar i2, IRTemp op1addr)
3395{
3396 IRTemp op1 = newTemp(Ity_I8);
3397 UChar op2;
3398 IRTemp result = newTemp(Ity_I8);
3399
3400 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3401 op2 = i2;
3402 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3403 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3404 store(mkexpr(op1addr), mkexpr(result));
3405
3406 return "niy";
3407}
3408
florian55085f82012-11-21 00:36:55 +00003409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003410s390_irgen_NIHF(UChar r1, UInt i2)
3411{
3412 IRTemp op1 = newTemp(Ity_I32);
3413 UInt op2;
3414 IRTemp result = newTemp(Ity_I32);
3415
3416 assign(op1, get_gpr_w0(r1));
3417 op2 = i2;
3418 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3419 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3420 put_gpr_w0(r1, mkexpr(result));
3421
3422 return "nihf";
3423}
3424
florian55085f82012-11-21 00:36:55 +00003425static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003426s390_irgen_NIHH(UChar r1, UShort i2)
3427{
3428 IRTemp op1 = newTemp(Ity_I16);
3429 UShort op2;
3430 IRTemp result = newTemp(Ity_I16);
3431
3432 assign(op1, get_gpr_hw0(r1));
3433 op2 = i2;
3434 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3435 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3436 put_gpr_hw0(r1, mkexpr(result));
3437
3438 return "nihh";
3439}
3440
florian55085f82012-11-21 00:36:55 +00003441static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003442s390_irgen_NIHL(UChar r1, UShort i2)
3443{
3444 IRTemp op1 = newTemp(Ity_I16);
3445 UShort op2;
3446 IRTemp result = newTemp(Ity_I16);
3447
3448 assign(op1, get_gpr_hw1(r1));
3449 op2 = i2;
3450 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3451 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3452 put_gpr_hw1(r1, mkexpr(result));
3453
3454 return "nihl";
3455}
3456
florian55085f82012-11-21 00:36:55 +00003457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003458s390_irgen_NILF(UChar r1, UInt i2)
3459{
3460 IRTemp op1 = newTemp(Ity_I32);
3461 UInt op2;
3462 IRTemp result = newTemp(Ity_I32);
3463
3464 assign(op1, get_gpr_w1(r1));
3465 op2 = i2;
3466 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3467 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3468 put_gpr_w1(r1, mkexpr(result));
3469
3470 return "nilf";
3471}
3472
florian55085f82012-11-21 00:36:55 +00003473static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003474s390_irgen_NILH(UChar r1, UShort i2)
3475{
3476 IRTemp op1 = newTemp(Ity_I16);
3477 UShort op2;
3478 IRTemp result = newTemp(Ity_I16);
3479
3480 assign(op1, get_gpr_hw2(r1));
3481 op2 = i2;
3482 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3483 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3484 put_gpr_hw2(r1, mkexpr(result));
3485
3486 return "nilh";
3487}
3488
florian55085f82012-11-21 00:36:55 +00003489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003490s390_irgen_NILL(UChar r1, UShort i2)
3491{
3492 IRTemp op1 = newTemp(Ity_I16);
3493 UShort op2;
3494 IRTemp result = newTemp(Ity_I16);
3495
3496 assign(op1, get_gpr_hw3(r1));
3497 op2 = i2;
3498 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3499 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3500 put_gpr_hw3(r1, mkexpr(result));
3501
3502 return "nill";
3503}
3504
florian55085f82012-11-21 00:36:55 +00003505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003506s390_irgen_BASR(UChar r1, UChar r2)
3507{
3508 IRTemp target = newTemp(Ity_I64);
3509
3510 if (r2 == 0) {
3511 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3512 } else {
3513 if (r1 != r2) {
3514 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3515 call_function(get_gpr_dw0(r2));
3516 } else {
3517 assign(target, get_gpr_dw0(r2));
3518 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3519 call_function(mkexpr(target));
3520 }
3521 }
3522
3523 return "basr";
3524}
3525
florian55085f82012-11-21 00:36:55 +00003526static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003527s390_irgen_BAS(UChar r1, IRTemp op2addr)
3528{
3529 IRTemp target = newTemp(Ity_I64);
3530
3531 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3532 assign(target, mkexpr(op2addr));
3533 call_function(mkexpr(target));
3534
3535 return "bas";
3536}
3537
florian55085f82012-11-21 00:36:55 +00003538static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003539s390_irgen_BCR(UChar r1, UChar r2)
3540{
3541 IRTemp cond = newTemp(Ity_I32);
3542
sewardja52e37e2011-04-28 18:48:06 +00003543 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3544 stmt(IRStmt_MBE(Imbe_Fence));
3545 }
3546
sewardj2019a972011-03-07 16:04:07 +00003547 if ((r2 == 0) || (r1 == 0)) {
3548 } else {
3549 if (r1 == 15) {
3550 return_from_function(get_gpr_dw0(r2));
3551 } else {
3552 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003553 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3554 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003555 }
3556 }
sewardj7ee97522011-05-09 21:45:04 +00003557 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003558 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3559
3560 return "bcr";
3561}
3562
florian55085f82012-11-21 00:36:55 +00003563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003564s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3565{
3566 IRTemp cond = newTemp(Ity_I32);
3567
3568 if (r1 == 0) {
3569 } else {
3570 if (r1 == 15) {
3571 always_goto(mkexpr(op2addr));
3572 } else {
3573 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003574 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3575 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003576 }
3577 }
sewardj7ee97522011-05-09 21:45:04 +00003578 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003579 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3580
3581 return "bc";
3582}
3583
florian55085f82012-11-21 00:36:55 +00003584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003585s390_irgen_BCTR(UChar r1, UChar r2)
3586{
3587 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3588 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003589 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3590 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003591 }
3592
3593 return "bctr";
3594}
3595
florian55085f82012-11-21 00:36:55 +00003596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003597s390_irgen_BCTGR(UChar r1, UChar r2)
3598{
3599 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3600 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003601 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3602 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003603 }
3604
3605 return "bctgr";
3606}
3607
florian55085f82012-11-21 00:36:55 +00003608static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003609s390_irgen_BCT(UChar r1, IRTemp op2addr)
3610{
3611 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003612 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3613 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003614
3615 return "bct";
3616}
3617
florian55085f82012-11-21 00:36:55 +00003618static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003619s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3620{
3621 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003622 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3623 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003624
3625 return "bctg";
3626}
3627
florian55085f82012-11-21 00:36:55 +00003628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003629s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3630{
3631 IRTemp value = newTemp(Ity_I32);
3632
3633 assign(value, get_gpr_w1(r3 | 1));
3634 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003635 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3636 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003637
3638 return "bxh";
3639}
3640
florian55085f82012-11-21 00:36:55 +00003641static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003642s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3643{
3644 IRTemp value = newTemp(Ity_I64);
3645
3646 assign(value, get_gpr_dw0(r3 | 1));
3647 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003648 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3649 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003650
3651 return "bxhg";
3652}
3653
florian55085f82012-11-21 00:36:55 +00003654static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003655s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3656{
3657 IRTemp value = newTemp(Ity_I32);
3658
3659 assign(value, get_gpr_w1(r3 | 1));
3660 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003661 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3662 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003663
3664 return "bxle";
3665}
3666
florian55085f82012-11-21 00:36:55 +00003667static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003668s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3669{
3670 IRTemp value = newTemp(Ity_I64);
3671
3672 assign(value, get_gpr_dw0(r3 | 1));
3673 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003674 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3675 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003676
3677 return "bxleg";
3678}
3679
florian55085f82012-11-21 00:36:55 +00003680static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003681s390_irgen_BRAS(UChar r1, UShort i2)
3682{
3683 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003684 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003685
3686 return "bras";
3687}
3688
florian55085f82012-11-21 00:36:55 +00003689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003690s390_irgen_BRASL(UChar r1, UInt i2)
3691{
3692 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003693 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003694
3695 return "brasl";
3696}
3697
florian55085f82012-11-21 00:36:55 +00003698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003699s390_irgen_BRC(UChar r1, UShort i2)
3700{
3701 IRTemp cond = newTemp(Ity_I32);
3702
3703 if (r1 == 0) {
3704 } else {
3705 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003706 always_goto_and_chase(
3707 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003708 } else {
3709 assign(cond, s390_call_calculate_cond(r1));
3710 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3711 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3712
3713 }
3714 }
sewardj7ee97522011-05-09 21:45:04 +00003715 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003716 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3717
3718 return "brc";
3719}
3720
florian55085f82012-11-21 00:36:55 +00003721static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003722s390_irgen_BRCL(UChar r1, UInt i2)
3723{
3724 IRTemp cond = newTemp(Ity_I32);
3725
3726 if (r1 == 0) {
3727 } else {
3728 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003729 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003730 } else {
3731 assign(cond, s390_call_calculate_cond(r1));
3732 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3733 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3734 }
3735 }
sewardj7ee97522011-05-09 21:45:04 +00003736 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003737 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3738
3739 return "brcl";
3740}
3741
florian55085f82012-11-21 00:36:55 +00003742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003743s390_irgen_BRCT(UChar r1, UShort i2)
3744{
3745 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3746 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3747 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3748
3749 return "brct";
3750}
3751
florian55085f82012-11-21 00:36:55 +00003752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003753s390_irgen_BRCTG(UChar r1, UShort i2)
3754{
3755 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3756 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3757 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3758
3759 return "brctg";
3760}
3761
florian55085f82012-11-21 00:36:55 +00003762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003763s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3764{
3765 IRTemp value = newTemp(Ity_I32);
3766
3767 assign(value, get_gpr_w1(r3 | 1));
3768 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3769 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3770 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3771
3772 return "brxh";
3773}
3774
florian55085f82012-11-21 00:36:55 +00003775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003776s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3777{
3778 IRTemp value = newTemp(Ity_I64);
3779
3780 assign(value, get_gpr_dw0(r3 | 1));
3781 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3782 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3783 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3784
3785 return "brxhg";
3786}
3787
florian55085f82012-11-21 00:36:55 +00003788static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003789s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3790{
3791 IRTemp value = newTemp(Ity_I32);
3792
3793 assign(value, get_gpr_w1(r3 | 1));
3794 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3795 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3796 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3797
3798 return "brxle";
3799}
3800
florian55085f82012-11-21 00:36:55 +00003801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003802s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3803{
3804 IRTemp value = newTemp(Ity_I64);
3805
3806 assign(value, get_gpr_dw0(r3 | 1));
3807 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3808 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3809 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3810
3811 return "brxlg";
3812}
3813
florian55085f82012-11-21 00:36:55 +00003814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003815s390_irgen_CR(UChar r1, UChar r2)
3816{
3817 IRTemp op1 = newTemp(Ity_I32);
3818 IRTemp op2 = newTemp(Ity_I32);
3819
3820 assign(op1, get_gpr_w1(r1));
3821 assign(op2, get_gpr_w1(r2));
3822 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3823
3824 return "cr";
3825}
3826
florian55085f82012-11-21 00:36:55 +00003827static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003828s390_irgen_CGR(UChar r1, UChar r2)
3829{
3830 IRTemp op1 = newTemp(Ity_I64);
3831 IRTemp op2 = newTemp(Ity_I64);
3832
3833 assign(op1, get_gpr_dw0(r1));
3834 assign(op2, get_gpr_dw0(r2));
3835 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3836
3837 return "cgr";
3838}
3839
florian55085f82012-11-21 00:36:55 +00003840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003841s390_irgen_CGFR(UChar r1, UChar r2)
3842{
3843 IRTemp op1 = newTemp(Ity_I64);
3844 IRTemp op2 = newTemp(Ity_I64);
3845
3846 assign(op1, get_gpr_dw0(r1));
3847 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3848 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3849
3850 return "cgfr";
3851}
3852
florian55085f82012-11-21 00:36:55 +00003853static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003854s390_irgen_C(UChar r1, IRTemp op2addr)
3855{
3856 IRTemp op1 = newTemp(Ity_I32);
3857 IRTemp op2 = newTemp(Ity_I32);
3858
3859 assign(op1, get_gpr_w1(r1));
3860 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3861 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3862
3863 return "c";
3864}
3865
florian55085f82012-11-21 00:36:55 +00003866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003867s390_irgen_CY(UChar r1, IRTemp op2addr)
3868{
3869 IRTemp op1 = newTemp(Ity_I32);
3870 IRTemp op2 = newTemp(Ity_I32);
3871
3872 assign(op1, get_gpr_w1(r1));
3873 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3874 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3875
3876 return "cy";
3877}
3878
florian55085f82012-11-21 00:36:55 +00003879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003880s390_irgen_CG(UChar r1, IRTemp op2addr)
3881{
3882 IRTemp op1 = newTemp(Ity_I64);
3883 IRTemp op2 = newTemp(Ity_I64);
3884
3885 assign(op1, get_gpr_dw0(r1));
3886 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3887 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3888
3889 return "cg";
3890}
3891
florian55085f82012-11-21 00:36:55 +00003892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003893s390_irgen_CGF(UChar r1, IRTemp op2addr)
3894{
3895 IRTemp op1 = newTemp(Ity_I64);
3896 IRTemp op2 = newTemp(Ity_I64);
3897
3898 assign(op1, get_gpr_dw0(r1));
3899 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3900 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3901
3902 return "cgf";
3903}
3904
florian55085f82012-11-21 00:36:55 +00003905static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003906s390_irgen_CFI(UChar r1, UInt i2)
3907{
3908 IRTemp op1 = newTemp(Ity_I32);
3909 Int op2;
3910
3911 assign(op1, get_gpr_w1(r1));
3912 op2 = (Int)i2;
3913 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3914 mkU32((UInt)op2)));
3915
3916 return "cfi";
3917}
3918
florian55085f82012-11-21 00:36:55 +00003919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003920s390_irgen_CGFI(UChar r1, UInt i2)
3921{
3922 IRTemp op1 = newTemp(Ity_I64);
3923 Long op2;
3924
3925 assign(op1, get_gpr_dw0(r1));
3926 op2 = (Long)(Int)i2;
3927 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3928 mkU64((ULong)op2)));
3929
3930 return "cgfi";
3931}
3932
florian55085f82012-11-21 00:36:55 +00003933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003934s390_irgen_CRL(UChar r1, UInt i2)
3935{
3936 IRTemp op1 = newTemp(Ity_I32);
3937 IRTemp op2 = newTemp(Ity_I32);
3938
3939 assign(op1, get_gpr_w1(r1));
3940 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3941 i2 << 1))));
3942 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3943
3944 return "crl";
3945}
3946
florian55085f82012-11-21 00:36:55 +00003947static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003948s390_irgen_CGRL(UChar r1, UInt i2)
3949{
3950 IRTemp op1 = newTemp(Ity_I64);
3951 IRTemp op2 = newTemp(Ity_I64);
3952
3953 assign(op1, get_gpr_dw0(r1));
3954 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3955 i2 << 1))));
3956 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3957
3958 return "cgrl";
3959}
3960
florian55085f82012-11-21 00:36:55 +00003961static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003962s390_irgen_CGFRL(UChar r1, UInt i2)
3963{
3964 IRTemp op1 = newTemp(Ity_I64);
3965 IRTemp op2 = newTemp(Ity_I64);
3966
3967 assign(op1, get_gpr_dw0(r1));
3968 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3969 ((ULong)(Long)(Int)i2 << 1)))));
3970 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3971
3972 return "cgfrl";
3973}
3974
florian55085f82012-11-21 00:36:55 +00003975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003976s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3977{
3978 IRTemp op1 = newTemp(Ity_I32);
3979 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003980 IRTemp cond = newTemp(Ity_I32);
3981
3982 if (m3 == 0) {
3983 } else {
3984 if (m3 == 14) {
3985 always_goto(mkexpr(op4addr));
3986 } else {
3987 assign(op1, get_gpr_w1(r1));
3988 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003989 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3990 op1, op2));
florianf321da72012-07-21 20:32:57 +00003991 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3992 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003993 }
3994 }
3995
3996 return "crb";
3997}
3998
florian55085f82012-11-21 00:36:55 +00003999static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004000s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4001{
4002 IRTemp op1 = newTemp(Ity_I64);
4003 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004004 IRTemp cond = newTemp(Ity_I32);
4005
4006 if (m3 == 0) {
4007 } else {
4008 if (m3 == 14) {
4009 always_goto(mkexpr(op4addr));
4010 } else {
4011 assign(op1, get_gpr_dw0(r1));
4012 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004013 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4014 op1, op2));
florianf321da72012-07-21 20:32:57 +00004015 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4016 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004017 }
4018 }
4019
4020 return "cgrb";
4021}
4022
florian55085f82012-11-21 00:36:55 +00004023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004024s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4025{
4026 IRTemp op1 = newTemp(Ity_I32);
4027 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004028 IRTemp cond = newTemp(Ity_I32);
4029
4030 if (m3 == 0) {
4031 } else {
4032 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004033 always_goto_and_chase(
4034 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004035 } else {
4036 assign(op1, get_gpr_w1(r1));
4037 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004038 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4039 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004040 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4041 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4042
4043 }
4044 }
4045
4046 return "crj";
4047}
4048
florian55085f82012-11-21 00:36:55 +00004049static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004050s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4051{
4052 IRTemp op1 = newTemp(Ity_I64);
4053 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004054 IRTemp cond = newTemp(Ity_I32);
4055
4056 if (m3 == 0) {
4057 } else {
4058 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004059 always_goto_and_chase(
4060 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004061 } else {
4062 assign(op1, get_gpr_dw0(r1));
4063 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004064 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4065 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004066 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4067 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4068
4069 }
4070 }
4071
4072 return "cgrj";
4073}
4074
florian55085f82012-11-21 00:36:55 +00004075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004076s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4077{
4078 IRTemp op1 = newTemp(Ity_I32);
4079 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004080 IRTemp cond = newTemp(Ity_I32);
4081
4082 if (m3 == 0) {
4083 } else {
4084 if (m3 == 14) {
4085 always_goto(mkexpr(op4addr));
4086 } else {
4087 assign(op1, get_gpr_w1(r1));
4088 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004089 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4090 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004091 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4092 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004093 }
4094 }
4095
4096 return "cib";
4097}
4098
florian55085f82012-11-21 00:36:55 +00004099static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004100s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4101{
4102 IRTemp op1 = newTemp(Ity_I64);
4103 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004104 IRTemp cond = newTemp(Ity_I32);
4105
4106 if (m3 == 0) {
4107 } else {
4108 if (m3 == 14) {
4109 always_goto(mkexpr(op4addr));
4110 } else {
4111 assign(op1, get_gpr_dw0(r1));
4112 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004113 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4114 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004115 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4116 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004117 }
4118 }
4119
4120 return "cgib";
4121}
4122
florian55085f82012-11-21 00:36:55 +00004123static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004124s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4125{
4126 IRTemp op1 = newTemp(Ity_I32);
4127 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004128 IRTemp cond = newTemp(Ity_I32);
4129
4130 if (m3 == 0) {
4131 } else {
4132 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004133 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004134 } else {
4135 assign(op1, get_gpr_w1(r1));
4136 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004137 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4138 mktemp(Ity_I32, mkU32((UInt)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 "cij";
4146}
4147
florian55085f82012-11-21 00:36:55 +00004148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004149s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4150{
4151 IRTemp op1 = newTemp(Ity_I64);
4152 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004153 IRTemp cond = newTemp(Ity_I32);
4154
4155 if (m3 == 0) {
4156 } else {
4157 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004158 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004159 } else {
4160 assign(op1, get_gpr_dw0(r1));
4161 op2 = (Long)(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_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004164 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4165 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4166
4167 }
4168 }
4169
4170 return "cgij";
4171}
4172
florian55085f82012-11-21 00:36:55 +00004173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004174s390_irgen_CH(UChar r1, IRTemp op2addr)
4175{
4176 IRTemp op1 = newTemp(Ity_I32);
4177 IRTemp op2 = newTemp(Ity_I32);
4178
4179 assign(op1, get_gpr_w1(r1));
4180 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4181 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4182
4183 return "ch";
4184}
4185
florian55085f82012-11-21 00:36:55 +00004186static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004187s390_irgen_CHY(UChar r1, IRTemp op2addr)
4188{
4189 IRTemp op1 = newTemp(Ity_I32);
4190 IRTemp op2 = newTemp(Ity_I32);
4191
4192 assign(op1, get_gpr_w1(r1));
4193 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4194 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4195
4196 return "chy";
4197}
4198
florian55085f82012-11-21 00:36:55 +00004199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004200s390_irgen_CGH(UChar r1, IRTemp op2addr)
4201{
4202 IRTemp op1 = newTemp(Ity_I64);
4203 IRTemp op2 = newTemp(Ity_I64);
4204
4205 assign(op1, get_gpr_dw0(r1));
4206 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4207 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4208
4209 return "cgh";
4210}
4211
florian55085f82012-11-21 00:36:55 +00004212static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004213s390_irgen_CHI(UChar r1, UShort i2)
4214{
4215 IRTemp op1 = newTemp(Ity_I32);
4216 Int op2;
4217
4218 assign(op1, get_gpr_w1(r1));
4219 op2 = (Int)(Short)i2;
4220 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4221 mkU32((UInt)op2)));
4222
4223 return "chi";
4224}
4225
florian55085f82012-11-21 00:36:55 +00004226static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004227s390_irgen_CGHI(UChar r1, UShort i2)
4228{
4229 IRTemp op1 = newTemp(Ity_I64);
4230 Long op2;
4231
4232 assign(op1, get_gpr_dw0(r1));
4233 op2 = (Long)(Short)i2;
4234 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4235 mkU64((ULong)op2)));
4236
4237 return "cghi";
4238}
4239
florian55085f82012-11-21 00:36:55 +00004240static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004241s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4242{
4243 IRTemp op1 = newTemp(Ity_I16);
4244 Short op2;
4245
4246 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4247 op2 = (Short)i2;
4248 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4249 mkU16((UShort)op2)));
4250
4251 return "chhsi";
4252}
4253
florian55085f82012-11-21 00:36:55 +00004254static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004255s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4256{
4257 IRTemp op1 = newTemp(Ity_I32);
4258 Int op2;
4259
4260 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4261 op2 = (Int)(Short)i2;
4262 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4263 mkU32((UInt)op2)));
4264
4265 return "chsi";
4266}
4267
florian55085f82012-11-21 00:36:55 +00004268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004269s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4270{
4271 IRTemp op1 = newTemp(Ity_I64);
4272 Long op2;
4273
4274 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4275 op2 = (Long)(Short)i2;
4276 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4277 mkU64((ULong)op2)));
4278
4279 return "cghsi";
4280}
4281
florian55085f82012-11-21 00:36:55 +00004282static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004283s390_irgen_CHRL(UChar r1, UInt i2)
4284{
4285 IRTemp op1 = newTemp(Ity_I32);
4286 IRTemp op2 = newTemp(Ity_I32);
4287
4288 assign(op1, get_gpr_w1(r1));
4289 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4290 ((ULong)(Long)(Int)i2 << 1)))));
4291 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4292
4293 return "chrl";
4294}
4295
florian55085f82012-11-21 00:36:55 +00004296static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004297s390_irgen_CGHRL(UChar r1, UInt i2)
4298{
4299 IRTemp op1 = newTemp(Ity_I64);
4300 IRTemp op2 = newTemp(Ity_I64);
4301
4302 assign(op1, get_gpr_dw0(r1));
4303 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4304 ((ULong)(Long)(Int)i2 << 1)))));
4305 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4306
4307 return "cghrl";
4308}
4309
florian55085f82012-11-21 00:36:55 +00004310static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004311s390_irgen_CHHR(UChar r1, UChar r2)
4312{
4313 IRTemp op1 = newTemp(Ity_I32);
4314 IRTemp op2 = newTemp(Ity_I32);
4315
4316 assign(op1, get_gpr_w0(r1));
4317 assign(op2, get_gpr_w0(r2));
4318 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4319
4320 return "chhr";
4321}
4322
florian55085f82012-11-21 00:36:55 +00004323static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004324s390_irgen_CHLR(UChar r1, UChar r2)
4325{
4326 IRTemp op1 = newTemp(Ity_I32);
4327 IRTemp op2 = newTemp(Ity_I32);
4328
4329 assign(op1, get_gpr_w0(r1));
4330 assign(op2, get_gpr_w1(r2));
4331 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4332
4333 return "chlr";
4334}
4335
florian55085f82012-11-21 00:36:55 +00004336static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004337s390_irgen_CHF(UChar r1, IRTemp op2addr)
4338{
4339 IRTemp op1 = newTemp(Ity_I32);
4340 IRTemp op2 = newTemp(Ity_I32);
4341
4342 assign(op1, get_gpr_w0(r1));
4343 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4344 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4345
4346 return "chf";
4347}
4348
florian55085f82012-11-21 00:36:55 +00004349static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004350s390_irgen_CIH(UChar r1, UInt i2)
4351{
4352 IRTemp op1 = newTemp(Ity_I32);
4353 Int op2;
4354
4355 assign(op1, get_gpr_w0(r1));
4356 op2 = (Int)i2;
4357 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4358 mkU32((UInt)op2)));
4359
4360 return "cih";
4361}
4362
florian55085f82012-11-21 00:36:55 +00004363static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004364s390_irgen_CLR(UChar r1, UChar r2)
4365{
4366 IRTemp op1 = newTemp(Ity_I32);
4367 IRTemp op2 = newTemp(Ity_I32);
4368
4369 assign(op1, get_gpr_w1(r1));
4370 assign(op2, get_gpr_w1(r2));
4371 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4372
4373 return "clr";
4374}
4375
florian55085f82012-11-21 00:36:55 +00004376static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004377s390_irgen_CLGR(UChar r1, UChar r2)
4378{
4379 IRTemp op1 = newTemp(Ity_I64);
4380 IRTemp op2 = newTemp(Ity_I64);
4381
4382 assign(op1, get_gpr_dw0(r1));
4383 assign(op2, get_gpr_dw0(r2));
4384 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4385
4386 return "clgr";
4387}
4388
florian55085f82012-11-21 00:36:55 +00004389static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004390s390_irgen_CLGFR(UChar r1, UChar r2)
4391{
4392 IRTemp op1 = newTemp(Ity_I64);
4393 IRTemp op2 = newTemp(Ity_I64);
4394
4395 assign(op1, get_gpr_dw0(r1));
4396 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4397 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4398
4399 return "clgfr";
4400}
4401
florian55085f82012-11-21 00:36:55 +00004402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004403s390_irgen_CL(UChar r1, IRTemp op2addr)
4404{
4405 IRTemp op1 = newTemp(Ity_I32);
4406 IRTemp op2 = newTemp(Ity_I32);
4407
4408 assign(op1, get_gpr_w1(r1));
4409 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4410 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4411
4412 return "cl";
4413}
4414
florian55085f82012-11-21 00:36:55 +00004415static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004416s390_irgen_CLY(UChar r1, IRTemp op2addr)
4417{
4418 IRTemp op1 = newTemp(Ity_I32);
4419 IRTemp op2 = newTemp(Ity_I32);
4420
4421 assign(op1, get_gpr_w1(r1));
4422 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4423 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4424
4425 return "cly";
4426}
4427
florian55085f82012-11-21 00:36:55 +00004428static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004429s390_irgen_CLG(UChar r1, IRTemp op2addr)
4430{
4431 IRTemp op1 = newTemp(Ity_I64);
4432 IRTemp op2 = newTemp(Ity_I64);
4433
4434 assign(op1, get_gpr_dw0(r1));
4435 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4436 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4437
4438 return "clg";
4439}
4440
florian55085f82012-11-21 00:36:55 +00004441static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004442s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4443{
4444 IRTemp op1 = newTemp(Ity_I64);
4445 IRTemp op2 = newTemp(Ity_I64);
4446
4447 assign(op1, get_gpr_dw0(r1));
4448 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4449 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4450
4451 return "clgf";
4452}
4453
florian55085f82012-11-21 00:36:55 +00004454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004455s390_irgen_CLFI(UChar r1, UInt i2)
4456{
4457 IRTemp op1 = newTemp(Ity_I32);
4458 UInt op2;
4459
4460 assign(op1, get_gpr_w1(r1));
4461 op2 = i2;
4462 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4463 mkU32(op2)));
4464
4465 return "clfi";
4466}
4467
florian55085f82012-11-21 00:36:55 +00004468static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004469s390_irgen_CLGFI(UChar r1, UInt i2)
4470{
4471 IRTemp op1 = newTemp(Ity_I64);
4472 ULong op2;
4473
4474 assign(op1, get_gpr_dw0(r1));
4475 op2 = (ULong)i2;
4476 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4477 mkU64(op2)));
4478
4479 return "clgfi";
4480}
4481
florian55085f82012-11-21 00:36:55 +00004482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004483s390_irgen_CLI(UChar i2, IRTemp op1addr)
4484{
4485 IRTemp op1 = newTemp(Ity_I8);
4486 UChar op2;
4487
4488 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4489 op2 = i2;
4490 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4491 mkU8(op2)));
4492
4493 return "cli";
4494}
4495
florian55085f82012-11-21 00:36:55 +00004496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004497s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4498{
4499 IRTemp op1 = newTemp(Ity_I8);
4500 UChar op2;
4501
4502 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4503 op2 = i2;
4504 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4505 mkU8(op2)));
4506
4507 return "cliy";
4508}
4509
florian55085f82012-11-21 00:36:55 +00004510static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004511s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4512{
4513 IRTemp op1 = newTemp(Ity_I32);
4514 UInt op2;
4515
4516 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4517 op2 = (UInt)i2;
4518 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4519 mkU32(op2)));
4520
4521 return "clfhsi";
4522}
4523
florian55085f82012-11-21 00:36:55 +00004524static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004525s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4526{
4527 IRTemp op1 = newTemp(Ity_I64);
4528 ULong op2;
4529
4530 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4531 op2 = (ULong)i2;
4532 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4533 mkU64(op2)));
4534
4535 return "clghsi";
4536}
4537
florian55085f82012-11-21 00:36:55 +00004538static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004539s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4540{
4541 IRTemp op1 = newTemp(Ity_I16);
4542 UShort op2;
4543
4544 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4545 op2 = i2;
4546 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4547 mkU16(op2)));
4548
4549 return "clhhsi";
4550}
4551
florian55085f82012-11-21 00:36:55 +00004552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004553s390_irgen_CLRL(UChar r1, UInt i2)
4554{
4555 IRTemp op1 = newTemp(Ity_I32);
4556 IRTemp op2 = newTemp(Ity_I32);
4557
4558 assign(op1, get_gpr_w1(r1));
4559 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4560 i2 << 1))));
4561 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4562
4563 return "clrl";
4564}
4565
florian55085f82012-11-21 00:36:55 +00004566static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004567s390_irgen_CLGRL(UChar r1, UInt i2)
4568{
4569 IRTemp op1 = newTemp(Ity_I64);
4570 IRTemp op2 = newTemp(Ity_I64);
4571
4572 assign(op1, get_gpr_dw0(r1));
4573 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4574 i2 << 1))));
4575 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4576
4577 return "clgrl";
4578}
4579
florian55085f82012-11-21 00:36:55 +00004580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004581s390_irgen_CLGFRL(UChar r1, UInt i2)
4582{
4583 IRTemp op1 = newTemp(Ity_I64);
4584 IRTemp op2 = newTemp(Ity_I64);
4585
4586 assign(op1, get_gpr_dw0(r1));
4587 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4588 ((ULong)(Long)(Int)i2 << 1)))));
4589 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4590
4591 return "clgfrl";
4592}
4593
florian55085f82012-11-21 00:36:55 +00004594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004595s390_irgen_CLHRL(UChar r1, UInt i2)
4596{
4597 IRTemp op1 = newTemp(Ity_I32);
4598 IRTemp op2 = newTemp(Ity_I32);
4599
4600 assign(op1, get_gpr_w1(r1));
4601 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4602 ((ULong)(Long)(Int)i2 << 1)))));
4603 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4604
4605 return "clhrl";
4606}
4607
florian55085f82012-11-21 00:36:55 +00004608static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004609s390_irgen_CLGHRL(UChar r1, UInt i2)
4610{
4611 IRTemp op1 = newTemp(Ity_I64);
4612 IRTemp op2 = newTemp(Ity_I64);
4613
4614 assign(op1, get_gpr_dw0(r1));
4615 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4616 ((ULong)(Long)(Int)i2 << 1)))));
4617 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4618
4619 return "clghrl";
4620}
4621
florian55085f82012-11-21 00:36:55 +00004622static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004623s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4624{
4625 IRTemp op1 = newTemp(Ity_I32);
4626 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004627 IRTemp cond = newTemp(Ity_I32);
4628
4629 if (m3 == 0) {
4630 } else {
4631 if (m3 == 14) {
4632 always_goto(mkexpr(op4addr));
4633 } else {
4634 assign(op1, get_gpr_w1(r1));
4635 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004636 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4637 op1, op2));
florianf321da72012-07-21 20:32:57 +00004638 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4639 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004640 }
4641 }
4642
4643 return "clrb";
4644}
4645
florian55085f82012-11-21 00:36:55 +00004646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004647s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4648{
4649 IRTemp op1 = newTemp(Ity_I64);
4650 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004651 IRTemp cond = newTemp(Ity_I32);
4652
4653 if (m3 == 0) {
4654 } else {
4655 if (m3 == 14) {
4656 always_goto(mkexpr(op4addr));
4657 } else {
4658 assign(op1, get_gpr_dw0(r1));
4659 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004660 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4661 op1, op2));
florianf321da72012-07-21 20:32:57 +00004662 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4663 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004664 }
4665 }
4666
4667 return "clgrb";
4668}
4669
florian55085f82012-11-21 00:36:55 +00004670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004671s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4672{
4673 IRTemp op1 = newTemp(Ity_I32);
4674 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004675 IRTemp cond = newTemp(Ity_I32);
4676
4677 if (m3 == 0) {
4678 } else {
4679 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004680 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004681 } else {
4682 assign(op1, get_gpr_w1(r1));
4683 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004684 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4685 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004686 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4687 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4688
4689 }
4690 }
4691
4692 return "clrj";
4693}
4694
florian55085f82012-11-21 00:36:55 +00004695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004696s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4697{
4698 IRTemp op1 = newTemp(Ity_I64);
4699 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004700 IRTemp cond = newTemp(Ity_I32);
4701
4702 if (m3 == 0) {
4703 } else {
4704 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004705 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004706 } else {
4707 assign(op1, get_gpr_dw0(r1));
4708 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004709 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4710 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004711 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4712 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4713
4714 }
4715 }
4716
4717 return "clgrj";
4718}
4719
florian55085f82012-11-21 00:36:55 +00004720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004721s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4722{
4723 IRTemp op1 = newTemp(Ity_I32);
4724 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004725 IRTemp cond = newTemp(Ity_I32);
4726
4727 if (m3 == 0) {
4728 } else {
4729 if (m3 == 14) {
4730 always_goto(mkexpr(op4addr));
4731 } else {
4732 assign(op1, get_gpr_w1(r1));
4733 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004734 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4735 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004736 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4737 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004738 }
4739 }
4740
4741 return "clib";
4742}
4743
florian55085f82012-11-21 00:36:55 +00004744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004745s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4746{
4747 IRTemp op1 = newTemp(Ity_I64);
4748 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004749 IRTemp cond = newTemp(Ity_I32);
4750
4751 if (m3 == 0) {
4752 } else {
4753 if (m3 == 14) {
4754 always_goto(mkexpr(op4addr));
4755 } else {
4756 assign(op1, get_gpr_dw0(r1));
4757 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004758 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4759 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004760 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4761 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004762 }
4763 }
4764
4765 return "clgib";
4766}
4767
florian55085f82012-11-21 00:36:55 +00004768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004769s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4770{
4771 IRTemp op1 = newTemp(Ity_I32);
4772 UInt op2;
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_w1(r1));
4781 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004782 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4783 mktemp(Ity_I32, mkU32(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 "clij";
4791}
4792
florian55085f82012-11-21 00:36:55 +00004793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004794s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4795{
4796 IRTemp op1 = newTemp(Ity_I64);
4797 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004798 IRTemp cond = newTemp(Ity_I32);
4799
4800 if (m3 == 0) {
4801 } else {
4802 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004803 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004804 } else {
4805 assign(op1, get_gpr_dw0(r1));
4806 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004807 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4808 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004809 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4810 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4811
4812 }
4813 }
4814
4815 return "clgij";
4816}
4817
florian55085f82012-11-21 00:36:55 +00004818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004819s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4820{
4821 IRTemp op1 = newTemp(Ity_I32);
4822 IRTemp op2 = newTemp(Ity_I32);
4823 IRTemp b0 = newTemp(Ity_I32);
4824 IRTemp b1 = newTemp(Ity_I32);
4825 IRTemp b2 = newTemp(Ity_I32);
4826 IRTemp b3 = newTemp(Ity_I32);
4827 IRTemp c0 = newTemp(Ity_I32);
4828 IRTemp c1 = newTemp(Ity_I32);
4829 IRTemp c2 = newTemp(Ity_I32);
4830 IRTemp c3 = newTemp(Ity_I32);
4831 UChar n;
4832
4833 n = 0;
4834 if ((r3 & 8) != 0) {
4835 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4836 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4837 n = n + 1;
4838 } else {
4839 assign(b0, mkU32(0));
4840 assign(c0, mkU32(0));
4841 }
4842 if ((r3 & 4) != 0) {
4843 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4844 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4845 mkU64(n)))));
4846 n = n + 1;
4847 } else {
4848 assign(b1, mkU32(0));
4849 assign(c1, mkU32(0));
4850 }
4851 if ((r3 & 2) != 0) {
4852 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4853 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4854 mkU64(n)))));
4855 n = n + 1;
4856 } else {
4857 assign(b2, mkU32(0));
4858 assign(c2, mkU32(0));
4859 }
4860 if ((r3 & 1) != 0) {
4861 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4862 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4863 mkU64(n)))));
4864 n = n + 1;
4865 } else {
4866 assign(b3, mkU32(0));
4867 assign(c3, mkU32(0));
4868 }
4869 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4870 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4871 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4872 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4873 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4874 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4875 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4876
4877 return "clm";
4878}
4879
florian55085f82012-11-21 00:36:55 +00004880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004881s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4882{
4883 IRTemp op1 = newTemp(Ity_I32);
4884 IRTemp op2 = newTemp(Ity_I32);
4885 IRTemp b0 = newTemp(Ity_I32);
4886 IRTemp b1 = newTemp(Ity_I32);
4887 IRTemp b2 = newTemp(Ity_I32);
4888 IRTemp b3 = newTemp(Ity_I32);
4889 IRTemp c0 = newTemp(Ity_I32);
4890 IRTemp c1 = newTemp(Ity_I32);
4891 IRTemp c2 = newTemp(Ity_I32);
4892 IRTemp c3 = newTemp(Ity_I32);
4893 UChar n;
4894
4895 n = 0;
4896 if ((r3 & 8) != 0) {
4897 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4898 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4899 n = n + 1;
4900 } else {
4901 assign(b0, mkU32(0));
4902 assign(c0, mkU32(0));
4903 }
4904 if ((r3 & 4) != 0) {
4905 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4906 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4907 mkU64(n)))));
4908 n = n + 1;
4909 } else {
4910 assign(b1, mkU32(0));
4911 assign(c1, mkU32(0));
4912 }
4913 if ((r3 & 2) != 0) {
4914 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4915 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4916 mkU64(n)))));
4917 n = n + 1;
4918 } else {
4919 assign(b2, mkU32(0));
4920 assign(c2, mkU32(0));
4921 }
4922 if ((r3 & 1) != 0) {
4923 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4924 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4925 mkU64(n)))));
4926 n = n + 1;
4927 } else {
4928 assign(b3, mkU32(0));
4929 assign(c3, mkU32(0));
4930 }
4931 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4932 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4933 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4934 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4935 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4936 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4937 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4938
4939 return "clmy";
4940}
4941
florian55085f82012-11-21 00:36:55 +00004942static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004943s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4944{
4945 IRTemp op1 = newTemp(Ity_I32);
4946 IRTemp op2 = newTemp(Ity_I32);
4947 IRTemp b0 = newTemp(Ity_I32);
4948 IRTemp b1 = newTemp(Ity_I32);
4949 IRTemp b2 = newTemp(Ity_I32);
4950 IRTemp b3 = newTemp(Ity_I32);
4951 IRTemp c0 = newTemp(Ity_I32);
4952 IRTemp c1 = newTemp(Ity_I32);
4953 IRTemp c2 = newTemp(Ity_I32);
4954 IRTemp c3 = newTemp(Ity_I32);
4955 UChar n;
4956
4957 n = 0;
4958 if ((r3 & 8) != 0) {
4959 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4960 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4961 n = n + 1;
4962 } else {
4963 assign(b0, mkU32(0));
4964 assign(c0, mkU32(0));
4965 }
4966 if ((r3 & 4) != 0) {
4967 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4968 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4969 mkU64(n)))));
4970 n = n + 1;
4971 } else {
4972 assign(b1, mkU32(0));
4973 assign(c1, mkU32(0));
4974 }
4975 if ((r3 & 2) != 0) {
4976 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4977 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4978 mkU64(n)))));
4979 n = n + 1;
4980 } else {
4981 assign(b2, mkU32(0));
4982 assign(c2, mkU32(0));
4983 }
4984 if ((r3 & 1) != 0) {
4985 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4986 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4987 mkU64(n)))));
4988 n = n + 1;
4989 } else {
4990 assign(b3, mkU32(0));
4991 assign(c3, mkU32(0));
4992 }
4993 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4994 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4995 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4996 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4997 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4998 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4999 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5000
5001 return "clmh";
5002}
5003
florian55085f82012-11-21 00:36:55 +00005004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005005s390_irgen_CLHHR(UChar r1, UChar r2)
5006{
5007 IRTemp op1 = newTemp(Ity_I32);
5008 IRTemp op2 = newTemp(Ity_I32);
5009
5010 assign(op1, get_gpr_w0(r1));
5011 assign(op2, get_gpr_w0(r2));
5012 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5013
5014 return "clhhr";
5015}
5016
florian55085f82012-11-21 00:36:55 +00005017static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005018s390_irgen_CLHLR(UChar r1, UChar r2)
5019{
5020 IRTemp op1 = newTemp(Ity_I32);
5021 IRTemp op2 = newTemp(Ity_I32);
5022
5023 assign(op1, get_gpr_w0(r1));
5024 assign(op2, get_gpr_w1(r2));
5025 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5026
5027 return "clhlr";
5028}
5029
florian55085f82012-11-21 00:36:55 +00005030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005031s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5032{
5033 IRTemp op1 = newTemp(Ity_I32);
5034 IRTemp op2 = newTemp(Ity_I32);
5035
5036 assign(op1, get_gpr_w0(r1));
5037 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5038 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5039
5040 return "clhf";
5041}
5042
florian55085f82012-11-21 00:36:55 +00005043static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005044s390_irgen_CLIH(UChar r1, UInt i2)
5045{
5046 IRTemp op1 = newTemp(Ity_I32);
5047 UInt op2;
5048
5049 assign(op1, get_gpr_w0(r1));
5050 op2 = i2;
5051 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5052 mkU32(op2)));
5053
5054 return "clih";
5055}
5056
florian55085f82012-11-21 00:36:55 +00005057static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005058s390_irgen_CPYA(UChar r1, UChar r2)
5059{
5060 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005061 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005062 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5063
5064 return "cpya";
5065}
5066
florian55085f82012-11-21 00:36:55 +00005067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005068s390_irgen_XR(UChar r1, UChar r2)
5069{
5070 IRTemp op1 = newTemp(Ity_I32);
5071 IRTemp op2 = newTemp(Ity_I32);
5072 IRTemp result = newTemp(Ity_I32);
5073
5074 if (r1 == r2) {
5075 assign(result, mkU32(0));
5076 } else {
5077 assign(op1, get_gpr_w1(r1));
5078 assign(op2, get_gpr_w1(r2));
5079 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5080 }
5081 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5082 put_gpr_w1(r1, mkexpr(result));
5083
5084 return "xr";
5085}
5086
florian55085f82012-11-21 00:36:55 +00005087static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005088s390_irgen_XGR(UChar r1, UChar r2)
5089{
5090 IRTemp op1 = newTemp(Ity_I64);
5091 IRTemp op2 = newTemp(Ity_I64);
5092 IRTemp result = newTemp(Ity_I64);
5093
5094 if (r1 == r2) {
5095 assign(result, mkU64(0));
5096 } else {
5097 assign(op1, get_gpr_dw0(r1));
5098 assign(op2, get_gpr_dw0(r2));
5099 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5100 }
5101 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5102 put_gpr_dw0(r1, mkexpr(result));
5103
5104 return "xgr";
5105}
5106
florian55085f82012-11-21 00:36:55 +00005107static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005108s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5109{
5110 IRTemp op2 = newTemp(Ity_I32);
5111 IRTemp op3 = newTemp(Ity_I32);
5112 IRTemp result = newTemp(Ity_I32);
5113
5114 assign(op2, get_gpr_w1(r2));
5115 assign(op3, get_gpr_w1(r3));
5116 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5117 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5118 put_gpr_w1(r1, mkexpr(result));
5119
5120 return "xrk";
5121}
5122
florian55085f82012-11-21 00:36:55 +00005123static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005124s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5125{
5126 IRTemp op2 = newTemp(Ity_I64);
5127 IRTemp op3 = newTemp(Ity_I64);
5128 IRTemp result = newTemp(Ity_I64);
5129
5130 assign(op2, get_gpr_dw0(r2));
5131 assign(op3, get_gpr_dw0(r3));
5132 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5133 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5134 put_gpr_dw0(r1, mkexpr(result));
5135
5136 return "xgrk";
5137}
5138
florian55085f82012-11-21 00:36:55 +00005139static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005140s390_irgen_X(UChar r1, IRTemp op2addr)
5141{
5142 IRTemp op1 = newTemp(Ity_I32);
5143 IRTemp op2 = newTemp(Ity_I32);
5144 IRTemp result = newTemp(Ity_I32);
5145
5146 assign(op1, get_gpr_w1(r1));
5147 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5148 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5149 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5150 put_gpr_w1(r1, mkexpr(result));
5151
5152 return "x";
5153}
5154
florian55085f82012-11-21 00:36:55 +00005155static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005156s390_irgen_XY(UChar r1, IRTemp op2addr)
5157{
5158 IRTemp op1 = newTemp(Ity_I32);
5159 IRTemp op2 = newTemp(Ity_I32);
5160 IRTemp result = newTemp(Ity_I32);
5161
5162 assign(op1, get_gpr_w1(r1));
5163 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5164 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5165 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5166 put_gpr_w1(r1, mkexpr(result));
5167
5168 return "xy";
5169}
5170
florian55085f82012-11-21 00:36:55 +00005171static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005172s390_irgen_XG(UChar r1, IRTemp op2addr)
5173{
5174 IRTemp op1 = newTemp(Ity_I64);
5175 IRTemp op2 = newTemp(Ity_I64);
5176 IRTemp result = newTemp(Ity_I64);
5177
5178 assign(op1, get_gpr_dw0(r1));
5179 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5180 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5181 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5182 put_gpr_dw0(r1, mkexpr(result));
5183
5184 return "xg";
5185}
5186
florian55085f82012-11-21 00:36:55 +00005187static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005188s390_irgen_XI(UChar i2, IRTemp op1addr)
5189{
5190 IRTemp op1 = newTemp(Ity_I8);
5191 UChar op2;
5192 IRTemp result = newTemp(Ity_I8);
5193
5194 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5195 op2 = i2;
5196 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5197 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5198 store(mkexpr(op1addr), mkexpr(result));
5199
5200 return "xi";
5201}
5202
florian55085f82012-11-21 00:36:55 +00005203static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005204s390_irgen_XIY(UChar i2, IRTemp op1addr)
5205{
5206 IRTemp op1 = newTemp(Ity_I8);
5207 UChar op2;
5208 IRTemp result = newTemp(Ity_I8);
5209
5210 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5211 op2 = i2;
5212 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5213 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5214 store(mkexpr(op1addr), mkexpr(result));
5215
5216 return "xiy";
5217}
5218
florian55085f82012-11-21 00:36:55 +00005219static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005220s390_irgen_XIHF(UChar r1, UInt i2)
5221{
5222 IRTemp op1 = newTemp(Ity_I32);
5223 UInt op2;
5224 IRTemp result = newTemp(Ity_I32);
5225
5226 assign(op1, get_gpr_w0(r1));
5227 op2 = i2;
5228 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5229 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5230 put_gpr_w0(r1, mkexpr(result));
5231
5232 return "xihf";
5233}
5234
florian55085f82012-11-21 00:36:55 +00005235static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005236s390_irgen_XILF(UChar r1, UInt i2)
5237{
5238 IRTemp op1 = newTemp(Ity_I32);
5239 UInt op2;
5240 IRTemp result = newTemp(Ity_I32);
5241
5242 assign(op1, get_gpr_w1(r1));
5243 op2 = i2;
5244 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5245 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5246 put_gpr_w1(r1, mkexpr(result));
5247
5248 return "xilf";
5249}
5250
florian55085f82012-11-21 00:36:55 +00005251static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005252s390_irgen_EAR(UChar r1, UChar r2)
5253{
5254 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005255 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005256 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5257
5258 return "ear";
5259}
5260
florian55085f82012-11-21 00:36:55 +00005261static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005262s390_irgen_IC(UChar r1, IRTemp op2addr)
5263{
5264 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5265
5266 return "ic";
5267}
5268
florian55085f82012-11-21 00:36:55 +00005269static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005270s390_irgen_ICY(UChar r1, IRTemp op2addr)
5271{
5272 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5273
5274 return "icy";
5275}
5276
florian55085f82012-11-21 00:36:55 +00005277static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005278s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5279{
5280 UChar n;
5281 IRTemp result = newTemp(Ity_I32);
5282 UInt mask;
5283
5284 n = 0;
5285 mask = (UInt)r3;
5286 if ((mask & 8) != 0) {
5287 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5288 n = n + 1;
5289 }
5290 if ((mask & 4) != 0) {
5291 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5292
5293 n = n + 1;
5294 }
5295 if ((mask & 2) != 0) {
5296 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5297
5298 n = n + 1;
5299 }
5300 if ((mask & 1) != 0) {
5301 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5302
5303 n = n + 1;
5304 }
5305 assign(result, get_gpr_w1(r1));
5306 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5307 mkU32(mask)));
5308
5309 return "icm";
5310}
5311
florian55085f82012-11-21 00:36:55 +00005312static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005313s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5314{
5315 UChar n;
5316 IRTemp result = newTemp(Ity_I32);
5317 UInt mask;
5318
5319 n = 0;
5320 mask = (UInt)r3;
5321 if ((mask & 8) != 0) {
5322 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5323 n = n + 1;
5324 }
5325 if ((mask & 4) != 0) {
5326 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5327
5328 n = n + 1;
5329 }
5330 if ((mask & 2) != 0) {
5331 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5332
5333 n = n + 1;
5334 }
5335 if ((mask & 1) != 0) {
5336 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5337
5338 n = n + 1;
5339 }
5340 assign(result, get_gpr_w1(r1));
5341 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5342 mkU32(mask)));
5343
5344 return "icmy";
5345}
5346
florian55085f82012-11-21 00:36:55 +00005347static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005348s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5349{
5350 UChar n;
5351 IRTemp result = newTemp(Ity_I32);
5352 UInt mask;
5353
5354 n = 0;
5355 mask = (UInt)r3;
5356 if ((mask & 8) != 0) {
5357 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5358 n = n + 1;
5359 }
5360 if ((mask & 4) != 0) {
5361 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5362
5363 n = n + 1;
5364 }
5365 if ((mask & 2) != 0) {
5366 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5367
5368 n = n + 1;
5369 }
5370 if ((mask & 1) != 0) {
5371 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5372
5373 n = n + 1;
5374 }
5375 assign(result, get_gpr_w0(r1));
5376 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5377 mkU32(mask)));
5378
5379 return "icmh";
5380}
5381
florian55085f82012-11-21 00:36:55 +00005382static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005383s390_irgen_IIHF(UChar r1, UInt i2)
5384{
5385 put_gpr_w0(r1, mkU32(i2));
5386
5387 return "iihf";
5388}
5389
florian55085f82012-11-21 00:36:55 +00005390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005391s390_irgen_IIHH(UChar r1, UShort i2)
5392{
5393 put_gpr_hw0(r1, mkU16(i2));
5394
5395 return "iihh";
5396}
5397
florian55085f82012-11-21 00:36:55 +00005398static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005399s390_irgen_IIHL(UChar r1, UShort i2)
5400{
5401 put_gpr_hw1(r1, mkU16(i2));
5402
5403 return "iihl";
5404}
5405
florian55085f82012-11-21 00:36:55 +00005406static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005407s390_irgen_IILF(UChar r1, UInt i2)
5408{
5409 put_gpr_w1(r1, mkU32(i2));
5410
5411 return "iilf";
5412}
5413
florian55085f82012-11-21 00:36:55 +00005414static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005415s390_irgen_IILH(UChar r1, UShort i2)
5416{
5417 put_gpr_hw2(r1, mkU16(i2));
5418
5419 return "iilh";
5420}
5421
florian55085f82012-11-21 00:36:55 +00005422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005423s390_irgen_IILL(UChar r1, UShort i2)
5424{
5425 put_gpr_hw3(r1, mkU16(i2));
5426
5427 return "iill";
5428}
5429
florian55085f82012-11-21 00:36:55 +00005430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005431s390_irgen_LR(UChar r1, UChar r2)
5432{
5433 put_gpr_w1(r1, get_gpr_w1(r2));
5434
5435 return "lr";
5436}
5437
florian55085f82012-11-21 00:36:55 +00005438static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005439s390_irgen_LGR(UChar r1, UChar r2)
5440{
5441 put_gpr_dw0(r1, get_gpr_dw0(r2));
5442
5443 return "lgr";
5444}
5445
florian55085f82012-11-21 00:36:55 +00005446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005447s390_irgen_LGFR(UChar r1, UChar r2)
5448{
5449 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5450
5451 return "lgfr";
5452}
5453
florian55085f82012-11-21 00:36:55 +00005454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005455s390_irgen_L(UChar r1, IRTemp op2addr)
5456{
5457 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5458
5459 return "l";
5460}
5461
florian55085f82012-11-21 00:36:55 +00005462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005463s390_irgen_LY(UChar r1, IRTemp op2addr)
5464{
5465 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5466
5467 return "ly";
5468}
5469
florian55085f82012-11-21 00:36:55 +00005470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005471s390_irgen_LG(UChar r1, IRTemp op2addr)
5472{
5473 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5474
5475 return "lg";
5476}
5477
florian55085f82012-11-21 00:36:55 +00005478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005479s390_irgen_LGF(UChar r1, IRTemp op2addr)
5480{
5481 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5482
5483 return "lgf";
5484}
5485
florian55085f82012-11-21 00:36:55 +00005486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005487s390_irgen_LGFI(UChar r1, UInt i2)
5488{
5489 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5490
5491 return "lgfi";
5492}
5493
florian55085f82012-11-21 00:36:55 +00005494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005495s390_irgen_LRL(UChar r1, UInt i2)
5496{
5497 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5498 i2 << 1))));
5499
5500 return "lrl";
5501}
5502
florian55085f82012-11-21 00:36:55 +00005503static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005504s390_irgen_LGRL(UChar r1, UInt i2)
5505{
5506 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5507 i2 << 1))));
5508
5509 return "lgrl";
5510}
5511
florian55085f82012-11-21 00:36:55 +00005512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005513s390_irgen_LGFRL(UChar r1, UInt i2)
5514{
5515 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5516 ((ULong)(Long)(Int)i2 << 1)))));
5517
5518 return "lgfrl";
5519}
5520
florian55085f82012-11-21 00:36:55 +00005521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005522s390_irgen_LA(UChar r1, IRTemp op2addr)
5523{
5524 put_gpr_dw0(r1, mkexpr(op2addr));
5525
5526 return "la";
5527}
5528
florian55085f82012-11-21 00:36:55 +00005529static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005530s390_irgen_LAY(UChar r1, IRTemp op2addr)
5531{
5532 put_gpr_dw0(r1, mkexpr(op2addr));
5533
5534 return "lay";
5535}
5536
florian55085f82012-11-21 00:36:55 +00005537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005538s390_irgen_LAE(UChar r1, IRTemp op2addr)
5539{
5540 put_gpr_dw0(r1, mkexpr(op2addr));
5541
5542 return "lae";
5543}
5544
florian55085f82012-11-21 00:36:55 +00005545static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005546s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5547{
5548 put_gpr_dw0(r1, mkexpr(op2addr));
5549
5550 return "laey";
5551}
5552
florian55085f82012-11-21 00:36:55 +00005553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005554s390_irgen_LARL(UChar r1, UInt i2)
5555{
5556 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5557
5558 return "larl";
5559}
5560
floriana265ee72012-12-02 20:58:17 +00005561/* The IR representation of LAA and friends is an approximation of what
5562 happens natively. Essentially a loop containing a compare-and-swap is
5563 constructed which will iterate until the CAS succeeds. As a consequence,
5564 instrumenters may see more memory accesses than happen natively. See also
5565 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005566static void
5567s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005568{
floriana265ee72012-12-02 20:58:17 +00005569 IRCAS *cas;
5570 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005571 IRTemp op2 = newTemp(Ity_I32);
5572 IRTemp op3 = newTemp(Ity_I32);
5573 IRTemp result = newTemp(Ity_I32);
5574
5575 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5576 assign(op3, get_gpr_w1(r3));
5577 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005578
5579 /* Place the addition of second operand and third operand at the
5580 second-operand location everytime */
5581 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5582 Iend_BE, mkexpr(op2addr),
5583 NULL, mkexpr(op2), /* expected value */
5584 NULL, mkexpr(result) /* new value */);
5585 stmt(IRStmt_CAS(cas));
5586
florianffc94012012-12-02 21:31:15 +00005587 /* Set CC according to 32-bit addition */
5588 if (is_signed) {
5589 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5590 } else {
5591 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5592 }
floriana265ee72012-12-02 20:58:17 +00005593
5594 /* If old_mem contains the expected value, then the CAS succeeded.
5595 Otherwise, it did not */
5596 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5597 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005598}
5599
5600static void
5601s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5602{
5603 IRCAS *cas;
5604 IRTemp old_mem = newTemp(Ity_I64);
5605 IRTemp op2 = newTemp(Ity_I64);
5606 IRTemp op3 = newTemp(Ity_I64);
5607 IRTemp result = newTemp(Ity_I64);
5608
5609 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5610 assign(op3, get_gpr_dw0(r3));
5611 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5612
5613 /* Place the addition of second operand and third operand at the
5614 second-operand location everytime */
5615 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5616 Iend_BE, mkexpr(op2addr),
5617 NULL, mkexpr(op2), /* expected value */
5618 NULL, mkexpr(result) /* new value */);
5619 stmt(IRStmt_CAS(cas));
5620
5621 /* Set CC according to 64-bit addition */
5622 if (is_signed) {
5623 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5624 } else {
5625 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5626 }
5627
5628 /* If old_mem contains the expected value, then the CAS succeeded.
5629 Otherwise, it did not */
5630 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5631 put_gpr_dw0(r1, mkexpr(old_mem));
5632}
5633
5634static void
5635s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5636{
5637 IRCAS *cas;
5638 IRTemp old_mem = newTemp(Ity_I32);
5639 IRTemp op2 = newTemp(Ity_I32);
5640 IRTemp op3 = newTemp(Ity_I32);
5641 IRTemp result = newTemp(Ity_I32);
5642
5643 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5644 assign(op3, get_gpr_w1(r3));
5645 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5646
5647 /* Place the addition of second operand and third operand at the
5648 second-operand location everytime */
5649 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5650 Iend_BE, mkexpr(op2addr),
5651 NULL, mkexpr(op2), /* expected value */
5652 NULL, mkexpr(result) /* new value */);
5653 stmt(IRStmt_CAS(cas));
5654
5655 /* Set CC according to bitwise operation */
5656 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5657
5658 /* If old_mem contains the expected value, then the CAS succeeded.
5659 Otherwise, it did not */
5660 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5661 put_gpr_w1(r1, mkexpr(old_mem));
5662}
5663
5664static void
5665s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5666{
5667 IRCAS *cas;
5668 IRTemp old_mem = newTemp(Ity_I64);
5669 IRTemp op2 = newTemp(Ity_I64);
5670 IRTemp op3 = newTemp(Ity_I64);
5671 IRTemp result = newTemp(Ity_I64);
5672
5673 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5674 assign(op3, get_gpr_dw0(r3));
5675 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5676
5677 /* Place the addition of second operand and third operand at the
5678 second-operand location everytime */
5679 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5680 Iend_BE, mkexpr(op2addr),
5681 NULL, mkexpr(op2), /* expected value */
5682 NULL, mkexpr(result) /* new value */);
5683 stmt(IRStmt_CAS(cas));
5684
5685 /* Set CC according to bitwise operation */
5686 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5687
5688 /* If old_mem contains the expected value, then the CAS succeeded.
5689 Otherwise, it did not */
5690 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5691 put_gpr_dw0(r1, mkexpr(old_mem));
5692}
5693
5694static const HChar *
5695s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5696{
5697 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005698
5699 return "laa";
5700}
5701
florian55085f82012-11-21 00:36:55 +00005702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005703s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5704{
florianffc94012012-12-02 21:31:15 +00005705 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005706
5707 return "laag";
5708}
5709
florian55085f82012-11-21 00:36:55 +00005710static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005711s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5712{
florianffc94012012-12-02 21:31:15 +00005713 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005714
5715 return "laal";
5716}
5717
florian55085f82012-11-21 00:36:55 +00005718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005719s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5720{
florianffc94012012-12-02 21:31:15 +00005721 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005722
5723 return "laalg";
5724}
5725
florian55085f82012-11-21 00:36:55 +00005726static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005727s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5728{
florianffc94012012-12-02 21:31:15 +00005729 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005730
5731 return "lan";
5732}
5733
florian55085f82012-11-21 00:36:55 +00005734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005735s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5736{
florianffc94012012-12-02 21:31:15 +00005737 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005738
5739 return "lang";
5740}
5741
florian55085f82012-11-21 00:36:55 +00005742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005743s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5744{
florianffc94012012-12-02 21:31:15 +00005745 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005746
5747 return "lax";
5748}
5749
florian55085f82012-11-21 00:36:55 +00005750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005751s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5752{
florianffc94012012-12-02 21:31:15 +00005753 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005754
5755 return "laxg";
5756}
5757
florian55085f82012-11-21 00:36:55 +00005758static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005759s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5760{
florianffc94012012-12-02 21:31:15 +00005761 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005762
5763 return "lao";
5764}
5765
florian55085f82012-11-21 00:36:55 +00005766static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005767s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5768{
florianffc94012012-12-02 21:31:15 +00005769 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005770
5771 return "laog";
5772}
5773
florian55085f82012-11-21 00:36:55 +00005774static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005775s390_irgen_LTR(UChar r1, UChar r2)
5776{
5777 IRTemp op2 = newTemp(Ity_I32);
5778
5779 assign(op2, get_gpr_w1(r2));
5780 put_gpr_w1(r1, mkexpr(op2));
5781 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5782
5783 return "ltr";
5784}
5785
florian55085f82012-11-21 00:36:55 +00005786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005787s390_irgen_LTGR(UChar r1, UChar r2)
5788{
5789 IRTemp op2 = newTemp(Ity_I64);
5790
5791 assign(op2, get_gpr_dw0(r2));
5792 put_gpr_dw0(r1, mkexpr(op2));
5793 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5794
5795 return "ltgr";
5796}
5797
florian55085f82012-11-21 00:36:55 +00005798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005799s390_irgen_LTGFR(UChar r1, UChar r2)
5800{
5801 IRTemp op2 = newTemp(Ity_I64);
5802
5803 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5804 put_gpr_dw0(r1, mkexpr(op2));
5805 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5806
5807 return "ltgfr";
5808}
5809
florian55085f82012-11-21 00:36:55 +00005810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005811s390_irgen_LT(UChar r1, IRTemp op2addr)
5812{
5813 IRTemp op2 = newTemp(Ity_I32);
5814
5815 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5816 put_gpr_w1(r1, mkexpr(op2));
5817 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5818
5819 return "lt";
5820}
5821
florian55085f82012-11-21 00:36:55 +00005822static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005823s390_irgen_LTG(UChar r1, IRTemp op2addr)
5824{
5825 IRTemp op2 = newTemp(Ity_I64);
5826
5827 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5828 put_gpr_dw0(r1, mkexpr(op2));
5829 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5830
5831 return "ltg";
5832}
5833
florian55085f82012-11-21 00:36:55 +00005834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005835s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5836{
5837 IRTemp op2 = newTemp(Ity_I64);
5838
5839 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5840 put_gpr_dw0(r1, mkexpr(op2));
5841 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5842
5843 return "ltgf";
5844}
5845
florian55085f82012-11-21 00:36:55 +00005846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005847s390_irgen_LBR(UChar r1, UChar r2)
5848{
5849 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5850
5851 return "lbr";
5852}
5853
florian55085f82012-11-21 00:36:55 +00005854static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005855s390_irgen_LGBR(UChar r1, UChar r2)
5856{
5857 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5858
5859 return "lgbr";
5860}
5861
florian55085f82012-11-21 00:36:55 +00005862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005863s390_irgen_LB(UChar r1, IRTemp op2addr)
5864{
5865 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5866
5867 return "lb";
5868}
5869
florian55085f82012-11-21 00:36:55 +00005870static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005871s390_irgen_LGB(UChar r1, IRTemp op2addr)
5872{
5873 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5874
5875 return "lgb";
5876}
5877
florian55085f82012-11-21 00:36:55 +00005878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005879s390_irgen_LBH(UChar r1, IRTemp op2addr)
5880{
5881 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5882
5883 return "lbh";
5884}
5885
florian55085f82012-11-21 00:36:55 +00005886static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005887s390_irgen_LCR(UChar r1, UChar r2)
5888{
5889 Int op1;
5890 IRTemp op2 = newTemp(Ity_I32);
5891 IRTemp result = newTemp(Ity_I32);
5892
5893 op1 = 0;
5894 assign(op2, get_gpr_w1(r2));
5895 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5896 put_gpr_w1(r1, mkexpr(result));
5897 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5898 op1)), op2);
5899
5900 return "lcr";
5901}
5902
florian55085f82012-11-21 00:36:55 +00005903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005904s390_irgen_LCGR(UChar r1, UChar r2)
5905{
5906 Long op1;
5907 IRTemp op2 = newTemp(Ity_I64);
5908 IRTemp result = newTemp(Ity_I64);
5909
5910 op1 = 0ULL;
5911 assign(op2, get_gpr_dw0(r2));
5912 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5913 put_gpr_dw0(r1, mkexpr(result));
5914 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5915 op1)), op2);
5916
5917 return "lcgr";
5918}
5919
florian55085f82012-11-21 00:36:55 +00005920static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005921s390_irgen_LCGFR(UChar r1, UChar r2)
5922{
5923 Long op1;
5924 IRTemp op2 = newTemp(Ity_I64);
5925 IRTemp result = newTemp(Ity_I64);
5926
5927 op1 = 0ULL;
5928 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5929 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5930 put_gpr_dw0(r1, mkexpr(result));
5931 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5932 op1)), op2);
5933
5934 return "lcgfr";
5935}
5936
florian55085f82012-11-21 00:36:55 +00005937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005938s390_irgen_LHR(UChar r1, UChar r2)
5939{
5940 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5941
5942 return "lhr";
5943}
5944
florian55085f82012-11-21 00:36:55 +00005945static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005946s390_irgen_LGHR(UChar r1, UChar r2)
5947{
5948 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5949
5950 return "lghr";
5951}
5952
florian55085f82012-11-21 00:36:55 +00005953static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005954s390_irgen_LH(UChar r1, IRTemp op2addr)
5955{
5956 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5957
5958 return "lh";
5959}
5960
florian55085f82012-11-21 00:36:55 +00005961static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005962s390_irgen_LHY(UChar r1, IRTemp op2addr)
5963{
5964 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5965
5966 return "lhy";
5967}
5968
florian55085f82012-11-21 00:36:55 +00005969static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005970s390_irgen_LGH(UChar r1, IRTemp op2addr)
5971{
5972 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5973
5974 return "lgh";
5975}
5976
florian55085f82012-11-21 00:36:55 +00005977static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005978s390_irgen_LHI(UChar r1, UShort i2)
5979{
5980 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5981
5982 return "lhi";
5983}
5984
florian55085f82012-11-21 00:36:55 +00005985static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005986s390_irgen_LGHI(UChar r1, UShort i2)
5987{
5988 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5989
5990 return "lghi";
5991}
5992
florian55085f82012-11-21 00:36:55 +00005993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005994s390_irgen_LHRL(UChar r1, UInt i2)
5995{
5996 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5997 ((ULong)(Long)(Int)i2 << 1)))));
5998
5999 return "lhrl";
6000}
6001
florian55085f82012-11-21 00:36:55 +00006002static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006003s390_irgen_LGHRL(UChar r1, UInt i2)
6004{
6005 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6006 ((ULong)(Long)(Int)i2 << 1)))));
6007
6008 return "lghrl";
6009}
6010
florian55085f82012-11-21 00:36:55 +00006011static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006012s390_irgen_LHH(UChar r1, IRTemp op2addr)
6013{
6014 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6015
6016 return "lhh";
6017}
6018
florian55085f82012-11-21 00:36:55 +00006019static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006020s390_irgen_LFH(UChar r1, IRTemp op2addr)
6021{
6022 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6023
6024 return "lfh";
6025}
6026
florian55085f82012-11-21 00:36:55 +00006027static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006028s390_irgen_LLGFR(UChar r1, UChar r2)
6029{
6030 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6031
6032 return "llgfr";
6033}
6034
florian55085f82012-11-21 00:36:55 +00006035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006036s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6037{
6038 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6039
6040 return "llgf";
6041}
6042
florian55085f82012-11-21 00:36:55 +00006043static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006044s390_irgen_LLGFRL(UChar r1, UInt i2)
6045{
6046 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6047 ((ULong)(Long)(Int)i2 << 1)))));
6048
6049 return "llgfrl";
6050}
6051
florian55085f82012-11-21 00:36:55 +00006052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006053s390_irgen_LLCR(UChar r1, UChar r2)
6054{
6055 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6056
6057 return "llcr";
6058}
6059
florian55085f82012-11-21 00:36:55 +00006060static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006061s390_irgen_LLGCR(UChar r1, UChar r2)
6062{
6063 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6064
6065 return "llgcr";
6066}
6067
florian55085f82012-11-21 00:36:55 +00006068static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006069s390_irgen_LLC(UChar r1, IRTemp op2addr)
6070{
6071 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6072
6073 return "llc";
6074}
6075
florian55085f82012-11-21 00:36:55 +00006076static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006077s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6078{
6079 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6080
6081 return "llgc";
6082}
6083
florian55085f82012-11-21 00:36:55 +00006084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006085s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6086{
6087 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6088
6089 return "llch";
6090}
6091
florian55085f82012-11-21 00:36:55 +00006092static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006093s390_irgen_LLHR(UChar r1, UChar r2)
6094{
6095 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6096
6097 return "llhr";
6098}
6099
florian55085f82012-11-21 00:36:55 +00006100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006101s390_irgen_LLGHR(UChar r1, UChar r2)
6102{
6103 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6104
6105 return "llghr";
6106}
6107
florian55085f82012-11-21 00:36:55 +00006108static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006109s390_irgen_LLH(UChar r1, IRTemp op2addr)
6110{
6111 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6112
6113 return "llh";
6114}
6115
florian55085f82012-11-21 00:36:55 +00006116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006117s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6118{
6119 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6120
6121 return "llgh";
6122}
6123
florian55085f82012-11-21 00:36:55 +00006124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006125s390_irgen_LLHRL(UChar r1, UInt i2)
6126{
6127 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6128 ((ULong)(Long)(Int)i2 << 1)))));
6129
6130 return "llhrl";
6131}
6132
florian55085f82012-11-21 00:36:55 +00006133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006134s390_irgen_LLGHRL(UChar r1, UInt i2)
6135{
6136 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6137 ((ULong)(Long)(Int)i2 << 1)))));
6138
6139 return "llghrl";
6140}
6141
florian55085f82012-11-21 00:36:55 +00006142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006143s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6144{
6145 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6146
6147 return "llhh";
6148}
6149
florian55085f82012-11-21 00:36:55 +00006150static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006151s390_irgen_LLIHF(UChar r1, UInt i2)
6152{
6153 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6154
6155 return "llihf";
6156}
6157
florian55085f82012-11-21 00:36:55 +00006158static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006159s390_irgen_LLIHH(UChar r1, UShort i2)
6160{
6161 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6162
6163 return "llihh";
6164}
6165
florian55085f82012-11-21 00:36:55 +00006166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006167s390_irgen_LLIHL(UChar r1, UShort i2)
6168{
6169 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6170
6171 return "llihl";
6172}
6173
florian55085f82012-11-21 00:36:55 +00006174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006175s390_irgen_LLILF(UChar r1, UInt i2)
6176{
6177 put_gpr_dw0(r1, mkU64(i2));
6178
6179 return "llilf";
6180}
6181
florian55085f82012-11-21 00:36:55 +00006182static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006183s390_irgen_LLILH(UChar r1, UShort i2)
6184{
6185 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6186
6187 return "llilh";
6188}
6189
florian55085f82012-11-21 00:36:55 +00006190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006191s390_irgen_LLILL(UChar r1, UShort i2)
6192{
6193 put_gpr_dw0(r1, mkU64(i2));
6194
6195 return "llill";
6196}
6197
florian55085f82012-11-21 00:36:55 +00006198static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006199s390_irgen_LLGTR(UChar r1, UChar r2)
6200{
6201 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6202 mkU32(2147483647))));
6203
6204 return "llgtr";
6205}
6206
florian55085f82012-11-21 00:36:55 +00006207static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006208s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6209{
6210 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6211 mkexpr(op2addr)), mkU32(2147483647))));
6212
6213 return "llgt";
6214}
6215
florian55085f82012-11-21 00:36:55 +00006216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006217s390_irgen_LNR(UChar r1, UChar r2)
6218{
6219 IRTemp op2 = newTemp(Ity_I32);
6220 IRTemp result = newTemp(Ity_I32);
6221
6222 assign(op2, get_gpr_w1(r2));
6223 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6224 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6225 put_gpr_w1(r1, mkexpr(result));
6226 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6227
6228 return "lnr";
6229}
6230
florian55085f82012-11-21 00:36:55 +00006231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006232s390_irgen_LNGR(UChar r1, UChar r2)
6233{
6234 IRTemp op2 = newTemp(Ity_I64);
6235 IRTemp result = newTemp(Ity_I64);
6236
6237 assign(op2, get_gpr_dw0(r2));
6238 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6239 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6240 put_gpr_dw0(r1, mkexpr(result));
6241 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6242
6243 return "lngr";
6244}
6245
florian55085f82012-11-21 00:36:55 +00006246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006247s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6248{
6249 IRTemp op2 = newTemp(Ity_I64);
6250 IRTemp result = newTemp(Ity_I64);
6251
6252 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6253 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6254 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6255 put_gpr_dw0(r1, mkexpr(result));
6256 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6257
6258 return "lngfr";
6259}
6260
florian55085f82012-11-21 00:36:55 +00006261static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006262s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6263{
florian6820ba52012-07-26 02:01:50 +00006264 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006265 put_gpr_w1(r1, get_gpr_w1(r2));
6266
6267 return "locr";
6268}
6269
florian55085f82012-11-21 00:36:55 +00006270static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006271s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6272{
florian6820ba52012-07-26 02:01:50 +00006273 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006274 put_gpr_dw0(r1, get_gpr_dw0(r2));
6275
6276 return "locgr";
6277}
6278
florian55085f82012-11-21 00:36:55 +00006279static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006280s390_irgen_LOC(UChar r1, IRTemp op2addr)
6281{
6282 /* condition is checked in format handler */
6283 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6284
6285 return "loc";
6286}
6287
florian55085f82012-11-21 00:36:55 +00006288static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006289s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6290{
6291 /* condition is checked in format handler */
6292 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6293
6294 return "locg";
6295}
6296
florian55085f82012-11-21 00:36:55 +00006297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006298s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6299{
6300 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6301 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6302 ));
6303
6304 return "lpq";
6305}
6306
florian55085f82012-11-21 00:36:55 +00006307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006308s390_irgen_LPR(UChar r1, UChar r2)
6309{
6310 IRTemp op2 = newTemp(Ity_I32);
6311 IRTemp result = newTemp(Ity_I32);
6312
6313 assign(op2, get_gpr_w1(r2));
6314 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6315 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6316 put_gpr_w1(r1, mkexpr(result));
6317 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6318
6319 return "lpr";
6320}
6321
florian55085f82012-11-21 00:36:55 +00006322static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006323s390_irgen_LPGR(UChar r1, UChar r2)
6324{
6325 IRTemp op2 = newTemp(Ity_I64);
6326 IRTemp result = newTemp(Ity_I64);
6327
6328 assign(op2, get_gpr_dw0(r2));
6329 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6330 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6331 put_gpr_dw0(r1, mkexpr(result));
6332 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6333
6334 return "lpgr";
6335}
6336
florian55085f82012-11-21 00:36:55 +00006337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006338s390_irgen_LPGFR(UChar r1, UChar r2)
6339{
6340 IRTemp op2 = newTemp(Ity_I64);
6341 IRTemp result = newTemp(Ity_I64);
6342
6343 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6344 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6345 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6346 put_gpr_dw0(r1, mkexpr(result));
6347 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6348
6349 return "lpgfr";
6350}
6351
florian55085f82012-11-21 00:36:55 +00006352static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006353s390_irgen_LRVR(UChar r1, UChar r2)
6354{
6355 IRTemp b0 = newTemp(Ity_I8);
6356 IRTemp b1 = newTemp(Ity_I8);
6357 IRTemp b2 = newTemp(Ity_I8);
6358 IRTemp b3 = newTemp(Ity_I8);
6359
6360 assign(b3, get_gpr_b7(r2));
6361 assign(b2, get_gpr_b6(r2));
6362 assign(b1, get_gpr_b5(r2));
6363 assign(b0, get_gpr_b4(r2));
6364 put_gpr_b4(r1, mkexpr(b3));
6365 put_gpr_b5(r1, mkexpr(b2));
6366 put_gpr_b6(r1, mkexpr(b1));
6367 put_gpr_b7(r1, mkexpr(b0));
6368
6369 return "lrvr";
6370}
6371
florian55085f82012-11-21 00:36:55 +00006372static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006373s390_irgen_LRVGR(UChar r1, UChar r2)
6374{
6375 IRTemp b0 = newTemp(Ity_I8);
6376 IRTemp b1 = newTemp(Ity_I8);
6377 IRTemp b2 = newTemp(Ity_I8);
6378 IRTemp b3 = newTemp(Ity_I8);
6379 IRTemp b4 = newTemp(Ity_I8);
6380 IRTemp b5 = newTemp(Ity_I8);
6381 IRTemp b6 = newTemp(Ity_I8);
6382 IRTemp b7 = newTemp(Ity_I8);
6383
6384 assign(b7, get_gpr_b7(r2));
6385 assign(b6, get_gpr_b6(r2));
6386 assign(b5, get_gpr_b5(r2));
6387 assign(b4, get_gpr_b4(r2));
6388 assign(b3, get_gpr_b3(r2));
6389 assign(b2, get_gpr_b2(r2));
6390 assign(b1, get_gpr_b1(r2));
6391 assign(b0, get_gpr_b0(r2));
6392 put_gpr_b0(r1, mkexpr(b7));
6393 put_gpr_b1(r1, mkexpr(b6));
6394 put_gpr_b2(r1, mkexpr(b5));
6395 put_gpr_b3(r1, mkexpr(b4));
6396 put_gpr_b4(r1, mkexpr(b3));
6397 put_gpr_b5(r1, mkexpr(b2));
6398 put_gpr_b6(r1, mkexpr(b1));
6399 put_gpr_b7(r1, mkexpr(b0));
6400
6401 return "lrvgr";
6402}
6403
florian55085f82012-11-21 00:36:55 +00006404static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006405s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6406{
6407 IRTemp op2 = newTemp(Ity_I16);
6408
6409 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6410 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6411 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6412
6413 return "lrvh";
6414}
6415
florian55085f82012-11-21 00:36:55 +00006416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006417s390_irgen_LRV(UChar r1, IRTemp op2addr)
6418{
6419 IRTemp op2 = newTemp(Ity_I32);
6420
6421 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6422 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6423 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6424 mkU8(8)), mkU32(255))));
6425 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6426 mkU8(16)), mkU32(255))));
6427 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6428 mkU8(24)), mkU32(255))));
6429
6430 return "lrv";
6431}
6432
florian55085f82012-11-21 00:36:55 +00006433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006434s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6435{
6436 IRTemp op2 = newTemp(Ity_I64);
6437
6438 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6439 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6440 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6441 mkU8(8)), mkU64(255))));
6442 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6443 mkU8(16)), mkU64(255))));
6444 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6445 mkU8(24)), mkU64(255))));
6446 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6447 mkU8(32)), mkU64(255))));
6448 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6449 mkU8(40)), mkU64(255))));
6450 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6451 mkU8(48)), mkU64(255))));
6452 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6453 mkU8(56)), mkU64(255))));
6454
6455 return "lrvg";
6456}
6457
florian55085f82012-11-21 00:36:55 +00006458static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006459s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6460{
6461 store(mkexpr(op1addr), mkU16(i2));
6462
6463 return "mvhhi";
6464}
6465
florian55085f82012-11-21 00:36:55 +00006466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006467s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6468{
6469 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6470
6471 return "mvhi";
6472}
6473
florian55085f82012-11-21 00:36:55 +00006474static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006475s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6476{
6477 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6478
6479 return "mvghi";
6480}
6481
florian55085f82012-11-21 00:36:55 +00006482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006483s390_irgen_MVI(UChar i2, IRTemp op1addr)
6484{
6485 store(mkexpr(op1addr), mkU8(i2));
6486
6487 return "mvi";
6488}
6489
florian55085f82012-11-21 00:36:55 +00006490static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006491s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6492{
6493 store(mkexpr(op1addr), mkU8(i2));
6494
6495 return "mviy";
6496}
6497
florian55085f82012-11-21 00:36:55 +00006498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006499s390_irgen_MR(UChar r1, UChar r2)
6500{
6501 IRTemp op1 = newTemp(Ity_I32);
6502 IRTemp op2 = newTemp(Ity_I32);
6503 IRTemp result = newTemp(Ity_I64);
6504
6505 assign(op1, get_gpr_w1(r1 + 1));
6506 assign(op2, get_gpr_w1(r2));
6507 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6508 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6509 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6510
6511 return "mr";
6512}
6513
florian55085f82012-11-21 00:36:55 +00006514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006515s390_irgen_M(UChar r1, IRTemp op2addr)
6516{
6517 IRTemp op1 = newTemp(Ity_I32);
6518 IRTemp op2 = newTemp(Ity_I32);
6519 IRTemp result = newTemp(Ity_I64);
6520
6521 assign(op1, get_gpr_w1(r1 + 1));
6522 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6523 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6524 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6525 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6526
6527 return "m";
6528}
6529
florian55085f82012-11-21 00:36:55 +00006530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006531s390_irgen_MFY(UChar r1, IRTemp op2addr)
6532{
6533 IRTemp op1 = newTemp(Ity_I32);
6534 IRTemp op2 = newTemp(Ity_I32);
6535 IRTemp result = newTemp(Ity_I64);
6536
6537 assign(op1, get_gpr_w1(r1 + 1));
6538 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6539 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6540 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6541 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6542
6543 return "mfy";
6544}
6545
florian55085f82012-11-21 00:36:55 +00006546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006547s390_irgen_MH(UChar r1, IRTemp op2addr)
6548{
6549 IRTemp op1 = newTemp(Ity_I32);
6550 IRTemp op2 = newTemp(Ity_I16);
6551 IRTemp result = newTemp(Ity_I64);
6552
6553 assign(op1, get_gpr_w1(r1));
6554 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6555 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6556 ));
6557 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6558
6559 return "mh";
6560}
6561
florian55085f82012-11-21 00:36:55 +00006562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006563s390_irgen_MHY(UChar r1, IRTemp op2addr)
6564{
6565 IRTemp op1 = newTemp(Ity_I32);
6566 IRTemp op2 = newTemp(Ity_I16);
6567 IRTemp result = newTemp(Ity_I64);
6568
6569 assign(op1, get_gpr_w1(r1));
6570 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6571 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6572 ));
6573 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6574
6575 return "mhy";
6576}
6577
florian55085f82012-11-21 00:36:55 +00006578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006579s390_irgen_MHI(UChar r1, UShort i2)
6580{
6581 IRTemp op1 = newTemp(Ity_I32);
6582 Short op2;
6583 IRTemp result = newTemp(Ity_I64);
6584
6585 assign(op1, get_gpr_w1(r1));
6586 op2 = (Short)i2;
6587 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6588 mkU16((UShort)op2))));
6589 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6590
6591 return "mhi";
6592}
6593
florian55085f82012-11-21 00:36:55 +00006594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006595s390_irgen_MGHI(UChar r1, UShort i2)
6596{
6597 IRTemp op1 = newTemp(Ity_I64);
6598 Short op2;
6599 IRTemp result = newTemp(Ity_I128);
6600
6601 assign(op1, get_gpr_dw0(r1));
6602 op2 = (Short)i2;
6603 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6604 mkU16((UShort)op2))));
6605 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6606
6607 return "mghi";
6608}
6609
florian55085f82012-11-21 00:36:55 +00006610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006611s390_irgen_MLR(UChar r1, UChar r2)
6612{
6613 IRTemp op1 = newTemp(Ity_I32);
6614 IRTemp op2 = newTemp(Ity_I32);
6615 IRTemp result = newTemp(Ity_I64);
6616
6617 assign(op1, get_gpr_w1(r1 + 1));
6618 assign(op2, get_gpr_w1(r2));
6619 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6620 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6621 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6622
6623 return "mlr";
6624}
6625
florian55085f82012-11-21 00:36:55 +00006626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006627s390_irgen_MLGR(UChar r1, UChar r2)
6628{
6629 IRTemp op1 = newTemp(Ity_I64);
6630 IRTemp op2 = newTemp(Ity_I64);
6631 IRTemp result = newTemp(Ity_I128);
6632
6633 assign(op1, get_gpr_dw0(r1 + 1));
6634 assign(op2, get_gpr_dw0(r2));
6635 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6636 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6637 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6638
6639 return "mlgr";
6640}
6641
florian55085f82012-11-21 00:36:55 +00006642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006643s390_irgen_ML(UChar r1, IRTemp op2addr)
6644{
6645 IRTemp op1 = newTemp(Ity_I32);
6646 IRTemp op2 = newTemp(Ity_I32);
6647 IRTemp result = newTemp(Ity_I64);
6648
6649 assign(op1, get_gpr_w1(r1 + 1));
6650 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6651 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6652 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6653 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6654
6655 return "ml";
6656}
6657
florian55085f82012-11-21 00:36:55 +00006658static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006659s390_irgen_MLG(UChar r1, IRTemp op2addr)
6660{
6661 IRTemp op1 = newTemp(Ity_I64);
6662 IRTemp op2 = newTemp(Ity_I64);
6663 IRTemp result = newTemp(Ity_I128);
6664
6665 assign(op1, get_gpr_dw0(r1 + 1));
6666 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6667 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6668 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6669 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6670
6671 return "mlg";
6672}
6673
florian55085f82012-11-21 00:36:55 +00006674static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006675s390_irgen_MSR(UChar r1, UChar r2)
6676{
6677 IRTemp op1 = newTemp(Ity_I32);
6678 IRTemp op2 = newTemp(Ity_I32);
6679 IRTemp result = newTemp(Ity_I64);
6680
6681 assign(op1, get_gpr_w1(r1));
6682 assign(op2, get_gpr_w1(r2));
6683 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6684 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6685
6686 return "msr";
6687}
6688
florian55085f82012-11-21 00:36:55 +00006689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006690s390_irgen_MSGR(UChar r1, UChar r2)
6691{
6692 IRTemp op1 = newTemp(Ity_I64);
6693 IRTemp op2 = newTemp(Ity_I64);
6694 IRTemp result = newTemp(Ity_I128);
6695
6696 assign(op1, get_gpr_dw0(r1));
6697 assign(op2, get_gpr_dw0(r2));
6698 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6699 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6700
6701 return "msgr";
6702}
6703
florian55085f82012-11-21 00:36:55 +00006704static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006705s390_irgen_MSGFR(UChar r1, UChar r2)
6706{
6707 IRTemp op1 = newTemp(Ity_I64);
6708 IRTemp op2 = newTemp(Ity_I32);
6709 IRTemp result = newTemp(Ity_I128);
6710
6711 assign(op1, get_gpr_dw0(r1));
6712 assign(op2, get_gpr_w1(r2));
6713 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6714 ));
6715 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6716
6717 return "msgfr";
6718}
6719
florian55085f82012-11-21 00:36:55 +00006720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006721s390_irgen_MS(UChar r1, IRTemp op2addr)
6722{
6723 IRTemp op1 = newTemp(Ity_I32);
6724 IRTemp op2 = newTemp(Ity_I32);
6725 IRTemp result = newTemp(Ity_I64);
6726
6727 assign(op1, get_gpr_w1(r1));
6728 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6729 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6730 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6731
6732 return "ms";
6733}
6734
florian55085f82012-11-21 00:36:55 +00006735static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006736s390_irgen_MSY(UChar r1, IRTemp op2addr)
6737{
6738 IRTemp op1 = newTemp(Ity_I32);
6739 IRTemp op2 = newTemp(Ity_I32);
6740 IRTemp result = newTemp(Ity_I64);
6741
6742 assign(op1, get_gpr_w1(r1));
6743 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6744 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6745 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6746
6747 return "msy";
6748}
6749
florian55085f82012-11-21 00:36:55 +00006750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006751s390_irgen_MSG(UChar r1, IRTemp op2addr)
6752{
6753 IRTemp op1 = newTemp(Ity_I64);
6754 IRTemp op2 = newTemp(Ity_I64);
6755 IRTemp result = newTemp(Ity_I128);
6756
6757 assign(op1, get_gpr_dw0(r1));
6758 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6759 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6760 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6761
6762 return "msg";
6763}
6764
florian55085f82012-11-21 00:36:55 +00006765static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006766s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6767{
6768 IRTemp op1 = newTemp(Ity_I64);
6769 IRTemp op2 = newTemp(Ity_I32);
6770 IRTemp result = newTemp(Ity_I128);
6771
6772 assign(op1, get_gpr_dw0(r1));
6773 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6774 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6775 ));
6776 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6777
6778 return "msgf";
6779}
6780
florian55085f82012-11-21 00:36:55 +00006781static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006782s390_irgen_MSFI(UChar r1, UInt i2)
6783{
6784 IRTemp op1 = newTemp(Ity_I32);
6785 Int op2;
6786 IRTemp result = newTemp(Ity_I64);
6787
6788 assign(op1, get_gpr_w1(r1));
6789 op2 = (Int)i2;
6790 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6791 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6792
6793 return "msfi";
6794}
6795
florian55085f82012-11-21 00:36:55 +00006796static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006797s390_irgen_MSGFI(UChar r1, UInt i2)
6798{
6799 IRTemp op1 = newTemp(Ity_I64);
6800 Int op2;
6801 IRTemp result = newTemp(Ity_I128);
6802
6803 assign(op1, get_gpr_dw0(r1));
6804 op2 = (Int)i2;
6805 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6806 op2))));
6807 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6808
6809 return "msgfi";
6810}
6811
florian55085f82012-11-21 00:36:55 +00006812static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006813s390_irgen_OR(UChar r1, UChar r2)
6814{
6815 IRTemp op1 = newTemp(Ity_I32);
6816 IRTemp op2 = newTemp(Ity_I32);
6817 IRTemp result = newTemp(Ity_I32);
6818
6819 assign(op1, get_gpr_w1(r1));
6820 assign(op2, get_gpr_w1(r2));
6821 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6822 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6823 put_gpr_w1(r1, mkexpr(result));
6824
6825 return "or";
6826}
6827
florian55085f82012-11-21 00:36:55 +00006828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006829s390_irgen_OGR(UChar r1, UChar r2)
6830{
6831 IRTemp op1 = newTemp(Ity_I64);
6832 IRTemp op2 = newTemp(Ity_I64);
6833 IRTemp result = newTemp(Ity_I64);
6834
6835 assign(op1, get_gpr_dw0(r1));
6836 assign(op2, get_gpr_dw0(r2));
6837 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6838 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6839 put_gpr_dw0(r1, mkexpr(result));
6840
6841 return "ogr";
6842}
6843
florian55085f82012-11-21 00:36:55 +00006844static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006845s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6846{
6847 IRTemp op2 = newTemp(Ity_I32);
6848 IRTemp op3 = newTemp(Ity_I32);
6849 IRTemp result = newTemp(Ity_I32);
6850
6851 assign(op2, get_gpr_w1(r2));
6852 assign(op3, get_gpr_w1(r3));
6853 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6854 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6855 put_gpr_w1(r1, mkexpr(result));
6856
6857 return "ork";
6858}
6859
florian55085f82012-11-21 00:36:55 +00006860static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006861s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6862{
6863 IRTemp op2 = newTemp(Ity_I64);
6864 IRTemp op3 = newTemp(Ity_I64);
6865 IRTemp result = newTemp(Ity_I64);
6866
6867 assign(op2, get_gpr_dw0(r2));
6868 assign(op3, get_gpr_dw0(r3));
6869 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6870 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6871 put_gpr_dw0(r1, mkexpr(result));
6872
6873 return "ogrk";
6874}
6875
florian55085f82012-11-21 00:36:55 +00006876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006877s390_irgen_O(UChar r1, IRTemp op2addr)
6878{
6879 IRTemp op1 = newTemp(Ity_I32);
6880 IRTemp op2 = newTemp(Ity_I32);
6881 IRTemp result = newTemp(Ity_I32);
6882
6883 assign(op1, get_gpr_w1(r1));
6884 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6885 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6886 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6887 put_gpr_w1(r1, mkexpr(result));
6888
6889 return "o";
6890}
6891
florian55085f82012-11-21 00:36:55 +00006892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006893s390_irgen_OY(UChar r1, IRTemp op2addr)
6894{
6895 IRTemp op1 = newTemp(Ity_I32);
6896 IRTemp op2 = newTemp(Ity_I32);
6897 IRTemp result = newTemp(Ity_I32);
6898
6899 assign(op1, get_gpr_w1(r1));
6900 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6901 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6902 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6903 put_gpr_w1(r1, mkexpr(result));
6904
6905 return "oy";
6906}
6907
florian55085f82012-11-21 00:36:55 +00006908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006909s390_irgen_OG(UChar r1, IRTemp op2addr)
6910{
6911 IRTemp op1 = newTemp(Ity_I64);
6912 IRTemp op2 = newTemp(Ity_I64);
6913 IRTemp result = newTemp(Ity_I64);
6914
6915 assign(op1, get_gpr_dw0(r1));
6916 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6917 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6918 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6919 put_gpr_dw0(r1, mkexpr(result));
6920
6921 return "og";
6922}
6923
florian55085f82012-11-21 00:36:55 +00006924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006925s390_irgen_OI(UChar i2, IRTemp op1addr)
6926{
6927 IRTemp op1 = newTemp(Ity_I8);
6928 UChar op2;
6929 IRTemp result = newTemp(Ity_I8);
6930
6931 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6932 op2 = i2;
6933 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6934 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6935 store(mkexpr(op1addr), mkexpr(result));
6936
6937 return "oi";
6938}
6939
florian55085f82012-11-21 00:36:55 +00006940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006941s390_irgen_OIY(UChar i2, IRTemp op1addr)
6942{
6943 IRTemp op1 = newTemp(Ity_I8);
6944 UChar op2;
6945 IRTemp result = newTemp(Ity_I8);
6946
6947 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6948 op2 = i2;
6949 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6950 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6951 store(mkexpr(op1addr), mkexpr(result));
6952
6953 return "oiy";
6954}
6955
florian55085f82012-11-21 00:36:55 +00006956static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006957s390_irgen_OIHF(UChar r1, UInt i2)
6958{
6959 IRTemp op1 = newTemp(Ity_I32);
6960 UInt op2;
6961 IRTemp result = newTemp(Ity_I32);
6962
6963 assign(op1, get_gpr_w0(r1));
6964 op2 = i2;
6965 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6966 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6967 put_gpr_w0(r1, mkexpr(result));
6968
6969 return "oihf";
6970}
6971
florian55085f82012-11-21 00:36:55 +00006972static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006973s390_irgen_OIHH(UChar r1, UShort i2)
6974{
6975 IRTemp op1 = newTemp(Ity_I16);
6976 UShort op2;
6977 IRTemp result = newTemp(Ity_I16);
6978
6979 assign(op1, get_gpr_hw0(r1));
6980 op2 = i2;
6981 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6982 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6983 put_gpr_hw0(r1, mkexpr(result));
6984
6985 return "oihh";
6986}
6987
florian55085f82012-11-21 00:36:55 +00006988static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006989s390_irgen_OIHL(UChar r1, UShort i2)
6990{
6991 IRTemp op1 = newTemp(Ity_I16);
6992 UShort op2;
6993 IRTemp result = newTemp(Ity_I16);
6994
6995 assign(op1, get_gpr_hw1(r1));
6996 op2 = i2;
6997 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6998 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6999 put_gpr_hw1(r1, mkexpr(result));
7000
7001 return "oihl";
7002}
7003
florian55085f82012-11-21 00:36:55 +00007004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007005s390_irgen_OILF(UChar r1, UInt i2)
7006{
7007 IRTemp op1 = newTemp(Ity_I32);
7008 UInt op2;
7009 IRTemp result = newTemp(Ity_I32);
7010
7011 assign(op1, get_gpr_w1(r1));
7012 op2 = i2;
7013 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7014 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7015 put_gpr_w1(r1, mkexpr(result));
7016
7017 return "oilf";
7018}
7019
florian55085f82012-11-21 00:36:55 +00007020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007021s390_irgen_OILH(UChar r1, UShort i2)
7022{
7023 IRTemp op1 = newTemp(Ity_I16);
7024 UShort op2;
7025 IRTemp result = newTemp(Ity_I16);
7026
7027 assign(op1, get_gpr_hw2(r1));
7028 op2 = i2;
7029 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7030 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7031 put_gpr_hw2(r1, mkexpr(result));
7032
7033 return "oilh";
7034}
7035
florian55085f82012-11-21 00:36:55 +00007036static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007037s390_irgen_OILL(UChar r1, UShort i2)
7038{
7039 IRTemp op1 = newTemp(Ity_I16);
7040 UShort op2;
7041 IRTemp result = newTemp(Ity_I16);
7042
7043 assign(op1, get_gpr_hw3(r1));
7044 op2 = i2;
7045 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7046 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7047 put_gpr_hw3(r1, mkexpr(result));
7048
7049 return "oill";
7050}
7051
florian55085f82012-11-21 00:36:55 +00007052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007053s390_irgen_PFD(void)
7054{
7055
7056 return "pfd";
7057}
7058
florian55085f82012-11-21 00:36:55 +00007059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007060s390_irgen_PFDRL(void)
7061{
7062
7063 return "pfdrl";
7064}
7065
florian55085f82012-11-21 00:36:55 +00007066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007067s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7068{
7069 IRTemp amount = newTemp(Ity_I64);
7070 IRTemp op = newTemp(Ity_I32);
7071
7072 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7073 assign(op, get_gpr_w1(r3));
7074 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7075 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7076 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7077
7078 return "rll";
7079}
7080
florian55085f82012-11-21 00:36:55 +00007081static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007082s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7083{
7084 IRTemp amount = newTemp(Ity_I64);
7085 IRTemp op = newTemp(Ity_I64);
7086
7087 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7088 assign(op, get_gpr_dw0(r3));
7089 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7090 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7091 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7092
7093 return "rllg";
7094}
7095
florian55085f82012-11-21 00:36:55 +00007096static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007097s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7098{
7099 UChar from;
7100 UChar to;
7101 UChar rot;
7102 UChar t_bit;
7103 ULong mask;
7104 ULong maskc;
7105 IRTemp result = newTemp(Ity_I64);
7106 IRTemp op2 = newTemp(Ity_I64);
7107
7108 from = i3 & 63;
7109 to = i4 & 63;
7110 rot = i5 & 63;
7111 t_bit = i3 & 128;
7112 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7113 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7114 mkU8(64 - rot))));
7115 if (from <= to) {
7116 mask = ~0ULL;
7117 mask = (mask >> from) & (mask << (63 - to));
7118 maskc = ~mask;
7119 } else {
7120 maskc = ~0ULL;
7121 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7122 mask = ~maskc;
7123 }
7124 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7125 ), mkU64(mask)));
7126 if (t_bit == 0) {
7127 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7128 mkU64(maskc)), mkexpr(result)));
7129 }
7130 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7131
7132 return "rnsbg";
7133}
7134
florian55085f82012-11-21 00:36:55 +00007135static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007136s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7137{
7138 UChar from;
7139 UChar to;
7140 UChar rot;
7141 UChar t_bit;
7142 ULong mask;
7143 ULong maskc;
7144 IRTemp result = newTemp(Ity_I64);
7145 IRTemp op2 = newTemp(Ity_I64);
7146
7147 from = i3 & 63;
7148 to = i4 & 63;
7149 rot = i5 & 63;
7150 t_bit = i3 & 128;
7151 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7152 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7153 mkU8(64 - rot))));
7154 if (from <= to) {
7155 mask = ~0ULL;
7156 mask = (mask >> from) & (mask << (63 - to));
7157 maskc = ~mask;
7158 } else {
7159 maskc = ~0ULL;
7160 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7161 mask = ~maskc;
7162 }
7163 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7164 ), mkU64(mask)));
7165 if (t_bit == 0) {
7166 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7167 mkU64(maskc)), mkexpr(result)));
7168 }
7169 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7170
7171 return "rxsbg";
7172}
7173
florian55085f82012-11-21 00:36:55 +00007174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007175s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7176{
7177 UChar from;
7178 UChar to;
7179 UChar rot;
7180 UChar t_bit;
7181 ULong mask;
7182 ULong maskc;
7183 IRTemp result = newTemp(Ity_I64);
7184 IRTemp op2 = newTemp(Ity_I64);
7185
7186 from = i3 & 63;
7187 to = i4 & 63;
7188 rot = i5 & 63;
7189 t_bit = i3 & 128;
7190 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7191 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7192 mkU8(64 - rot))));
7193 if (from <= to) {
7194 mask = ~0ULL;
7195 mask = (mask >> from) & (mask << (63 - to));
7196 maskc = ~mask;
7197 } else {
7198 maskc = ~0ULL;
7199 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7200 mask = ~maskc;
7201 }
7202 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7203 ), mkU64(mask)));
7204 if (t_bit == 0) {
7205 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7206 mkU64(maskc)), mkexpr(result)));
7207 }
7208 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7209
7210 return "rosbg";
7211}
7212
florian55085f82012-11-21 00:36:55 +00007213static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007214s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7215{
7216 UChar from;
7217 UChar to;
7218 UChar rot;
7219 UChar z_bit;
7220 ULong mask;
7221 ULong maskc;
7222 IRTemp op2 = newTemp(Ity_I64);
7223 IRTemp result = newTemp(Ity_I64);
7224
7225 from = i3 & 63;
7226 to = i4 & 63;
7227 rot = i5 & 63;
7228 z_bit = i4 & 128;
7229 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7230 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7231 mkU8(64 - rot))));
7232 if (from <= to) {
7233 mask = ~0ULL;
7234 mask = (mask >> from) & (mask << (63 - to));
7235 maskc = ~mask;
7236 } else {
7237 maskc = ~0ULL;
7238 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7239 mask = ~maskc;
7240 }
7241 if (z_bit == 0) {
7242 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7243 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7244 } else {
7245 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7246 }
7247 assign(result, get_gpr_dw0(r1));
7248 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7249
7250 return "risbg";
7251}
7252
florian55085f82012-11-21 00:36:55 +00007253static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007254s390_irgen_SAR(UChar r1, UChar r2)
7255{
7256 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007257 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007258 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7259
7260 return "sar";
7261}
7262
florian55085f82012-11-21 00:36:55 +00007263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007264s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7265{
7266 IRTemp p1 = newTemp(Ity_I64);
7267 IRTemp p2 = newTemp(Ity_I64);
7268 IRTemp op = newTemp(Ity_I64);
7269 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007270 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007271 IRTemp shift_amount = newTemp(Ity_I64);
7272
7273 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7274 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7275 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7276 ));
7277 sign_mask = 1ULL << 63;
7278 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7279 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007280 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7281 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007282 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7283 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7284 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7285
7286 return "slda";
7287}
7288
florian55085f82012-11-21 00:36:55 +00007289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007290s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7291{
7292 IRTemp p1 = newTemp(Ity_I64);
7293 IRTemp p2 = newTemp(Ity_I64);
7294 IRTemp result = newTemp(Ity_I64);
7295
7296 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7297 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7298 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7299 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7300 mkexpr(op2addr), mkU64(63)))));
7301 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7302 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7303
7304 return "sldl";
7305}
7306
florian55085f82012-11-21 00:36:55 +00007307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007308s390_irgen_SLA(UChar r1, IRTemp op2addr)
7309{
7310 IRTemp uop = newTemp(Ity_I32);
7311 IRTemp result = newTemp(Ity_I32);
7312 UInt sign_mask;
7313 IRTemp shift_amount = newTemp(Ity_I64);
7314 IRTemp op = newTemp(Ity_I32);
7315
7316 assign(op, get_gpr_w1(r1));
7317 assign(uop, get_gpr_w1(r1));
7318 sign_mask = 2147483648U;
7319 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7320 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7321 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7322 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7323 put_gpr_w1(r1, mkexpr(result));
7324 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7325
7326 return "sla";
7327}
7328
florian55085f82012-11-21 00:36:55 +00007329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007330s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7331{
7332 IRTemp uop = newTemp(Ity_I32);
7333 IRTemp result = newTemp(Ity_I32);
7334 UInt sign_mask;
7335 IRTemp shift_amount = newTemp(Ity_I64);
7336 IRTemp op = newTemp(Ity_I32);
7337
7338 assign(op, get_gpr_w1(r3));
7339 assign(uop, get_gpr_w1(r3));
7340 sign_mask = 2147483648U;
7341 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7342 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7343 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7344 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7345 put_gpr_w1(r1, mkexpr(result));
7346 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7347
7348 return "slak";
7349}
7350
florian55085f82012-11-21 00:36:55 +00007351static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007352s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7353{
7354 IRTemp uop = newTemp(Ity_I64);
7355 IRTemp result = newTemp(Ity_I64);
7356 ULong sign_mask;
7357 IRTemp shift_amount = newTemp(Ity_I64);
7358 IRTemp op = newTemp(Ity_I64);
7359
7360 assign(op, get_gpr_dw0(r3));
7361 assign(uop, get_gpr_dw0(r3));
7362 sign_mask = 9223372036854775808ULL;
7363 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7364 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7365 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7366 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7367 put_gpr_dw0(r1, mkexpr(result));
7368 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7369
7370 return "slag";
7371}
7372
florian55085f82012-11-21 00:36:55 +00007373static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007374s390_irgen_SLL(UChar r1, IRTemp op2addr)
7375{
7376 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7377 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7378
7379 return "sll";
7380}
7381
florian55085f82012-11-21 00:36:55 +00007382static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007383s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7384{
7385 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7386 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7387
7388 return "sllk";
7389}
7390
florian55085f82012-11-21 00:36:55 +00007391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007392s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7393{
7394 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7395 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7396
7397 return "sllg";
7398}
7399
florian55085f82012-11-21 00:36:55 +00007400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007401s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7402{
7403 IRTemp p1 = newTemp(Ity_I64);
7404 IRTemp p2 = newTemp(Ity_I64);
7405 IRTemp result = newTemp(Ity_I64);
7406
7407 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7408 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7409 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7410 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7411 mkexpr(op2addr), mkU64(63)))));
7412 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7413 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7414 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7415
7416 return "srda";
7417}
7418
florian55085f82012-11-21 00:36:55 +00007419static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007420s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7421{
7422 IRTemp p1 = newTemp(Ity_I64);
7423 IRTemp p2 = newTemp(Ity_I64);
7424 IRTemp result = newTemp(Ity_I64);
7425
7426 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7427 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7428 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7429 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7430 mkexpr(op2addr), mkU64(63)))));
7431 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7432 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7433
7434 return "srdl";
7435}
7436
florian55085f82012-11-21 00:36:55 +00007437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007438s390_irgen_SRA(UChar r1, IRTemp op2addr)
7439{
7440 IRTemp result = newTemp(Ity_I32);
7441 IRTemp op = newTemp(Ity_I32);
7442
7443 assign(op, get_gpr_w1(r1));
7444 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7445 mkexpr(op2addr), mkU64(63)))));
7446 put_gpr_w1(r1, mkexpr(result));
7447 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7448
7449 return "sra";
7450}
7451
florian55085f82012-11-21 00:36:55 +00007452static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007453s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7454{
7455 IRTemp result = newTemp(Ity_I32);
7456 IRTemp op = newTemp(Ity_I32);
7457
7458 assign(op, get_gpr_w1(r3));
7459 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7460 mkexpr(op2addr), mkU64(63)))));
7461 put_gpr_w1(r1, mkexpr(result));
7462 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7463
7464 return "srak";
7465}
7466
florian55085f82012-11-21 00:36:55 +00007467static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007468s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7469{
7470 IRTemp result = newTemp(Ity_I64);
7471 IRTemp op = newTemp(Ity_I64);
7472
7473 assign(op, get_gpr_dw0(r3));
7474 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7475 mkexpr(op2addr), mkU64(63)))));
7476 put_gpr_dw0(r1, mkexpr(result));
7477 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7478
7479 return "srag";
7480}
7481
florian55085f82012-11-21 00:36:55 +00007482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007483s390_irgen_SRL(UChar r1, IRTemp op2addr)
7484{
7485 IRTemp op = newTemp(Ity_I32);
7486
7487 assign(op, get_gpr_w1(r1));
7488 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7489 mkexpr(op2addr), mkU64(63)))));
7490
7491 return "srl";
7492}
7493
florian55085f82012-11-21 00:36:55 +00007494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007495s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7496{
7497 IRTemp op = newTemp(Ity_I32);
7498
7499 assign(op, get_gpr_w1(r3));
7500 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7501 mkexpr(op2addr), mkU64(63)))));
7502
7503 return "srlk";
7504}
7505
florian55085f82012-11-21 00:36:55 +00007506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007507s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7508{
7509 IRTemp op = newTemp(Ity_I64);
7510
7511 assign(op, get_gpr_dw0(r3));
7512 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7513 mkexpr(op2addr), mkU64(63)))));
7514
7515 return "srlg";
7516}
7517
florian55085f82012-11-21 00:36:55 +00007518static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007519s390_irgen_ST(UChar r1, IRTemp op2addr)
7520{
7521 store(mkexpr(op2addr), get_gpr_w1(r1));
7522
7523 return "st";
7524}
7525
florian55085f82012-11-21 00:36:55 +00007526static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007527s390_irgen_STY(UChar r1, IRTemp op2addr)
7528{
7529 store(mkexpr(op2addr), get_gpr_w1(r1));
7530
7531 return "sty";
7532}
7533
florian55085f82012-11-21 00:36:55 +00007534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007535s390_irgen_STG(UChar r1, IRTemp op2addr)
7536{
7537 store(mkexpr(op2addr), get_gpr_dw0(r1));
7538
7539 return "stg";
7540}
7541
florian55085f82012-11-21 00:36:55 +00007542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007543s390_irgen_STRL(UChar r1, UInt i2)
7544{
7545 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7546 get_gpr_w1(r1));
7547
7548 return "strl";
7549}
7550
florian55085f82012-11-21 00:36:55 +00007551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007552s390_irgen_STGRL(UChar r1, UInt i2)
7553{
7554 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7555 get_gpr_dw0(r1));
7556
7557 return "stgrl";
7558}
7559
florian55085f82012-11-21 00:36:55 +00007560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007561s390_irgen_STC(UChar r1, IRTemp op2addr)
7562{
7563 store(mkexpr(op2addr), get_gpr_b7(r1));
7564
7565 return "stc";
7566}
7567
florian55085f82012-11-21 00:36:55 +00007568static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007569s390_irgen_STCY(UChar r1, IRTemp op2addr)
7570{
7571 store(mkexpr(op2addr), get_gpr_b7(r1));
7572
7573 return "stcy";
7574}
7575
florian55085f82012-11-21 00:36:55 +00007576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007577s390_irgen_STCH(UChar r1, IRTemp op2addr)
7578{
7579 store(mkexpr(op2addr), get_gpr_b3(r1));
7580
7581 return "stch";
7582}
7583
florian55085f82012-11-21 00:36:55 +00007584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007585s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7586{
7587 UChar mask;
7588 UChar n;
7589
7590 mask = (UChar)r3;
7591 n = 0;
7592 if ((mask & 8) != 0) {
7593 store(mkexpr(op2addr), get_gpr_b4(r1));
7594 n = n + 1;
7595 }
7596 if ((mask & 4) != 0) {
7597 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7598 n = n + 1;
7599 }
7600 if ((mask & 2) != 0) {
7601 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7602 n = n + 1;
7603 }
7604 if ((mask & 1) != 0) {
7605 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7606 }
7607
7608 return "stcm";
7609}
7610
florian55085f82012-11-21 00:36:55 +00007611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007612s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7613{
7614 UChar mask;
7615 UChar n;
7616
7617 mask = (UChar)r3;
7618 n = 0;
7619 if ((mask & 8) != 0) {
7620 store(mkexpr(op2addr), get_gpr_b4(r1));
7621 n = n + 1;
7622 }
7623 if ((mask & 4) != 0) {
7624 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7625 n = n + 1;
7626 }
7627 if ((mask & 2) != 0) {
7628 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7629 n = n + 1;
7630 }
7631 if ((mask & 1) != 0) {
7632 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7633 }
7634
7635 return "stcmy";
7636}
7637
florian55085f82012-11-21 00:36:55 +00007638static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007639s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7640{
7641 UChar mask;
7642 UChar n;
7643
7644 mask = (UChar)r3;
7645 n = 0;
7646 if ((mask & 8) != 0) {
7647 store(mkexpr(op2addr), get_gpr_b0(r1));
7648 n = n + 1;
7649 }
7650 if ((mask & 4) != 0) {
7651 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7652 n = n + 1;
7653 }
7654 if ((mask & 2) != 0) {
7655 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7656 n = n + 1;
7657 }
7658 if ((mask & 1) != 0) {
7659 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7660 }
7661
7662 return "stcmh";
7663}
7664
florian55085f82012-11-21 00:36:55 +00007665static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007666s390_irgen_STH(UChar r1, IRTemp op2addr)
7667{
7668 store(mkexpr(op2addr), get_gpr_hw3(r1));
7669
7670 return "sth";
7671}
7672
florian55085f82012-11-21 00:36:55 +00007673static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007674s390_irgen_STHY(UChar r1, IRTemp op2addr)
7675{
7676 store(mkexpr(op2addr), get_gpr_hw3(r1));
7677
7678 return "sthy";
7679}
7680
florian55085f82012-11-21 00:36:55 +00007681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007682s390_irgen_STHRL(UChar r1, UInt i2)
7683{
7684 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7685 get_gpr_hw3(r1));
7686
7687 return "sthrl";
7688}
7689
florian55085f82012-11-21 00:36:55 +00007690static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007691s390_irgen_STHH(UChar r1, IRTemp op2addr)
7692{
7693 store(mkexpr(op2addr), get_gpr_hw1(r1));
7694
7695 return "sthh";
7696}
7697
florian55085f82012-11-21 00:36:55 +00007698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007699s390_irgen_STFH(UChar r1, IRTemp op2addr)
7700{
7701 store(mkexpr(op2addr), get_gpr_w0(r1));
7702
7703 return "stfh";
7704}
7705
florian55085f82012-11-21 00:36:55 +00007706static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007707s390_irgen_STOC(UChar r1, IRTemp op2addr)
7708{
7709 /* condition is checked in format handler */
7710 store(mkexpr(op2addr), get_gpr_w1(r1));
7711
7712 return "stoc";
7713}
7714
florian55085f82012-11-21 00:36:55 +00007715static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007716s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7717{
7718 /* condition is checked in format handler */
7719 store(mkexpr(op2addr), get_gpr_dw0(r1));
7720
7721 return "stocg";
7722}
7723
florian55085f82012-11-21 00:36:55 +00007724static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007725s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7726{
7727 store(mkexpr(op2addr), get_gpr_dw0(r1));
7728 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7729
7730 return "stpq";
7731}
7732
florian55085f82012-11-21 00:36:55 +00007733static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007734s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7735{
7736 store(mkexpr(op2addr), get_gpr_b7(r1));
7737 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7738
7739 return "strvh";
7740}
7741
florian55085f82012-11-21 00:36:55 +00007742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007743s390_irgen_STRV(UChar r1, IRTemp op2addr)
7744{
7745 store(mkexpr(op2addr), get_gpr_b7(r1));
7746 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7747 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7748 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7749
7750 return "strv";
7751}
7752
florian55085f82012-11-21 00:36:55 +00007753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007754s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7755{
7756 store(mkexpr(op2addr), get_gpr_b7(r1));
7757 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7758 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7759 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7760 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7761 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7762 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7763 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7764
7765 return "strvg";
7766}
7767
florian55085f82012-11-21 00:36:55 +00007768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007769s390_irgen_SR(UChar r1, UChar r2)
7770{
7771 IRTemp op1 = newTemp(Ity_I32);
7772 IRTemp op2 = newTemp(Ity_I32);
7773 IRTemp result = newTemp(Ity_I32);
7774
7775 assign(op1, get_gpr_w1(r1));
7776 assign(op2, get_gpr_w1(r2));
7777 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7778 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7779 put_gpr_w1(r1, mkexpr(result));
7780
7781 return "sr";
7782}
7783
florian55085f82012-11-21 00:36:55 +00007784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007785s390_irgen_SGR(UChar r1, UChar r2)
7786{
7787 IRTemp op1 = newTemp(Ity_I64);
7788 IRTemp op2 = newTemp(Ity_I64);
7789 IRTemp result = newTemp(Ity_I64);
7790
7791 assign(op1, get_gpr_dw0(r1));
7792 assign(op2, get_gpr_dw0(r2));
7793 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7794 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7795 put_gpr_dw0(r1, mkexpr(result));
7796
7797 return "sgr";
7798}
7799
florian55085f82012-11-21 00:36:55 +00007800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007801s390_irgen_SGFR(UChar r1, UChar r2)
7802{
7803 IRTemp op1 = newTemp(Ity_I64);
7804 IRTemp op2 = newTemp(Ity_I64);
7805 IRTemp result = newTemp(Ity_I64);
7806
7807 assign(op1, get_gpr_dw0(r1));
7808 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7809 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7810 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7811 put_gpr_dw0(r1, mkexpr(result));
7812
7813 return "sgfr";
7814}
7815
florian55085f82012-11-21 00:36:55 +00007816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007817s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7818{
7819 IRTemp op2 = newTemp(Ity_I32);
7820 IRTemp op3 = newTemp(Ity_I32);
7821 IRTemp result = newTemp(Ity_I32);
7822
7823 assign(op2, get_gpr_w1(r2));
7824 assign(op3, get_gpr_w1(r3));
7825 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7826 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7827 put_gpr_w1(r1, mkexpr(result));
7828
7829 return "srk";
7830}
7831
florian55085f82012-11-21 00:36:55 +00007832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007833s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7834{
7835 IRTemp op2 = newTemp(Ity_I64);
7836 IRTemp op3 = newTemp(Ity_I64);
7837 IRTemp result = newTemp(Ity_I64);
7838
7839 assign(op2, get_gpr_dw0(r2));
7840 assign(op3, get_gpr_dw0(r3));
7841 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7842 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7843 put_gpr_dw0(r1, mkexpr(result));
7844
7845 return "sgrk";
7846}
7847
florian55085f82012-11-21 00:36:55 +00007848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007849s390_irgen_S(UChar r1, IRTemp op2addr)
7850{
7851 IRTemp op1 = newTemp(Ity_I32);
7852 IRTemp op2 = newTemp(Ity_I32);
7853 IRTemp result = newTemp(Ity_I32);
7854
7855 assign(op1, get_gpr_w1(r1));
7856 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7857 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7858 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7859 put_gpr_w1(r1, mkexpr(result));
7860
7861 return "s";
7862}
7863
florian55085f82012-11-21 00:36:55 +00007864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007865s390_irgen_SY(UChar r1, IRTemp op2addr)
7866{
7867 IRTemp op1 = newTemp(Ity_I32);
7868 IRTemp op2 = newTemp(Ity_I32);
7869 IRTemp result = newTemp(Ity_I32);
7870
7871 assign(op1, get_gpr_w1(r1));
7872 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7873 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7874 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7875 put_gpr_w1(r1, mkexpr(result));
7876
7877 return "sy";
7878}
7879
florian55085f82012-11-21 00:36:55 +00007880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007881s390_irgen_SG(UChar r1, IRTemp op2addr)
7882{
7883 IRTemp op1 = newTemp(Ity_I64);
7884 IRTemp op2 = newTemp(Ity_I64);
7885 IRTemp result = newTemp(Ity_I64);
7886
7887 assign(op1, get_gpr_dw0(r1));
7888 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7889 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7890 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7891 put_gpr_dw0(r1, mkexpr(result));
7892
7893 return "sg";
7894}
7895
florian55085f82012-11-21 00:36:55 +00007896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007897s390_irgen_SGF(UChar r1, IRTemp op2addr)
7898{
7899 IRTemp op1 = newTemp(Ity_I64);
7900 IRTemp op2 = newTemp(Ity_I64);
7901 IRTemp result = newTemp(Ity_I64);
7902
7903 assign(op1, get_gpr_dw0(r1));
7904 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7905 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7906 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7907 put_gpr_dw0(r1, mkexpr(result));
7908
7909 return "sgf";
7910}
7911
florian55085f82012-11-21 00:36:55 +00007912static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007913s390_irgen_SH(UChar r1, IRTemp op2addr)
7914{
7915 IRTemp op1 = newTemp(Ity_I32);
7916 IRTemp op2 = newTemp(Ity_I32);
7917 IRTemp result = newTemp(Ity_I32);
7918
7919 assign(op1, get_gpr_w1(r1));
7920 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7921 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7922 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7923 put_gpr_w1(r1, mkexpr(result));
7924
7925 return "sh";
7926}
7927
florian55085f82012-11-21 00:36:55 +00007928static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007929s390_irgen_SHY(UChar r1, IRTemp op2addr)
7930{
7931 IRTemp op1 = newTemp(Ity_I32);
7932 IRTemp op2 = newTemp(Ity_I32);
7933 IRTemp result = newTemp(Ity_I32);
7934
7935 assign(op1, get_gpr_w1(r1));
7936 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7937 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7938 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7939 put_gpr_w1(r1, mkexpr(result));
7940
7941 return "shy";
7942}
7943
florian55085f82012-11-21 00:36:55 +00007944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007945s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7946{
7947 IRTemp op2 = newTemp(Ity_I32);
7948 IRTemp op3 = newTemp(Ity_I32);
7949 IRTemp result = newTemp(Ity_I32);
7950
7951 assign(op2, get_gpr_w0(r1));
7952 assign(op3, get_gpr_w0(r2));
7953 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7954 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7955 put_gpr_w0(r1, mkexpr(result));
7956
7957 return "shhhr";
7958}
7959
florian55085f82012-11-21 00:36:55 +00007960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007961s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7962{
7963 IRTemp op2 = newTemp(Ity_I32);
7964 IRTemp op3 = newTemp(Ity_I32);
7965 IRTemp result = newTemp(Ity_I32);
7966
7967 assign(op2, get_gpr_w0(r1));
7968 assign(op3, get_gpr_w1(r2));
7969 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7970 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7971 put_gpr_w0(r1, mkexpr(result));
7972
7973 return "shhlr";
7974}
7975
florian55085f82012-11-21 00:36:55 +00007976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007977s390_irgen_SLR(UChar r1, UChar r2)
7978{
7979 IRTemp op1 = newTemp(Ity_I32);
7980 IRTemp op2 = newTemp(Ity_I32);
7981 IRTemp result = newTemp(Ity_I32);
7982
7983 assign(op1, get_gpr_w1(r1));
7984 assign(op2, get_gpr_w1(r2));
7985 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7986 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7987 put_gpr_w1(r1, mkexpr(result));
7988
7989 return "slr";
7990}
7991
florian55085f82012-11-21 00:36:55 +00007992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007993s390_irgen_SLGR(UChar r1, UChar r2)
7994{
7995 IRTemp op1 = newTemp(Ity_I64);
7996 IRTemp op2 = newTemp(Ity_I64);
7997 IRTemp result = newTemp(Ity_I64);
7998
7999 assign(op1, get_gpr_dw0(r1));
8000 assign(op2, get_gpr_dw0(r2));
8001 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8002 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8003 put_gpr_dw0(r1, mkexpr(result));
8004
8005 return "slgr";
8006}
8007
florian55085f82012-11-21 00:36:55 +00008008static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008009s390_irgen_SLGFR(UChar r1, UChar r2)
8010{
8011 IRTemp op1 = newTemp(Ity_I64);
8012 IRTemp op2 = newTemp(Ity_I64);
8013 IRTemp result = newTemp(Ity_I64);
8014
8015 assign(op1, get_gpr_dw0(r1));
8016 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8017 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8018 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8019 put_gpr_dw0(r1, mkexpr(result));
8020
8021 return "slgfr";
8022}
8023
florian55085f82012-11-21 00:36:55 +00008024static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008025s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8026{
8027 IRTemp op2 = newTemp(Ity_I32);
8028 IRTemp op3 = newTemp(Ity_I32);
8029 IRTemp result = newTemp(Ity_I32);
8030
8031 assign(op2, get_gpr_w1(r2));
8032 assign(op3, get_gpr_w1(r3));
8033 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8034 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8035 put_gpr_w1(r1, mkexpr(result));
8036
8037 return "slrk";
8038}
8039
florian55085f82012-11-21 00:36:55 +00008040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008041s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8042{
8043 IRTemp op2 = newTemp(Ity_I64);
8044 IRTemp op3 = newTemp(Ity_I64);
8045 IRTemp result = newTemp(Ity_I64);
8046
8047 assign(op2, get_gpr_dw0(r2));
8048 assign(op3, get_gpr_dw0(r3));
8049 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8050 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8051 put_gpr_dw0(r1, mkexpr(result));
8052
8053 return "slgrk";
8054}
8055
florian55085f82012-11-21 00:36:55 +00008056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008057s390_irgen_SL(UChar r1, IRTemp op2addr)
8058{
8059 IRTemp op1 = newTemp(Ity_I32);
8060 IRTemp op2 = newTemp(Ity_I32);
8061 IRTemp result = newTemp(Ity_I32);
8062
8063 assign(op1, get_gpr_w1(r1));
8064 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8065 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8066 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8067 put_gpr_w1(r1, mkexpr(result));
8068
8069 return "sl";
8070}
8071
florian55085f82012-11-21 00:36:55 +00008072static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008073s390_irgen_SLY(UChar r1, IRTemp op2addr)
8074{
8075 IRTemp op1 = newTemp(Ity_I32);
8076 IRTemp op2 = newTemp(Ity_I32);
8077 IRTemp result = newTemp(Ity_I32);
8078
8079 assign(op1, get_gpr_w1(r1));
8080 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8081 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8082 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8083 put_gpr_w1(r1, mkexpr(result));
8084
8085 return "sly";
8086}
8087
florian55085f82012-11-21 00:36:55 +00008088static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008089s390_irgen_SLG(UChar r1, IRTemp op2addr)
8090{
8091 IRTemp op1 = newTemp(Ity_I64);
8092 IRTemp op2 = newTemp(Ity_I64);
8093 IRTemp result = newTemp(Ity_I64);
8094
8095 assign(op1, get_gpr_dw0(r1));
8096 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8097 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8098 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8099 put_gpr_dw0(r1, mkexpr(result));
8100
8101 return "slg";
8102}
8103
florian55085f82012-11-21 00:36:55 +00008104static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008105s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8106{
8107 IRTemp op1 = newTemp(Ity_I64);
8108 IRTemp op2 = newTemp(Ity_I64);
8109 IRTemp result = newTemp(Ity_I64);
8110
8111 assign(op1, get_gpr_dw0(r1));
8112 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8113 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8114 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8115 put_gpr_dw0(r1, mkexpr(result));
8116
8117 return "slgf";
8118}
8119
florian55085f82012-11-21 00:36:55 +00008120static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008121s390_irgen_SLFI(UChar r1, UInt i2)
8122{
8123 IRTemp op1 = newTemp(Ity_I32);
8124 UInt op2;
8125 IRTemp result = newTemp(Ity_I32);
8126
8127 assign(op1, get_gpr_w1(r1));
8128 op2 = i2;
8129 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8130 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8131 mkU32(op2)));
8132 put_gpr_w1(r1, mkexpr(result));
8133
8134 return "slfi";
8135}
8136
florian55085f82012-11-21 00:36:55 +00008137static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008138s390_irgen_SLGFI(UChar r1, UInt i2)
8139{
8140 IRTemp op1 = newTemp(Ity_I64);
8141 ULong op2;
8142 IRTemp result = newTemp(Ity_I64);
8143
8144 assign(op1, get_gpr_dw0(r1));
8145 op2 = (ULong)i2;
8146 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8147 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8148 mkU64(op2)));
8149 put_gpr_dw0(r1, mkexpr(result));
8150
8151 return "slgfi";
8152}
8153
florian55085f82012-11-21 00:36:55 +00008154static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008155s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8156{
8157 IRTemp op2 = newTemp(Ity_I32);
8158 IRTemp op3 = newTemp(Ity_I32);
8159 IRTemp result = newTemp(Ity_I32);
8160
8161 assign(op2, get_gpr_w0(r1));
8162 assign(op3, get_gpr_w0(r2));
8163 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8164 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8165 put_gpr_w0(r1, mkexpr(result));
8166
8167 return "slhhhr";
8168}
8169
florian55085f82012-11-21 00:36:55 +00008170static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008171s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8172{
8173 IRTemp op2 = newTemp(Ity_I32);
8174 IRTemp op3 = newTemp(Ity_I32);
8175 IRTemp result = newTemp(Ity_I32);
8176
8177 assign(op2, get_gpr_w0(r1));
8178 assign(op3, get_gpr_w1(r2));
8179 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8180 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8181 put_gpr_w0(r1, mkexpr(result));
8182
8183 return "slhhlr";
8184}
8185
florian55085f82012-11-21 00:36:55 +00008186static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008187s390_irgen_SLBR(UChar r1, UChar r2)
8188{
8189 IRTemp op1 = newTemp(Ity_I32);
8190 IRTemp op2 = newTemp(Ity_I32);
8191 IRTemp result = newTemp(Ity_I32);
8192 IRTemp borrow_in = newTemp(Ity_I32);
8193
8194 assign(op1, get_gpr_w1(r1));
8195 assign(op2, get_gpr_w1(r2));
8196 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8197 s390_call_calculate_cc(), mkU8(1))));
8198 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8199 mkexpr(borrow_in)));
8200 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8201 put_gpr_w1(r1, mkexpr(result));
8202
8203 return "slbr";
8204}
8205
florian55085f82012-11-21 00:36:55 +00008206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008207s390_irgen_SLBGR(UChar r1, UChar r2)
8208{
8209 IRTemp op1 = newTemp(Ity_I64);
8210 IRTemp op2 = newTemp(Ity_I64);
8211 IRTemp result = newTemp(Ity_I64);
8212 IRTemp borrow_in = newTemp(Ity_I64);
8213
8214 assign(op1, get_gpr_dw0(r1));
8215 assign(op2, get_gpr_dw0(r2));
8216 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8217 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8218 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8219 mkexpr(borrow_in)));
8220 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8221 put_gpr_dw0(r1, mkexpr(result));
8222
8223 return "slbgr";
8224}
8225
florian55085f82012-11-21 00:36:55 +00008226static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008227s390_irgen_SLB(UChar r1, IRTemp op2addr)
8228{
8229 IRTemp op1 = newTemp(Ity_I32);
8230 IRTemp op2 = newTemp(Ity_I32);
8231 IRTemp result = newTemp(Ity_I32);
8232 IRTemp borrow_in = newTemp(Ity_I32);
8233
8234 assign(op1, get_gpr_w1(r1));
8235 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8236 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8237 s390_call_calculate_cc(), mkU8(1))));
8238 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8239 mkexpr(borrow_in)));
8240 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8241 put_gpr_w1(r1, mkexpr(result));
8242
8243 return "slb";
8244}
8245
florian55085f82012-11-21 00:36:55 +00008246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008247s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8248{
8249 IRTemp op1 = newTemp(Ity_I64);
8250 IRTemp op2 = newTemp(Ity_I64);
8251 IRTemp result = newTemp(Ity_I64);
8252 IRTemp borrow_in = newTemp(Ity_I64);
8253
8254 assign(op1, get_gpr_dw0(r1));
8255 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8256 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8257 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8258 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8259 mkexpr(borrow_in)));
8260 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8261 put_gpr_dw0(r1, mkexpr(result));
8262
8263 return "slbg";
8264}
8265
florian55085f82012-11-21 00:36:55 +00008266static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008267s390_irgen_SVC(UChar i)
8268{
8269 IRTemp sysno = newTemp(Ity_I64);
8270
8271 if (i != 0) {
8272 assign(sysno, mkU64(i));
8273 } else {
8274 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8275 }
8276 system_call(mkexpr(sysno));
8277
8278 return "svc";
8279}
8280
florian55085f82012-11-21 00:36:55 +00008281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008282s390_irgen_TM(UChar i2, IRTemp op1addr)
8283{
8284 UChar mask;
8285 IRTemp value = newTemp(Ity_I8);
8286
8287 mask = i2;
8288 assign(value, load(Ity_I8, mkexpr(op1addr)));
8289 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8290 mkU8(mask)));
8291
8292 return "tm";
8293}
8294
florian55085f82012-11-21 00:36:55 +00008295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008296s390_irgen_TMY(UChar i2, IRTemp op1addr)
8297{
8298 UChar mask;
8299 IRTemp value = newTemp(Ity_I8);
8300
8301 mask = i2;
8302 assign(value, load(Ity_I8, mkexpr(op1addr)));
8303 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8304 mkU8(mask)));
8305
8306 return "tmy";
8307}
8308
florian55085f82012-11-21 00:36:55 +00008309static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008310s390_irgen_TMHH(UChar r1, UShort i2)
8311{
8312 UShort mask;
8313 IRTemp value = newTemp(Ity_I16);
8314
8315 mask = i2;
8316 assign(value, get_gpr_hw0(r1));
8317 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8318 mkU16(mask)));
8319
8320 return "tmhh";
8321}
8322
florian55085f82012-11-21 00:36:55 +00008323static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008324s390_irgen_TMHL(UChar r1, UShort i2)
8325{
8326 UShort mask;
8327 IRTemp value = newTemp(Ity_I16);
8328
8329 mask = i2;
8330 assign(value, get_gpr_hw1(r1));
8331 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8332 mkU16(mask)));
8333
8334 return "tmhl";
8335}
8336
florian55085f82012-11-21 00:36:55 +00008337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008338s390_irgen_TMLH(UChar r1, UShort i2)
8339{
8340 UShort mask;
8341 IRTemp value = newTemp(Ity_I16);
8342
8343 mask = i2;
8344 assign(value, get_gpr_hw2(r1));
8345 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8346 mkU16(mask)));
8347
8348 return "tmlh";
8349}
8350
florian55085f82012-11-21 00:36:55 +00008351static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008352s390_irgen_TMLL(UChar r1, UShort i2)
8353{
8354 UShort mask;
8355 IRTemp value = newTemp(Ity_I16);
8356
8357 mask = i2;
8358 assign(value, get_gpr_hw3(r1));
8359 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8360 mkU16(mask)));
8361
8362 return "tmll";
8363}
8364
florian55085f82012-11-21 00:36:55 +00008365static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008366s390_irgen_EFPC(UChar r1)
8367{
8368 put_gpr_w1(r1, get_fpc_w0());
8369
8370 return "efpc";
8371}
8372
florian55085f82012-11-21 00:36:55 +00008373static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008374s390_irgen_LER(UChar r1, UChar r2)
8375{
8376 put_fpr_w0(r1, get_fpr_w0(r2));
8377
8378 return "ler";
8379}
8380
florian55085f82012-11-21 00:36:55 +00008381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008382s390_irgen_LDR(UChar r1, UChar r2)
8383{
8384 put_fpr_dw0(r1, get_fpr_dw0(r2));
8385
8386 return "ldr";
8387}
8388
florian55085f82012-11-21 00:36:55 +00008389static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008390s390_irgen_LXR(UChar r1, UChar r2)
8391{
8392 put_fpr_dw0(r1, get_fpr_dw0(r2));
8393 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8394
8395 return "lxr";
8396}
8397
florian55085f82012-11-21 00:36:55 +00008398static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008399s390_irgen_LE(UChar r1, IRTemp op2addr)
8400{
8401 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8402
8403 return "le";
8404}
8405
florian55085f82012-11-21 00:36:55 +00008406static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008407s390_irgen_LD(UChar r1, IRTemp op2addr)
8408{
8409 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8410
8411 return "ld";
8412}
8413
florian55085f82012-11-21 00:36:55 +00008414static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008415s390_irgen_LEY(UChar r1, IRTemp op2addr)
8416{
8417 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8418
8419 return "ley";
8420}
8421
florian55085f82012-11-21 00:36:55 +00008422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008423s390_irgen_LDY(UChar r1, IRTemp op2addr)
8424{
8425 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8426
8427 return "ldy";
8428}
8429
florian55085f82012-11-21 00:36:55 +00008430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008431s390_irgen_LFPC(IRTemp op2addr)
8432{
8433 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8434
8435 return "lfpc";
8436}
8437
florian55085f82012-11-21 00:36:55 +00008438static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008439s390_irgen_LZER(UChar r1)
8440{
8441 put_fpr_w0(r1, mkF32i(0x0));
8442
8443 return "lzer";
8444}
8445
florian55085f82012-11-21 00:36:55 +00008446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008447s390_irgen_LZDR(UChar r1)
8448{
8449 put_fpr_dw0(r1, mkF64i(0x0));
8450
8451 return "lzdr";
8452}
8453
florian55085f82012-11-21 00:36:55 +00008454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008455s390_irgen_LZXR(UChar r1)
8456{
8457 put_fpr_dw0(r1, mkF64i(0x0));
8458 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8459
8460 return "lzxr";
8461}
8462
florian55085f82012-11-21 00:36:55 +00008463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008464s390_irgen_SRNM(IRTemp op2addr)
8465{
florianf0fa1be2012-09-18 20:24:38 +00008466 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008467
florianf0fa1be2012-09-18 20:24:38 +00008468 input_mask = 3;
8469 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008470
florianf0fa1be2012-09-18 20:24:38 +00008471 put_fpc_w0(binop(Iop_Or32,
8472 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8473 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8474 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008475 return "srnm";
8476}
8477
florian55085f82012-11-21 00:36:55 +00008478static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008479s390_irgen_SRNMB(IRTemp op2addr)
8480{
8481 UInt input_mask, fpc_mask;
8482
8483 input_mask = 7;
8484 fpc_mask = 7;
8485
8486 put_fpc_w0(binop(Iop_Or32,
8487 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8488 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8489 mkU32(input_mask))));
8490 return "srnmb";
8491}
8492
florian81a4bfe2012-09-20 01:25:28 +00008493static void
florianf0fa1be2012-09-18 20:24:38 +00008494s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8495{
8496 if (b2 == 0) { /* This is the typical case */
8497 if (d2 > 3) {
8498 if (s390_host_has_fpext && d2 == 7) {
8499 /* ok */
8500 } else {
8501 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008502 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008503 }
8504 }
8505 }
8506
8507 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8508}
8509
8510
florian55085f82012-11-21 00:36:55 +00008511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008512s390_irgen_SFPC(UChar r1)
8513{
8514 put_fpc_w0(get_gpr_w1(r1));
8515
8516 return "sfpc";
8517}
8518
florian55085f82012-11-21 00:36:55 +00008519static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008520s390_irgen_STE(UChar r1, IRTemp op2addr)
8521{
8522 store(mkexpr(op2addr), get_fpr_w0(r1));
8523
8524 return "ste";
8525}
8526
florian55085f82012-11-21 00:36:55 +00008527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008528s390_irgen_STD(UChar r1, IRTemp op2addr)
8529{
8530 store(mkexpr(op2addr), get_fpr_dw0(r1));
8531
8532 return "std";
8533}
8534
florian55085f82012-11-21 00:36:55 +00008535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008536s390_irgen_STEY(UChar r1, IRTemp op2addr)
8537{
8538 store(mkexpr(op2addr), get_fpr_w0(r1));
8539
8540 return "stey";
8541}
8542
florian55085f82012-11-21 00:36:55 +00008543static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008544s390_irgen_STDY(UChar r1, IRTemp op2addr)
8545{
8546 store(mkexpr(op2addr), get_fpr_dw0(r1));
8547
8548 return "stdy";
8549}
8550
florian55085f82012-11-21 00:36:55 +00008551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008552s390_irgen_STFPC(IRTemp op2addr)
8553{
8554 store(mkexpr(op2addr), get_fpc_w0());
8555
8556 return "stfpc";
8557}
8558
florian55085f82012-11-21 00:36:55 +00008559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008560s390_irgen_AEBR(UChar r1, UChar r2)
8561{
8562 IRTemp op1 = newTemp(Ity_F32);
8563 IRTemp op2 = newTemp(Ity_F32);
8564 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008565 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008566
8567 assign(op1, get_fpr_w0(r1));
8568 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008569 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008570 mkexpr(op2)));
8571 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8572 put_fpr_w0(r1, mkexpr(result));
8573
8574 return "aebr";
8575}
8576
florian55085f82012-11-21 00:36:55 +00008577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008578s390_irgen_ADBR(UChar r1, UChar r2)
8579{
8580 IRTemp op1 = newTemp(Ity_F64);
8581 IRTemp op2 = newTemp(Ity_F64);
8582 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008583 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008584
8585 assign(op1, get_fpr_dw0(r1));
8586 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008587 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008588 mkexpr(op2)));
8589 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8590 put_fpr_dw0(r1, mkexpr(result));
8591
8592 return "adbr";
8593}
8594
florian55085f82012-11-21 00:36:55 +00008595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008596s390_irgen_AEB(UChar r1, IRTemp op2addr)
8597{
8598 IRTemp op1 = newTemp(Ity_F32);
8599 IRTemp op2 = newTemp(Ity_F32);
8600 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008601 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008602
8603 assign(op1, get_fpr_w0(r1));
8604 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008605 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008606 mkexpr(op2)));
8607 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8608 put_fpr_w0(r1, mkexpr(result));
8609
8610 return "aeb";
8611}
8612
florian55085f82012-11-21 00:36:55 +00008613static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008614s390_irgen_ADB(UChar r1, IRTemp op2addr)
8615{
8616 IRTemp op1 = newTemp(Ity_F64);
8617 IRTemp op2 = newTemp(Ity_F64);
8618 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008619 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008620
8621 assign(op1, get_fpr_dw0(r1));
8622 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008623 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008624 mkexpr(op2)));
8625 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8626 put_fpr_dw0(r1, mkexpr(result));
8627
8628 return "adb";
8629}
8630
florian55085f82012-11-21 00:36:55 +00008631static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008632s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8633 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008634{
florian125e20d2012-10-07 15:42:37 +00008635 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008636 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008637 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008638 }
sewardj2019a972011-03-07 16:04:07 +00008639 IRTemp op2 = newTemp(Ity_I32);
8640
8641 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008642 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008643 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008644
8645 return "cefbr";
8646}
8647
florian55085f82012-11-21 00:36:55 +00008648static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008649s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8650 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008651{
8652 IRTemp op2 = newTemp(Ity_I32);
8653
8654 assign(op2, get_gpr_w1(r2));
8655 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8656
8657 return "cdfbr";
8658}
8659
florian55085f82012-11-21 00:36:55 +00008660static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008661s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8662 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008663{
florian125e20d2012-10-07 15:42:37 +00008664 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008665 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008666 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008667 }
sewardj2019a972011-03-07 16:04:07 +00008668 IRTemp op2 = newTemp(Ity_I64);
8669
8670 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008671 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008672 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008673
8674 return "cegbr";
8675}
8676
florian55085f82012-11-21 00:36:55 +00008677static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008678s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8679 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008680{
florian125e20d2012-10-07 15:42:37 +00008681 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008682 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008683 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008684 }
sewardj2019a972011-03-07 16:04:07 +00008685 IRTemp op2 = newTemp(Ity_I64);
8686
8687 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008688 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008689 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008690
8691 return "cdgbr";
8692}
8693
florian55085f82012-11-21 00:36:55 +00008694static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008695s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8696 UChar r1, UChar r2)
8697{
floriane75dafa2012-09-01 17:54:09 +00008698 if (! s390_host_has_fpext) {
8699 emulation_failure(EmFail_S390X_fpext);
8700 } else {
8701 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008702
floriane75dafa2012-09-01 17:54:09 +00008703 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008704 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008705 mkexpr(op2)));
8706 }
florian1c8f7ff2012-09-01 00:12:11 +00008707 return "celfbr";
8708}
8709
florian55085f82012-11-21 00:36:55 +00008710static const HChar *
floriand2129202012-09-01 20:01:39 +00008711s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8712 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008713{
floriane75dafa2012-09-01 17:54:09 +00008714 if (! s390_host_has_fpext) {
8715 emulation_failure(EmFail_S390X_fpext);
8716 } else {
8717 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008718
floriane75dafa2012-09-01 17:54:09 +00008719 assign(op2, get_gpr_w1(r2));
8720 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8721 }
florian1c8f7ff2012-09-01 00:12:11 +00008722 return "cdlfbr";
8723}
8724
florian55085f82012-11-21 00:36:55 +00008725static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008726s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8727 UChar r1, UChar r2)
8728{
floriane75dafa2012-09-01 17:54:09 +00008729 if (! s390_host_has_fpext) {
8730 emulation_failure(EmFail_S390X_fpext);
8731 } else {
8732 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008733
floriane75dafa2012-09-01 17:54:09 +00008734 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008735 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008736 mkexpr(op2)));
8737 }
florian1c8f7ff2012-09-01 00:12:11 +00008738 return "celgbr";
8739}
8740
florian55085f82012-11-21 00:36:55 +00008741static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008742s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8743 UChar r1, UChar r2)
8744{
floriane75dafa2012-09-01 17:54:09 +00008745 if (! s390_host_has_fpext) {
8746 emulation_failure(EmFail_S390X_fpext);
8747 } else {
8748 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008749
floriane75dafa2012-09-01 17:54:09 +00008750 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008751 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8752 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008753 mkexpr(op2)));
8754 }
florian1c8f7ff2012-09-01 00:12:11 +00008755 return "cdlgbr";
8756}
8757
florian55085f82012-11-21 00:36:55 +00008758static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008759s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8760 UChar r1, UChar r2)
8761{
floriane75dafa2012-09-01 17:54:09 +00008762 if (! s390_host_has_fpext) {
8763 emulation_failure(EmFail_S390X_fpext);
8764 } else {
8765 IRTemp op = newTemp(Ity_F32);
8766 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008767 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008768
floriane75dafa2012-09-01 17:54:09 +00008769 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008770 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008771 mkexpr(op)));
8772 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008773 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008774 }
florian1c8f7ff2012-09-01 00:12:11 +00008775 return "clfebr";
8776}
8777
florian55085f82012-11-21 00:36:55 +00008778static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008779s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8780 UChar r1, UChar r2)
8781{
floriane75dafa2012-09-01 17:54:09 +00008782 if (! s390_host_has_fpext) {
8783 emulation_failure(EmFail_S390X_fpext);
8784 } else {
8785 IRTemp op = newTemp(Ity_F64);
8786 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008787 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008788
floriane75dafa2012-09-01 17:54:09 +00008789 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008790 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008791 mkexpr(op)));
8792 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008793 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008794 }
florian1c8f7ff2012-09-01 00:12:11 +00008795 return "clfdbr";
8796}
8797
florian55085f82012-11-21 00:36:55 +00008798static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008799s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8800 UChar r1, UChar r2)
8801{
floriane75dafa2012-09-01 17:54:09 +00008802 if (! s390_host_has_fpext) {
8803 emulation_failure(EmFail_S390X_fpext);
8804 } else {
8805 IRTemp op = newTemp(Ity_F32);
8806 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008807 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008808
floriane75dafa2012-09-01 17:54:09 +00008809 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008810 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008811 mkexpr(op)));
8812 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008813 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008814 }
florian1c8f7ff2012-09-01 00:12:11 +00008815 return "clgebr";
8816}
8817
florian55085f82012-11-21 00:36:55 +00008818static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008819s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8820 UChar r1, UChar r2)
8821{
floriane75dafa2012-09-01 17:54:09 +00008822 if (! s390_host_has_fpext) {
8823 emulation_failure(EmFail_S390X_fpext);
8824 } else {
8825 IRTemp op = newTemp(Ity_F64);
8826 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008827 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008828
floriane75dafa2012-09-01 17:54:09 +00008829 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008830 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008831 mkexpr(op)));
8832 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008833 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008834 }
florian1c8f7ff2012-09-01 00:12:11 +00008835 return "clgdbr";
8836}
8837
florian55085f82012-11-21 00:36:55 +00008838static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008839s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8840 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008841{
8842 IRTemp op = newTemp(Ity_F32);
8843 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008844 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008845
8846 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008847 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008848 mkexpr(op)));
8849 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008850 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008851
8852 return "cfebr";
8853}
8854
florian55085f82012-11-21 00:36:55 +00008855static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008856s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8857 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008858{
8859 IRTemp op = newTemp(Ity_F64);
8860 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008861 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008862
8863 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008864 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008865 mkexpr(op)));
8866 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008867 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008868
8869 return "cfdbr";
8870}
8871
florian55085f82012-11-21 00:36:55 +00008872static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008873s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8874 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008875{
8876 IRTemp op = newTemp(Ity_F32);
8877 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008878 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008879
8880 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008881 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008882 mkexpr(op)));
8883 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008884 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008885
8886 return "cgebr";
8887}
8888
florian55085f82012-11-21 00:36:55 +00008889static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008890s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8891 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008892{
8893 IRTemp op = newTemp(Ity_F64);
8894 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008895 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008896
8897 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008898 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008899 mkexpr(op)));
8900 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008901 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008902
8903 return "cgdbr";
8904}
8905
florian55085f82012-11-21 00:36:55 +00008906static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008907s390_irgen_DEBR(UChar r1, UChar r2)
8908{
8909 IRTemp op1 = newTemp(Ity_F32);
8910 IRTemp op2 = newTemp(Ity_F32);
8911 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008912 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008913
8914 assign(op1, get_fpr_w0(r1));
8915 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008916 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008917 mkexpr(op2)));
8918 put_fpr_w0(r1, mkexpr(result));
8919
8920 return "debr";
8921}
8922
florian55085f82012-11-21 00:36:55 +00008923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008924s390_irgen_DDBR(UChar r1, UChar r2)
8925{
8926 IRTemp op1 = newTemp(Ity_F64);
8927 IRTemp op2 = newTemp(Ity_F64);
8928 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008929 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008930
8931 assign(op1, get_fpr_dw0(r1));
8932 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008933 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008934 mkexpr(op2)));
8935 put_fpr_dw0(r1, mkexpr(result));
8936
8937 return "ddbr";
8938}
8939
florian55085f82012-11-21 00:36:55 +00008940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008941s390_irgen_DEB(UChar r1, IRTemp op2addr)
8942{
8943 IRTemp op1 = newTemp(Ity_F32);
8944 IRTemp op2 = newTemp(Ity_F32);
8945 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008946 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008947
8948 assign(op1, get_fpr_w0(r1));
8949 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008950 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008951 mkexpr(op2)));
8952 put_fpr_w0(r1, mkexpr(result));
8953
8954 return "deb";
8955}
8956
florian55085f82012-11-21 00:36:55 +00008957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008958s390_irgen_DDB(UChar r1, IRTemp op2addr)
8959{
8960 IRTemp op1 = newTemp(Ity_F64);
8961 IRTemp op2 = newTemp(Ity_F64);
8962 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008963 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008964
8965 assign(op1, get_fpr_dw0(r1));
8966 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008967 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008968 mkexpr(op2)));
8969 put_fpr_dw0(r1, mkexpr(result));
8970
8971 return "ddb";
8972}
8973
florian55085f82012-11-21 00:36:55 +00008974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008975s390_irgen_LTEBR(UChar r1, UChar r2)
8976{
8977 IRTemp result = newTemp(Ity_F32);
8978
8979 assign(result, get_fpr_w0(r2));
8980 put_fpr_w0(r1, mkexpr(result));
8981 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8982
8983 return "ltebr";
8984}
8985
florian55085f82012-11-21 00:36:55 +00008986static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008987s390_irgen_LTDBR(UChar r1, UChar r2)
8988{
8989 IRTemp result = newTemp(Ity_F64);
8990
8991 assign(result, get_fpr_dw0(r2));
8992 put_fpr_dw0(r1, mkexpr(result));
8993 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8994
8995 return "ltdbr";
8996}
8997
florian55085f82012-11-21 00:36:55 +00008998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008999s390_irgen_LCEBR(UChar r1, UChar r2)
9000{
9001 IRTemp result = newTemp(Ity_F32);
9002
9003 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9004 put_fpr_w0(r1, mkexpr(result));
9005 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9006
9007 return "lcebr";
9008}
9009
florian55085f82012-11-21 00:36:55 +00009010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009011s390_irgen_LCDBR(UChar r1, UChar r2)
9012{
9013 IRTemp result = newTemp(Ity_F64);
9014
9015 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9016 put_fpr_dw0(r1, mkexpr(result));
9017 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9018
9019 return "lcdbr";
9020}
9021
florian55085f82012-11-21 00:36:55 +00009022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009023s390_irgen_LDEBR(UChar r1, UChar r2)
9024{
9025 IRTemp op = newTemp(Ity_F32);
9026
9027 assign(op, get_fpr_w0(r2));
9028 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9029
9030 return "ldebr";
9031}
9032
florian55085f82012-11-21 00:36:55 +00009033static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009034s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9035{
9036 IRTemp op = newTemp(Ity_F32);
9037
9038 assign(op, load(Ity_F32, mkexpr(op2addr)));
9039 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9040
9041 return "ldeb";
9042}
9043
florian55085f82012-11-21 00:36:55 +00009044static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009045s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9046 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009047{
florian125e20d2012-10-07 15:42:37 +00009048 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009049 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009050 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009051 }
sewardj2019a972011-03-07 16:04:07 +00009052 IRTemp op = newTemp(Ity_F64);
9053
9054 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009055 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009056 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009057
9058 return "ledbr";
9059}
9060
florian55085f82012-11-21 00:36:55 +00009061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009062s390_irgen_MEEBR(UChar r1, UChar r2)
9063{
9064 IRTemp op1 = newTemp(Ity_F32);
9065 IRTemp op2 = newTemp(Ity_F32);
9066 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009067 IRRoundingMode rounding_mode =
9068 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009069
9070 assign(op1, get_fpr_w0(r1));
9071 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009072 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009073 mkexpr(op2)));
9074 put_fpr_w0(r1, mkexpr(result));
9075
9076 return "meebr";
9077}
9078
florian55085f82012-11-21 00:36:55 +00009079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009080s390_irgen_MDBR(UChar r1, UChar r2)
9081{
9082 IRTemp op1 = newTemp(Ity_F64);
9083 IRTemp op2 = newTemp(Ity_F64);
9084 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009085 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009086
9087 assign(op1, get_fpr_dw0(r1));
9088 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009089 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009090 mkexpr(op2)));
9091 put_fpr_dw0(r1, mkexpr(result));
9092
9093 return "mdbr";
9094}
9095
florian55085f82012-11-21 00:36:55 +00009096static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009097s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9098{
9099 IRTemp op1 = newTemp(Ity_F32);
9100 IRTemp op2 = newTemp(Ity_F32);
9101 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009102 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009103
9104 assign(op1, get_fpr_w0(r1));
9105 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009106 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009107 mkexpr(op2)));
9108 put_fpr_w0(r1, mkexpr(result));
9109
9110 return "meeb";
9111}
9112
florian55085f82012-11-21 00:36:55 +00009113static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009114s390_irgen_MDB(UChar r1, IRTemp op2addr)
9115{
9116 IRTemp op1 = newTemp(Ity_F64);
9117 IRTemp op2 = newTemp(Ity_F64);
9118 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009119 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009120
9121 assign(op1, get_fpr_dw0(r1));
9122 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009123 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009124 mkexpr(op2)));
9125 put_fpr_dw0(r1, mkexpr(result));
9126
9127 return "mdb";
9128}
9129
florian55085f82012-11-21 00:36:55 +00009130static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009131s390_irgen_SEBR(UChar r1, UChar r2)
9132{
9133 IRTemp op1 = newTemp(Ity_F32);
9134 IRTemp op2 = newTemp(Ity_F32);
9135 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009136 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009137
9138 assign(op1, get_fpr_w0(r1));
9139 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009140 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009141 mkexpr(op2)));
9142 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9143 put_fpr_w0(r1, mkexpr(result));
9144
9145 return "sebr";
9146}
9147
florian55085f82012-11-21 00:36:55 +00009148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009149s390_irgen_SDBR(UChar r1, UChar r2)
9150{
9151 IRTemp op1 = newTemp(Ity_F64);
9152 IRTemp op2 = newTemp(Ity_F64);
9153 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009154 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009155
9156 assign(op1, get_fpr_dw0(r1));
9157 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009158 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009159 mkexpr(op2)));
9160 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9161 put_fpr_dw0(r1, mkexpr(result));
9162
9163 return "sdbr";
9164}
9165
florian55085f82012-11-21 00:36:55 +00009166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009167s390_irgen_SEB(UChar r1, IRTemp op2addr)
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, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009176 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009177 mkexpr(op2)));
9178 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9179 put_fpr_w0(r1, mkexpr(result));
9180
9181 return "seb";
9182}
9183
florian55085f82012-11-21 00:36:55 +00009184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009185s390_irgen_SDB(UChar r1, IRTemp op2addr)
9186{
9187 IRTemp op1 = newTemp(Ity_F64);
9188 IRTemp op2 = newTemp(Ity_F64);
9189 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009190 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009191
9192 assign(op1, get_fpr_dw0(r1));
9193 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009194 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009195 mkexpr(op2)));
9196 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9197 put_fpr_dw0(r1, mkexpr(result));
9198
9199 return "sdb";
9200}
9201
florian55085f82012-11-21 00:36:55 +00009202static const HChar *
florian12390202012-11-10 22:34:14 +00009203s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9204{
9205 IRTemp op1 = newTemp(Ity_D64);
9206 IRTemp op2 = newTemp(Ity_D64);
9207 IRTemp result = newTemp(Ity_D64);
9208 IRTemp rounding_mode;
9209
9210 vassert(s390_host_has_dfp);
9211 vassert(m4 == 0 || s390_host_has_fpext);
9212 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9213 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9214 rounding_mode = encode_dfp_rounding_mode(m4);
9215 assign(op1, get_dpr_dw0(r2));
9216 assign(op2, get_dpr_dw0(r3));
9217 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9218 mkexpr(op2)));
9219 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9220 put_dpr_dw0(r1, mkexpr(result));
9221
9222 return (m4 == 0) ? "adtr" : "adtra";
9223}
9224
florian55085f82012-11-21 00:36:55 +00009225static const HChar *
floriane38f6412012-12-21 17:32:12 +00009226s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9227{
9228 IRTemp op1 = newTemp(Ity_D128);
9229 IRTemp op2 = newTemp(Ity_D128);
9230 IRTemp result = newTemp(Ity_D128);
9231 IRTemp rounding_mode;
9232
9233 vassert(s390_host_has_dfp);
9234 vassert(m4 == 0 || s390_host_has_fpext);
9235 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9236 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9237 rounding_mode = encode_dfp_rounding_mode(m4);
9238 assign(op1, get_dpr_pair(r2));
9239 assign(op2, get_dpr_pair(r3));
9240 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9241 mkexpr(op2)));
9242 put_dpr_pair(r1, mkexpr(result));
9243
9244 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9245
9246 return (m4 == 0) ? "axtr" : "axtra";
9247}
9248
9249static const HChar *
9250s390_irgen_CDTR(UChar r1, UChar r2)
9251{
9252 IRTemp op1 = newTemp(Ity_D64);
9253 IRTemp op2 = newTemp(Ity_D64);
9254 IRTemp cc_vex = newTemp(Ity_I32);
9255 IRTemp cc_s390 = newTemp(Ity_I32);
9256
9257 assign(op1, get_dpr_dw0(r1));
9258 assign(op2, get_dpr_dw0(r2));
9259 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9260
florian2d3d87f2012-12-21 21:05:17 +00009261 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009262 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9263
9264 return "cdtr";
9265}
9266
9267static const HChar *
9268s390_irgen_CXTR(UChar r1, UChar r2)
9269{
9270 IRTemp op1 = newTemp(Ity_D128);
9271 IRTemp op2 = newTemp(Ity_D128);
9272 IRTemp cc_vex = newTemp(Ity_I32);
9273 IRTemp cc_s390 = newTemp(Ity_I32);
9274
9275 assign(op1, get_dpr_pair(r1));
9276 assign(op2, get_dpr_pair(r2));
9277 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9278
florian2d3d87f2012-12-21 21:05:17 +00009279 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009280 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9281
9282 return "cxtr";
9283}
9284
9285static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009286s390_irgen_CEDTR(UChar r1, UChar r2)
9287{
9288 IRTemp op1 = newTemp(Ity_D64);
9289 IRTemp op2 = newTemp(Ity_D64);
9290 IRTemp cc_vex = newTemp(Ity_I32);
9291 IRTemp cc_s390 = newTemp(Ity_I32);
9292
9293 vassert(s390_host_has_dfp);
9294 assign(op1, get_dpr_dw0(r1));
9295 assign(op2, get_dpr_dw0(r2));
9296 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9297
9298 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9299 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9300
9301 return "cedtr";
9302}
9303
9304static const HChar *
9305s390_irgen_CEXTR(UChar r1, UChar r2)
9306{
9307 IRTemp op1 = newTemp(Ity_D128);
9308 IRTemp op2 = newTemp(Ity_D128);
9309 IRTemp cc_vex = newTemp(Ity_I32);
9310 IRTemp cc_s390 = newTemp(Ity_I32);
9311
9312 vassert(s390_host_has_dfp);
9313 assign(op1, get_dpr_pair(r1));
9314 assign(op2, get_dpr_pair(r2));
9315 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9316
9317 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9318 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9319
9320 return "cextr";
9321}
9322
9323static const HChar *
florian12390202012-11-10 22:34:14 +00009324s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9325{
9326 IRTemp op1 = newTemp(Ity_D64);
9327 IRTemp op2 = newTemp(Ity_D64);
9328 IRTemp result = newTemp(Ity_D64);
9329 IRTemp rounding_mode;
9330
9331 vassert(s390_host_has_dfp);
9332 vassert(m4 == 0 || s390_host_has_fpext);
9333 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9334 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9335 rounding_mode = encode_dfp_rounding_mode(m4);
9336 assign(op1, get_dpr_dw0(r2));
9337 assign(op2, get_dpr_dw0(r3));
9338 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9339 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009340 put_dpr_dw0(r1, mkexpr(result));
9341
9342 return (m4 == 0) ? "ddtr" : "ddtra";
9343}
9344
florian55085f82012-11-21 00:36:55 +00009345static const HChar *
floriane38f6412012-12-21 17:32:12 +00009346s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9347{
9348 IRTemp op1 = newTemp(Ity_D128);
9349 IRTemp op2 = newTemp(Ity_D128);
9350 IRTemp result = newTemp(Ity_D128);
9351 IRTemp rounding_mode;
9352
9353 vassert(s390_host_has_dfp);
9354 vassert(m4 == 0 || s390_host_has_fpext);
9355 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9356 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9357 rounding_mode = encode_dfp_rounding_mode(m4);
9358 assign(op1, get_dpr_pair(r2));
9359 assign(op2, get_dpr_pair(r3));
9360 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9361 mkexpr(op2)));
9362 put_dpr_pair(r1, mkexpr(result));
9363
9364 return (m4 == 0) ? "dxtr" : "dxtra";
9365}
9366
9367static const HChar *
9368s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9369{
9370 IRTemp op = newTemp(Ity_D32);
9371
9372 vassert(s390_host_has_dfp);
9373
9374 assign(op, get_dpr_w0(r2));
9375 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
9376
9377 return "ldetr";
9378}
9379
9380static const HChar *
9381s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9382{
9383 IRTemp op = newTemp(Ity_D64);
9384
9385 assign(op, get_dpr_dw0(r2));
9386 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
9387
9388 return "lxdtr";
9389}
9390
9391static const HChar *
9392s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
9393 UChar r1, UChar r2)
9394{
9395 vassert(s390_host_has_dfp);
9396 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9397 emulation_warning(EmWarn_S390X_fpext_rounding);
9398 m3 = S390_DFP_ROUND_PER_FPC_0;
9399 }
9400 IRTemp result = newTemp(Ity_D64);
9401
9402 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
9403 get_dpr_pair(r2)));
9404 put_dpr_dw0(r1, mkexpr(result));
9405
9406 return "ldxtr";
9407}
9408
9409static const HChar *
9410s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
9411 UChar r1, UChar r2)
9412{
9413 vassert(s390_host_has_dfp);
9414 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9415 emulation_warning(EmWarn_S390X_fpext_rounding);
9416 m3 = S390_DFP_ROUND_PER_FPC_0;
9417 }
9418 IRTemp op = newTemp(Ity_D64);
9419
9420 assign(op, get_dpr_dw0(r2));
9421 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
9422 mkexpr(op)));
9423
9424 return "ledtr";
9425}
9426
9427static const HChar *
9428s390_irgen_LTDTR(UChar r1, UChar r2)
9429{
9430 IRTemp result = newTemp(Ity_D64);
9431
9432 assign(result, get_dpr_dw0(r2));
9433 put_dpr_dw0(r1, mkexpr(result));
9434 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9435
9436 return "ltdtr";
9437}
9438
9439static const HChar *
9440s390_irgen_LTXTR(UChar r1, UChar r2)
9441{
9442 IRTemp result = newTemp(Ity_D128);
9443
9444 assign(result, get_dpr_pair(r2));
9445 put_dpr_pair(r1, mkexpr(result));
9446 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9447
9448 return "ltxtr";
9449}
9450
9451static const HChar *
florian12390202012-11-10 22:34:14 +00009452s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9453{
9454 IRTemp op1 = newTemp(Ity_D64);
9455 IRTemp op2 = newTemp(Ity_D64);
9456 IRTemp result = newTemp(Ity_D64);
9457 IRTemp rounding_mode;
9458
9459 vassert(s390_host_has_dfp);
9460 vassert(m4 == 0 || s390_host_has_fpext);
9461 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9462 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9463 rounding_mode = encode_dfp_rounding_mode(m4);
9464 assign(op1, get_dpr_dw0(r2));
9465 assign(op2, get_dpr_dw0(r3));
9466 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9467 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009468 put_dpr_dw0(r1, mkexpr(result));
9469
9470 return (m4 == 0) ? "mdtr" : "mdtra";
9471}
9472
florian55085f82012-11-21 00:36:55 +00009473static const HChar *
floriane38f6412012-12-21 17:32:12 +00009474s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9475{
9476 IRTemp op1 = newTemp(Ity_D128);
9477 IRTemp op2 = newTemp(Ity_D128);
9478 IRTemp result = newTemp(Ity_D128);
9479 IRTemp rounding_mode;
9480
9481 vassert(s390_host_has_dfp);
9482 vassert(m4 == 0 || s390_host_has_fpext);
9483 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9484 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9485 rounding_mode = encode_dfp_rounding_mode(m4);
9486 assign(op1, get_dpr_pair(r2));
9487 assign(op2, get_dpr_pair(r3));
9488 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
9489 mkexpr(op2)));
9490 put_dpr_pair(r1, mkexpr(result));
9491
9492 return (m4 == 0) ? "mxtr" : "mxtra";
9493}
9494
9495static const HChar *
florian12390202012-11-10 22:34:14 +00009496s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9497{
9498 IRTemp op1 = newTemp(Ity_D64);
9499 IRTemp op2 = newTemp(Ity_D64);
9500 IRTemp result = newTemp(Ity_D64);
9501 IRTemp rounding_mode;
9502
9503 vassert(s390_host_has_dfp);
9504 vassert(m4 == 0 || s390_host_has_fpext);
9505 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9506 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9507 rounding_mode = encode_dfp_rounding_mode(m4);
9508 assign(op1, get_dpr_dw0(r2));
9509 assign(op2, get_dpr_dw0(r3));
9510 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9511 mkexpr(op2)));
9512 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9513 put_dpr_dw0(r1, mkexpr(result));
9514
9515 return (m4 == 0) ? "sdtr" : "sdtra";
9516}
9517
floriane38f6412012-12-21 17:32:12 +00009518static const HChar *
9519s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9520{
9521 IRTemp op1 = newTemp(Ity_D128);
9522 IRTemp op2 = newTemp(Ity_D128);
9523 IRTemp result = newTemp(Ity_D128);
9524 IRTemp rounding_mode;
9525
9526 vassert(s390_host_has_dfp);
9527 vassert(m4 == 0 || s390_host_has_fpext);
9528 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9529 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9530 rounding_mode = encode_dfp_rounding_mode(m4);
9531 assign(op1, get_dpr_pair(r2));
9532 assign(op2, get_dpr_pair(r3));
9533 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
9534 mkexpr(op2)));
9535 put_dpr_pair(r1, mkexpr(result));
9536
9537 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9538
9539 return (m4 == 0) ? "sxtr" : "sxtra";
9540}
sewardj2019a972011-03-07 16:04:07 +00009541
florian55085f82012-11-21 00:36:55 +00009542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009543s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9544{
florian79e839e2012-05-05 02:20:30 +00009545 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009546
florian79e839e2012-05-05 02:20:30 +00009547 assign(len, mkU64(length));
9548 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009549
9550 return "clc";
9551}
9552
florian55085f82012-11-21 00:36:55 +00009553static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009554s390_irgen_CLCL(UChar r1, UChar r2)
9555{
9556 IRTemp addr1 = newTemp(Ity_I64);
9557 IRTemp addr2 = newTemp(Ity_I64);
9558 IRTemp addr1_load = newTemp(Ity_I64);
9559 IRTemp addr2_load = newTemp(Ity_I64);
9560 IRTemp len1 = newTemp(Ity_I32);
9561 IRTemp len2 = newTemp(Ity_I32);
9562 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9563 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9564 IRTemp single1 = newTemp(Ity_I8);
9565 IRTemp single2 = newTemp(Ity_I8);
9566 IRTemp pad = newTemp(Ity_I8);
9567
9568 assign(addr1, get_gpr_dw0(r1));
9569 assign(r1p1, get_gpr_w1(r1 + 1));
9570 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9571 assign(addr2, get_gpr_dw0(r2));
9572 assign(r2p1, get_gpr_w1(r2 + 1));
9573 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9574 assign(pad, get_gpr_b4(r2 + 1));
9575
9576 /* len1 == 0 and len2 == 0? Exit */
9577 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009578 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9579 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009580
9581 /* Because mkite evaluates both the then-clause and the else-clause
9582 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9583 may be NULL and loading from there would segfault. So we provide a
9584 valid dummy address in that case. Loading from there does no harm and
9585 the value will be discarded at runtime. */
9586 assign(addr1_load,
9587 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9588 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9589 assign(single1,
9590 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9591 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9592
9593 assign(addr2_load,
9594 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9595 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9596 assign(single2,
9597 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9598 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9599
9600 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9601 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009602 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009603
9604 /* Update len1 and addr1, unless len1 == 0. */
9605 put_gpr_dw0(r1,
9606 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9607 mkexpr(addr1),
9608 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9609
9610 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9611 put_gpr_w1(r1 + 1,
9612 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9613 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9614 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9615
9616 /* Update len2 and addr2, unless len2 == 0. */
9617 put_gpr_dw0(r2,
9618 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9619 mkexpr(addr2),
9620 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9621
9622 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9623 put_gpr_w1(r2 + 1,
9624 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9625 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9626 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9627
florian6820ba52012-07-26 02:01:50 +00009628 iterate();
florianb0c9a132011-09-08 15:37:39 +00009629
9630 return "clcl";
9631}
9632
florian55085f82012-11-21 00:36:55 +00009633static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009634s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9635{
9636 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9637
9638 addr1 = newTemp(Ity_I64);
9639 addr3 = newTemp(Ity_I64);
9640 addr1_load = newTemp(Ity_I64);
9641 addr3_load = newTemp(Ity_I64);
9642 len1 = newTemp(Ity_I64);
9643 len3 = newTemp(Ity_I64);
9644 single1 = newTemp(Ity_I8);
9645 single3 = newTemp(Ity_I8);
9646
9647 assign(addr1, get_gpr_dw0(r1));
9648 assign(len1, get_gpr_dw0(r1 + 1));
9649 assign(addr3, get_gpr_dw0(r3));
9650 assign(len3, get_gpr_dw0(r3 + 1));
9651
9652 /* len1 == 0 and len3 == 0? Exit */
9653 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009654 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9655 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009656
9657 /* A mux requires both ways to be possible. This is a way to prevent clcle
9658 from reading from addr1 if it should read from the pad. Since the pad
9659 has no address, just read from the instruction, we discard that anyway */
9660 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009661 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9662 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009663
9664 /* same for addr3 */
9665 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009666 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9667 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009668
9669 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009670 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9671 unop(Iop_64to8, mkexpr(pad2)),
9672 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009673
9674 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009675 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9676 unop(Iop_64to8, mkexpr(pad2)),
9677 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009678
9679 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9680 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009681 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009682
9683 /* If a length in 0 we must not change this length and the address */
9684 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009685 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9686 mkexpr(addr1),
9687 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009688
9689 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009690 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9691 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009692
9693 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009694 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9695 mkexpr(addr3),
9696 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009697
9698 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009699 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9700 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009701
florian6820ba52012-07-26 02:01:50 +00009702 iterate();
sewardj2019a972011-03-07 16:04:07 +00009703
9704 return "clcle";
9705}
floriana64c2432011-07-16 02:11:50 +00009706
florianb0bf6602012-05-05 00:01:16 +00009707
sewardj2019a972011-03-07 16:04:07 +00009708static void
9709s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9710{
florianb0bf6602012-05-05 00:01:16 +00009711 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9712}
sewardj2019a972011-03-07 16:04:07 +00009713
sewardj2019a972011-03-07 16:04:07 +00009714
florianb0bf6602012-05-05 00:01:16 +00009715static void
9716s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9717{
9718 s390_irgen_xonc(Iop_And8, length, start1, start2);
9719}
sewardj2019a972011-03-07 16:04:07 +00009720
sewardj2019a972011-03-07 16:04:07 +00009721
florianb0bf6602012-05-05 00:01:16 +00009722static void
9723s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9724{
9725 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009726}
9727
9728
9729static void
9730s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9731{
9732 IRTemp current1 = newTemp(Ity_I8);
9733 IRTemp current2 = newTemp(Ity_I8);
9734 IRTemp counter = newTemp(Ity_I64);
9735
9736 assign(counter, get_counter_dw0());
9737 put_counter_dw0(mkU64(0));
9738
9739 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9740 mkexpr(counter))));
9741 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9742 mkexpr(counter))));
9743 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9744 False);
9745
9746 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009747 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009748
9749 /* Check for end of field */
9750 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009751 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009752 put_counter_dw0(mkU64(0));
9753}
9754
9755static void
9756s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9757{
9758 IRTemp counter = newTemp(Ity_I64);
9759
9760 assign(counter, get_counter_dw0());
9761
9762 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9763 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9764
9765 /* Check for end of field */
9766 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009767 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009768 put_counter_dw0(mkU64(0));
9769}
9770
florianf87d4fb2012-05-05 02:55:24 +00009771static void
9772s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9773{
9774 IRTemp op = newTemp(Ity_I8);
9775 IRTemp op1 = newTemp(Ity_I8);
9776 IRTemp result = newTemp(Ity_I64);
9777 IRTemp counter = newTemp(Ity_I64);
9778
9779 assign(counter, get_counter_dw0());
9780
9781 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9782
9783 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9784
9785 assign(op1, load(Ity_I8, mkexpr(result)));
9786 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9787
9788 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009789 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009790 put_counter_dw0(mkU64(0));
9791}
sewardj2019a972011-03-07 16:04:07 +00009792
9793
9794static void
9795s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009796 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +00009797 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +00009798{
9799 struct SS {
9800 unsigned int op : 8;
9801 unsigned int l : 8;
9802 unsigned int b1 : 4;
9803 unsigned int d1 : 12;
9804 unsigned int b2 : 4;
9805 unsigned int d2 : 12;
9806 };
9807 union {
9808 struct SS dec;
9809 unsigned long bytes;
9810 } ss;
9811 IRTemp cond;
9812 IRDirty *d;
9813 IRTemp torun;
9814
9815 IRTemp start1 = newTemp(Ity_I64);
9816 IRTemp start2 = newTemp(Ity_I64);
9817 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9818 cond = newTemp(Ity_I1);
9819 torun = newTemp(Ity_I64);
9820
9821 assign(torun, load(Ity_I64, mkexpr(addr2)));
9822 /* Start with a check that the saved code is still correct */
9823 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9824 /* If not, save the new value */
9825 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9826 mkIRExprVec_1(mkexpr(torun)));
9827 d->guard = mkexpr(cond);
9828 stmt(IRStmt_Dirty(d));
9829
9830 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009831 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9832 mkU64(guest_IA_curr_instr)));
9833 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009834 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009835
9836 ss.bytes = last_execute_target;
9837 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9838 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9839 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9840 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9841 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9842 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9843 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009844
sewardj2019a972011-03-07 16:04:07 +00009845 last_execute_target = 0;
9846}
9847
florian55085f82012-11-21 00:36:55 +00009848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009849s390_irgen_EX(UChar r1, IRTemp addr2)
9850{
9851 switch(last_execute_target & 0xff00000000000000ULL) {
9852 case 0:
9853 {
9854 /* no code information yet */
9855 IRDirty *d;
9856
9857 /* so safe the code... */
9858 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9859 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9860 stmt(IRStmt_Dirty(d));
9861 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009862 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9863 mkU64(guest_IA_curr_instr)));
9864 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009865 restart_if(IRExpr_Const(IRConst_U1(True)));
9866
sewardj2019a972011-03-07 16:04:07 +00009867 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009868 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009869 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009870 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009871 break;
9872 }
9873
9874 case 0xd200000000000000ULL:
9875 /* special case MVC */
9876 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +00009877 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +00009878
9879 case 0xd500000000000000ULL:
9880 /* special case CLC */
9881 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +00009882 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +00009883
9884 case 0xd700000000000000ULL:
9885 /* special case XC */
9886 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +00009887 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +00009888
florianb0bf6602012-05-05 00:01:16 +00009889 case 0xd600000000000000ULL:
9890 /* special case OC */
9891 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +00009892 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +00009893
9894 case 0xd400000000000000ULL:
9895 /* special case NC */
9896 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +00009897 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +00009898
florianf87d4fb2012-05-05 02:55:24 +00009899 case 0xdc00000000000000ULL:
9900 /* special case TR */
9901 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +00009902 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +00009903
sewardj2019a972011-03-07 16:04:07 +00009904 default:
9905 {
9906 /* everything else will get a self checking prefix that also checks the
9907 register content */
9908 IRDirty *d;
9909 UChar *bytes;
9910 IRTemp cond;
9911 IRTemp orperand;
9912 IRTemp torun;
9913
9914 cond = newTemp(Ity_I1);
9915 orperand = newTemp(Ity_I64);
9916 torun = newTemp(Ity_I64);
9917
9918 if (r1 == 0)
9919 assign(orperand, mkU64(0));
9920 else
9921 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9922 /* This code is going to be translated */
9923 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9924 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9925
9926 /* Start with a check that saved code is still correct */
9927 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9928 mkU64(last_execute_target)));
9929 /* If not, save the new value */
9930 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9931 mkIRExprVec_1(mkexpr(torun)));
9932 d->guard = mkexpr(cond);
9933 stmt(IRStmt_Dirty(d));
9934
9935 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009936 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9937 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009938 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009939
9940 /* Now comes the actual translation */
9941 bytes = (UChar *) &last_execute_target;
9942 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9943 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009944 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009945 vex_printf(" which was executed by\n");
9946 /* dont make useless translations in the next execute */
9947 last_execute_target = 0;
9948 }
9949 }
9950 return "ex";
9951}
9952
florian55085f82012-11-21 00:36:55 +00009953static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009954s390_irgen_EXRL(UChar r1, UInt offset)
9955{
9956 IRTemp addr = newTemp(Ity_I64);
9957 /* we might save one round trip because we know the target */
9958 if (!last_execute_target)
9959 last_execute_target = *(ULong *)(HWord)
9960 (guest_IA_curr_instr + offset * 2UL);
9961 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9962 s390_irgen_EX(r1, addr);
9963 return "exrl";
9964}
9965
florian55085f82012-11-21 00:36:55 +00009966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009967s390_irgen_IPM(UChar r1)
9968{
9969 // As long as we dont support SPM, lets just assume 0 as program mask
9970 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9971 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9972
9973 return "ipm";
9974}
9975
9976
florian55085f82012-11-21 00:36:55 +00009977static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009978s390_irgen_SRST(UChar r1, UChar r2)
9979{
9980 IRTemp address = newTemp(Ity_I64);
9981 IRTemp next = newTemp(Ity_I64);
9982 IRTemp delim = newTemp(Ity_I8);
9983 IRTemp counter = newTemp(Ity_I64);
9984 IRTemp byte = newTemp(Ity_I8);
9985
9986 assign(address, get_gpr_dw0(r2));
9987 assign(next, get_gpr_dw0(r1));
9988
9989 assign(counter, get_counter_dw0());
9990 put_counter_dw0(mkU64(0));
9991
9992 // start = next? CC=2 and out r1 and r2 unchanged
9993 s390_cc_set(2);
9994 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009995 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009996
9997 assign(byte, load(Ity_I8, mkexpr(address)));
9998 assign(delim, get_gpr_b7(0));
9999
10000 // byte = delim? CC=1, R1=address
10001 s390_cc_set(1);
10002 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000010003 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010004
10005 // else: all equal, no end yet, loop
10006 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10007 put_gpr_dw0(r1, mkexpr(next));
10008 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010009
florian6820ba52012-07-26 02:01:50 +000010010 iterate();
sewardj2019a972011-03-07 16:04:07 +000010011
10012 return "srst";
10013}
10014
florian55085f82012-11-21 00:36:55 +000010015static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010016s390_irgen_CLST(UChar r1, UChar r2)
10017{
10018 IRTemp address1 = newTemp(Ity_I64);
10019 IRTemp address2 = newTemp(Ity_I64);
10020 IRTemp end = newTemp(Ity_I8);
10021 IRTemp counter = newTemp(Ity_I64);
10022 IRTemp byte1 = newTemp(Ity_I8);
10023 IRTemp byte2 = newTemp(Ity_I8);
10024
10025 assign(address1, get_gpr_dw0(r1));
10026 assign(address2, get_gpr_dw0(r2));
10027 assign(end, get_gpr_b7(0));
10028 assign(counter, get_counter_dw0());
10029 put_counter_dw0(mkU64(0));
10030 assign(byte1, load(Ity_I8, mkexpr(address1)));
10031 assign(byte2, load(Ity_I8, mkexpr(address2)));
10032
10033 // end in both? all equal, reset r1 and r2 to start values
10034 s390_cc_set(0);
10035 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
10036 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010037 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10038 binop(Iop_Or8,
10039 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10040 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010041
10042 put_gpr_dw0(r1, mkexpr(address1));
10043 put_gpr_dw0(r2, mkexpr(address2));
10044
10045 // End found in string1
10046 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010047 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010048
10049 // End found in string2
10050 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010051 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010052
10053 // string1 < string2
10054 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010055 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10056 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010057
10058 // string2 < string1
10059 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010060 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10061 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010062
10063 // else: all equal, no end yet, loop
10064 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10065 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10066 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010067
florian6820ba52012-07-26 02:01:50 +000010068 iterate();
sewardj2019a972011-03-07 16:04:07 +000010069
10070 return "clst";
10071}
10072
10073static void
10074s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10075{
10076 UChar reg;
10077 IRTemp addr = newTemp(Ity_I64);
10078
10079 assign(addr, mkexpr(op2addr));
10080 reg = r1;
10081 do {
10082 IRTemp old = addr;
10083
10084 reg %= 16;
10085 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10086 addr = newTemp(Ity_I64);
10087 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10088 reg++;
10089 } while (reg != (r3 + 1));
10090}
10091
florian55085f82012-11-21 00:36:55 +000010092static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010093s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10094{
10095 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10096
10097 return "lm";
10098}
10099
florian55085f82012-11-21 00:36:55 +000010100static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010101s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
10102{
10103 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10104
10105 return "lmy";
10106}
10107
florian55085f82012-11-21 00:36:55 +000010108static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010109s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
10110{
10111 UChar reg;
10112 IRTemp addr = newTemp(Ity_I64);
10113
10114 assign(addr, mkexpr(op2addr));
10115 reg = r1;
10116 do {
10117 IRTemp old = addr;
10118
10119 reg %= 16;
10120 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
10121 addr = newTemp(Ity_I64);
10122 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10123 reg++;
10124 } while (reg != (r3 + 1));
10125
10126 return "lmh";
10127}
10128
florian55085f82012-11-21 00:36:55 +000010129static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010130s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
10131{
10132 UChar reg;
10133 IRTemp addr = newTemp(Ity_I64);
10134
10135 assign(addr, mkexpr(op2addr));
10136 reg = r1;
10137 do {
10138 IRTemp old = addr;
10139
10140 reg %= 16;
10141 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
10142 addr = newTemp(Ity_I64);
10143 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10144 reg++;
10145 } while (reg != (r3 + 1));
10146
10147 return "lmg";
10148}
10149
10150static void
10151s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10152{
10153 UChar reg;
10154 IRTemp addr = newTemp(Ity_I64);
10155
10156 assign(addr, mkexpr(op2addr));
10157 reg = r1;
10158 do {
10159 IRTemp old = addr;
10160
10161 reg %= 16;
10162 store(mkexpr(addr), get_gpr_w1(reg));
10163 addr = newTemp(Ity_I64);
10164 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10165 reg++;
10166 } while( reg != (r3 + 1));
10167}
10168
florian55085f82012-11-21 00:36:55 +000010169static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010170s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
10171{
10172 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10173
10174 return "stm";
10175}
10176
florian55085f82012-11-21 00:36:55 +000010177static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010178s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
10179{
10180 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10181
10182 return "stmy";
10183}
10184
florian55085f82012-11-21 00:36:55 +000010185static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010186s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
10187{
10188 UChar reg;
10189 IRTemp addr = newTemp(Ity_I64);
10190
10191 assign(addr, mkexpr(op2addr));
10192 reg = r1;
10193 do {
10194 IRTemp old = addr;
10195
10196 reg %= 16;
10197 store(mkexpr(addr), get_gpr_w0(reg));
10198 addr = newTemp(Ity_I64);
10199 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10200 reg++;
10201 } while( reg != (r3 + 1));
10202
10203 return "stmh";
10204}
10205
florian55085f82012-11-21 00:36:55 +000010206static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010207s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
10208{
10209 UChar reg;
10210 IRTemp addr = newTemp(Ity_I64);
10211
10212 assign(addr, mkexpr(op2addr));
10213 reg = r1;
10214 do {
10215 IRTemp old = addr;
10216
10217 reg %= 16;
10218 store(mkexpr(addr), get_gpr_dw0(reg));
10219 addr = newTemp(Ity_I64);
10220 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10221 reg++;
10222 } while( reg != (r3 + 1));
10223
10224 return "stmg";
10225}
10226
10227static void
florianb0bf6602012-05-05 00:01:16 +000010228s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000010229{
10230 IRTemp old1 = newTemp(Ity_I8);
10231 IRTemp old2 = newTemp(Ity_I8);
10232 IRTemp new1 = newTemp(Ity_I8);
10233 IRTemp counter = newTemp(Ity_I32);
10234 IRTemp addr1 = newTemp(Ity_I64);
10235
10236 assign(counter, get_counter_w0());
10237
10238 assign(addr1, binop(Iop_Add64, mkexpr(start1),
10239 unop(Iop_32Uto64, mkexpr(counter))));
10240
10241 assign(old1, load(Ity_I8, mkexpr(addr1)));
10242 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10243 unop(Iop_32Uto64,mkexpr(counter)))));
10244 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
10245
10246 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000010247 if (op == Iop_Xor8) {
10248 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000010249 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
10250 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000010251 } else
10252 store(mkexpr(addr1), mkexpr(new1));
10253 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
10254 get_counter_w1()));
10255
10256 /* Check for end of field */
10257 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010258 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010259 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
10260 False);
10261 put_counter_dw0(mkU64(0));
10262}
10263
florian55085f82012-11-21 00:36:55 +000010264static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010265s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
10266{
florianb0bf6602012-05-05 00:01:16 +000010267 IRTemp len = newTemp(Ity_I32);
10268
10269 assign(len, mkU32(length));
10270 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010271
10272 return "xc";
10273}
10274
sewardjb63967e2011-03-24 08:50:04 +000010275static void
10276s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
10277{
10278 IRTemp counter = newTemp(Ity_I32);
10279 IRTemp start = newTemp(Ity_I64);
10280 IRTemp addr = newTemp(Ity_I64);
10281
10282 assign(start,
10283 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
10284
10285 if (length < 8) {
10286 UInt i;
10287
10288 for (i = 0; i <= length; ++i) {
10289 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
10290 }
10291 } else {
10292 assign(counter, get_counter_w0());
10293
10294 assign(addr, binop(Iop_Add64, mkexpr(start),
10295 unop(Iop_32Uto64, mkexpr(counter))));
10296
10297 store(mkexpr(addr), mkU8(0));
10298
10299 /* Check for end of field */
10300 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010301 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000010302
10303 /* Reset counter */
10304 put_counter_dw0(mkU64(0));
10305 }
10306
10307 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
10308
sewardj7ee97522011-05-09 21:45:04 +000010309 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000010310 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
10311}
10312
florian55085f82012-11-21 00:36:55 +000010313static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010314s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
10315{
florianb0bf6602012-05-05 00:01:16 +000010316 IRTemp len = newTemp(Ity_I32);
10317
10318 assign(len, mkU32(length));
10319 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010320
10321 return "nc";
10322}
10323
florian55085f82012-11-21 00:36:55 +000010324static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010325s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
10326{
florianb0bf6602012-05-05 00:01:16 +000010327 IRTemp len = newTemp(Ity_I32);
10328
10329 assign(len, mkU32(length));
10330 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010331
10332 return "oc";
10333}
10334
10335
florian55085f82012-11-21 00:36:55 +000010336static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010337s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
10338{
florian79e839e2012-05-05 02:20:30 +000010339 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010340
florian79e839e2012-05-05 02:20:30 +000010341 assign(len, mkU64(length));
10342 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010343
10344 return "mvc";
10345}
10346
florian55085f82012-11-21 00:36:55 +000010347static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010348s390_irgen_MVCL(UChar r1, UChar r2)
10349{
10350 IRTemp addr1 = newTemp(Ity_I64);
10351 IRTemp addr2 = newTemp(Ity_I64);
10352 IRTemp addr2_load = newTemp(Ity_I64);
10353 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10354 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10355 IRTemp len1 = newTemp(Ity_I32);
10356 IRTemp len2 = newTemp(Ity_I32);
10357 IRTemp pad = newTemp(Ity_I8);
10358 IRTemp single = newTemp(Ity_I8);
10359
10360 assign(addr1, get_gpr_dw0(r1));
10361 assign(r1p1, get_gpr_w1(r1 + 1));
10362 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10363 assign(addr2, get_gpr_dw0(r2));
10364 assign(r2p1, get_gpr_w1(r2 + 1));
10365 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10366 assign(pad, get_gpr_b4(r2 + 1));
10367
10368 /* len1 == 0 ? */
10369 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010370 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010371
10372 /* Check for destructive overlap:
10373 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
10374 s390_cc_set(3);
10375 IRTemp cond1 = newTemp(Ity_I32);
10376 assign(cond1, unop(Iop_1Uto32,
10377 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
10378 IRTemp cond2 = newTemp(Ity_I32);
10379 assign(cond2, unop(Iop_1Uto32,
10380 binop(Iop_CmpLT64U, mkexpr(addr1),
10381 binop(Iop_Add64, mkexpr(addr2),
10382 unop(Iop_32Uto64, mkexpr(len1))))));
10383 IRTemp cond3 = newTemp(Ity_I32);
10384 assign(cond3, unop(Iop_1Uto32,
10385 binop(Iop_CmpLT64U,
10386 mkexpr(addr1),
10387 binop(Iop_Add64, mkexpr(addr2),
10388 unop(Iop_32Uto64, mkexpr(len2))))));
10389
florian6820ba52012-07-26 02:01:50 +000010390 next_insn_if(binop(Iop_CmpEQ32,
10391 binop(Iop_And32,
10392 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10393 mkexpr(cond3)),
10394 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010395
10396 /* See s390_irgen_CLCL for explanation why we cannot load directly
10397 and need two steps. */
10398 assign(addr2_load,
10399 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10400 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10401 assign(single,
10402 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10403 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10404
10405 store(mkexpr(addr1), mkexpr(single));
10406
10407 /* Update addr1 and len1 */
10408 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10409 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10410
10411 /* Update addr2 and len2 */
10412 put_gpr_dw0(r2,
10413 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10414 mkexpr(addr2),
10415 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10416
10417 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10418 put_gpr_w1(r2 + 1,
10419 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10420 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10421 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10422
10423 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010424 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010425
10426 return "mvcl";
10427}
10428
10429
florian55085f82012-11-21 00:36:55 +000010430static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010431s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10432{
10433 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10434
10435 addr1 = newTemp(Ity_I64);
10436 addr3 = newTemp(Ity_I64);
10437 addr3_load = newTemp(Ity_I64);
10438 len1 = newTemp(Ity_I64);
10439 len3 = newTemp(Ity_I64);
10440 single = newTemp(Ity_I8);
10441
10442 assign(addr1, get_gpr_dw0(r1));
10443 assign(len1, get_gpr_dw0(r1 + 1));
10444 assign(addr3, get_gpr_dw0(r3));
10445 assign(len3, get_gpr_dw0(r3 + 1));
10446
10447 // len1 == 0 ?
10448 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010449 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010450
10451 /* This is a hack to prevent mvcle from reading from addr3 if it
10452 should read from the pad. Since the pad has no address, just
10453 read from the instruction, we discard that anyway */
10454 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010455 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10456 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010457
10458 assign(single,
florian6ad49522011-09-09 02:38:55 +000010459 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10460 unop(Iop_64to8, mkexpr(pad2)),
10461 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010462 store(mkexpr(addr1), mkexpr(single));
10463
10464 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10465
10466 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10467
10468 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010469 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10470 mkexpr(addr3),
10471 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010472
10473 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010474 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10475 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010476
sewardj2019a972011-03-07 16:04:07 +000010477 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010478 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010479
10480 return "mvcle";
10481}
10482
florian55085f82012-11-21 00:36:55 +000010483static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010484s390_irgen_MVST(UChar r1, UChar r2)
10485{
10486 IRTemp addr1 = newTemp(Ity_I64);
10487 IRTemp addr2 = newTemp(Ity_I64);
10488 IRTemp end = newTemp(Ity_I8);
10489 IRTemp byte = newTemp(Ity_I8);
10490 IRTemp counter = newTemp(Ity_I64);
10491
10492 assign(addr1, get_gpr_dw0(r1));
10493 assign(addr2, get_gpr_dw0(r2));
10494 assign(counter, get_counter_dw0());
10495 assign(end, get_gpr_b7(0));
10496 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10497 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10498
10499 // We use unlimited as cpu-determined number
10500 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010501 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010502
10503 // and always set cc=1 at the end + update r1
10504 s390_cc_set(1);
10505 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10506 put_counter_dw0(mkU64(0));
10507
10508 return "mvst";
10509}
10510
10511static void
10512s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10513{
10514 IRTemp op1 = newTemp(Ity_I64);
10515 IRTemp result = newTemp(Ity_I64);
10516
10517 assign(op1, binop(Iop_32HLto64,
10518 get_gpr_w1(r1), // high 32 bits
10519 get_gpr_w1(r1 + 1))); // low 32 bits
10520 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10521 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10522 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10523}
10524
10525static void
10526s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10527{
10528 IRTemp op1 = newTemp(Ity_I128);
10529 IRTemp result = newTemp(Ity_I128);
10530
10531 assign(op1, binop(Iop_64HLto128,
10532 get_gpr_dw0(r1), // high 64 bits
10533 get_gpr_dw0(r1 + 1))); // low 64 bits
10534 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10535 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10536 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10537}
10538
10539static void
10540s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10541{
10542 IRTemp op1 = newTemp(Ity_I64);
10543 IRTemp result = newTemp(Ity_I128);
10544
10545 assign(op1, get_gpr_dw0(r1 + 1));
10546 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10547 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10548 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10549}
10550
florian55085f82012-11-21 00:36:55 +000010551static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010552s390_irgen_DR(UChar r1, UChar r2)
10553{
10554 IRTemp op2 = newTemp(Ity_I32);
10555
10556 assign(op2, get_gpr_w1(r2));
10557
10558 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10559
10560 return "dr";
10561}
10562
florian55085f82012-11-21 00:36:55 +000010563static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010564s390_irgen_D(UChar r1, IRTemp op2addr)
10565{
10566 IRTemp op2 = newTemp(Ity_I32);
10567
10568 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10569
10570 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10571
10572 return "d";
10573}
10574
florian55085f82012-11-21 00:36:55 +000010575static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010576s390_irgen_DLR(UChar r1, UChar r2)
10577{
10578 IRTemp op2 = newTemp(Ity_I32);
10579
10580 assign(op2, get_gpr_w1(r2));
10581
10582 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10583
florian7cd1cde2012-08-16 23:57:43 +000010584 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010585}
10586
florian55085f82012-11-21 00:36:55 +000010587static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010588s390_irgen_DL(UChar r1, IRTemp op2addr)
10589{
10590 IRTemp op2 = newTemp(Ity_I32);
10591
10592 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10593
10594 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10595
10596 return "dl";
10597}
10598
florian55085f82012-11-21 00:36:55 +000010599static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010600s390_irgen_DLG(UChar r1, IRTemp op2addr)
10601{
10602 IRTemp op2 = newTemp(Ity_I64);
10603
10604 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10605
10606 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10607
10608 return "dlg";
10609}
10610
florian55085f82012-11-21 00:36:55 +000010611static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010612s390_irgen_DLGR(UChar r1, UChar r2)
10613{
10614 IRTemp op2 = newTemp(Ity_I64);
10615
10616 assign(op2, get_gpr_dw0(r2));
10617
10618 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10619
10620 return "dlgr";
10621}
10622
florian55085f82012-11-21 00:36:55 +000010623static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010624s390_irgen_DSGR(UChar r1, UChar r2)
10625{
10626 IRTemp op2 = newTemp(Ity_I64);
10627
10628 assign(op2, get_gpr_dw0(r2));
10629
10630 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10631
10632 return "dsgr";
10633}
10634
florian55085f82012-11-21 00:36:55 +000010635static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010636s390_irgen_DSG(UChar r1, IRTemp op2addr)
10637{
10638 IRTemp op2 = newTemp(Ity_I64);
10639
10640 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10641
10642 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10643
10644 return "dsg";
10645}
10646
florian55085f82012-11-21 00:36:55 +000010647static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010648s390_irgen_DSGFR(UChar r1, UChar r2)
10649{
10650 IRTemp op2 = newTemp(Ity_I64);
10651
10652 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10653
10654 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10655
10656 return "dsgfr";
10657}
10658
florian55085f82012-11-21 00:36:55 +000010659static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010660s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10661{
10662 IRTemp op2 = newTemp(Ity_I64);
10663
10664 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10665
10666 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10667
10668 return "dsgf";
10669}
10670
10671static void
10672s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10673{
10674 UChar reg;
10675 IRTemp addr = newTemp(Ity_I64);
10676
10677 assign(addr, mkexpr(op2addr));
10678 reg = r1;
10679 do {
10680 IRTemp old = addr;
10681
10682 reg %= 16;
10683 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10684 addr = newTemp(Ity_I64);
10685 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10686 reg++;
10687 } while (reg != (r3 + 1));
10688}
10689
florian55085f82012-11-21 00:36:55 +000010690static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010691s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10692{
10693 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10694
10695 return "lam";
10696}
10697
florian55085f82012-11-21 00:36:55 +000010698static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010699s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10700{
10701 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10702
10703 return "lamy";
10704}
10705
10706static void
10707s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10708{
10709 UChar reg;
10710 IRTemp addr = newTemp(Ity_I64);
10711
10712 assign(addr, mkexpr(op2addr));
10713 reg = r1;
10714 do {
10715 IRTemp old = addr;
10716
10717 reg %= 16;
10718 store(mkexpr(addr), get_ar_w0(reg));
10719 addr = newTemp(Ity_I64);
10720 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10721 reg++;
10722 } while (reg != (r3 + 1));
10723}
10724
florian55085f82012-11-21 00:36:55 +000010725static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010726s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10727{
10728 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10729
10730 return "stam";
10731}
10732
florian55085f82012-11-21 00:36:55 +000010733static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010734s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10735{
10736 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10737
10738 return "stamy";
10739}
10740
10741
10742/* Implementation for 32-bit compare-and-swap */
10743static void
10744s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10745{
10746 IRCAS *cas;
10747 IRTemp op1 = newTemp(Ity_I32);
10748 IRTemp old_mem = newTemp(Ity_I32);
10749 IRTemp op3 = newTemp(Ity_I32);
10750 IRTemp result = newTemp(Ity_I32);
10751 IRTemp nequal = newTemp(Ity_I1);
10752
10753 assign(op1, get_gpr_w1(r1));
10754 assign(op3, get_gpr_w1(r3));
10755
10756 /* The first and second operands are compared. If they are equal,
10757 the third operand is stored at the second- operand location. */
10758 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10759 Iend_BE, mkexpr(op2addr),
10760 NULL, mkexpr(op1), /* expected value */
10761 NULL, mkexpr(op3) /* new value */);
10762 stmt(IRStmt_CAS(cas));
10763
10764 /* Set CC. Operands compared equal -> 0, else 1. */
10765 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10766 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10767
10768 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10769 Otherwise, store the old_value from memory in r1 and yield. */
10770 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10771 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010772 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010773}
10774
florian55085f82012-11-21 00:36:55 +000010775static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010776s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10777{
10778 s390_irgen_cas_32(r1, r3, op2addr);
10779
10780 return "cs";
10781}
10782
florian55085f82012-11-21 00:36:55 +000010783static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010784s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10785{
10786 s390_irgen_cas_32(r1, r3, op2addr);
10787
10788 return "csy";
10789}
10790
florian55085f82012-11-21 00:36:55 +000010791static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010792s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10793{
10794 IRCAS *cas;
10795 IRTemp op1 = newTemp(Ity_I64);
10796 IRTemp old_mem = newTemp(Ity_I64);
10797 IRTemp op3 = newTemp(Ity_I64);
10798 IRTemp result = newTemp(Ity_I64);
10799 IRTemp nequal = newTemp(Ity_I1);
10800
10801 assign(op1, get_gpr_dw0(r1));
10802 assign(op3, get_gpr_dw0(r3));
10803
10804 /* The first and second operands are compared. If they are equal,
10805 the third operand is stored at the second- operand location. */
10806 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10807 Iend_BE, mkexpr(op2addr),
10808 NULL, mkexpr(op1), /* expected value */
10809 NULL, mkexpr(op3) /* new value */);
10810 stmt(IRStmt_CAS(cas));
10811
10812 /* Set CC. Operands compared equal -> 0, else 1. */
10813 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10814 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10815
10816 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10817 Otherwise, store the old_value from memory in r1 and yield. */
10818 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10819 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010820 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010821
10822 return "csg";
10823}
10824
florian448cbba2012-06-06 02:26:01 +000010825/* Implementation for 32-bit compare-double-and-swap */
10826static void
10827s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10828{
10829 IRCAS *cas;
10830 IRTemp op1_high = newTemp(Ity_I32);
10831 IRTemp op1_low = newTemp(Ity_I32);
10832 IRTemp old_mem_high = newTemp(Ity_I32);
10833 IRTemp old_mem_low = newTemp(Ity_I32);
10834 IRTemp op3_high = newTemp(Ity_I32);
10835 IRTemp op3_low = newTemp(Ity_I32);
10836 IRTemp result = newTemp(Ity_I32);
10837 IRTemp nequal = newTemp(Ity_I1);
10838
10839 assign(op1_high, get_gpr_w1(r1));
10840 assign(op1_low, get_gpr_w1(r1+1));
10841 assign(op3_high, get_gpr_w1(r3));
10842 assign(op3_low, get_gpr_w1(r3+1));
10843
10844 /* The first and second operands are compared. If they are equal,
10845 the third operand is stored at the second-operand location. */
10846 cas = mkIRCAS(old_mem_high, old_mem_low,
10847 Iend_BE, mkexpr(op2addr),
10848 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10849 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10850 stmt(IRStmt_CAS(cas));
10851
10852 /* Set CC. Operands compared equal -> 0, else 1. */
10853 assign(result, unop(Iop_1Uto32,
10854 binop(Iop_CmpNE32,
10855 binop(Iop_Or32,
10856 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10857 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10858 mkU32(0))));
10859
10860 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10861
10862 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10863 Otherwise, store the old_value from memory in r1 and yield. */
10864 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10865 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10866 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010867 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010868}
10869
florian55085f82012-11-21 00:36:55 +000010870static const HChar *
florian448cbba2012-06-06 02:26:01 +000010871s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10872{
10873 s390_irgen_cdas_32(r1, r3, op2addr);
10874
10875 return "cds";
10876}
10877
florian55085f82012-11-21 00:36:55 +000010878static const HChar *
florian448cbba2012-06-06 02:26:01 +000010879s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10880{
10881 s390_irgen_cdas_32(r1, r3, op2addr);
10882
10883 return "cdsy";
10884}
10885
florian55085f82012-11-21 00:36:55 +000010886static const HChar *
florian448cbba2012-06-06 02:26:01 +000010887s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10888{
10889 IRCAS *cas;
10890 IRTemp op1_high = newTemp(Ity_I64);
10891 IRTemp op1_low = newTemp(Ity_I64);
10892 IRTemp old_mem_high = newTemp(Ity_I64);
10893 IRTemp old_mem_low = newTemp(Ity_I64);
10894 IRTemp op3_high = newTemp(Ity_I64);
10895 IRTemp op3_low = newTemp(Ity_I64);
10896 IRTemp result = newTemp(Ity_I64);
10897 IRTemp nequal = newTemp(Ity_I1);
10898
10899 assign(op1_high, get_gpr_dw0(r1));
10900 assign(op1_low, get_gpr_dw0(r1+1));
10901 assign(op3_high, get_gpr_dw0(r3));
10902 assign(op3_low, get_gpr_dw0(r3+1));
10903
10904 /* The first and second operands are compared. If they are equal,
10905 the third operand is stored at the second-operand location. */
10906 cas = mkIRCAS(old_mem_high, old_mem_low,
10907 Iend_BE, mkexpr(op2addr),
10908 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10909 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10910 stmt(IRStmt_CAS(cas));
10911
10912 /* Set CC. Operands compared equal -> 0, else 1. */
10913 assign(result, unop(Iop_1Uto64,
10914 binop(Iop_CmpNE64,
10915 binop(Iop_Or64,
10916 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10917 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10918 mkU64(0))));
10919
10920 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10921
10922 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10923 Otherwise, store the old_value from memory in r1 and yield. */
10924 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10925 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10926 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010927 yield_if(mkexpr(nequal));
10928
florian448cbba2012-06-06 02:26:01 +000010929 return "cdsg";
10930}
10931
sewardj2019a972011-03-07 16:04:07 +000010932
10933/* Binary floating point */
10934
florian55085f82012-11-21 00:36:55 +000010935static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010936s390_irgen_AXBR(UChar r1, UChar r2)
10937{
10938 IRTemp op1 = newTemp(Ity_F128);
10939 IRTemp op2 = newTemp(Ity_F128);
10940 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010941 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010942
10943 assign(op1, get_fpr_pair(r1));
10944 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010945 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010946 mkexpr(op2)));
10947 put_fpr_pair(r1, mkexpr(result));
10948
10949 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10950
10951 return "axbr";
10952}
10953
florian55085f82012-11-21 00:36:55 +000010954static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010955s390_irgen_CEBR(UChar r1, UChar r2)
10956{
10957 IRTemp op1 = newTemp(Ity_F32);
10958 IRTemp op2 = newTemp(Ity_F32);
10959 IRTemp cc_vex = newTemp(Ity_I32);
10960 IRTemp cc_s390 = newTemp(Ity_I32);
10961
10962 assign(op1, get_fpr_w0(r1));
10963 assign(op2, get_fpr_w0(r2));
10964 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10965
florian2d3d87f2012-12-21 21:05:17 +000010966 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000010967 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10968
10969 return "cebr";
10970}
10971
florian55085f82012-11-21 00:36:55 +000010972static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010973s390_irgen_CDBR(UChar r1, UChar r2)
10974{
10975 IRTemp op1 = newTemp(Ity_F64);
10976 IRTemp op2 = newTemp(Ity_F64);
10977 IRTemp cc_vex = newTemp(Ity_I32);
10978 IRTemp cc_s390 = newTemp(Ity_I32);
10979
10980 assign(op1, get_fpr_dw0(r1));
10981 assign(op2, get_fpr_dw0(r2));
10982 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10983
florian2d3d87f2012-12-21 21:05:17 +000010984 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000010985 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10986
10987 return "cdbr";
10988}
10989
florian55085f82012-11-21 00:36:55 +000010990static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010991s390_irgen_CXBR(UChar r1, UChar r2)
10992{
10993 IRTemp op1 = newTemp(Ity_F128);
10994 IRTemp op2 = newTemp(Ity_F128);
10995 IRTemp cc_vex = newTemp(Ity_I32);
10996 IRTemp cc_s390 = newTemp(Ity_I32);
10997
10998 assign(op1, get_fpr_pair(r1));
10999 assign(op2, get_fpr_pair(r2));
11000 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
11001
florian2d3d87f2012-12-21 21:05:17 +000011002 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011003 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11004
11005 return "cxbr";
11006}
11007
florian55085f82012-11-21 00:36:55 +000011008static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011009s390_irgen_CEB(UChar r1, IRTemp op2addr)
11010{
11011 IRTemp op1 = newTemp(Ity_F32);
11012 IRTemp op2 = newTemp(Ity_F32);
11013 IRTemp cc_vex = newTemp(Ity_I32);
11014 IRTemp cc_s390 = newTemp(Ity_I32);
11015
11016 assign(op1, get_fpr_w0(r1));
11017 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11018 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11019
florian2d3d87f2012-12-21 21:05:17 +000011020 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011021 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11022
11023 return "ceb";
11024}
11025
florian55085f82012-11-21 00:36:55 +000011026static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011027s390_irgen_CDB(UChar r1, IRTemp op2addr)
11028{
11029 IRTemp op1 = newTemp(Ity_F64);
11030 IRTemp op2 = newTemp(Ity_F64);
11031 IRTemp cc_vex = newTemp(Ity_I32);
11032 IRTemp cc_s390 = newTemp(Ity_I32);
11033
11034 assign(op1, get_fpr_dw0(r1));
11035 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11036 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11037
florian2d3d87f2012-12-21 21:05:17 +000011038 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011039 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11040
11041 return "cdb";
11042}
11043
florian55085f82012-11-21 00:36:55 +000011044static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011045s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11046 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011047{
11048 IRTemp op2 = newTemp(Ity_I32);
11049
11050 assign(op2, get_gpr_w1(r2));
11051 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11052
11053 return "cxfbr";
11054}
11055
florian55085f82012-11-21 00:36:55 +000011056static const HChar *
floriand2129202012-09-01 20:01:39 +000011057s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11058 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011059{
floriane75dafa2012-09-01 17:54:09 +000011060 if (! s390_host_has_fpext) {
11061 emulation_failure(EmFail_S390X_fpext);
11062 } else {
11063 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011064
floriane75dafa2012-09-01 17:54:09 +000011065 assign(op2, get_gpr_w1(r2));
11066 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11067 }
florian1c8f7ff2012-09-01 00:12:11 +000011068 return "cxlfbr";
11069}
11070
11071
florian55085f82012-11-21 00:36:55 +000011072static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011073s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11074 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011075{
11076 IRTemp op2 = newTemp(Ity_I64);
11077
11078 assign(op2, get_gpr_dw0(r2));
11079 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11080
11081 return "cxgbr";
11082}
11083
florian55085f82012-11-21 00:36:55 +000011084static const HChar *
floriand2129202012-09-01 20:01:39 +000011085s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11086 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011087{
floriane75dafa2012-09-01 17:54:09 +000011088 if (! s390_host_has_fpext) {
11089 emulation_failure(EmFail_S390X_fpext);
11090 } else {
11091 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011092
floriane75dafa2012-09-01 17:54:09 +000011093 assign(op2, get_gpr_dw0(r2));
11094 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11095 }
florian1c8f7ff2012-09-01 00:12:11 +000011096 return "cxlgbr";
11097}
11098
florian55085f82012-11-21 00:36:55 +000011099static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011100s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11101 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011102{
11103 IRTemp op = newTemp(Ity_F128);
11104 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011105 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011106
11107 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011108 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011109 mkexpr(op)));
11110 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011111 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011112
11113 return "cfxbr";
11114}
11115
florian55085f82012-11-21 00:36:55 +000011116static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011117s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
11118 UChar r1, UChar r2)
11119{
floriane75dafa2012-09-01 17:54:09 +000011120 if (! s390_host_has_fpext) {
11121 emulation_failure(EmFail_S390X_fpext);
11122 } else {
11123 IRTemp op = newTemp(Ity_F128);
11124 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011125 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011126
floriane75dafa2012-09-01 17:54:09 +000011127 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011128 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011129 mkexpr(op)));
11130 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011131 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011132 }
florian1c8f7ff2012-09-01 00:12:11 +000011133 return "clfxbr";
11134}
11135
11136
florian55085f82012-11-21 00:36:55 +000011137static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011138s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
11139 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011140{
11141 IRTemp op = newTemp(Ity_F128);
11142 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011143 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011144
11145 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011146 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011147 mkexpr(op)));
11148 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011149 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011150
11151 return "cgxbr";
11152}
11153
florian55085f82012-11-21 00:36:55 +000011154static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011155s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
11156 UChar r1, UChar r2)
11157{
floriane75dafa2012-09-01 17:54:09 +000011158 if (! s390_host_has_fpext) {
11159 emulation_failure(EmFail_S390X_fpext);
11160 } else {
11161 IRTemp op = newTemp(Ity_F128);
11162 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011163 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011164
floriane75dafa2012-09-01 17:54:09 +000011165 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011166 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011167 mkexpr(op)));
11168 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011169 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
11170 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011171 }
florian1c8f7ff2012-09-01 00:12:11 +000011172 return "clgxbr";
11173}
11174
florian55085f82012-11-21 00:36:55 +000011175static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011176s390_irgen_DXBR(UChar r1, UChar r2)
11177{
11178 IRTemp op1 = newTemp(Ity_F128);
11179 IRTemp op2 = newTemp(Ity_F128);
11180 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011181 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011182
11183 assign(op1, get_fpr_pair(r1));
11184 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011185 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011186 mkexpr(op2)));
11187 put_fpr_pair(r1, mkexpr(result));
11188
11189 return "dxbr";
11190}
11191
florian55085f82012-11-21 00:36:55 +000011192static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011193s390_irgen_LTXBR(UChar r1, UChar r2)
11194{
11195 IRTemp result = newTemp(Ity_F128);
11196
11197 assign(result, get_fpr_pair(r2));
11198 put_fpr_pair(r1, mkexpr(result));
11199 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11200
11201 return "ltxbr";
11202}
11203
florian55085f82012-11-21 00:36:55 +000011204static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011205s390_irgen_LCXBR(UChar r1, UChar r2)
11206{
11207 IRTemp result = newTemp(Ity_F128);
11208
11209 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
11210 put_fpr_pair(r1, mkexpr(result));
11211 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11212
11213 return "lcxbr";
11214}
11215
florian55085f82012-11-21 00:36:55 +000011216static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011217s390_irgen_LXDBR(UChar r1, UChar r2)
11218{
11219 IRTemp op = newTemp(Ity_F64);
11220
11221 assign(op, get_fpr_dw0(r2));
11222 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11223
11224 return "lxdbr";
11225}
11226
florian55085f82012-11-21 00:36:55 +000011227static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011228s390_irgen_LXEBR(UChar r1, UChar r2)
11229{
11230 IRTemp op = newTemp(Ity_F32);
11231
11232 assign(op, get_fpr_w0(r2));
11233 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11234
11235 return "lxebr";
11236}
11237
florian55085f82012-11-21 00:36:55 +000011238static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011239s390_irgen_LXDB(UChar r1, IRTemp op2addr)
11240{
11241 IRTemp op = newTemp(Ity_F64);
11242
11243 assign(op, load(Ity_F64, mkexpr(op2addr)));
11244 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11245
11246 return "lxdb";
11247}
11248
florian55085f82012-11-21 00:36:55 +000011249static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011250s390_irgen_LXEB(UChar r1, IRTemp op2addr)
11251{
11252 IRTemp op = newTemp(Ity_F32);
11253
11254 assign(op, load(Ity_F32, mkexpr(op2addr)));
11255 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11256
11257 return "lxeb";
11258}
11259
florian55085f82012-11-21 00:36:55 +000011260static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011261s390_irgen_LNEBR(UChar r1, UChar r2)
11262{
11263 IRTemp result = newTemp(Ity_F32);
11264
11265 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
11266 put_fpr_w0(r1, mkexpr(result));
11267 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11268
11269 return "lnebr";
11270}
11271
florian55085f82012-11-21 00:36:55 +000011272static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011273s390_irgen_LNDBR(UChar r1, UChar r2)
11274{
11275 IRTemp result = newTemp(Ity_F64);
11276
11277 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11278 put_fpr_dw0(r1, mkexpr(result));
11279 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11280
11281 return "lndbr";
11282}
11283
florian55085f82012-11-21 00:36:55 +000011284static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011285s390_irgen_LNXBR(UChar r1, UChar r2)
11286{
11287 IRTemp result = newTemp(Ity_F128);
11288
11289 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
11290 put_fpr_pair(r1, mkexpr(result));
11291 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11292
11293 return "lnxbr";
11294}
11295
florian55085f82012-11-21 00:36:55 +000011296static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011297s390_irgen_LPEBR(UChar r1, UChar r2)
11298{
11299 IRTemp result = newTemp(Ity_F32);
11300
11301 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
11302 put_fpr_w0(r1, mkexpr(result));
11303 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11304
11305 return "lpebr";
11306}
11307
florian55085f82012-11-21 00:36:55 +000011308static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011309s390_irgen_LPDBR(UChar r1, UChar r2)
11310{
11311 IRTemp result = newTemp(Ity_F64);
11312
11313 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11314 put_fpr_dw0(r1, mkexpr(result));
11315 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11316
11317 return "lpdbr";
11318}
11319
florian55085f82012-11-21 00:36:55 +000011320static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011321s390_irgen_LPXBR(UChar r1, UChar r2)
11322{
11323 IRTemp result = newTemp(Ity_F128);
11324
11325 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
11326 put_fpr_pair(r1, mkexpr(result));
11327 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11328
11329 return "lpxbr";
11330}
11331
florian55085f82012-11-21 00:36:55 +000011332static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011333s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
11334 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011335{
florian125e20d2012-10-07 15:42:37 +000011336 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011337 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011338 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011339 }
sewardj2019a972011-03-07 16:04:07 +000011340 IRTemp result = newTemp(Ity_F64);
11341
floriandb4fcaa2012-09-05 19:54:08 +000011342 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011343 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011344 put_fpr_dw0(r1, mkexpr(result));
11345
11346 return "ldxbr";
11347}
11348
florian55085f82012-11-21 00:36:55 +000011349static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011350s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11351 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011352{
florian125e20d2012-10-07 15:42:37 +000011353 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011354 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011355 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011356 }
sewardj2019a972011-03-07 16:04:07 +000011357 IRTemp result = newTemp(Ity_F32);
11358
floriandb4fcaa2012-09-05 19:54:08 +000011359 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011360 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011361 put_fpr_w0(r1, mkexpr(result));
11362
11363 return "lexbr";
11364}
11365
florian55085f82012-11-21 00:36:55 +000011366static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011367s390_irgen_MXBR(UChar r1, UChar r2)
11368{
11369 IRTemp op1 = newTemp(Ity_F128);
11370 IRTemp op2 = newTemp(Ity_F128);
11371 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011372 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011373
11374 assign(op1, get_fpr_pair(r1));
11375 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011376 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011377 mkexpr(op2)));
11378 put_fpr_pair(r1, mkexpr(result));
11379
11380 return "mxbr";
11381}
11382
florian55085f82012-11-21 00:36:55 +000011383static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011384s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11385{
florian125e20d2012-10-07 15:42:37 +000011386 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011387
floriandb4fcaa2012-09-05 19:54:08 +000011388 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011389 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011390
11391 return "maebr";
11392}
11393
florian55085f82012-11-21 00:36:55 +000011394static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011395s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11396{
florian125e20d2012-10-07 15:42:37 +000011397 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011398
floriandb4fcaa2012-09-05 19:54:08 +000011399 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011400 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011401
11402 return "madbr";
11403}
11404
florian55085f82012-11-21 00:36:55 +000011405static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011406s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11407{
11408 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011409 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011410
floriandb4fcaa2012-09-05 19:54:08 +000011411 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011412 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011413
11414 return "maeb";
11415}
11416
florian55085f82012-11-21 00:36:55 +000011417static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011418s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11419{
11420 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011421 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011422
floriandb4fcaa2012-09-05 19:54:08 +000011423 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011424 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011425
11426 return "madb";
11427}
11428
florian55085f82012-11-21 00:36:55 +000011429static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011430s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11431{
florian125e20d2012-10-07 15:42:37 +000011432 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011433
floriandb4fcaa2012-09-05 19:54:08 +000011434 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011435 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011436
11437 return "msebr";
11438}
11439
florian55085f82012-11-21 00:36:55 +000011440static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011441s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11442{
florian125e20d2012-10-07 15:42:37 +000011443 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011444
floriandb4fcaa2012-09-05 19:54:08 +000011445 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011446 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011447
11448 return "msdbr";
11449}
11450
florian55085f82012-11-21 00:36:55 +000011451static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011452s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11453{
11454 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011455 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011456
floriandb4fcaa2012-09-05 19:54:08 +000011457 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011458 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011459
11460 return "mseb";
11461}
11462
florian55085f82012-11-21 00:36:55 +000011463static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011464s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11465{
11466 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011467 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011468
floriandb4fcaa2012-09-05 19:54:08 +000011469 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011470 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011471
11472 return "msdb";
11473}
11474
florian55085f82012-11-21 00:36:55 +000011475static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011476s390_irgen_SQEBR(UChar r1, UChar r2)
11477{
11478 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011479 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011480
floriandb4fcaa2012-09-05 19:54:08 +000011481 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011482 put_fpr_w0(r1, mkexpr(result));
11483
11484 return "sqebr";
11485}
11486
florian55085f82012-11-21 00:36:55 +000011487static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011488s390_irgen_SQDBR(UChar r1, UChar r2)
11489{
11490 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011491 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011492
floriandb4fcaa2012-09-05 19:54:08 +000011493 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011494 put_fpr_dw0(r1, mkexpr(result));
11495
11496 return "sqdbr";
11497}
11498
florian55085f82012-11-21 00:36:55 +000011499static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011500s390_irgen_SQXBR(UChar r1, UChar r2)
11501{
11502 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011503 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011504
floriandb4fcaa2012-09-05 19:54:08 +000011505 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11506 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011507 put_fpr_pair(r1, mkexpr(result));
11508
11509 return "sqxbr";
11510}
11511
florian55085f82012-11-21 00:36:55 +000011512static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011513s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11514{
11515 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011516 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011517
11518 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011519 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011520
11521 return "sqeb";
11522}
11523
florian55085f82012-11-21 00:36:55 +000011524static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011525s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11526{
11527 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011528 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011529
11530 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011531 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011532
11533 return "sqdb";
11534}
11535
florian55085f82012-11-21 00:36:55 +000011536static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011537s390_irgen_SXBR(UChar r1, UChar r2)
11538{
11539 IRTemp op1 = newTemp(Ity_F128);
11540 IRTemp op2 = newTemp(Ity_F128);
11541 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011542 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011543
11544 assign(op1, get_fpr_pair(r1));
11545 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011546 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011547 mkexpr(op2)));
11548 put_fpr_pair(r1, mkexpr(result));
11549 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11550
11551 return "sxbr";
11552}
11553
florian55085f82012-11-21 00:36:55 +000011554static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011555s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11556{
11557 IRTemp value = newTemp(Ity_F32);
11558
11559 assign(value, get_fpr_w0(r1));
11560
11561 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11562
11563 return "tceb";
11564}
11565
florian55085f82012-11-21 00:36:55 +000011566static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011567s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11568{
11569 IRTemp value = newTemp(Ity_F64);
11570
11571 assign(value, get_fpr_dw0(r1));
11572
11573 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11574
11575 return "tcdb";
11576}
11577
florian55085f82012-11-21 00:36:55 +000011578static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011579s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11580{
11581 IRTemp value = newTemp(Ity_F128);
11582
11583 assign(value, get_fpr_pair(r1));
11584
11585 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11586
11587 return "tcxb";
11588}
11589
florian55085f82012-11-21 00:36:55 +000011590static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011591s390_irgen_LCDFR(UChar r1, UChar r2)
11592{
11593 IRTemp result = newTemp(Ity_F64);
11594
11595 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11596 put_fpr_dw0(r1, mkexpr(result));
11597
11598 return "lcdfr";
11599}
11600
florian55085f82012-11-21 00:36:55 +000011601static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011602s390_irgen_LNDFR(UChar r1, UChar r2)
11603{
11604 IRTemp result = newTemp(Ity_F64);
11605
11606 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11607 put_fpr_dw0(r1, mkexpr(result));
11608
11609 return "lndfr";
11610}
11611
florian55085f82012-11-21 00:36:55 +000011612static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011613s390_irgen_LPDFR(UChar r1, UChar r2)
11614{
11615 IRTemp result = newTemp(Ity_F64);
11616
11617 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11618 put_fpr_dw0(r1, mkexpr(result));
11619
11620 return "lpdfr";
11621}
11622
florian55085f82012-11-21 00:36:55 +000011623static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011624s390_irgen_LDGR(UChar r1, UChar r2)
11625{
11626 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11627
11628 return "ldgr";
11629}
11630
florian55085f82012-11-21 00:36:55 +000011631static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011632s390_irgen_LGDR(UChar r1, UChar r2)
11633{
11634 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11635
11636 return "lgdr";
11637}
11638
11639
florian55085f82012-11-21 00:36:55 +000011640static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011641s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11642{
11643 IRTemp sign = newTemp(Ity_I64);
11644 IRTemp value = newTemp(Ity_I64);
11645
11646 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11647 mkU64(1ULL << 63)));
11648 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11649 mkU64((1ULL << 63) - 1)));
11650 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11651 mkexpr(sign))));
11652
11653 return "cpsdr";
11654}
11655
11656
sewardj2019a972011-03-07 16:04:07 +000011657static IRExpr *
11658s390_call_cvb(IRExpr *in)
11659{
11660 IRExpr **args, *call;
11661
11662 args = mkIRExprVec_1(in);
11663 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11664 "s390_do_cvb", &s390_do_cvb, args);
11665
11666 /* Nothing is excluded from definedness checking. */
11667 call->Iex.CCall.cee->mcx_mask = 0;
11668
11669 return call;
11670}
11671
florian55085f82012-11-21 00:36:55 +000011672static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011673s390_irgen_CVB(UChar r1, IRTemp op2addr)
11674{
11675 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11676
11677 return "cvb";
11678}
11679
florian55085f82012-11-21 00:36:55 +000011680static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011681s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11682{
11683 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11684
11685 return "cvby";
11686}
11687
11688
sewardj2019a972011-03-07 16:04:07 +000011689static IRExpr *
11690s390_call_cvd(IRExpr *in)
11691{
11692 IRExpr **args, *call;
11693
11694 args = mkIRExprVec_1(in);
11695 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11696 "s390_do_cvd", &s390_do_cvd, args);
11697
11698 /* Nothing is excluded from definedness checking. */
11699 call->Iex.CCall.cee->mcx_mask = 0;
11700
11701 return call;
11702}
11703
florian55085f82012-11-21 00:36:55 +000011704static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011705s390_irgen_CVD(UChar r1, IRTemp op2addr)
11706{
florian11b8ee82012-08-06 13:35:33 +000011707 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011708
11709 return "cvd";
11710}
11711
florian55085f82012-11-21 00:36:55 +000011712static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011713s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11714{
11715 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11716
11717 return "cvdy";
11718}
11719
florian55085f82012-11-21 00:36:55 +000011720static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011721s390_irgen_FLOGR(UChar r1, UChar r2)
11722{
11723 IRTemp input = newTemp(Ity_I64);
11724 IRTemp not_zero = newTemp(Ity_I64);
11725 IRTemp tmpnum = newTemp(Ity_I64);
11726 IRTemp num = newTemp(Ity_I64);
11727 IRTemp shift_amount = newTemp(Ity_I8);
11728
11729 /* We use the "count leading zeroes" operator because the number of
11730 leading zeroes is identical with the bit position of the first '1' bit.
11731 However, that operator does not work when the input value is zero.
11732 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11733 the modified value. If input == 0, then the result is 64. Otherwise,
11734 the result of Clz64 is what we want. */
11735
11736 assign(input, get_gpr_dw0(r2));
11737 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11738 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11739
11740 /* num = (input == 0) ? 64 : tmpnum */
11741 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11742 /* == 0 */ mkU64(64),
11743 /* != 0 */ mkexpr(tmpnum)));
11744
11745 put_gpr_dw0(r1, mkexpr(num));
11746
11747 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11748 is to first shift the input value by NUM + 1 bits to the left which
11749 causes the leftmost '1' bit to disappear. Then we shift logically to
11750 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11751 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11752 the width of the value-to-be-shifted, we need to special case
11753 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11754 For both such INPUT values the result will be 0. */
11755
11756 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11757 mkU64(1))));
11758
11759 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011760 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11761 /* == 0 || == 1*/ mkU64(0),
11762 /* otherwise */
11763 binop(Iop_Shr64,
11764 binop(Iop_Shl64, mkexpr(input),
11765 mkexpr(shift_amount)),
11766 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011767
11768 /* Compare the original value as an unsigned integer with 0. */
11769 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11770 mktemp(Ity_I64, mkU64(0)), False);
11771
11772 return "flogr";
11773}
11774
florian55085f82012-11-21 00:36:55 +000011775static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011776s390_irgen_STCK(IRTemp op2addr)
11777{
11778 IRDirty *d;
11779 IRTemp cc = newTemp(Ity_I64);
11780
11781 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11782 &s390x_dirtyhelper_STCK,
11783 mkIRExprVec_1(mkexpr(op2addr)));
11784 d->mFx = Ifx_Write;
11785 d->mAddr = mkexpr(op2addr);
11786 d->mSize = 8;
11787 stmt(IRStmt_Dirty(d));
11788 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11789 mkexpr(cc), mkU64(0), mkU64(0));
11790 return "stck";
11791}
11792
florian55085f82012-11-21 00:36:55 +000011793static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011794s390_irgen_STCKF(IRTemp op2addr)
11795{
florianc5c669b2012-08-26 14:32:28 +000011796 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011797 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011798 } else {
11799 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011800
florianc5c669b2012-08-26 14:32:28 +000011801 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11802 &s390x_dirtyhelper_STCKF,
11803 mkIRExprVec_1(mkexpr(op2addr)));
11804 d->mFx = Ifx_Write;
11805 d->mAddr = mkexpr(op2addr);
11806 d->mSize = 8;
11807 stmt(IRStmt_Dirty(d));
11808 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11809 mkexpr(cc), mkU64(0), mkU64(0));
11810 }
sewardj1e5fea62011-05-17 16:18:36 +000011811 return "stckf";
11812}
11813
florian55085f82012-11-21 00:36:55 +000011814static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011815s390_irgen_STCKE(IRTemp op2addr)
11816{
11817 IRDirty *d;
11818 IRTemp cc = newTemp(Ity_I64);
11819
11820 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11821 &s390x_dirtyhelper_STCKE,
11822 mkIRExprVec_1(mkexpr(op2addr)));
11823 d->mFx = Ifx_Write;
11824 d->mAddr = mkexpr(op2addr);
11825 d->mSize = 16;
11826 stmt(IRStmt_Dirty(d));
11827 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11828 mkexpr(cc), mkU64(0), mkU64(0));
11829 return "stcke";
11830}
11831
florian55085f82012-11-21 00:36:55 +000011832static const HChar *
florian933065d2011-07-11 01:48:02 +000011833s390_irgen_STFLE(IRTemp op2addr)
11834{
florian4e0083e2012-08-26 03:41:56 +000011835 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011836 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011837 return "stfle";
11838 }
11839
florian933065d2011-07-11 01:48:02 +000011840 IRDirty *d;
11841 IRTemp cc = newTemp(Ity_I64);
11842
11843 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11844 &s390x_dirtyhelper_STFLE,
11845 mkIRExprVec_1(mkexpr(op2addr)));
11846
11847 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11848
sewardjc9069f22012-06-01 16:09:50 +000011849 d->nFxState = 1;
11850 vex_bzero(&d->fxState, sizeof(d->fxState));
11851
florian933065d2011-07-11 01:48:02 +000011852 d->fxState[0].fx = Ifx_Modify; /* read then write */
11853 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11854 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011855
11856 d->mAddr = mkexpr(op2addr);
11857 /* Pretend all double words are written */
11858 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11859 d->mFx = Ifx_Write;
11860
11861 stmt(IRStmt_Dirty(d));
11862
11863 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11864
11865 return "stfle";
11866}
11867
florian55085f82012-11-21 00:36:55 +000011868static const HChar *
floriana4384a32011-08-11 16:58:45 +000011869s390_irgen_CKSM(UChar r1,UChar r2)
11870{
11871 IRTemp addr = newTemp(Ity_I64);
11872 IRTemp op = newTemp(Ity_I32);
11873 IRTemp len = newTemp(Ity_I64);
11874 IRTemp oldval = newTemp(Ity_I32);
11875 IRTemp mask = newTemp(Ity_I32);
11876 IRTemp newop = newTemp(Ity_I32);
11877 IRTemp result = newTemp(Ity_I32);
11878 IRTemp result1 = newTemp(Ity_I32);
11879 IRTemp inc = newTemp(Ity_I64);
11880
11881 assign(oldval, get_gpr_w1(r1));
11882 assign(addr, get_gpr_dw0(r2));
11883 assign(len, get_gpr_dw0(r2+1));
11884
11885 /* Condition code is always zero. */
11886 s390_cc_set(0);
11887
11888 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011889 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011890
11891 /* Assiging the increment variable to adjust address and length
11892 later on. */
11893 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11894 mkexpr(len), mkU64(4)));
11895
11896 /* If length < 4 the final 4-byte 2nd operand value is computed by
11897 appending the remaining bytes to the right with 0. This is done
11898 by AND'ing the 4 bytes loaded from memory with an appropriate
11899 mask. If length >= 4, that mask is simply 0xffffffff. */
11900
11901 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11902 /* Mask computation when len < 4:
11903 0xffffffff << (32 - (len % 4)*8) */
11904 binop(Iop_Shl32, mkU32(0xffffffff),
11905 unop(Iop_32to8,
11906 binop(Iop_Sub32, mkU32(32),
11907 binop(Iop_Shl32,
11908 unop(Iop_64to32,
11909 binop(Iop_And64,
11910 mkexpr(len), mkU64(3))),
11911 mkU8(3))))),
11912 mkU32(0xffffffff)));
11913
11914 assign(op, load(Ity_I32, mkexpr(addr)));
11915 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11916 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11917
11918 /* Checking for carry */
11919 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11920 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11921 mkexpr(result)));
11922
11923 put_gpr_w1(r1, mkexpr(result1));
11924 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11925 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11926
florian6820ba52012-07-26 02:01:50 +000011927 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011928
11929 return "cksm";
11930}
11931
florian55085f82012-11-21 00:36:55 +000011932static const HChar *
florian9af37692012-01-15 21:01:16 +000011933s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11934{
11935 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11936 src_addr = newTemp(Ity_I64);
11937 des_addr = newTemp(Ity_I64);
11938 tab_addr = newTemp(Ity_I64);
11939 test_byte = newTemp(Ity_I8);
11940 src_len = newTemp(Ity_I64);
11941
11942 assign(src_addr, get_gpr_dw0(r2));
11943 assign(des_addr, get_gpr_dw0(r1));
11944 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011945 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011946 assign(test_byte, get_gpr_b7(0));
11947
11948 IRTemp op = newTemp(Ity_I8);
11949 IRTemp op1 = newTemp(Ity_I8);
11950 IRTemp result = newTemp(Ity_I64);
11951
11952 /* End of source string? We're done; proceed to next insn */
11953 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011954 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011955
11956 /* Load character from source string, index translation table and
11957 store translated character in op1. */
11958 assign(op, load(Ity_I8, mkexpr(src_addr)));
11959
11960 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11961 mkexpr(tab_addr)));
11962 assign(op1, load(Ity_I8, mkexpr(result)));
11963
11964 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11965 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011966 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011967 }
11968 store(get_gpr_dw0(r1), mkexpr(op1));
11969
11970 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11971 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11972 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11973
florian6820ba52012-07-26 02:01:50 +000011974 iterate();
florian9af37692012-01-15 21:01:16 +000011975
11976 return "troo";
11977}
11978
florian55085f82012-11-21 00:36:55 +000011979static const HChar *
florian730448f2012-02-04 17:07:07 +000011980s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11981{
11982 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11983 src_addr = newTemp(Ity_I64);
11984 des_addr = newTemp(Ity_I64);
11985 tab_addr = newTemp(Ity_I64);
11986 test_byte = newTemp(Ity_I8);
11987 src_len = newTemp(Ity_I64);
11988
11989 assign(src_addr, get_gpr_dw0(r2));
11990 assign(des_addr, get_gpr_dw0(r1));
11991 assign(tab_addr, get_gpr_dw0(1));
11992 assign(src_len, get_gpr_dw0(r1+1));
11993 assign(test_byte, get_gpr_b7(0));
11994
11995 IRTemp op = newTemp(Ity_I16);
11996 IRTemp op1 = newTemp(Ity_I8);
11997 IRTemp result = newTemp(Ity_I64);
11998
11999 /* End of source string? We're done; proceed to next insn */
12000 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012001 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012002
12003 /* Load character from source string, index translation table and
12004 store translated character in op1. */
12005 assign(op, load(Ity_I16, mkexpr(src_addr)));
12006
12007 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12008 mkexpr(tab_addr)));
12009
12010 assign(op1, load(Ity_I8, mkexpr(result)));
12011
12012 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12013 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012014 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012015 }
12016 store(get_gpr_dw0(r1), mkexpr(op1));
12017
12018 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12019 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12020 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12021
florian6820ba52012-07-26 02:01:50 +000012022 iterate();
florian730448f2012-02-04 17:07:07 +000012023
12024 return "trto";
12025}
12026
florian55085f82012-11-21 00:36:55 +000012027static const HChar *
florian730448f2012-02-04 17:07:07 +000012028s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
12029{
12030 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12031 src_addr = newTemp(Ity_I64);
12032 des_addr = newTemp(Ity_I64);
12033 tab_addr = newTemp(Ity_I64);
12034 test_byte = newTemp(Ity_I16);
12035 src_len = newTemp(Ity_I64);
12036
12037 assign(src_addr, get_gpr_dw0(r2));
12038 assign(des_addr, get_gpr_dw0(r1));
12039 assign(tab_addr, get_gpr_dw0(1));
12040 assign(src_len, get_gpr_dw0(r1+1));
12041 assign(test_byte, get_gpr_hw3(0));
12042
12043 IRTemp op = newTemp(Ity_I8);
12044 IRTemp op1 = newTemp(Ity_I16);
12045 IRTemp result = newTemp(Ity_I64);
12046
12047 /* End of source string? We're done; proceed to next insn */
12048 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012049 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012050
12051 /* Load character from source string, index translation table and
12052 store translated character in op1. */
12053 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12054
12055 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12056 mkexpr(tab_addr)));
12057 assign(op1, load(Ity_I16, mkexpr(result)));
12058
12059 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12060 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012061 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012062 }
12063 store(get_gpr_dw0(r1), mkexpr(op1));
12064
12065 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12066 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12067 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12068
florian6820ba52012-07-26 02:01:50 +000012069 iterate();
florian730448f2012-02-04 17:07:07 +000012070
12071 return "trot";
12072}
12073
florian55085f82012-11-21 00:36:55 +000012074static const HChar *
florian730448f2012-02-04 17:07:07 +000012075s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12076{
12077 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12078 src_addr = newTemp(Ity_I64);
12079 des_addr = newTemp(Ity_I64);
12080 tab_addr = newTemp(Ity_I64);
12081 test_byte = newTemp(Ity_I16);
12082 src_len = newTemp(Ity_I64);
12083
12084 assign(src_addr, get_gpr_dw0(r2));
12085 assign(des_addr, get_gpr_dw0(r1));
12086 assign(tab_addr, get_gpr_dw0(1));
12087 assign(src_len, get_gpr_dw0(r1+1));
12088 assign(test_byte, get_gpr_hw3(0));
12089
12090 IRTemp op = newTemp(Ity_I16);
12091 IRTemp op1 = newTemp(Ity_I16);
12092 IRTemp result = newTemp(Ity_I64);
12093
12094 /* End of source string? We're done; proceed to next insn */
12095 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012096 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012097
12098 /* Load character from source string, index translation table and
12099 store translated character in op1. */
12100 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12101
12102 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12103 mkexpr(tab_addr)));
12104 assign(op1, load(Ity_I16, mkexpr(result)));
12105
12106 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12107 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012108 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012109 }
12110
12111 store(get_gpr_dw0(r1), mkexpr(op1));
12112
12113 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12114 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12115 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12116
florian6820ba52012-07-26 02:01:50 +000012117 iterate();
florian730448f2012-02-04 17:07:07 +000012118
12119 return "trtt";
12120}
12121
florian55085f82012-11-21 00:36:55 +000012122static const HChar *
florian730448f2012-02-04 17:07:07 +000012123s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
12124{
florianf87d4fb2012-05-05 02:55:24 +000012125 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000012126
florianf87d4fb2012-05-05 02:55:24 +000012127 assign(len, mkU64(length));
12128 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000012129
12130 return "tr";
12131}
12132
florian55085f82012-11-21 00:36:55 +000012133static const HChar *
florian730448f2012-02-04 17:07:07 +000012134s390_irgen_TRE(UChar r1,UChar r2)
12135{
12136 IRTemp src_addr, tab_addr, src_len, test_byte;
12137 src_addr = newTemp(Ity_I64);
12138 tab_addr = newTemp(Ity_I64);
12139 src_len = newTemp(Ity_I64);
12140 test_byte = newTemp(Ity_I8);
12141
12142 assign(src_addr, get_gpr_dw0(r1));
12143 assign(src_len, get_gpr_dw0(r1+1));
12144 assign(tab_addr, get_gpr_dw0(r2));
12145 assign(test_byte, get_gpr_b7(0));
12146
12147 IRTemp op = newTemp(Ity_I8);
12148 IRTemp op1 = newTemp(Ity_I8);
12149 IRTemp result = newTemp(Ity_I64);
12150
12151 /* End of source string? We're done; proceed to next insn */
12152 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012153 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012154
12155 /* Load character from source string and compare with test byte */
12156 assign(op, load(Ity_I8, mkexpr(src_addr)));
12157
12158 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012159 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012160
12161 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12162 mkexpr(tab_addr)));
12163
12164 assign(op1, load(Ity_I8, mkexpr(result)));
12165
12166 store(get_gpr_dw0(r1), mkexpr(op1));
12167 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12168 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12169
florian6820ba52012-07-26 02:01:50 +000012170 iterate();
florian730448f2012-02-04 17:07:07 +000012171
12172 return "tre";
12173}
12174
floriana0100c92012-07-20 00:06:35 +000012175static IRExpr *
12176s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
12177{
12178 IRExpr **args, *call;
12179 args = mkIRExprVec_2(srcval, low_surrogate);
12180 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12181 "s390_do_cu21", &s390_do_cu21, args);
12182
12183 /* Nothing is excluded from definedness checking. */
12184 call->Iex.CCall.cee->mcx_mask = 0;
12185
12186 return call;
12187}
12188
florian55085f82012-11-21 00:36:55 +000012189static const HChar *
floriana0100c92012-07-20 00:06:35 +000012190s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
12191{
12192 IRTemp addr1 = newTemp(Ity_I64);
12193 IRTemp addr2 = newTemp(Ity_I64);
12194 IRTemp len1 = newTemp(Ity_I64);
12195 IRTemp len2 = newTemp(Ity_I64);
12196
12197 assign(addr1, get_gpr_dw0(r1));
12198 assign(addr2, get_gpr_dw0(r2));
12199 assign(len1, get_gpr_dw0(r1 + 1));
12200 assign(len2, get_gpr_dw0(r2 + 1));
12201
12202 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12203 there are less than 2 bytes left, then the 2nd operand is exhausted
12204 and we're done here. cc = 0 */
12205 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012206 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000012207
12208 /* There are at least two bytes there. Read them. */
12209 IRTemp srcval = newTemp(Ity_I32);
12210 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12211
12212 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12213 inside the interval [0xd800 - 0xdbff] */
12214 IRTemp is_high_surrogate = newTemp(Ity_I32);
12215 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12216 mkU32(1), mkU32(0));
12217 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12218 mkU32(1), mkU32(0));
12219 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12220
12221 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12222 then the 2nd operand is exhausted and we're done here. cc = 0 */
12223 IRExpr *not_enough_bytes =
12224 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12225
florian6820ba52012-07-26 02:01:50 +000012226 next_insn_if(binop(Iop_CmpEQ32,
12227 binop(Iop_And32, mkexpr(is_high_surrogate),
12228 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000012229
12230 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12231 surrogate, read the next two bytes (low surrogate). */
12232 IRTemp low_surrogate = newTemp(Ity_I32);
12233 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12234
12235 assign(low_surrogate,
12236 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12237 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12238 mkU32(0))); // any value is fine; it will not be used
12239
12240 /* Call the helper */
12241 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012242 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
12243 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000012244
12245 /* Before we can test whether the 1st operand is exhausted we need to
12246 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12247 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12248 IRExpr *invalid_low_surrogate =
12249 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12250
12251 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012252 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000012253 }
12254
12255 /* Now test whether the 1st operand is exhausted */
12256 IRTemp num_bytes = newTemp(Ity_I64);
12257 assign(num_bytes, binop(Iop_And64,
12258 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12259 mkU64(0xff)));
12260 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012261 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000012262
12263 /* Extract the bytes to be stored at addr1 */
12264 IRTemp data = newTemp(Ity_I64);
12265 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12266
12267 /* To store the bytes construct 4 dirty helper calls. The helper calls
12268 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12269 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012270 UInt i;
floriana0100c92012-07-20 00:06:35 +000012271 for (i = 1; i <= 4; ++i) {
12272 IRDirty *d;
12273
12274 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12275 &s390x_dirtyhelper_CUxy,
12276 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12277 mkexpr(num_bytes)));
12278 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12279 d->mFx = Ifx_Write;
12280 d->mAddr = mkexpr(addr1);
12281 d->mSize = i;
12282 stmt(IRStmt_Dirty(d));
12283 }
12284
12285 /* Update source address and length */
12286 IRTemp num_src_bytes = newTemp(Ity_I64);
12287 assign(num_src_bytes,
12288 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12289 mkU64(4), mkU64(2)));
12290 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12291 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12292
12293 /* Update destination address and length */
12294 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12295 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12296
florian6820ba52012-07-26 02:01:50 +000012297 iterate();
floriana0100c92012-07-20 00:06:35 +000012298
12299 return "cu21";
12300}
12301
florian2a415a12012-07-21 17:41:36 +000012302static IRExpr *
12303s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
12304{
12305 IRExpr **args, *call;
12306 args = mkIRExprVec_2(srcval, low_surrogate);
12307 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12308 "s390_do_cu24", &s390_do_cu24, args);
12309
12310 /* Nothing is excluded from definedness checking. */
12311 call->Iex.CCall.cee->mcx_mask = 0;
12312
12313 return call;
12314}
12315
florian55085f82012-11-21 00:36:55 +000012316static const HChar *
florian2a415a12012-07-21 17:41:36 +000012317s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
12318{
12319 IRTemp addr1 = newTemp(Ity_I64);
12320 IRTemp addr2 = newTemp(Ity_I64);
12321 IRTemp len1 = newTemp(Ity_I64);
12322 IRTemp len2 = newTemp(Ity_I64);
12323
12324 assign(addr1, get_gpr_dw0(r1));
12325 assign(addr2, get_gpr_dw0(r2));
12326 assign(len1, get_gpr_dw0(r1 + 1));
12327 assign(len2, get_gpr_dw0(r2 + 1));
12328
12329 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12330 there are less than 2 bytes left, then the 2nd operand is exhausted
12331 and we're done here. cc = 0 */
12332 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012333 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000012334
12335 /* There are at least two bytes there. Read them. */
12336 IRTemp srcval = newTemp(Ity_I32);
12337 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12338
12339 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12340 inside the interval [0xd800 - 0xdbff] */
12341 IRTemp is_high_surrogate = newTemp(Ity_I32);
12342 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12343 mkU32(1), mkU32(0));
12344 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12345 mkU32(1), mkU32(0));
12346 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12347
12348 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12349 then the 2nd operand is exhausted and we're done here. cc = 0 */
12350 IRExpr *not_enough_bytes =
12351 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12352
florian6820ba52012-07-26 02:01:50 +000012353 next_insn_if(binop(Iop_CmpEQ32,
12354 binop(Iop_And32, mkexpr(is_high_surrogate),
12355 not_enough_bytes),
12356 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012357
12358 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12359 surrogate, read the next two bytes (low surrogate). */
12360 IRTemp low_surrogate = newTemp(Ity_I32);
12361 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12362
12363 assign(low_surrogate,
12364 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12365 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12366 mkU32(0))); // any value is fine; it will not be used
12367
12368 /* Call the helper */
12369 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012370 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12371 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012372
12373 /* Before we can test whether the 1st operand is exhausted we need to
12374 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12375 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12376 IRExpr *invalid_low_surrogate =
12377 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12378
12379 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012380 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012381 }
12382
12383 /* Now test whether the 1st operand is exhausted */
12384 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012385 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012386
12387 /* Extract the bytes to be stored at addr1 */
12388 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12389
12390 store(mkexpr(addr1), data);
12391
12392 /* Update source address and length */
12393 IRTemp num_src_bytes = newTemp(Ity_I64);
12394 assign(num_src_bytes,
12395 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12396 mkU64(4), mkU64(2)));
12397 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12398 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12399
12400 /* Update destination address and length */
12401 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12402 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12403
florian6820ba52012-07-26 02:01:50 +000012404 iterate();
florian2a415a12012-07-21 17:41:36 +000012405
12406 return "cu24";
12407}
floriana4384a32011-08-11 16:58:45 +000012408
florian956194b2012-07-28 22:18:32 +000012409static IRExpr *
12410s390_call_cu42(IRExpr *srcval)
12411{
12412 IRExpr **args, *call;
12413 args = mkIRExprVec_1(srcval);
12414 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12415 "s390_do_cu42", &s390_do_cu42, args);
12416
12417 /* Nothing is excluded from definedness checking. */
12418 call->Iex.CCall.cee->mcx_mask = 0;
12419
12420 return call;
12421}
12422
florian55085f82012-11-21 00:36:55 +000012423static const HChar *
florian956194b2012-07-28 22:18:32 +000012424s390_irgen_CU42(UChar r1, UChar r2)
12425{
12426 IRTemp addr1 = newTemp(Ity_I64);
12427 IRTemp addr2 = newTemp(Ity_I64);
12428 IRTemp len1 = newTemp(Ity_I64);
12429 IRTemp len2 = newTemp(Ity_I64);
12430
12431 assign(addr1, get_gpr_dw0(r1));
12432 assign(addr2, get_gpr_dw0(r2));
12433 assign(len1, get_gpr_dw0(r1 + 1));
12434 assign(len2, get_gpr_dw0(r2 + 1));
12435
12436 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12437 there are less than 4 bytes left, then the 2nd operand is exhausted
12438 and we're done here. cc = 0 */
12439 s390_cc_set(0);
12440 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12441
12442 /* Read the 2nd operand. */
12443 IRTemp srcval = newTemp(Ity_I32);
12444 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12445
12446 /* Call the helper */
12447 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012448 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012449
12450 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12451 cc=2 outranks cc=1 (1st operand exhausted) */
12452 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12453
12454 s390_cc_set(2);
12455 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12456
12457 /* Now test whether the 1st operand is exhausted */
12458 IRTemp num_bytes = newTemp(Ity_I64);
12459 assign(num_bytes, binop(Iop_And64,
12460 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12461 mkU64(0xff)));
12462 s390_cc_set(1);
12463 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12464
12465 /* Extract the bytes to be stored at addr1 */
12466 IRTemp data = newTemp(Ity_I64);
12467 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12468
12469 /* To store the bytes construct 2 dirty helper calls. The helper calls
12470 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12471 that only one of them will be called at runtime. */
12472
12473 Int i;
12474 for (i = 2; i <= 4; ++i) {
12475 IRDirty *d;
12476
12477 if (i == 3) continue; // skip this one
12478
12479 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12480 &s390x_dirtyhelper_CUxy,
12481 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12482 mkexpr(num_bytes)));
12483 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12484 d->mFx = Ifx_Write;
12485 d->mAddr = mkexpr(addr1);
12486 d->mSize = i;
12487 stmt(IRStmt_Dirty(d));
12488 }
12489
12490 /* Update source address and length */
12491 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12492 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12493
12494 /* Update destination address and length */
12495 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12496 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12497
12498 iterate();
12499
12500 return "cu42";
12501}
12502
florian6d9b9b22012-08-03 18:35:39 +000012503static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012504s390_call_cu41(IRExpr *srcval)
12505{
12506 IRExpr **args, *call;
12507 args = mkIRExprVec_1(srcval);
12508 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12509 "s390_do_cu41", &s390_do_cu41, args);
12510
12511 /* Nothing is excluded from definedness checking. */
12512 call->Iex.CCall.cee->mcx_mask = 0;
12513
12514 return call;
12515}
12516
florian55085f82012-11-21 00:36:55 +000012517static const HChar *
florianaf2194f2012-08-06 00:07:54 +000012518s390_irgen_CU41(UChar r1, UChar r2)
12519{
12520 IRTemp addr1 = newTemp(Ity_I64);
12521 IRTemp addr2 = newTemp(Ity_I64);
12522 IRTemp len1 = newTemp(Ity_I64);
12523 IRTemp len2 = newTemp(Ity_I64);
12524
12525 assign(addr1, get_gpr_dw0(r1));
12526 assign(addr2, get_gpr_dw0(r2));
12527 assign(len1, get_gpr_dw0(r1 + 1));
12528 assign(len2, get_gpr_dw0(r2 + 1));
12529
12530 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12531 there are less than 4 bytes left, then the 2nd operand is exhausted
12532 and we're done here. cc = 0 */
12533 s390_cc_set(0);
12534 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12535
12536 /* Read the 2nd operand. */
12537 IRTemp srcval = newTemp(Ity_I32);
12538 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12539
12540 /* Call the helper */
12541 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012542 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012543
12544 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12545 cc=2 outranks cc=1 (1st operand exhausted) */
12546 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12547
12548 s390_cc_set(2);
12549 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12550
12551 /* Now test whether the 1st operand is exhausted */
12552 IRTemp num_bytes = newTemp(Ity_I64);
12553 assign(num_bytes, binop(Iop_And64,
12554 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12555 mkU64(0xff)));
12556 s390_cc_set(1);
12557 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12558
12559 /* Extract the bytes to be stored at addr1 */
12560 IRTemp data = newTemp(Ity_I64);
12561 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12562
12563 /* To store the bytes construct 4 dirty helper calls. The helper calls
12564 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12565 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012566 UInt i;
florianaf2194f2012-08-06 00:07:54 +000012567 for (i = 1; i <= 4; ++i) {
12568 IRDirty *d;
12569
12570 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12571 &s390x_dirtyhelper_CUxy,
12572 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12573 mkexpr(num_bytes)));
12574 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12575 d->mFx = Ifx_Write;
12576 d->mAddr = mkexpr(addr1);
12577 d->mSize = i;
12578 stmt(IRStmt_Dirty(d));
12579 }
12580
12581 /* Update source address and length */
12582 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12583 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12584
12585 /* Update destination address and length */
12586 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12587 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12588
12589 iterate();
12590
12591 return "cu41";
12592}
12593
12594static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012595s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012596{
12597 IRExpr **args, *call;
12598 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012599 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12600 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012601
12602 /* Nothing is excluded from definedness checking. */
12603 call->Iex.CCall.cee->mcx_mask = 0;
12604
12605 return call;
12606}
12607
12608static IRExpr *
12609s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12610 IRExpr *byte4, IRExpr *stuff)
12611{
12612 IRExpr **args, *call;
12613 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12614 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12615 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12616
12617 /* Nothing is excluded from definedness checking. */
12618 call->Iex.CCall.cee->mcx_mask = 0;
12619
12620 return call;
12621}
12622
florian3f8a96a2012-08-05 02:59:55 +000012623static IRExpr *
12624s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12625 IRExpr *byte4, IRExpr *stuff)
12626{
12627 IRExpr **args, *call;
12628 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12629 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12630 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12631
12632 /* Nothing is excluded from definedness checking. */
12633 call->Iex.CCall.cee->mcx_mask = 0;
12634
12635 return call;
12636}
12637
12638static void
12639s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012640{
12641 IRTemp addr1 = newTemp(Ity_I64);
12642 IRTemp addr2 = newTemp(Ity_I64);
12643 IRTemp len1 = newTemp(Ity_I64);
12644 IRTemp len2 = newTemp(Ity_I64);
12645
12646 assign(addr1, get_gpr_dw0(r1));
12647 assign(addr2, get_gpr_dw0(r2));
12648 assign(len1, get_gpr_dw0(r1 + 1));
12649 assign(len2, get_gpr_dw0(r2 + 1));
12650
12651 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12652
12653 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12654 there is less than 1 byte left, then the 2nd operand is exhausted
12655 and we're done here. cc = 0 */
12656 s390_cc_set(0);
12657 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12658
12659 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012660 IRTemp byte1 = newTemp(Ity_I64);
12661 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012662
12663 /* Call the helper to get number of bytes and invalid byte indicator */
12664 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012665 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012666 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012667
12668 /* Check for invalid 1st byte */
12669 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12670 s390_cc_set(2);
12671 next_insn_if(is_invalid);
12672
12673 /* How many bytes do we have to read? */
12674 IRTemp num_src_bytes = newTemp(Ity_I64);
12675 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12676
12677 /* Now test whether the 2nd operand is exhausted */
12678 s390_cc_set(0);
12679 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12680
12681 /* Read the remaining bytes */
12682 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12683
12684 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12685 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012686 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012687 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12688 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012689 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012690 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12691 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012692 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012693
12694 /* Call the helper to get the converted value and invalid byte indicator.
12695 We can pass at most 5 arguments; therefore some encoding is needed
12696 here */
12697 IRExpr *stuff = binop(Iop_Or64,
12698 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12699 mkU64(extended_checking));
12700 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012701
12702 if (is_cu12) {
12703 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12704 byte4, stuff));
12705 } else {
12706 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12707 byte4, stuff));
12708 }
florian6d9b9b22012-08-03 18:35:39 +000012709
12710 /* Check for invalid character */
12711 s390_cc_set(2);
12712 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12713 next_insn_if(is_invalid);
12714
12715 /* Now test whether the 1st operand is exhausted */
12716 IRTemp num_bytes = newTemp(Ity_I64);
12717 assign(num_bytes, binop(Iop_And64,
12718 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12719 mkU64(0xff)));
12720 s390_cc_set(1);
12721 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12722
12723 /* Extract the bytes to be stored at addr1 */
12724 IRTemp data = newTemp(Ity_I64);
12725 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12726
florian3f8a96a2012-08-05 02:59:55 +000012727 if (is_cu12) {
12728 /* To store the bytes construct 2 dirty helper calls. The helper calls
12729 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12730 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012731
florian3f8a96a2012-08-05 02:59:55 +000012732 Int i;
12733 for (i = 2; i <= 4; ++i) {
12734 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012735
florian3f8a96a2012-08-05 02:59:55 +000012736 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012737
florian3f8a96a2012-08-05 02:59:55 +000012738 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12739 &s390x_dirtyhelper_CUxy,
12740 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12741 mkexpr(num_bytes)));
12742 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12743 d->mFx = Ifx_Write;
12744 d->mAddr = mkexpr(addr1);
12745 d->mSize = i;
12746 stmt(IRStmt_Dirty(d));
12747 }
12748 } else {
12749 // cu14
12750 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012751 }
12752
12753 /* Update source address and length */
12754 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12755 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12756
12757 /* Update destination address and length */
12758 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12759 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12760
12761 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012762}
12763
florian55085f82012-11-21 00:36:55 +000012764static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012765s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12766{
12767 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012768
12769 return "cu12";
12770}
12771
florian55085f82012-11-21 00:36:55 +000012772static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012773s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12774{
12775 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12776
12777 return "cu14";
12778}
12779
florian8c88cb62012-08-26 18:58:13 +000012780static IRExpr *
12781s390_call_ecag(IRExpr *op2addr)
12782{
12783 IRExpr **args, *call;
12784
12785 args = mkIRExprVec_1(op2addr);
12786 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12787 "s390_do_ecag", &s390_do_ecag, args);
12788
12789 /* Nothing is excluded from definedness checking. */
12790 call->Iex.CCall.cee->mcx_mask = 0;
12791
12792 return call;
12793}
12794
florian55085f82012-11-21 00:36:55 +000012795static const HChar *
floriand2129202012-09-01 20:01:39 +000012796s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012797{
12798 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012799 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012800 } else {
12801 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12802 }
12803
12804 return "ecag";
12805}
12806
12807
florianb7def222012-12-04 04:45:32 +000012808/* New insns are added here.
12809 If an insn is contingent on a facility being installed also
12810 check whether the list of supported facilities in function
12811 s390x_dirtyhelper_STFLE needs updating */
12812
sewardj2019a972011-03-07 16:04:07 +000012813/*------------------------------------------------------------*/
12814/*--- Build IR for special instructions ---*/
12815/*------------------------------------------------------------*/
12816
florianb4df7682011-07-05 02:09:01 +000012817static void
sewardj2019a972011-03-07 16:04:07 +000012818s390_irgen_client_request(void)
12819{
12820 if (0)
12821 vex_printf("%%R3 = client_request ( %%R2 )\n");
12822
florianf9e1ed72012-04-17 02:41:56 +000012823 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12824 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012825
florianf9e1ed72012-04-17 02:41:56 +000012826 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012827 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012828
12829 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012830}
12831
florianb4df7682011-07-05 02:09:01 +000012832static void
sewardj2019a972011-03-07 16:04:07 +000012833s390_irgen_guest_NRADDR(void)
12834{
12835 if (0)
12836 vex_printf("%%R3 = guest_NRADDR\n");
12837
floriane88b3c92011-07-05 02:48:39 +000012838 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012839}
12840
florianb4df7682011-07-05 02:09:01 +000012841static void
sewardj2019a972011-03-07 16:04:07 +000012842s390_irgen_call_noredir(void)
12843{
florianf9e1ed72012-04-17 02:41:56 +000012844 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12845 + S390_SPECIAL_OP_SIZE;
12846
sewardj2019a972011-03-07 16:04:07 +000012847 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012848 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012849
12850 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012851 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012852
12853 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012854 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012855}
12856
12857/* Force proper alignment for the structures below. */
12858#pragma pack(1)
12859
12860
12861static s390_decode_t
12862s390_decode_2byte_and_irgen(UChar *bytes)
12863{
12864 typedef union {
12865 struct {
12866 unsigned int op : 16;
12867 } E;
12868 struct {
12869 unsigned int op : 8;
12870 unsigned int i : 8;
12871 } I;
12872 struct {
12873 unsigned int op : 8;
12874 unsigned int r1 : 4;
12875 unsigned int r2 : 4;
12876 } RR;
12877 } formats;
12878 union {
12879 formats fmt;
12880 UShort value;
12881 } ovl;
12882
12883 vassert(sizeof(formats) == 2);
12884
florianffbd84d2012-12-09 02:06:29 +000012885 ((UChar *)(&ovl.value))[0] = bytes[0];
12886 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000012887
12888 switch (ovl.value & 0xffff) {
12889 case 0x0101: /* PR */ goto unimplemented;
12890 case 0x0102: /* UPT */ goto unimplemented;
12891 case 0x0104: /* PTFF */ goto unimplemented;
12892 case 0x0107: /* SCKPF */ goto unimplemented;
12893 case 0x010a: /* PFPO */ goto unimplemented;
12894 case 0x010b: /* TAM */ goto unimplemented;
12895 case 0x010c: /* SAM24 */ goto unimplemented;
12896 case 0x010d: /* SAM31 */ goto unimplemented;
12897 case 0x010e: /* SAM64 */ goto unimplemented;
12898 case 0x01ff: /* TRAP2 */ goto unimplemented;
12899 }
12900
12901 switch ((ovl.value & 0xff00) >> 8) {
12902 case 0x04: /* SPM */ goto unimplemented;
12903 case 0x05: /* BALR */ goto unimplemented;
12904 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12905 goto ok;
12906 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12907 goto ok;
12908 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12909 case 0x0b: /* BSM */ goto unimplemented;
12910 case 0x0c: /* BASSM */ goto unimplemented;
12911 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12912 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012913 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12914 goto ok;
12915 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12916 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012917 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12918 goto ok;
12919 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12920 goto ok;
12921 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12922 goto ok;
12923 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12924 goto ok;
12925 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12926 goto ok;
12927 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12928 goto ok;
12929 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12930 goto ok;
12931 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12932 goto ok;
12933 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12934 goto ok;
12935 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12936 goto ok;
12937 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12938 goto ok;
12939 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12940 goto ok;
12941 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12942 goto ok;
12943 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12944 goto ok;
12945 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12946 goto ok;
12947 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12948 goto ok;
12949 case 0x20: /* LPDR */ goto unimplemented;
12950 case 0x21: /* LNDR */ goto unimplemented;
12951 case 0x22: /* LTDR */ goto unimplemented;
12952 case 0x23: /* LCDR */ goto unimplemented;
12953 case 0x24: /* HDR */ goto unimplemented;
12954 case 0x25: /* LDXR */ goto unimplemented;
12955 case 0x26: /* MXR */ goto unimplemented;
12956 case 0x27: /* MXDR */ goto unimplemented;
12957 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12958 goto ok;
12959 case 0x29: /* CDR */ goto unimplemented;
12960 case 0x2a: /* ADR */ goto unimplemented;
12961 case 0x2b: /* SDR */ goto unimplemented;
12962 case 0x2c: /* MDR */ goto unimplemented;
12963 case 0x2d: /* DDR */ goto unimplemented;
12964 case 0x2e: /* AWR */ goto unimplemented;
12965 case 0x2f: /* SWR */ goto unimplemented;
12966 case 0x30: /* LPER */ goto unimplemented;
12967 case 0x31: /* LNER */ goto unimplemented;
12968 case 0x32: /* LTER */ goto unimplemented;
12969 case 0x33: /* LCER */ goto unimplemented;
12970 case 0x34: /* HER */ goto unimplemented;
12971 case 0x35: /* LEDR */ goto unimplemented;
12972 case 0x36: /* AXR */ goto unimplemented;
12973 case 0x37: /* SXR */ goto unimplemented;
12974 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12975 goto ok;
12976 case 0x39: /* CER */ goto unimplemented;
12977 case 0x3a: /* AER */ goto unimplemented;
12978 case 0x3b: /* SER */ goto unimplemented;
12979 case 0x3c: /* MDER */ goto unimplemented;
12980 case 0x3d: /* DER */ goto unimplemented;
12981 case 0x3e: /* AUR */ goto unimplemented;
12982 case 0x3f: /* SUR */ goto unimplemented;
12983 }
12984
12985 return S390_DECODE_UNKNOWN_INSN;
12986
12987ok:
12988 return S390_DECODE_OK;
12989
12990unimplemented:
12991 return S390_DECODE_UNIMPLEMENTED_INSN;
12992}
12993
12994static s390_decode_t
12995s390_decode_4byte_and_irgen(UChar *bytes)
12996{
12997 typedef union {
12998 struct {
12999 unsigned int op1 : 8;
13000 unsigned int r1 : 4;
13001 unsigned int op2 : 4;
13002 unsigned int i2 : 16;
13003 } RI;
13004 struct {
13005 unsigned int op : 16;
13006 unsigned int : 8;
13007 unsigned int r1 : 4;
13008 unsigned int r2 : 4;
13009 } RRE;
13010 struct {
13011 unsigned int op : 16;
13012 unsigned int r1 : 4;
13013 unsigned int : 4;
13014 unsigned int r3 : 4;
13015 unsigned int r2 : 4;
13016 } RRF;
13017 struct {
13018 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000013019 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000013020 unsigned int m4 : 4;
13021 unsigned int r1 : 4;
13022 unsigned int r2 : 4;
13023 } RRF2;
13024 struct {
13025 unsigned int op : 16;
13026 unsigned int r3 : 4;
13027 unsigned int : 4;
13028 unsigned int r1 : 4;
13029 unsigned int r2 : 4;
13030 } RRF3;
13031 struct {
13032 unsigned int op : 16;
13033 unsigned int r3 : 4;
13034 unsigned int : 4;
13035 unsigned int r1 : 4;
13036 unsigned int r2 : 4;
13037 } RRR;
13038 struct {
13039 unsigned int op : 16;
13040 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013041 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013042 unsigned int r1 : 4;
13043 unsigned int r2 : 4;
13044 } RRF4;
13045 struct {
floriane38f6412012-12-21 17:32:12 +000013046 unsigned int op : 16;
13047 unsigned int : 4;
13048 unsigned int m4 : 4;
13049 unsigned int r1 : 4;
13050 unsigned int r2 : 4;
13051 } RRF5;
13052 struct {
sewardj2019a972011-03-07 16:04:07 +000013053 unsigned int op : 8;
13054 unsigned int r1 : 4;
13055 unsigned int r3 : 4;
13056 unsigned int b2 : 4;
13057 unsigned int d2 : 12;
13058 } RS;
13059 struct {
13060 unsigned int op : 8;
13061 unsigned int r1 : 4;
13062 unsigned int r3 : 4;
13063 unsigned int i2 : 16;
13064 } RSI;
13065 struct {
13066 unsigned int op : 8;
13067 unsigned int r1 : 4;
13068 unsigned int x2 : 4;
13069 unsigned int b2 : 4;
13070 unsigned int d2 : 12;
13071 } RX;
13072 struct {
13073 unsigned int op : 16;
13074 unsigned int b2 : 4;
13075 unsigned int d2 : 12;
13076 } S;
13077 struct {
13078 unsigned int op : 8;
13079 unsigned int i2 : 8;
13080 unsigned int b1 : 4;
13081 unsigned int d1 : 12;
13082 } SI;
13083 } formats;
13084 union {
13085 formats fmt;
13086 UInt value;
13087 } ovl;
13088
13089 vassert(sizeof(formats) == 4);
13090
florianffbd84d2012-12-09 02:06:29 +000013091 ((UChar *)(&ovl.value))[0] = bytes[0];
13092 ((UChar *)(&ovl.value))[1] = bytes[1];
13093 ((UChar *)(&ovl.value))[2] = bytes[2];
13094 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013095
13096 switch ((ovl.value & 0xff0f0000) >> 16) {
13097 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13098 ovl.fmt.RI.i2); goto ok;
13099 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13100 ovl.fmt.RI.i2); goto ok;
13101 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
13102 ovl.fmt.RI.i2); goto ok;
13103 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
13104 ovl.fmt.RI.i2); goto ok;
13105 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
13106 ovl.fmt.RI.i2); goto ok;
13107 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
13108 ovl.fmt.RI.i2); goto ok;
13109 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
13110 ovl.fmt.RI.i2); goto ok;
13111 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
13112 ovl.fmt.RI.i2); goto ok;
13113 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
13114 ovl.fmt.RI.i2); goto ok;
13115 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
13116 ovl.fmt.RI.i2); goto ok;
13117 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
13118 ovl.fmt.RI.i2); goto ok;
13119 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
13120 ovl.fmt.RI.i2); goto ok;
13121 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
13122 ovl.fmt.RI.i2); goto ok;
13123 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
13124 ovl.fmt.RI.i2); goto ok;
13125 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
13126 ovl.fmt.RI.i2); goto ok;
13127 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
13128 ovl.fmt.RI.i2); goto ok;
13129 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
13130 ovl.fmt.RI.i2); goto ok;
13131 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
13132 ovl.fmt.RI.i2); goto ok;
13133 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
13134 ovl.fmt.RI.i2); goto ok;
13135 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
13136 ovl.fmt.RI.i2); goto ok;
13137 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13138 goto ok;
13139 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
13140 ovl.fmt.RI.i2); goto ok;
13141 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
13142 ovl.fmt.RI.i2); goto ok;
13143 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
13144 ovl.fmt.RI.i2); goto ok;
13145 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13146 goto ok;
13147 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
13148 ovl.fmt.RI.i2); goto ok;
13149 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13150 goto ok;
13151 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
13152 ovl.fmt.RI.i2); goto ok;
13153 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13154 goto ok;
13155 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
13156 ovl.fmt.RI.i2); goto ok;
13157 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13158 goto ok;
13159 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
13160 ovl.fmt.RI.i2); goto ok;
13161 }
13162
13163 switch ((ovl.value & 0xffff0000) >> 16) {
13164 case 0x8000: /* SSM */ goto unimplemented;
13165 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013166 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013167 case 0xb202: /* STIDP */ goto unimplemented;
13168 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013169 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
13170 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013171 case 0xb206: /* SCKC */ goto unimplemented;
13172 case 0xb207: /* STCKC */ goto unimplemented;
13173 case 0xb208: /* SPT */ goto unimplemented;
13174 case 0xb209: /* STPT */ goto unimplemented;
13175 case 0xb20a: /* SPKA */ goto unimplemented;
13176 case 0xb20b: /* IPK */ goto unimplemented;
13177 case 0xb20d: /* PTLB */ goto unimplemented;
13178 case 0xb210: /* SPX */ goto unimplemented;
13179 case 0xb211: /* STPX */ goto unimplemented;
13180 case 0xb212: /* STAP */ goto unimplemented;
13181 case 0xb214: /* SIE */ goto unimplemented;
13182 case 0xb218: /* PC */ goto unimplemented;
13183 case 0xb219: /* SAC */ goto unimplemented;
13184 case 0xb21a: /* CFC */ goto unimplemented;
13185 case 0xb221: /* IPTE */ goto unimplemented;
13186 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
13187 case 0xb223: /* IVSK */ goto unimplemented;
13188 case 0xb224: /* IAC */ goto unimplemented;
13189 case 0xb225: /* SSAR */ goto unimplemented;
13190 case 0xb226: /* EPAR */ goto unimplemented;
13191 case 0xb227: /* ESAR */ goto unimplemented;
13192 case 0xb228: /* PT */ goto unimplemented;
13193 case 0xb229: /* ISKE */ goto unimplemented;
13194 case 0xb22a: /* RRBE */ goto unimplemented;
13195 case 0xb22b: /* SSKE */ goto unimplemented;
13196 case 0xb22c: /* TB */ goto unimplemented;
13197 case 0xb22d: /* DXR */ goto unimplemented;
13198 case 0xb22e: /* PGIN */ goto unimplemented;
13199 case 0xb22f: /* PGOUT */ goto unimplemented;
13200 case 0xb230: /* CSCH */ goto unimplemented;
13201 case 0xb231: /* HSCH */ goto unimplemented;
13202 case 0xb232: /* MSCH */ goto unimplemented;
13203 case 0xb233: /* SSCH */ goto unimplemented;
13204 case 0xb234: /* STSCH */ goto unimplemented;
13205 case 0xb235: /* TSCH */ goto unimplemented;
13206 case 0xb236: /* TPI */ goto unimplemented;
13207 case 0xb237: /* SAL */ goto unimplemented;
13208 case 0xb238: /* RSCH */ goto unimplemented;
13209 case 0xb239: /* STCRW */ goto unimplemented;
13210 case 0xb23a: /* STCPS */ goto unimplemented;
13211 case 0xb23b: /* RCHP */ goto unimplemented;
13212 case 0xb23c: /* SCHM */ goto unimplemented;
13213 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000013214 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
13215 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013216 case 0xb244: /* SQDR */ goto unimplemented;
13217 case 0xb245: /* SQER */ goto unimplemented;
13218 case 0xb246: /* STURA */ goto unimplemented;
13219 case 0xb247: /* MSTA */ goto unimplemented;
13220 case 0xb248: /* PALB */ goto unimplemented;
13221 case 0xb249: /* EREG */ goto unimplemented;
13222 case 0xb24a: /* ESTA */ goto unimplemented;
13223 case 0xb24b: /* LURA */ goto unimplemented;
13224 case 0xb24c: /* TAR */ goto unimplemented;
13225 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
13226 ovl.fmt.RRE.r2); goto ok;
13227 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13228 goto ok;
13229 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13230 goto ok;
13231 case 0xb250: /* CSP */ goto unimplemented;
13232 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
13233 ovl.fmt.RRE.r2); goto ok;
13234 case 0xb254: /* MVPG */ goto unimplemented;
13235 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
13236 ovl.fmt.RRE.r2); goto ok;
13237 case 0xb257: /* CUSE */ goto unimplemented;
13238 case 0xb258: /* BSG */ goto unimplemented;
13239 case 0xb25a: /* BSA */ goto unimplemented;
13240 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
13241 ovl.fmt.RRE.r2); goto ok;
13242 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
13243 ovl.fmt.RRE.r2); goto ok;
13244 case 0xb263: /* CMPSC */ goto unimplemented;
13245 case 0xb274: /* SIGA */ goto unimplemented;
13246 case 0xb276: /* XSCH */ goto unimplemented;
13247 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013248 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 +000013249 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013250 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 +000013251 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013252 case 0xb280: /* LPP */ goto unimplemented;
13253 case 0xb284: /* LCCTL */ goto unimplemented;
13254 case 0xb285: /* LPCTL */ goto unimplemented;
13255 case 0xb286: /* QSI */ goto unimplemented;
13256 case 0xb287: /* LSCTL */ goto unimplemented;
13257 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013258 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
13259 goto ok;
13260 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13261 goto ok;
13262 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13263 goto ok;
florian730448f2012-02-04 17:07:07 +000013264 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 +000013265 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
13266 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13267 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000013268 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
13269 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13270 goto ok;
florian933065d2011-07-11 01:48:02 +000013271 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
13272 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013273 case 0xb2b1: /* STFL */ goto unimplemented;
13274 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000013275 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
13276 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013277 case 0xb2b9: /* SRNMT */ goto unimplemented;
13278 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013279 case 0xb2e0: /* SCCTR */ goto unimplemented;
13280 case 0xb2e1: /* SPCTR */ goto unimplemented;
13281 case 0xb2e4: /* ECCTR */ goto unimplemented;
13282 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013283 case 0xb2e8: /* PPA */ goto unimplemented;
13284 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013285 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013286 case 0xb2f8: /* TEND */ goto unimplemented;
13287 case 0xb2fa: /* NIAI */ goto unimplemented;
13288 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013289 case 0xb2ff: /* TRAP4 */ goto unimplemented;
13290 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
13291 ovl.fmt.RRE.r2); goto ok;
13292 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
13293 ovl.fmt.RRE.r2); goto ok;
13294 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
13295 ovl.fmt.RRE.r2); goto ok;
13296 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
13297 ovl.fmt.RRE.r2); goto ok;
13298 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
13299 ovl.fmt.RRE.r2); goto ok;
13300 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
13301 ovl.fmt.RRE.r2); goto ok;
13302 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
13303 ovl.fmt.RRE.r2); goto ok;
13304 case 0xb307: /* MXDBR */ goto unimplemented;
13305 case 0xb308: /* KEBR */ goto unimplemented;
13306 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
13307 ovl.fmt.RRE.r2); goto ok;
13308 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
13309 ovl.fmt.RRE.r2); goto ok;
13310 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
13311 ovl.fmt.RRE.r2); goto ok;
13312 case 0xb30c: /* MDEBR */ goto unimplemented;
13313 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
13314 ovl.fmt.RRE.r2); goto ok;
13315 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
13316 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13317 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
13318 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13319 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
13320 ovl.fmt.RRE.r2); goto ok;
13321 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
13322 ovl.fmt.RRE.r2); goto ok;
13323 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
13324 ovl.fmt.RRE.r2); goto ok;
13325 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
13326 ovl.fmt.RRE.r2); goto ok;
13327 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
13328 ovl.fmt.RRE.r2); goto ok;
13329 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
13330 ovl.fmt.RRE.r2); goto ok;
13331 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
13332 ovl.fmt.RRE.r2); goto ok;
13333 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
13334 ovl.fmt.RRE.r2); goto ok;
13335 case 0xb318: /* KDBR */ goto unimplemented;
13336 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
13337 ovl.fmt.RRE.r2); goto ok;
13338 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
13339 ovl.fmt.RRE.r2); goto ok;
13340 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
13341 ovl.fmt.RRE.r2); goto ok;
13342 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
13343 ovl.fmt.RRE.r2); goto ok;
13344 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
13345 ovl.fmt.RRE.r2); goto ok;
13346 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
13347 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13348 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
13349 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13350 case 0xb324: /* LDER */ goto unimplemented;
13351 case 0xb325: /* LXDR */ goto unimplemented;
13352 case 0xb326: /* LXER */ goto unimplemented;
13353 case 0xb32e: /* MAER */ goto unimplemented;
13354 case 0xb32f: /* MSER */ goto unimplemented;
13355 case 0xb336: /* SQXR */ goto unimplemented;
13356 case 0xb337: /* MEER */ goto unimplemented;
13357 case 0xb338: /* MAYLR */ goto unimplemented;
13358 case 0xb339: /* MYLR */ goto unimplemented;
13359 case 0xb33a: /* MAYR */ goto unimplemented;
13360 case 0xb33b: /* MYR */ goto unimplemented;
13361 case 0xb33c: /* MAYHR */ goto unimplemented;
13362 case 0xb33d: /* MYHR */ goto unimplemented;
13363 case 0xb33e: /* MADR */ goto unimplemented;
13364 case 0xb33f: /* MSDR */ goto unimplemented;
13365 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
13366 ovl.fmt.RRE.r2); goto ok;
13367 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
13368 ovl.fmt.RRE.r2); goto ok;
13369 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
13370 ovl.fmt.RRE.r2); goto ok;
13371 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
13372 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013373 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13374 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13375 ovl.fmt.RRF2.r2); goto ok;
13376 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13377 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13378 ovl.fmt.RRF2.r2); goto ok;
13379 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13380 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13381 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013382 case 0xb347: /* FIXBR */ goto unimplemented;
13383 case 0xb348: /* KXBR */ goto unimplemented;
13384 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13385 ovl.fmt.RRE.r2); goto ok;
13386 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13387 ovl.fmt.RRE.r2); goto ok;
13388 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13389 ovl.fmt.RRE.r2); goto ok;
13390 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13391 ovl.fmt.RRE.r2); goto ok;
13392 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13393 ovl.fmt.RRE.r2); goto ok;
13394 case 0xb350: /* TBEDR */ goto unimplemented;
13395 case 0xb351: /* TBDR */ goto unimplemented;
13396 case 0xb353: /* DIEBR */ goto unimplemented;
13397 case 0xb357: /* FIEBR */ goto unimplemented;
13398 case 0xb358: /* THDER */ goto unimplemented;
13399 case 0xb359: /* THDR */ goto unimplemented;
13400 case 0xb35b: /* DIDBR */ goto unimplemented;
13401 case 0xb35f: /* FIDBR */ goto unimplemented;
13402 case 0xb360: /* LPXR */ goto unimplemented;
13403 case 0xb361: /* LNXR */ goto unimplemented;
13404 case 0xb362: /* LTXR */ goto unimplemented;
13405 case 0xb363: /* LCXR */ goto unimplemented;
13406 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13407 ovl.fmt.RRE.r2); goto ok;
13408 case 0xb366: /* LEXR */ goto unimplemented;
13409 case 0xb367: /* FIXR */ goto unimplemented;
13410 case 0xb369: /* CXR */ goto unimplemented;
13411 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13412 ovl.fmt.RRE.r2); goto ok;
13413 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13414 ovl.fmt.RRE.r2); goto ok;
13415 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13416 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13417 goto ok;
13418 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13419 ovl.fmt.RRE.r2); goto ok;
13420 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13421 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13422 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13423 case 0xb377: /* FIER */ goto unimplemented;
13424 case 0xb37f: /* FIDR */ goto unimplemented;
13425 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13426 case 0xb385: /* SFASR */ goto unimplemented;
13427 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013428 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13429 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13430 ovl.fmt.RRF2.r2); goto ok;
13431 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13432 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13433 ovl.fmt.RRF2.r2); goto ok;
13434 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13435 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13436 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013437 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13438 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13439 ovl.fmt.RRF2.r2); goto ok;
13440 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13441 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13442 ovl.fmt.RRF2.r2); goto ok;
13443 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13444 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13445 ovl.fmt.RRF2.r2); goto ok;
13446 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13447 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13448 ovl.fmt.RRF2.r2); goto ok;
13449 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13450 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13451 ovl.fmt.RRF2.r2); goto ok;
13452 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13453 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13454 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013455 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13456 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13457 ovl.fmt.RRF2.r2); goto ok;
13458 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13459 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13460 ovl.fmt.RRF2.r2); goto ok;
13461 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13462 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13463 ovl.fmt.RRF2.r2); goto ok;
13464 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13465 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13466 ovl.fmt.RRF2.r2); goto ok;
13467 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13468 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13469 ovl.fmt.RRF2.r2); goto ok;
13470 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13471 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13472 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013473 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13474 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13475 ovl.fmt.RRF2.r2); goto ok;
13476 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13477 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13478 ovl.fmt.RRF2.r2); goto ok;
13479 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13480 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13481 ovl.fmt.RRF2.r2); goto ok;
13482 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13483 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13484 ovl.fmt.RRF2.r2); goto ok;
13485 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13486 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13487 ovl.fmt.RRF2.r2); goto ok;
13488 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13489 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13490 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013491 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13492 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13493 ovl.fmt.RRF2.r2); goto ok;
13494 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13495 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13496 ovl.fmt.RRF2.r2); goto ok;
13497 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13498 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13499 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013500 case 0xb3b4: /* CEFR */ goto unimplemented;
13501 case 0xb3b5: /* CDFR */ goto unimplemented;
13502 case 0xb3b6: /* CXFR */ goto unimplemented;
13503 case 0xb3b8: /* CFER */ goto unimplemented;
13504 case 0xb3b9: /* CFDR */ goto unimplemented;
13505 case 0xb3ba: /* CFXR */ goto unimplemented;
13506 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13507 ovl.fmt.RRE.r2); goto ok;
13508 case 0xb3c4: /* CEGR */ goto unimplemented;
13509 case 0xb3c5: /* CDGR */ goto unimplemented;
13510 case 0xb3c6: /* CXGR */ goto unimplemented;
13511 case 0xb3c8: /* CGER */ goto unimplemented;
13512 case 0xb3c9: /* CGDR */ goto unimplemented;
13513 case 0xb3ca: /* CGXR */ goto unimplemented;
13514 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13515 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013516 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13517 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13518 ovl.fmt.RRF4.r2); goto ok;
13519 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13520 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13521 ovl.fmt.RRF4.r2); goto ok;
13522 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13523 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13524 ovl.fmt.RRF4.r2); goto ok;
13525 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13526 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13527 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000013528 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
13529 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13530 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
13531 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13532 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013533 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13534 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013535 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013536 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
13537 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13538 ovl.fmt.RRF4.r2); goto ok;
13539 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
13540 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13541 ovl.fmt.RRF4.r2); goto ok;
13542 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
13543 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13544 ovl.fmt.RRF4.r2); goto ok;
13545 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
13546 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13547 ovl.fmt.RRF4.r2); goto ok;
13548 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
13549 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13550 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
13551 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13552 ovl.fmt.RRF2.r2); goto ok;
13553 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
13554 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013555 case 0xb3df: /* FIXTR */ goto unimplemented;
13556 case 0xb3e0: /* KDTR */ goto unimplemented;
13557 case 0xb3e1: /* CGDTR */ goto unimplemented;
13558 case 0xb3e2: /* CUDTR */ goto unimplemented;
13559 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013560 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
13561 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013562 case 0xb3e5: /* EEDTR */ goto unimplemented;
13563 case 0xb3e7: /* ESDTR */ goto unimplemented;
13564 case 0xb3e8: /* KXTR */ goto unimplemented;
13565 case 0xb3e9: /* CGXTR */ goto unimplemented;
13566 case 0xb3ea: /* CUXTR */ goto unimplemented;
13567 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013568 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
13569 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013570 case 0xb3ed: /* EEXTR */ goto unimplemented;
13571 case 0xb3ef: /* ESXTR */ goto unimplemented;
13572 case 0xb3f1: /* CDGTR */ goto unimplemented;
13573 case 0xb3f2: /* CDUTR */ goto unimplemented;
13574 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000013575 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
13576 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013577 case 0xb3f5: /* QADTR */ goto unimplemented;
13578 case 0xb3f6: /* IEDTR */ goto unimplemented;
13579 case 0xb3f7: /* RRDTR */ goto unimplemented;
13580 case 0xb3f9: /* CXGTR */ goto unimplemented;
13581 case 0xb3fa: /* CXUTR */ goto unimplemented;
13582 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000013583 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
13584 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013585 case 0xb3fd: /* QAXTR */ goto unimplemented;
13586 case 0xb3fe: /* IEXTR */ goto unimplemented;
13587 case 0xb3ff: /* RRXTR */ goto unimplemented;
13588 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13589 ovl.fmt.RRE.r2); goto ok;
13590 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13591 ovl.fmt.RRE.r2); goto ok;
13592 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13593 ovl.fmt.RRE.r2); goto ok;
13594 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13595 ovl.fmt.RRE.r2); goto ok;
13596 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13597 ovl.fmt.RRE.r2); goto ok;
13598 case 0xb905: /* LURAG */ goto unimplemented;
13599 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13600 ovl.fmt.RRE.r2); goto ok;
13601 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13602 ovl.fmt.RRE.r2); goto ok;
13603 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13604 ovl.fmt.RRE.r2); goto ok;
13605 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13606 ovl.fmt.RRE.r2); goto ok;
13607 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13608 ovl.fmt.RRE.r2); goto ok;
13609 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13610 ovl.fmt.RRE.r2); goto ok;
13611 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13612 ovl.fmt.RRE.r2); goto ok;
13613 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13614 ovl.fmt.RRE.r2); goto ok;
13615 case 0xb90e: /* EREGG */ goto unimplemented;
13616 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13617 ovl.fmt.RRE.r2); goto ok;
13618 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13619 ovl.fmt.RRE.r2); goto ok;
13620 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13621 ovl.fmt.RRE.r2); goto ok;
13622 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13623 ovl.fmt.RRE.r2); goto ok;
13624 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13625 ovl.fmt.RRE.r2); goto ok;
13626 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13627 ovl.fmt.RRE.r2); goto ok;
13628 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13629 ovl.fmt.RRE.r2); goto ok;
13630 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13631 ovl.fmt.RRE.r2); goto ok;
13632 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13633 ovl.fmt.RRE.r2); goto ok;
13634 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13635 ovl.fmt.RRE.r2); goto ok;
13636 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13637 ovl.fmt.RRE.r2); goto ok;
13638 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13639 ovl.fmt.RRE.r2); goto ok;
13640 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13641 ovl.fmt.RRE.r2); goto ok;
13642 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13643 ovl.fmt.RRE.r2); goto ok;
13644 case 0xb91e: /* KMAC */ goto unimplemented;
13645 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13646 ovl.fmt.RRE.r2); goto ok;
13647 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13648 ovl.fmt.RRE.r2); goto ok;
13649 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13650 ovl.fmt.RRE.r2); goto ok;
13651 case 0xb925: /* STURG */ goto unimplemented;
13652 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13653 ovl.fmt.RRE.r2); goto ok;
13654 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13655 ovl.fmt.RRE.r2); goto ok;
13656 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013657 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013658 case 0xb92b: /* KMO */ goto unimplemented;
13659 case 0xb92c: /* PCC */ goto unimplemented;
13660 case 0xb92d: /* KMCTR */ goto unimplemented;
13661 case 0xb92e: /* KM */ goto unimplemented;
13662 case 0xb92f: /* KMC */ goto unimplemented;
13663 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13664 ovl.fmt.RRE.r2); goto ok;
13665 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13666 ovl.fmt.RRE.r2); goto ok;
13667 case 0xb93e: /* KIMD */ goto unimplemented;
13668 case 0xb93f: /* KLMD */ goto unimplemented;
13669 case 0xb941: /* CFDTR */ goto unimplemented;
13670 case 0xb942: /* CLGDTR */ goto unimplemented;
13671 case 0xb943: /* CLFDTR */ goto unimplemented;
13672 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13673 ovl.fmt.RRE.r2); goto ok;
13674 case 0xb949: /* CFXTR */ goto unimplemented;
13675 case 0xb94a: /* CLGXTR */ goto unimplemented;
13676 case 0xb94b: /* CLFXTR */ goto unimplemented;
13677 case 0xb951: /* CDFTR */ goto unimplemented;
13678 case 0xb952: /* CDLGTR */ goto unimplemented;
13679 case 0xb953: /* CDLFTR */ goto unimplemented;
13680 case 0xb959: /* CXFTR */ goto unimplemented;
13681 case 0xb95a: /* CXLGTR */ goto unimplemented;
13682 case 0xb95b: /* CXLFTR */ goto unimplemented;
13683 case 0xb960: /* CGRT */ goto unimplemented;
13684 case 0xb961: /* CLGRT */ goto unimplemented;
13685 case 0xb972: /* CRT */ goto unimplemented;
13686 case 0xb973: /* CLRT */ goto unimplemented;
13687 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13688 ovl.fmt.RRE.r2); goto ok;
13689 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13690 ovl.fmt.RRE.r2); goto ok;
13691 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13692 ovl.fmt.RRE.r2); goto ok;
13693 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13694 ovl.fmt.RRE.r2); goto ok;
13695 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13696 ovl.fmt.RRE.r2); goto ok;
13697 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13698 ovl.fmt.RRE.r2); goto ok;
13699 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13700 ovl.fmt.RRE.r2); goto ok;
13701 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13702 ovl.fmt.RRE.r2); goto ok;
13703 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13704 ovl.fmt.RRE.r2); goto ok;
13705 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13706 ovl.fmt.RRE.r2); goto ok;
13707 case 0xb98a: /* CSPG */ goto unimplemented;
13708 case 0xb98d: /* EPSW */ goto unimplemented;
13709 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013710 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013711 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13712 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13713 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13714 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13715 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13716 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013717 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13718 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013719 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13720 ovl.fmt.RRE.r2); goto ok;
13721 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13722 ovl.fmt.RRE.r2); goto ok;
13723 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13724 ovl.fmt.RRE.r2); goto ok;
13725 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13726 ovl.fmt.RRE.r2); goto ok;
13727 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13728 ovl.fmt.RRE.r2); goto ok;
13729 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13730 ovl.fmt.RRE.r2); goto ok;
13731 case 0xb99a: /* EPAIR */ goto unimplemented;
13732 case 0xb99b: /* ESAIR */ goto unimplemented;
13733 case 0xb99d: /* ESEA */ goto unimplemented;
13734 case 0xb99e: /* PTI */ goto unimplemented;
13735 case 0xb99f: /* SSAIR */ goto unimplemented;
13736 case 0xb9a2: /* PTF */ goto unimplemented;
13737 case 0xb9aa: /* LPTEA */ goto unimplemented;
13738 case 0xb9ae: /* RRBM */ goto unimplemented;
13739 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013740 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13741 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13742 goto ok;
florian2a415a12012-07-21 17:41:36 +000013743 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13744 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13745 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013746 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13747 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013748 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13749 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013750 case 0xb9bd: /* TRTRE */ goto unimplemented;
13751 case 0xb9be: /* SRSTU */ goto unimplemented;
13752 case 0xb9bf: /* TRTE */ goto unimplemented;
13753 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13754 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13755 goto ok;
13756 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13757 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13758 goto ok;
13759 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13760 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13761 goto ok;
13762 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13763 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13764 goto ok;
13765 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13766 ovl.fmt.RRE.r2); goto ok;
13767 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13768 ovl.fmt.RRE.r2); goto ok;
13769 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13770 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13771 goto ok;
13772 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13773 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13774 goto ok;
13775 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13776 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13777 goto ok;
13778 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13779 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13780 goto ok;
13781 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13782 ovl.fmt.RRE.r2); goto ok;
13783 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13784 ovl.fmt.RRE.r2); goto ok;
13785 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013786 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13787 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13788 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013789 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13790 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13791 goto ok;
13792 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13793 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13794 goto ok;
13795 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13796 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13797 goto ok;
13798 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13799 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13800 goto ok;
13801 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13802 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13803 goto ok;
13804 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13805 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13806 goto ok;
13807 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13808 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13809 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013810 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13811 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13812 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013813 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13814 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13815 goto ok;
13816 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13817 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13818 goto ok;
13819 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13820 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13821 goto ok;
13822 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13823 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13824 goto ok;
13825 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13826 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13827 goto ok;
13828 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13829 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13830 goto ok;
13831 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13832 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13833 goto ok;
13834 }
13835
13836 switch ((ovl.value & 0xff000000) >> 24) {
13837 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13838 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13839 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13840 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13841 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13842 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13843 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13844 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13845 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13846 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13847 case 0x45: /* BAL */ goto unimplemented;
13848 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13849 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13850 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13851 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13852 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13853 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13854 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13855 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13856 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13857 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13858 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13859 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13860 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13861 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13862 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13863 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13864 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13865 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13866 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13867 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13868 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13869 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13870 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13871 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13872 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13873 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13874 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13875 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13876 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13877 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13878 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13879 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13880 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13881 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13882 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13883 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13884 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13885 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13886 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13887 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13888 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13889 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13890 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13891 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13892 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13893 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13894 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13895 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13896 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13897 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13898 case 0x67: /* MXD */ goto unimplemented;
13899 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13900 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13901 case 0x69: /* CD */ goto unimplemented;
13902 case 0x6a: /* AD */ goto unimplemented;
13903 case 0x6b: /* SD */ goto unimplemented;
13904 case 0x6c: /* MD */ goto unimplemented;
13905 case 0x6d: /* DD */ goto unimplemented;
13906 case 0x6e: /* AW */ goto unimplemented;
13907 case 0x6f: /* SW */ goto unimplemented;
13908 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13909 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13910 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13911 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13912 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13913 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13914 case 0x79: /* CE */ goto unimplemented;
13915 case 0x7a: /* AE */ goto unimplemented;
13916 case 0x7b: /* SE */ goto unimplemented;
13917 case 0x7c: /* MDE */ goto unimplemented;
13918 case 0x7d: /* DE */ goto unimplemented;
13919 case 0x7e: /* AU */ goto unimplemented;
13920 case 0x7f: /* SU */ goto unimplemented;
13921 case 0x83: /* DIAG */ goto unimplemented;
13922 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13923 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13924 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13925 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13926 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13927 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13928 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13929 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13930 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13931 ovl.fmt.RS.d2); goto ok;
13932 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13933 ovl.fmt.RS.d2); goto ok;
13934 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13935 ovl.fmt.RS.d2); goto ok;
13936 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13937 ovl.fmt.RS.d2); goto ok;
13938 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13939 ovl.fmt.RS.d2); goto ok;
13940 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13941 ovl.fmt.RS.d2); goto ok;
13942 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13943 ovl.fmt.RS.d2); goto ok;
13944 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13945 ovl.fmt.RS.d2); goto ok;
13946 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13947 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13948 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13949 ovl.fmt.SI.d1); goto ok;
13950 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13951 ovl.fmt.SI.d1); goto ok;
13952 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13953 ovl.fmt.SI.d1); goto ok;
13954 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13955 ovl.fmt.SI.d1); goto ok;
13956 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13957 ovl.fmt.SI.d1); goto ok;
13958 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13959 ovl.fmt.SI.d1); goto ok;
13960 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13961 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13962 case 0x99: /* TRACE */ goto unimplemented;
13963 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13964 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13965 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13966 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13967 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13968 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13969 goto ok;
13970 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13971 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13972 goto ok;
13973 case 0xac: /* STNSM */ goto unimplemented;
13974 case 0xad: /* STOSM */ goto unimplemented;
13975 case 0xae: /* SIGP */ goto unimplemented;
13976 case 0xaf: /* MC */ goto unimplemented;
13977 case 0xb1: /* LRA */ goto unimplemented;
13978 case 0xb6: /* STCTL */ goto unimplemented;
13979 case 0xb7: /* LCTL */ goto unimplemented;
13980 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13981 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013982 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13983 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013984 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13985 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13986 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13987 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13988 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13989 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13990 }
13991
13992 return S390_DECODE_UNKNOWN_INSN;
13993
13994ok:
13995 return S390_DECODE_OK;
13996
13997unimplemented:
13998 return S390_DECODE_UNIMPLEMENTED_INSN;
13999}
14000
14001static s390_decode_t
14002s390_decode_6byte_and_irgen(UChar *bytes)
14003{
14004 typedef union {
14005 struct {
14006 unsigned int op1 : 8;
14007 unsigned int r1 : 4;
14008 unsigned int r3 : 4;
14009 unsigned int i2 : 16;
14010 unsigned int : 8;
14011 unsigned int op2 : 8;
14012 } RIE;
14013 struct {
14014 unsigned int op1 : 8;
14015 unsigned int r1 : 4;
14016 unsigned int r2 : 4;
14017 unsigned int i3 : 8;
14018 unsigned int i4 : 8;
14019 unsigned int i5 : 8;
14020 unsigned int op2 : 8;
14021 } RIE_RRUUU;
14022 struct {
14023 unsigned int op1 : 8;
14024 unsigned int r1 : 4;
14025 unsigned int : 4;
14026 unsigned int i2 : 16;
14027 unsigned int m3 : 4;
14028 unsigned int : 4;
14029 unsigned int op2 : 8;
14030 } RIEv1;
14031 struct {
14032 unsigned int op1 : 8;
14033 unsigned int r1 : 4;
14034 unsigned int r2 : 4;
14035 unsigned int i4 : 16;
14036 unsigned int m3 : 4;
14037 unsigned int : 4;
14038 unsigned int op2 : 8;
14039 } RIE_RRPU;
14040 struct {
14041 unsigned int op1 : 8;
14042 unsigned int r1 : 4;
14043 unsigned int m3 : 4;
14044 unsigned int i4 : 16;
14045 unsigned int i2 : 8;
14046 unsigned int op2 : 8;
14047 } RIEv3;
14048 struct {
14049 unsigned int op1 : 8;
14050 unsigned int r1 : 4;
14051 unsigned int op2 : 4;
14052 unsigned int i2 : 32;
14053 } RIL;
14054 struct {
14055 unsigned int op1 : 8;
14056 unsigned int r1 : 4;
14057 unsigned int m3 : 4;
14058 unsigned int b4 : 4;
14059 unsigned int d4 : 12;
14060 unsigned int i2 : 8;
14061 unsigned int op2 : 8;
14062 } RIS;
14063 struct {
14064 unsigned int op1 : 8;
14065 unsigned int r1 : 4;
14066 unsigned int r2 : 4;
14067 unsigned int b4 : 4;
14068 unsigned int d4 : 12;
14069 unsigned int m3 : 4;
14070 unsigned int : 4;
14071 unsigned int op2 : 8;
14072 } RRS;
14073 struct {
14074 unsigned int op1 : 8;
14075 unsigned int l1 : 4;
14076 unsigned int : 4;
14077 unsigned int b1 : 4;
14078 unsigned int d1 : 12;
14079 unsigned int : 8;
14080 unsigned int op2 : 8;
14081 } RSL;
14082 struct {
14083 unsigned int op1 : 8;
14084 unsigned int r1 : 4;
14085 unsigned int r3 : 4;
14086 unsigned int b2 : 4;
14087 unsigned int dl2 : 12;
14088 unsigned int dh2 : 8;
14089 unsigned int op2 : 8;
14090 } RSY;
14091 struct {
14092 unsigned int op1 : 8;
14093 unsigned int r1 : 4;
14094 unsigned int x2 : 4;
14095 unsigned int b2 : 4;
14096 unsigned int d2 : 12;
14097 unsigned int : 8;
14098 unsigned int op2 : 8;
14099 } RXE;
14100 struct {
14101 unsigned int op1 : 8;
14102 unsigned int r3 : 4;
14103 unsigned int x2 : 4;
14104 unsigned int b2 : 4;
14105 unsigned int d2 : 12;
14106 unsigned int r1 : 4;
14107 unsigned int : 4;
14108 unsigned int op2 : 8;
14109 } RXF;
14110 struct {
14111 unsigned int op1 : 8;
14112 unsigned int r1 : 4;
14113 unsigned int x2 : 4;
14114 unsigned int b2 : 4;
14115 unsigned int dl2 : 12;
14116 unsigned int dh2 : 8;
14117 unsigned int op2 : 8;
14118 } RXY;
14119 struct {
14120 unsigned int op1 : 8;
14121 unsigned int i2 : 8;
14122 unsigned int b1 : 4;
14123 unsigned int dl1 : 12;
14124 unsigned int dh1 : 8;
14125 unsigned int op2 : 8;
14126 } SIY;
14127 struct {
14128 unsigned int op : 8;
14129 unsigned int l : 8;
14130 unsigned int b1 : 4;
14131 unsigned int d1 : 12;
14132 unsigned int b2 : 4;
14133 unsigned int d2 : 12;
14134 } SS;
14135 struct {
14136 unsigned int op : 8;
14137 unsigned int l1 : 4;
14138 unsigned int l2 : 4;
14139 unsigned int b1 : 4;
14140 unsigned int d1 : 12;
14141 unsigned int b2 : 4;
14142 unsigned int d2 : 12;
14143 } SS_LLRDRD;
14144 struct {
14145 unsigned int op : 8;
14146 unsigned int r1 : 4;
14147 unsigned int r3 : 4;
14148 unsigned int b2 : 4;
14149 unsigned int d2 : 12;
14150 unsigned int b4 : 4;
14151 unsigned int d4 : 12;
14152 } SS_RRRDRD2;
14153 struct {
14154 unsigned int op : 16;
14155 unsigned int b1 : 4;
14156 unsigned int d1 : 12;
14157 unsigned int b2 : 4;
14158 unsigned int d2 : 12;
14159 } SSE;
14160 struct {
14161 unsigned int op1 : 8;
14162 unsigned int r3 : 4;
14163 unsigned int op2 : 4;
14164 unsigned int b1 : 4;
14165 unsigned int d1 : 12;
14166 unsigned int b2 : 4;
14167 unsigned int d2 : 12;
14168 } SSF;
14169 struct {
14170 unsigned int op : 16;
14171 unsigned int b1 : 4;
14172 unsigned int d1 : 12;
14173 unsigned int i2 : 16;
14174 } SIL;
14175 } formats;
14176 union {
14177 formats fmt;
14178 ULong value;
14179 } ovl;
14180
14181 vassert(sizeof(formats) == 6);
14182
florianffbd84d2012-12-09 02:06:29 +000014183 ((UChar *)(&ovl.value))[0] = bytes[0];
14184 ((UChar *)(&ovl.value))[1] = bytes[1];
14185 ((UChar *)(&ovl.value))[2] = bytes[2];
14186 ((UChar *)(&ovl.value))[3] = bytes[3];
14187 ((UChar *)(&ovl.value))[4] = bytes[4];
14188 ((UChar *)(&ovl.value))[5] = bytes[5];
14189 ((UChar *)(&ovl.value))[6] = 0x0;
14190 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000014191
14192 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
14193 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
14194 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14195 ovl.fmt.RXY.dl2,
14196 ovl.fmt.RXY.dh2); goto ok;
14197 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
14198 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
14199 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14200 ovl.fmt.RXY.dl2,
14201 ovl.fmt.RXY.dh2); goto ok;
14202 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
14203 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14204 ovl.fmt.RXY.dl2,
14205 ovl.fmt.RXY.dh2); goto ok;
14206 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
14207 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14208 ovl.fmt.RXY.dl2,
14209 ovl.fmt.RXY.dh2); goto ok;
14210 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
14211 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14212 ovl.fmt.RXY.dl2,
14213 ovl.fmt.RXY.dh2); goto ok;
14214 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
14215 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14216 ovl.fmt.RXY.dl2,
14217 ovl.fmt.RXY.dh2); goto ok;
14218 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
14219 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14220 ovl.fmt.RXY.dl2,
14221 ovl.fmt.RXY.dh2); goto ok;
14222 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
14223 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14224 ovl.fmt.RXY.dl2,
14225 ovl.fmt.RXY.dh2); goto ok;
14226 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
14227 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14228 ovl.fmt.RXY.dl2,
14229 ovl.fmt.RXY.dh2); goto ok;
14230 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
14231 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
14232 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14233 ovl.fmt.RXY.dl2,
14234 ovl.fmt.RXY.dh2); goto ok;
14235 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
14236 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14237 ovl.fmt.RXY.dl2,
14238 ovl.fmt.RXY.dh2); goto ok;
14239 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
14240 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
14241 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14242 ovl.fmt.RXY.dl2,
14243 ovl.fmt.RXY.dh2); goto ok;
14244 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
14245 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14246 ovl.fmt.RXY.dl2,
14247 ovl.fmt.RXY.dh2); goto ok;
14248 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
14249 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14250 ovl.fmt.RXY.dl2,
14251 ovl.fmt.RXY.dh2); goto ok;
14252 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
14253 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14254 ovl.fmt.RXY.dl2,
14255 ovl.fmt.RXY.dh2); goto ok;
14256 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
14257 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14258 ovl.fmt.RXY.dl2,
14259 ovl.fmt.RXY.dh2); goto ok;
14260 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
14261 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14262 ovl.fmt.RXY.dl2,
14263 ovl.fmt.RXY.dh2); goto ok;
14264 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
14265 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14266 ovl.fmt.RXY.dl2,
14267 ovl.fmt.RXY.dh2); goto ok;
14268 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
14269 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14270 ovl.fmt.RXY.dl2,
14271 ovl.fmt.RXY.dh2); goto ok;
14272 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
14273 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14274 ovl.fmt.RXY.dl2,
14275 ovl.fmt.RXY.dh2); goto ok;
14276 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
14277 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14278 ovl.fmt.RXY.dl2,
14279 ovl.fmt.RXY.dh2); goto ok;
14280 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
14281 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14282 ovl.fmt.RXY.dl2,
14283 ovl.fmt.RXY.dh2); goto ok;
14284 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
14285 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14286 ovl.fmt.RXY.dl2,
14287 ovl.fmt.RXY.dh2); goto ok;
14288 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
14289 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14290 ovl.fmt.RXY.dl2,
14291 ovl.fmt.RXY.dh2); goto ok;
14292 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
14293 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14294 ovl.fmt.RXY.dl2,
14295 ovl.fmt.RXY.dh2); goto ok;
14296 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
14297 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14298 ovl.fmt.RXY.dl2,
14299 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014300 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014301 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
14302 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14303 ovl.fmt.RXY.dl2,
14304 ovl.fmt.RXY.dh2); goto ok;
14305 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
14306 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
14307 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14308 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14309 ovl.fmt.RXY.dh2); goto ok;
14310 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
14311 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14312 ovl.fmt.RXY.dl2,
14313 ovl.fmt.RXY.dh2); goto ok;
14314 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
14315 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14316 ovl.fmt.RXY.dl2,
14317 ovl.fmt.RXY.dh2); goto ok;
14318 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
14319 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14320 ovl.fmt.RXY.dl2,
14321 ovl.fmt.RXY.dh2); goto ok;
14322 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
14323 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14324 ovl.fmt.RXY.dl2,
14325 ovl.fmt.RXY.dh2); goto ok;
14326 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
14327 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14328 ovl.fmt.RXY.dl2,
14329 ovl.fmt.RXY.dh2); goto ok;
14330 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
14331 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14332 ovl.fmt.RXY.dl2,
14333 ovl.fmt.RXY.dh2); goto ok;
14334 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
14335 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14336 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14337 ovl.fmt.RXY.dh2); goto ok;
14338 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
14339 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14340 ovl.fmt.RXY.dl2,
14341 ovl.fmt.RXY.dh2); goto ok;
14342 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
14343 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14344 ovl.fmt.RXY.dl2,
14345 ovl.fmt.RXY.dh2); goto ok;
14346 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
14347 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14348 ovl.fmt.RXY.dl2,
14349 ovl.fmt.RXY.dh2); goto ok;
14350 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
14351 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14352 ovl.fmt.RXY.dl2,
14353 ovl.fmt.RXY.dh2); goto ok;
14354 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
14355 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14356 ovl.fmt.RXY.dl2,
14357 ovl.fmt.RXY.dh2); goto ok;
14358 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
14359 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14360 ovl.fmt.RXY.dl2,
14361 ovl.fmt.RXY.dh2); goto ok;
14362 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
14363 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14364 ovl.fmt.RXY.dl2,
14365 ovl.fmt.RXY.dh2); goto ok;
14366 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
14367 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14368 ovl.fmt.RXY.dl2,
14369 ovl.fmt.RXY.dh2); goto ok;
14370 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
14371 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14372 ovl.fmt.RXY.dl2,
14373 ovl.fmt.RXY.dh2); goto ok;
14374 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
14375 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14376 ovl.fmt.RXY.dl2,
14377 ovl.fmt.RXY.dh2); goto ok;
14378 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
14379 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14380 ovl.fmt.RXY.dl2,
14381 ovl.fmt.RXY.dh2); goto ok;
14382 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
14383 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14384 ovl.fmt.RXY.dl2,
14385 ovl.fmt.RXY.dh2); goto ok;
14386 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
14387 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14388 ovl.fmt.RXY.dl2,
14389 ovl.fmt.RXY.dh2); goto ok;
14390 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
14391 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14392 ovl.fmt.RXY.dl2,
14393 ovl.fmt.RXY.dh2); goto ok;
14394 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
14395 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14396 ovl.fmt.RXY.dl2,
14397 ovl.fmt.RXY.dh2); goto ok;
14398 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
14399 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14400 ovl.fmt.RXY.dl2,
14401 ovl.fmt.RXY.dh2); goto ok;
14402 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
14403 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14404 ovl.fmt.RXY.dl2,
14405 ovl.fmt.RXY.dh2); goto ok;
14406 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
14407 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14408 ovl.fmt.RXY.dl2,
14409 ovl.fmt.RXY.dh2); goto ok;
14410 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
14411 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14412 ovl.fmt.RXY.dl2,
14413 ovl.fmt.RXY.dh2); goto ok;
14414 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
14415 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14416 ovl.fmt.RXY.dl2,
14417 ovl.fmt.RXY.dh2); goto ok;
14418 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
14419 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14420 ovl.fmt.RXY.dl2,
14421 ovl.fmt.RXY.dh2); goto ok;
14422 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
14423 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14424 ovl.fmt.RXY.dl2,
14425 ovl.fmt.RXY.dh2); goto ok;
14426 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
14427 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14428 ovl.fmt.RXY.dl2,
14429 ovl.fmt.RXY.dh2); goto ok;
14430 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
14431 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14432 ovl.fmt.RXY.dl2,
14433 ovl.fmt.RXY.dh2); goto ok;
14434 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
14435 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14436 ovl.fmt.RXY.dl2,
14437 ovl.fmt.RXY.dh2); goto ok;
14438 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
14439 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14440 ovl.fmt.RXY.dl2,
14441 ovl.fmt.RXY.dh2); goto ok;
14442 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
14443 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14444 ovl.fmt.RXY.dl2,
14445 ovl.fmt.RXY.dh2); goto ok;
14446 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
14447 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14448 ovl.fmt.RXY.dl2,
14449 ovl.fmt.RXY.dh2); goto ok;
14450 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
14451 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14452 ovl.fmt.RXY.dl2,
14453 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014454 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014455 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
14456 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14457 ovl.fmt.RXY.dl2,
14458 ovl.fmt.RXY.dh2); goto ok;
14459 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14460 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14461 ovl.fmt.RXY.dl2,
14462 ovl.fmt.RXY.dh2); goto ok;
14463 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14464 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14465 ovl.fmt.RXY.dl2,
14466 ovl.fmt.RXY.dh2); goto ok;
14467 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14468 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14469 ovl.fmt.RXY.dl2,
14470 ovl.fmt.RXY.dh2); goto ok;
14471 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14472 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14473 ovl.fmt.RXY.dl2,
14474 ovl.fmt.RXY.dh2); goto ok;
14475 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14476 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14477 ovl.fmt.RXY.dl2,
14478 ovl.fmt.RXY.dh2); goto ok;
14479 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14480 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14481 ovl.fmt.RXY.dl2,
14482 ovl.fmt.RXY.dh2); goto ok;
14483 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
14484 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14485 ovl.fmt.RXY.dl2,
14486 ovl.fmt.RXY.dh2); goto ok;
14487 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
14488 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14489 ovl.fmt.RXY.dl2,
14490 ovl.fmt.RXY.dh2); goto ok;
14491 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
14492 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14493 ovl.fmt.RXY.dl2,
14494 ovl.fmt.RXY.dh2); goto ok;
14495 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
14496 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14497 ovl.fmt.RXY.dl2,
14498 ovl.fmt.RXY.dh2); goto ok;
14499 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
14500 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14501 ovl.fmt.RXY.dl2,
14502 ovl.fmt.RXY.dh2); goto ok;
14503 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
14504 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14505 ovl.fmt.RXY.dl2,
14506 ovl.fmt.RXY.dh2); goto ok;
14507 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
14508 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14509 ovl.fmt.RXY.dl2,
14510 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014511 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
14512 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
14513 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014514 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
14515 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14516 ovl.fmt.RXY.dl2,
14517 ovl.fmt.RXY.dh2); goto ok;
14518 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
14519 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14520 ovl.fmt.RXY.dl2,
14521 ovl.fmt.RXY.dh2); goto ok;
14522 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
14523 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14524 ovl.fmt.RXY.dl2,
14525 ovl.fmt.RXY.dh2); goto ok;
14526 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
14527 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14528 ovl.fmt.RXY.dl2,
14529 ovl.fmt.RXY.dh2); goto ok;
14530 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
14531 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14532 ovl.fmt.RXY.dl2,
14533 ovl.fmt.RXY.dh2); goto ok;
14534 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
14535 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14536 ovl.fmt.RXY.dl2,
14537 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014538 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014539 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
14540 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14541 ovl.fmt.RXY.dl2,
14542 ovl.fmt.RXY.dh2); goto ok;
14543 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
14544 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14545 ovl.fmt.RXY.dl2,
14546 ovl.fmt.RXY.dh2); goto ok;
14547 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
14548 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14549 ovl.fmt.RXY.dl2,
14550 ovl.fmt.RXY.dh2); goto ok;
14551 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
14552 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14553 ovl.fmt.RXY.dl2,
14554 ovl.fmt.RXY.dh2); goto ok;
14555 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14556 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14557 ovl.fmt.RSY.dl2,
14558 ovl.fmt.RSY.dh2); goto ok;
14559 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14560 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14561 ovl.fmt.RSY.dl2,
14562 ovl.fmt.RSY.dh2); goto ok;
14563 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14564 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14565 ovl.fmt.RSY.dl2,
14566 ovl.fmt.RSY.dh2); goto ok;
14567 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14568 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14569 ovl.fmt.RSY.dl2,
14570 ovl.fmt.RSY.dh2); goto ok;
14571 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14572 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14573 ovl.fmt.RSY.dl2,
14574 ovl.fmt.RSY.dh2); goto ok;
14575 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14576 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14577 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14578 ovl.fmt.RSY.dl2,
14579 ovl.fmt.RSY.dh2); goto ok;
14580 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14581 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14582 ovl.fmt.RSY.dl2,
14583 ovl.fmt.RSY.dh2); goto ok;
14584 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14585 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14586 ovl.fmt.RSY.dl2,
14587 ovl.fmt.RSY.dh2); goto ok;
14588 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14589 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14590 ovl.fmt.RSY.dl2,
14591 ovl.fmt.RSY.dh2); goto ok;
14592 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14593 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14594 ovl.fmt.RSY.dl2,
14595 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014596 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014597 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
14598 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14599 ovl.fmt.RSY.dl2,
14600 ovl.fmt.RSY.dh2); goto ok;
14601 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14602 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
14603 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14604 ovl.fmt.RSY.dl2,
14605 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014606 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014607 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14608 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14609 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14610 ovl.fmt.RSY.dh2); goto ok;
14611 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14612 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14613 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14614 ovl.fmt.RSY.dh2); goto ok;
14615 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14616 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14617 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14618 ovl.fmt.RSY.dl2,
14619 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014620 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
14621 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14622 ovl.fmt.RSY.dl2,
14623 ovl.fmt.RSY.dh2); goto ok;
14624 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
14625 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14626 ovl.fmt.RSY.dl2,
14627 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014628 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
14629 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14630 ovl.fmt.RSY.dl2,
14631 ovl.fmt.RSY.dh2); goto ok;
14632 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14633 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14634 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14635 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014636 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
14637 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14638 ovl.fmt.RSY.dl2,
14639 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014640 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14641 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14642 ovl.fmt.SIY.dh1); goto ok;
14643 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14644 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14645 ovl.fmt.SIY.dh1); goto ok;
14646 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14647 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14648 ovl.fmt.SIY.dh1); goto ok;
14649 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14650 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14651 ovl.fmt.SIY.dh1); goto ok;
14652 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14653 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14654 ovl.fmt.SIY.dh1); goto ok;
14655 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14656 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14657 ovl.fmt.SIY.dh1); goto ok;
14658 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14659 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14660 ovl.fmt.SIY.dh1); goto ok;
14661 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14662 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14663 ovl.fmt.SIY.dh1); goto ok;
14664 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14665 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14666 ovl.fmt.SIY.dh1); goto ok;
14667 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14668 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14669 ovl.fmt.SIY.dh1); goto ok;
14670 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14671 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14672 ovl.fmt.RSY.dl2,
14673 ovl.fmt.RSY.dh2); goto ok;
14674 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14675 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14676 ovl.fmt.RSY.dl2,
14677 ovl.fmt.RSY.dh2); goto ok;
14678 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14679 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14680 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14681 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14682 ovl.fmt.RSY.dl2,
14683 ovl.fmt.RSY.dh2); goto ok;
14684 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14685 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14686 ovl.fmt.RSY.dl2,
14687 ovl.fmt.RSY.dh2); goto ok;
14688 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14689 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14690 ovl.fmt.RSY.dl2,
14691 ovl.fmt.RSY.dh2); goto ok;
14692 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14693 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14694 ovl.fmt.RSY.dl2,
14695 ovl.fmt.RSY.dh2); goto ok;
14696 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14697 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14698 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14699 ovl.fmt.RSY.dh2); goto ok;
14700 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14701 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14702 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14703 ovl.fmt.RSY.dl2,
14704 ovl.fmt.RSY.dh2); goto ok;
14705 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14706 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14707 ovl.fmt.RSY.dl2,
14708 ovl.fmt.RSY.dh2); goto ok;
14709 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14710 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14711 ovl.fmt.RSY.dl2,
14712 ovl.fmt.RSY.dh2); goto ok;
14713 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14714 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14715 ovl.fmt.RSY.dl2,
14716 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014717 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14718 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14719 ovl.fmt.RSY.dl2,
14720 ovl.fmt.RSY.dh2,
14721 S390_XMNM_LOCG); goto ok;
14722 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14723 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14724 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14725 ovl.fmt.RSY.dh2,
14726 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014727 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14728 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14729 ovl.fmt.RSY.dl2,
14730 ovl.fmt.RSY.dh2); goto ok;
14731 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14732 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14733 ovl.fmt.RSY.dl2,
14734 ovl.fmt.RSY.dh2); goto ok;
14735 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14736 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14737 ovl.fmt.RSY.dl2,
14738 ovl.fmt.RSY.dh2); goto ok;
14739 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14740 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14741 ovl.fmt.RSY.dl2,
14742 ovl.fmt.RSY.dh2); goto ok;
14743 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14744 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14745 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14746 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014747 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14748 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14749 ovl.fmt.RSY.dl2,
14750 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14751 goto ok;
14752 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14753 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14754 ovl.fmt.RSY.dl2,
14755 ovl.fmt.RSY.dh2,
14756 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014757 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14758 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14759 ovl.fmt.RSY.dl2,
14760 ovl.fmt.RSY.dh2); goto ok;
14761 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14762 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14763 ovl.fmt.RSY.dl2,
14764 ovl.fmt.RSY.dh2); goto ok;
14765 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14766 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14767 ovl.fmt.RSY.dl2,
14768 ovl.fmt.RSY.dh2); goto ok;
14769 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14770 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14771 ovl.fmt.RSY.dl2,
14772 ovl.fmt.RSY.dh2); goto ok;
14773 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14774 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14775 ovl.fmt.RSY.dl2,
14776 ovl.fmt.RSY.dh2); goto ok;
14777 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14778 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14779 goto ok;
14780 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14781 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14782 goto ok;
14783 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14784 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14785 ovl.fmt.RIE_RRUUU.r1,
14786 ovl.fmt.RIE_RRUUU.r2,
14787 ovl.fmt.RIE_RRUUU.i3,
14788 ovl.fmt.RIE_RRUUU.i4,
14789 ovl.fmt.RIE_RRUUU.i5);
14790 goto ok;
14791 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14792 ovl.fmt.RIE_RRUUU.r1,
14793 ovl.fmt.RIE_RRUUU.r2,
14794 ovl.fmt.RIE_RRUUU.i3,
14795 ovl.fmt.RIE_RRUUU.i4,
14796 ovl.fmt.RIE_RRUUU.i5);
14797 goto ok;
14798 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14799 ovl.fmt.RIE_RRUUU.r1,
14800 ovl.fmt.RIE_RRUUU.r2,
14801 ovl.fmt.RIE_RRUUU.i3,
14802 ovl.fmt.RIE_RRUUU.i4,
14803 ovl.fmt.RIE_RRUUU.i5);
14804 goto ok;
14805 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14806 ovl.fmt.RIE_RRUUU.r1,
14807 ovl.fmt.RIE_RRUUU.r2,
14808 ovl.fmt.RIE_RRUUU.i3,
14809 ovl.fmt.RIE_RRUUU.i4,
14810 ovl.fmt.RIE_RRUUU.i5);
14811 goto ok;
florian2289cd42012-12-05 04:23:42 +000014812 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014813 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14814 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14815 ovl.fmt.RIE_RRPU.r1,
14816 ovl.fmt.RIE_RRPU.r2,
14817 ovl.fmt.RIE_RRPU.i4,
14818 ovl.fmt.RIE_RRPU.m3); goto ok;
14819 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14820 ovl.fmt.RIE_RRPU.r1,
14821 ovl.fmt.RIE_RRPU.r2,
14822 ovl.fmt.RIE_RRPU.i4,
14823 ovl.fmt.RIE_RRPU.m3); goto ok;
14824 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14825 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14826 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14827 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14828 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14829 ovl.fmt.RIE_RRPU.r1,
14830 ovl.fmt.RIE_RRPU.r2,
14831 ovl.fmt.RIE_RRPU.i4,
14832 ovl.fmt.RIE_RRPU.m3); goto ok;
14833 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14834 ovl.fmt.RIE_RRPU.r1,
14835 ovl.fmt.RIE_RRPU.r2,
14836 ovl.fmt.RIE_RRPU.i4,
14837 ovl.fmt.RIE_RRPU.m3); goto ok;
14838 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14839 ovl.fmt.RIEv3.r1,
14840 ovl.fmt.RIEv3.m3,
14841 ovl.fmt.RIEv3.i4,
14842 ovl.fmt.RIEv3.i2); goto ok;
14843 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14844 ovl.fmt.RIEv3.r1,
14845 ovl.fmt.RIEv3.m3,
14846 ovl.fmt.RIEv3.i4,
14847 ovl.fmt.RIEv3.i2); goto ok;
14848 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14849 ovl.fmt.RIEv3.r1,
14850 ovl.fmt.RIEv3.m3,
14851 ovl.fmt.RIEv3.i4,
14852 ovl.fmt.RIEv3.i2); goto ok;
14853 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14854 ovl.fmt.RIEv3.r1,
14855 ovl.fmt.RIEv3.m3,
14856 ovl.fmt.RIEv3.i4,
14857 ovl.fmt.RIEv3.i2); goto ok;
14858 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14859 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14860 goto ok;
14861 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14862 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14863 ovl.fmt.RIE.i2); goto ok;
14864 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14865 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14866 ovl.fmt.RIE.i2); goto ok;
14867 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14868 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14869 ovl.fmt.RIE.i2); goto ok;
14870 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14871 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14872 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14873 goto ok;
14874 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14875 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14876 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14877 goto ok;
14878 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14879 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14880 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14881 goto ok;
14882 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14883 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14884 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14885 goto ok;
14886 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14887 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14888 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14889 ovl.fmt.RIS.i2); goto ok;
14890 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14891 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14892 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14893 ovl.fmt.RIS.i2); goto ok;
14894 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14895 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14896 ovl.fmt.RIS.d4,
14897 ovl.fmt.RIS.i2); goto ok;
14898 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14899 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14900 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14901 ovl.fmt.RIS.i2); goto ok;
14902 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14903 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14904 ovl.fmt.RXE.d2); goto ok;
14905 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14906 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14907 ovl.fmt.RXE.d2); goto ok;
14908 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14909 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14910 ovl.fmt.RXE.d2); goto ok;
14911 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14912 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14913 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14914 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14915 ovl.fmt.RXE.d2); goto ok;
14916 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14917 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14918 ovl.fmt.RXE.d2); goto ok;
14919 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14920 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14921 ovl.fmt.RXE.d2); goto ok;
14922 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14923 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14924 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14925 ovl.fmt.RXE.d2); goto ok;
14926 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14927 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14928 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14929 ovl.fmt.RXF.r1); goto ok;
14930 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14931 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14932 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14933 ovl.fmt.RXF.r1); goto ok;
14934 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14935 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14936 ovl.fmt.RXE.d2); goto ok;
14937 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14938 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14939 ovl.fmt.RXE.d2); goto ok;
14940 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14941 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14942 ovl.fmt.RXE.d2); goto ok;
14943 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14944 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14945 ovl.fmt.RXE.d2); goto ok;
14946 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14947 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14948 ovl.fmt.RXE.d2); goto ok;
14949 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14950 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14951 ovl.fmt.RXE.d2); goto ok;
14952 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14953 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14954 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14955 ovl.fmt.RXE.d2); goto ok;
14956 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14957 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14958 ovl.fmt.RXE.d2); goto ok;
14959 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14960 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14961 ovl.fmt.RXE.d2); goto ok;
14962 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14963 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14964 ovl.fmt.RXE.d2); goto ok;
14965 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14966 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14967 ovl.fmt.RXE.d2); goto ok;
14968 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14969 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14970 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14971 ovl.fmt.RXF.r1); goto ok;
14972 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14973 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14974 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14975 ovl.fmt.RXF.r1); goto ok;
14976 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14977 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14978 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14979 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14980 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14981 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14982 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14983 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14984 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14985 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14986 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14987 case 0xed000000003bULL: /* MY */ goto unimplemented;
14988 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14989 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14990 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14991 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14992 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14993 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14994 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14995 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14996 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14997 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14998 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14999 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
15000 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
15001 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
15002 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
15003 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15004 ovl.fmt.RXY.dl2,
15005 ovl.fmt.RXY.dh2); goto ok;
15006 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
15007 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15008 ovl.fmt.RXY.dl2,
15009 ovl.fmt.RXY.dh2); goto ok;
15010 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
15011 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15012 ovl.fmt.RXY.dl2,
15013 ovl.fmt.RXY.dh2); goto ok;
15014 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
15015 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15016 ovl.fmt.RXY.dl2,
15017 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015018 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
15019 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
15020 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
15021 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015022 }
15023
15024 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
15025 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
15026 ovl.fmt.RIL.i2); goto ok;
15027 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
15028 ovl.fmt.RIL.i2); goto ok;
15029 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
15030 ovl.fmt.RIL.i2); goto ok;
15031 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
15032 ovl.fmt.RIL.i2); goto ok;
15033 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
15034 ovl.fmt.RIL.i2); goto ok;
15035 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
15036 ovl.fmt.RIL.i2); goto ok;
15037 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
15038 ovl.fmt.RIL.i2); goto ok;
15039 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
15040 ovl.fmt.RIL.i2); goto ok;
15041 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
15042 ovl.fmt.RIL.i2); goto ok;
15043 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
15044 ovl.fmt.RIL.i2); goto ok;
15045 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
15046 ovl.fmt.RIL.i2); goto ok;
15047 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
15048 ovl.fmt.RIL.i2); goto ok;
15049 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
15050 ovl.fmt.RIL.i2); goto ok;
15051 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
15052 ovl.fmt.RIL.i2); goto ok;
15053 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
15054 ovl.fmt.RIL.i2); goto ok;
15055 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
15056 ovl.fmt.RIL.i2); goto ok;
15057 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
15058 ovl.fmt.RIL.i2); goto ok;
15059 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
15060 ovl.fmt.RIL.i2); goto ok;
15061 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
15062 ovl.fmt.RIL.i2); goto ok;
15063 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
15064 ovl.fmt.RIL.i2); goto ok;
15065 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
15066 ovl.fmt.RIL.i2); goto ok;
15067 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
15068 ovl.fmt.RIL.i2); goto ok;
15069 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
15070 ovl.fmt.RIL.i2); goto ok;
15071 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
15072 ovl.fmt.RIL.i2); goto ok;
15073 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
15074 ovl.fmt.RIL.i2); goto ok;
15075 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
15076 ovl.fmt.RIL.i2); goto ok;
15077 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
15078 ovl.fmt.RIL.i2); goto ok;
15079 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
15080 ovl.fmt.RIL.i2); goto ok;
15081 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
15082 ovl.fmt.RIL.i2); goto ok;
15083 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
15084 ovl.fmt.RIL.i2); goto ok;
15085 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
15086 ovl.fmt.RIL.i2); goto ok;
15087 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
15088 ovl.fmt.RIL.i2); goto ok;
15089 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
15090 ovl.fmt.RIL.i2); goto ok;
15091 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
15092 ovl.fmt.RIL.i2); goto ok;
15093 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
15094 ovl.fmt.RIL.i2); goto ok;
15095 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
15096 ovl.fmt.RIL.i2); goto ok;
15097 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
15098 ovl.fmt.RIL.i2); goto ok;
15099 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
15100 ovl.fmt.RIL.i2); goto ok;
15101 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
15102 ovl.fmt.RIL.i2); goto ok;
15103 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
15104 ovl.fmt.RIL.i2); goto ok;
15105 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
15106 ovl.fmt.RIL.i2); goto ok;
15107 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
15108 ovl.fmt.RIL.i2); goto ok;
15109 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
15110 ovl.fmt.RIL.i2); goto ok;
15111 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
15112 ovl.fmt.RIL.i2); goto ok;
15113 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
15114 ovl.fmt.RIL.i2); goto ok;
15115 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
15116 ovl.fmt.RIL.i2); goto ok;
15117 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
15118 ovl.fmt.RIL.i2); goto ok;
15119 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
15120 ovl.fmt.RIL.i2); goto ok;
15121 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
15122 ovl.fmt.RIL.i2); goto ok;
15123 case 0xc800ULL: /* MVCOS */ goto unimplemented;
15124 case 0xc801ULL: /* ECTG */ goto unimplemented;
15125 case 0xc802ULL: /* CSST */ goto unimplemented;
15126 case 0xc804ULL: /* LPD */ goto unimplemented;
15127 case 0xc805ULL: /* LPDG */ goto unimplemented;
15128 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
15129 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
15130 ovl.fmt.RIL.i2); goto ok;
15131 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
15132 ovl.fmt.RIL.i2); goto ok;
15133 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
15134 ovl.fmt.RIL.i2); goto ok;
15135 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
15136 ovl.fmt.RIL.i2); goto ok;
15137 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
15138 ovl.fmt.RIL.i2); goto ok;
15139 }
15140
15141 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000015142 case 0xc5ULL: /* BPRP */ goto unimplemented;
15143 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015144 case 0xd0ULL: /* TRTR */ goto unimplemented;
15145 case 0xd1ULL: /* MVN */ goto unimplemented;
15146 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
15147 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15148 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15149 case 0xd3ULL: /* MVZ */ goto unimplemented;
15150 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
15151 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15152 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15153 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
15154 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15155 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15156 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
15157 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15158 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000015159 case 0xd7ULL:
15160 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
15161 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
15162 else
15163 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
15164 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15165 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
15166 goto ok;
sewardj2019a972011-03-07 16:04:07 +000015167 case 0xd9ULL: /* MVCK */ goto unimplemented;
15168 case 0xdaULL: /* MVCP */ goto unimplemented;
15169 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015170 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
15171 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15172 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015173 case 0xddULL: /* TRT */ goto unimplemented;
15174 case 0xdeULL: /* ED */ goto unimplemented;
15175 case 0xdfULL: /* EDMK */ goto unimplemented;
15176 case 0xe1ULL: /* PKU */ goto unimplemented;
15177 case 0xe2ULL: /* UNPKU */ goto unimplemented;
15178 case 0xe8ULL: /* MVCIN */ goto unimplemented;
15179 case 0xe9ULL: /* PKA */ goto unimplemented;
15180 case 0xeaULL: /* UNPKA */ goto unimplemented;
15181 case 0xeeULL: /* PLO */ goto unimplemented;
15182 case 0xefULL: /* LMD */ goto unimplemented;
15183 case 0xf0ULL: /* SRP */ goto unimplemented;
15184 case 0xf1ULL: /* MVO */ goto unimplemented;
15185 case 0xf2ULL: /* PACK */ goto unimplemented;
15186 case 0xf3ULL: /* UNPK */ goto unimplemented;
15187 case 0xf8ULL: /* ZAP */ goto unimplemented;
15188 case 0xf9ULL: /* CP */ goto unimplemented;
15189 case 0xfaULL: /* AP */ goto unimplemented;
15190 case 0xfbULL: /* SP */ goto unimplemented;
15191 case 0xfcULL: /* MP */ goto unimplemented;
15192 case 0xfdULL: /* DP */ goto unimplemented;
15193 }
15194
15195 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
15196 case 0xe500ULL: /* LASP */ goto unimplemented;
15197 case 0xe501ULL: /* TPROT */ goto unimplemented;
15198 case 0xe502ULL: /* STRAG */ goto unimplemented;
15199 case 0xe50eULL: /* MVCSK */ goto unimplemented;
15200 case 0xe50fULL: /* MVCDK */ goto unimplemented;
15201 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
15202 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15203 goto ok;
15204 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
15205 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15206 goto ok;
15207 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
15208 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15209 goto ok;
15210 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
15211 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15212 goto ok;
15213 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
15214 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15215 goto ok;
15216 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
15217 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15218 goto ok;
15219 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
15220 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15221 goto ok;
15222 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
15223 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15224 goto ok;
15225 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
15226 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15227 goto ok;
florian2289cd42012-12-05 04:23:42 +000015228 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
15229 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015230 }
15231
15232 return S390_DECODE_UNKNOWN_INSN;
15233
15234ok:
15235 return S390_DECODE_OK;
15236
15237unimplemented:
15238 return S390_DECODE_UNIMPLEMENTED_INSN;
15239}
15240
15241/* Handle "special" instructions. */
15242static s390_decode_t
15243s390_decode_special_and_irgen(UChar *bytes)
15244{
15245 s390_decode_t status = S390_DECODE_OK;
15246
15247 /* Got a "Special" instruction preamble. Which one is it? */
15248 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
15249 s390_irgen_client_request();
15250 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
15251 s390_irgen_guest_NRADDR();
15252 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
15253 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000015254 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
15255 vex_inject_ir(irsb, Iend_BE);
15256
15257 /* Invalidate the current insn. The reason is that the IRop we're
15258 injecting here can change. In which case the translation has to
15259 be redone. For ease of handling, we simply invalidate all the
15260 time. */
15261 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
15262 mkU64(guest_IA_curr_instr)));
15263 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
15264 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
15265 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
15266 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
15267
15268 put_IA(mkaddr_expr(guest_IA_next_instr));
15269 dis_res->whatNext = Dis_StopHere;
15270 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000015271 } else {
15272 /* We don't know what it is. */
15273 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
15274 }
15275
15276 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15277
15278 return status;
15279}
15280
15281
15282/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000015283static UInt
sewardj2019a972011-03-07 16:04:07 +000015284s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
15285{
15286 s390_decode_t status;
15287
15288 dis_res = dres;
15289
15290 /* Spot the 8-byte preamble: 18ff lr r15,r15
15291 1811 lr r1,r1
15292 1822 lr r2,r2
15293 1833 lr r3,r3 */
15294 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
15295 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
15296 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
15297
15298 /* Handle special instruction that follows that preamble. */
15299 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000015300
15301 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15302 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15303
15304 status =
15305 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000015306 } else {
15307 /* Handle normal instructions. */
15308 switch (insn_length) {
15309 case 2:
15310 status = s390_decode_2byte_and_irgen(bytes);
15311 break;
15312
15313 case 4:
15314 status = s390_decode_4byte_and_irgen(bytes);
15315 break;
15316
15317 case 6:
15318 status = s390_decode_6byte_and_irgen(bytes);
15319 break;
15320
15321 default:
15322 status = S390_DECODE_ERROR;
15323 break;
15324 }
15325 }
florian5fcbba22011-07-27 20:40:22 +000015326 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000015327 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
15328 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000015329 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000015330 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000015331 }
15332
15333 if (status == S390_DECODE_OK) return insn_length; /* OK */
15334
15335 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000015336 if (sigill_diag) {
15337 vex_printf("vex s390->IR: ");
15338 switch (status) {
15339 case S390_DECODE_UNKNOWN_INSN:
15340 vex_printf("unknown insn: ");
15341 break;
sewardj2019a972011-03-07 16:04:07 +000015342
sewardj442e51a2012-12-06 18:08:04 +000015343 case S390_DECODE_UNIMPLEMENTED_INSN:
15344 vex_printf("unimplemented insn: ");
15345 break;
sewardj2019a972011-03-07 16:04:07 +000015346
sewardj442e51a2012-12-06 18:08:04 +000015347 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
15348 vex_printf("unimplemented special insn: ");
15349 break;
sewardj2019a972011-03-07 16:04:07 +000015350
sewardj442e51a2012-12-06 18:08:04 +000015351 default:
15352 case S390_DECODE_ERROR:
15353 vex_printf("decoding error: ");
15354 break;
15355 }
15356
15357 vex_printf("%02x%02x", bytes[0], bytes[1]);
15358 if (insn_length > 2) {
15359 vex_printf(" %02x%02x", bytes[2], bytes[3]);
15360 }
15361 if (insn_length > 4) {
15362 vex_printf(" %02x%02x", bytes[4], bytes[5]);
15363 }
15364 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000015365 }
15366
sewardj2019a972011-03-07 16:04:07 +000015367 return 0; /* Failed */
15368}
15369
15370
sewardj2019a972011-03-07 16:04:07 +000015371/* Disassemble a single instruction INSN into IR. */
15372static DisResult
florian420c5012011-07-22 02:12:28 +000015373disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000015374{
15375 UChar byte;
15376 UInt insn_length;
15377 DisResult dres;
15378
15379 /* ---------------------------------------------------- */
15380 /* --- Compute instruction length -- */
15381 /* ---------------------------------------------------- */
15382
15383 /* Get the first byte of the insn. */
15384 byte = insn[0];
15385
15386 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
15387 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
15388 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
15389
15390 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15391
15392 /* ---------------------------------------------------- */
15393 /* --- Initialise the DisResult data -- */
15394 /* ---------------------------------------------------- */
15395 dres.whatNext = Dis_Continue;
15396 dres.len = insn_length;
15397 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000015398 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000015399
floriana99f20e2011-07-17 14:16:41 +000015400 /* fixs390: consider chasing of conditional jumps */
15401
sewardj2019a972011-03-07 16:04:07 +000015402 /* Normal and special instruction handling starts here. */
15403 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
15404 /* All decode failures end up here. The decoder has already issued an
15405 error message.
15406 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000015407 not been executed, and (is currently) the next to be executed.
15408 The insn address in the guest state needs to be set to
15409 guest_IA_curr_instr, otherwise the complaint will report an
15410 incorrect address. */
15411 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000015412
florian8844a632012-04-13 04:04:06 +000015413 dres.whatNext = Dis_StopHere;
15414 dres.jk_StopHere = Ijk_NoDecode;
15415 dres.continueAt = 0;
15416 dres.len = 0;
15417 } else {
15418 /* Decode success */
15419 switch (dres.whatNext) {
15420 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015421 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015422 break;
15423 case Dis_ResteerU:
15424 case Dis_ResteerC:
15425 put_IA(mkaddr_expr(dres.continueAt));
15426 break;
15427 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000015428 if (dres.jk_StopHere == Ijk_EmWarn ||
15429 dres.jk_StopHere == Ijk_EmFail) {
15430 /* We assume here, that emulation warnings are not given for
15431 insns that transfer control. There is no good way to
15432 do that. */
15433 put_IA(mkaddr_expr(guest_IA_next_instr));
15434 }
florian8844a632012-04-13 04:04:06 +000015435 break;
15436 default:
15437 vassert(0);
15438 }
sewardj2019a972011-03-07 16:04:07 +000015439 }
15440
15441 return dres;
15442}
15443
15444
15445/*------------------------------------------------------------*/
15446/*--- Top-level fn ---*/
15447/*------------------------------------------------------------*/
15448
15449/* Disassemble a single instruction into IR. The instruction
15450 is located in host memory at &guest_code[delta]. */
15451
15452DisResult
15453disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015454 Bool (*resteerOkFn)(void *, Addr64),
15455 Bool resteerCisOk,
15456 void *callback_opaque,
15457 UChar *guest_code,
15458 Long delta,
15459 Addr64 guest_IP,
15460 VexArch guest_arch,
15461 VexArchInfo *archinfo,
15462 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000015463 Bool host_bigendian,
15464 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000015465{
15466 vassert(guest_arch == VexArchS390X);
15467
15468 /* The instruction decoder requires a big-endian machine. */
15469 vassert(host_bigendian == True);
15470
15471 /* Set globals (see top of this file) */
15472 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015473 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015474 resteer_fn = resteerOkFn;
15475 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000015476 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000015477
florian420c5012011-07-22 02:12:28 +000015478 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015479}
15480
15481/*---------------------------------------------------------------*/
15482/*--- end guest_s390_toIR.c ---*/
15483/*---------------------------------------------------------------*/