blob: 25cfb988741f0d4b3cb7d3f708c4b1ed06ed6e44 [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
florian99dd03e2013-01-29 03:56:06 +0000243 return IRExpr_ITE(condition, iftrue, iffalse);
sewardj2019a972011-03-07 16:04:07 +0000244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
635 op = mkU64(opc);
636 dep1 = mkexpr(d1);
637 dep2 = mkU64(0);
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, dep1, dep2, ndep);
641}
642
643
644/* Write a floating point value and an integer into the flags thunk. The
645 integer value is zero-extended first. */
646static void
647s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
648{
649 IRExpr *op, *dep1, *dep2, *ndep;
650
651 op = mkU64(opc);
652 dep1 = mkexpr(d1);
653 dep2 = s390_cc_widen(d2, False);
654 ndep = mkU64(0);
655
656 s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a 128-bit floating point value into the flags thunk. This is
661 done by splitting the value into two 64-bits values. */
662static void
663s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
664{
665 IRExpr *op, *hi, *lo, *ndep;
666
667 op = mkU64(opc);
668 hi = unop(Iop_F128HItoF64, mkexpr(d1));
669 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, hi, lo, ndep);
673}
674
675
676/* Write a 128-bit floating point value and an integer into the flags thunk.
677 The integer value is zero-extended first. */
678static void
679s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
680{
681 IRExpr *op, *hi, *lo, *lox, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
686 ndep = s390_cc_widen(nd, False);
687
688 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
689
690 s390_cc_thunk_fill(op, hi, lox, ndep);
691}
692
693
floriane38f6412012-12-21 17:32:12 +0000694/* Write a 128-bit decimal floating point value into the flags thunk.
695 This is done by splitting the value into two 64-bits values. */
696static void
697s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
698{
699 IRExpr *op, *hi, *lo, *ndep;
700
701 op = mkU64(opc);
702 hi = unop(Iop_D128HItoD64, mkexpr(d1));
703 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
704 ndep = mkU64(0);
705
706 s390_cc_thunk_fill(op, hi, lo, ndep);
707}
708
709
floriance9e3db2012-12-27 20:14:03 +0000710/* Write a 128-bit decimal floating point value and an integer into the flags
711 thunk. The integer value is zero-extended first. */
712static void
713s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
714{
715 IRExpr *op, *hi, *lo, *lox, *ndep;
716
717 op = mkU64(opc);
718 hi = unop(Iop_D128HItoD64, mkexpr(d1));
719 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
720 ndep = s390_cc_widen(nd, False);
721
722 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
723
724 s390_cc_thunk_fill(op, hi, lox, ndep);
725}
726
727
sewardj2019a972011-03-07 16:04:07 +0000728static void
729s390_cc_set(UInt val)
730{
731 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
732 mkU64(val), mkU64(0), mkU64(0));
733}
734
735/* Build IR to calculate the condition code from flags thunk.
736 Returns an expression of type Ity_I32 */
737static IRExpr *
738s390_call_calculate_cc(void)
739{
740 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
741
florian428dfdd2012-03-27 03:09:49 +0000742 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
743 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
744 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
745 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000746
747 args = mkIRExprVec_4(op, dep1, dep2, ndep);
748 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
749 "s390_calculate_cc", &s390_calculate_cc, args);
750
751 /* Exclude OP and NDEP from definedness checking. We're only
752 interested in DEP1 and DEP2. */
753 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
754
755 return call;
756}
757
758/* Build IR to calculate the internal condition code for a "compare and branch"
759 insn. Returns an expression of type Ity_I32 */
760static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000761s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000762{
florianff9613f2012-05-12 15:26:44 +0000763 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000764
florianff9613f2012-05-12 15:26:44 +0000765 switch (opc) {
766 case S390_CC_OP_SIGNED_COMPARE:
767 dep1 = s390_cc_widen(op1, True);
768 dep2 = s390_cc_widen(op2, True);
769 break;
770
771 case S390_CC_OP_UNSIGNED_COMPARE:
772 dep1 = s390_cc_widen(op1, False);
773 dep2 = s390_cc_widen(op2, False);
774 break;
775
776 default:
777 vpanic("s390_call_calculate_icc");
778 }
779
780 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000781 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000782
florianff9613f2012-05-12 15:26:44 +0000783 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000784 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000785 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000786
florianff9613f2012-05-12 15:26:44 +0000787 /* Exclude the requested condition, OP and NDEP from definedness
788 checking. We're only interested in DEP1 and DEP2. */
789 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000790
791 return call;
792}
793
794/* Build IR to calculate the condition code from flags thunk.
795 Returns an expression of type Ity_I32 */
796static IRExpr *
797s390_call_calculate_cond(UInt m)
798{
799 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
800
801 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000802 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
803 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
804 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
805 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000806
807 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
808 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
809 "s390_calculate_cond", &s390_calculate_cond, args);
810
811 /* Exclude the requested condition, OP and NDEP from definedness
812 checking. We're only interested in DEP1 and DEP2. */
813 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
814
815 return call;
816}
817
818#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
819#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
820#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
821#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
822#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
823#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
824#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
825 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
826#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
827 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000828
829
sewardj2019a972011-03-07 16:04:07 +0000830
831
832/*------------------------------------------------------------*/
833/*--- Guest register access ---*/
834/*------------------------------------------------------------*/
835
836
837/*------------------------------------------------------------*/
838/*--- ar registers ---*/
839/*------------------------------------------------------------*/
840
841/* Return the guest state offset of a ar register. */
842static UInt
843ar_offset(UInt archreg)
844{
845 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000846 S390X_GUEST_OFFSET(guest_a0),
847 S390X_GUEST_OFFSET(guest_a1),
848 S390X_GUEST_OFFSET(guest_a2),
849 S390X_GUEST_OFFSET(guest_a3),
850 S390X_GUEST_OFFSET(guest_a4),
851 S390X_GUEST_OFFSET(guest_a5),
852 S390X_GUEST_OFFSET(guest_a6),
853 S390X_GUEST_OFFSET(guest_a7),
854 S390X_GUEST_OFFSET(guest_a8),
855 S390X_GUEST_OFFSET(guest_a9),
856 S390X_GUEST_OFFSET(guest_a10),
857 S390X_GUEST_OFFSET(guest_a11),
858 S390X_GUEST_OFFSET(guest_a12),
859 S390X_GUEST_OFFSET(guest_a13),
860 S390X_GUEST_OFFSET(guest_a14),
861 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000862 };
863
864 vassert(archreg < 16);
865
866 return offset[archreg];
867}
868
869
870/* Return the guest state offset of word #0 of a ar register. */
871static __inline__ UInt
872ar_w0_offset(UInt archreg)
873{
874 return ar_offset(archreg) + 0;
875}
876
877/* Write word #0 of a ar to the guest state. */
878static __inline__ void
879put_ar_w0(UInt archreg, IRExpr *expr)
880{
881 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
882
883 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
884}
885
886/* Read word #0 of a ar register. */
887static __inline__ IRExpr *
888get_ar_w0(UInt archreg)
889{
890 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
891}
892
893
894/*------------------------------------------------------------*/
895/*--- fpr registers ---*/
896/*------------------------------------------------------------*/
897
898/* Return the guest state offset of a fpr register. */
899static UInt
900fpr_offset(UInt archreg)
901{
902 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000903 S390X_GUEST_OFFSET(guest_f0),
904 S390X_GUEST_OFFSET(guest_f1),
905 S390X_GUEST_OFFSET(guest_f2),
906 S390X_GUEST_OFFSET(guest_f3),
907 S390X_GUEST_OFFSET(guest_f4),
908 S390X_GUEST_OFFSET(guest_f5),
909 S390X_GUEST_OFFSET(guest_f6),
910 S390X_GUEST_OFFSET(guest_f7),
911 S390X_GUEST_OFFSET(guest_f8),
912 S390X_GUEST_OFFSET(guest_f9),
913 S390X_GUEST_OFFSET(guest_f10),
914 S390X_GUEST_OFFSET(guest_f11),
915 S390X_GUEST_OFFSET(guest_f12),
916 S390X_GUEST_OFFSET(guest_f13),
917 S390X_GUEST_OFFSET(guest_f14),
918 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000919 };
920
921 vassert(archreg < 16);
922
923 return offset[archreg];
924}
925
926
927/* Return the guest state offset of word #0 of a fpr register. */
928static __inline__ UInt
929fpr_w0_offset(UInt archreg)
930{
931 return fpr_offset(archreg) + 0;
932}
933
934/* Write word #0 of a fpr to the guest state. */
935static __inline__ void
936put_fpr_w0(UInt archreg, IRExpr *expr)
937{
938 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
939
940 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
941}
942
943/* Read word #0 of a fpr register. */
944static __inline__ IRExpr *
945get_fpr_w0(UInt archreg)
946{
947 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
948}
949
950/* Return the guest state offset of double word #0 of a fpr register. */
951static __inline__ UInt
952fpr_dw0_offset(UInt archreg)
953{
954 return fpr_offset(archreg) + 0;
955}
956
957/* Write double word #0 of a fpr to the guest state. */
958static __inline__ void
959put_fpr_dw0(UInt archreg, IRExpr *expr)
960{
961 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
962
963 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
964}
965
966/* Read double word #0 of a fpr register. */
967static __inline__ IRExpr *
968get_fpr_dw0(UInt archreg)
969{
970 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
971}
972
floriane38f6412012-12-21 17:32:12 +0000973/* Write word #0 of a dpr to the guest state. */
974static __inline__ void
975put_dpr_w0(UInt archreg, IRExpr *expr)
976{
977 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
978
979 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
980}
981
982/* Read word #0 of a dpr register. */
983static __inline__ IRExpr *
984get_dpr_w0(UInt archreg)
985{
986 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
987}
988
florian12390202012-11-10 22:34:14 +0000989/* Write double word #0 of a fpr containg DFP value to the guest state. */
990static __inline__ void
991put_dpr_dw0(UInt archreg, IRExpr *expr)
992{
993 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
994
995 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
996}
997
998/* Read double word #0 of a fpr register containing DFP value. */
999static __inline__ IRExpr *
1000get_dpr_dw0(UInt archreg)
1001{
1002 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1003}
sewardj2019a972011-03-07 16:04:07 +00001004
1005/*------------------------------------------------------------*/
1006/*--- gpr registers ---*/
1007/*------------------------------------------------------------*/
1008
1009/* Return the guest state offset of a gpr register. */
1010static UInt
1011gpr_offset(UInt archreg)
1012{
1013 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001014 S390X_GUEST_OFFSET(guest_r0),
1015 S390X_GUEST_OFFSET(guest_r1),
1016 S390X_GUEST_OFFSET(guest_r2),
1017 S390X_GUEST_OFFSET(guest_r3),
1018 S390X_GUEST_OFFSET(guest_r4),
1019 S390X_GUEST_OFFSET(guest_r5),
1020 S390X_GUEST_OFFSET(guest_r6),
1021 S390X_GUEST_OFFSET(guest_r7),
1022 S390X_GUEST_OFFSET(guest_r8),
1023 S390X_GUEST_OFFSET(guest_r9),
1024 S390X_GUEST_OFFSET(guest_r10),
1025 S390X_GUEST_OFFSET(guest_r11),
1026 S390X_GUEST_OFFSET(guest_r12),
1027 S390X_GUEST_OFFSET(guest_r13),
1028 S390X_GUEST_OFFSET(guest_r14),
1029 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001030 };
1031
1032 vassert(archreg < 16);
1033
1034 return offset[archreg];
1035}
1036
1037
1038/* Return the guest state offset of word #0 of a gpr register. */
1039static __inline__ UInt
1040gpr_w0_offset(UInt archreg)
1041{
1042 return gpr_offset(archreg) + 0;
1043}
1044
1045/* Write word #0 of a gpr to the guest state. */
1046static __inline__ void
1047put_gpr_w0(UInt archreg, IRExpr *expr)
1048{
1049 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1050
1051 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1052}
1053
1054/* Read word #0 of a gpr register. */
1055static __inline__ IRExpr *
1056get_gpr_w0(UInt archreg)
1057{
1058 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1059}
1060
1061/* Return the guest state offset of double word #0 of a gpr register. */
1062static __inline__ UInt
1063gpr_dw0_offset(UInt archreg)
1064{
1065 return gpr_offset(archreg) + 0;
1066}
1067
1068/* Write double word #0 of a gpr to the guest state. */
1069static __inline__ void
1070put_gpr_dw0(UInt archreg, IRExpr *expr)
1071{
1072 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1073
1074 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1075}
1076
1077/* Read double word #0 of a gpr register. */
1078static __inline__ IRExpr *
1079get_gpr_dw0(UInt archreg)
1080{
1081 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1082}
1083
1084/* Return the guest state offset of half word #1 of a gpr register. */
1085static __inline__ UInt
1086gpr_hw1_offset(UInt archreg)
1087{
1088 return gpr_offset(archreg) + 2;
1089}
1090
1091/* Write half word #1 of a gpr to the guest state. */
1092static __inline__ void
1093put_gpr_hw1(UInt archreg, IRExpr *expr)
1094{
1095 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1096
1097 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1098}
1099
1100/* Read half word #1 of a gpr register. */
1101static __inline__ IRExpr *
1102get_gpr_hw1(UInt archreg)
1103{
1104 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1105}
1106
1107/* Return the guest state offset of byte #6 of a gpr register. */
1108static __inline__ UInt
1109gpr_b6_offset(UInt archreg)
1110{
1111 return gpr_offset(archreg) + 6;
1112}
1113
1114/* Write byte #6 of a gpr to the guest state. */
1115static __inline__ void
1116put_gpr_b6(UInt archreg, IRExpr *expr)
1117{
1118 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1119
1120 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1121}
1122
1123/* Read byte #6 of a gpr register. */
1124static __inline__ IRExpr *
1125get_gpr_b6(UInt archreg)
1126{
1127 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1128}
1129
1130/* Return the guest state offset of byte #3 of a gpr register. */
1131static __inline__ UInt
1132gpr_b3_offset(UInt archreg)
1133{
1134 return gpr_offset(archreg) + 3;
1135}
1136
1137/* Write byte #3 of a gpr to the guest state. */
1138static __inline__ void
1139put_gpr_b3(UInt archreg, IRExpr *expr)
1140{
1141 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1142
1143 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1144}
1145
1146/* Read byte #3 of a gpr register. */
1147static __inline__ IRExpr *
1148get_gpr_b3(UInt archreg)
1149{
1150 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1151}
1152
1153/* Return the guest state offset of byte #0 of a gpr register. */
1154static __inline__ UInt
1155gpr_b0_offset(UInt archreg)
1156{
1157 return gpr_offset(archreg) + 0;
1158}
1159
1160/* Write byte #0 of a gpr to the guest state. */
1161static __inline__ void
1162put_gpr_b0(UInt archreg, IRExpr *expr)
1163{
1164 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1165
1166 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1167}
1168
1169/* Read byte #0 of a gpr register. */
1170static __inline__ IRExpr *
1171get_gpr_b0(UInt archreg)
1172{
1173 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1174}
1175
1176/* Return the guest state offset of word #1 of a gpr register. */
1177static __inline__ UInt
1178gpr_w1_offset(UInt archreg)
1179{
1180 return gpr_offset(archreg) + 4;
1181}
1182
1183/* Write word #1 of a gpr to the guest state. */
1184static __inline__ void
1185put_gpr_w1(UInt archreg, IRExpr *expr)
1186{
1187 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1188
1189 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1190}
1191
1192/* Read word #1 of a gpr register. */
1193static __inline__ IRExpr *
1194get_gpr_w1(UInt archreg)
1195{
1196 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1197}
1198
1199/* Return the guest state offset of half word #3 of a gpr register. */
1200static __inline__ UInt
1201gpr_hw3_offset(UInt archreg)
1202{
1203 return gpr_offset(archreg) + 6;
1204}
1205
1206/* Write half word #3 of a gpr to the guest state. */
1207static __inline__ void
1208put_gpr_hw3(UInt archreg, IRExpr *expr)
1209{
1210 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1211
1212 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1213}
1214
1215/* Read half word #3 of a gpr register. */
1216static __inline__ IRExpr *
1217get_gpr_hw3(UInt archreg)
1218{
1219 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1220}
1221
1222/* Return the guest state offset of byte #7 of a gpr register. */
1223static __inline__ UInt
1224gpr_b7_offset(UInt archreg)
1225{
1226 return gpr_offset(archreg) + 7;
1227}
1228
1229/* Write byte #7 of a gpr to the guest state. */
1230static __inline__ void
1231put_gpr_b7(UInt archreg, IRExpr *expr)
1232{
1233 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1234
1235 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1236}
1237
1238/* Read byte #7 of a gpr register. */
1239static __inline__ IRExpr *
1240get_gpr_b7(UInt archreg)
1241{
1242 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1243}
1244
1245/* Return the guest state offset of half word #0 of a gpr register. */
1246static __inline__ UInt
1247gpr_hw0_offset(UInt archreg)
1248{
1249 return gpr_offset(archreg) + 0;
1250}
1251
1252/* Write half word #0 of a gpr to the guest state. */
1253static __inline__ void
1254put_gpr_hw0(UInt archreg, IRExpr *expr)
1255{
1256 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1257
1258 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1259}
1260
1261/* Read half word #0 of a gpr register. */
1262static __inline__ IRExpr *
1263get_gpr_hw0(UInt archreg)
1264{
1265 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1266}
1267
1268/* Return the guest state offset of byte #4 of a gpr register. */
1269static __inline__ UInt
1270gpr_b4_offset(UInt archreg)
1271{
1272 return gpr_offset(archreg) + 4;
1273}
1274
1275/* Write byte #4 of a gpr to the guest state. */
1276static __inline__ void
1277put_gpr_b4(UInt archreg, IRExpr *expr)
1278{
1279 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1280
1281 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1282}
1283
1284/* Read byte #4 of a gpr register. */
1285static __inline__ IRExpr *
1286get_gpr_b4(UInt archreg)
1287{
1288 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1289}
1290
1291/* Return the guest state offset of byte #1 of a gpr register. */
1292static __inline__ UInt
1293gpr_b1_offset(UInt archreg)
1294{
1295 return gpr_offset(archreg) + 1;
1296}
1297
1298/* Write byte #1 of a gpr to the guest state. */
1299static __inline__ void
1300put_gpr_b1(UInt archreg, IRExpr *expr)
1301{
1302 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1303
1304 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1305}
1306
1307/* Read byte #1 of a gpr register. */
1308static __inline__ IRExpr *
1309get_gpr_b1(UInt archreg)
1310{
1311 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1312}
1313
1314/* Return the guest state offset of half word #2 of a gpr register. */
1315static __inline__ UInt
1316gpr_hw2_offset(UInt archreg)
1317{
1318 return gpr_offset(archreg) + 4;
1319}
1320
1321/* Write half word #2 of a gpr to the guest state. */
1322static __inline__ void
1323put_gpr_hw2(UInt archreg, IRExpr *expr)
1324{
1325 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1326
1327 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1328}
1329
1330/* Read half word #2 of a gpr register. */
1331static __inline__ IRExpr *
1332get_gpr_hw2(UInt archreg)
1333{
1334 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1335}
1336
1337/* Return the guest state offset of byte #5 of a gpr register. */
1338static __inline__ UInt
1339gpr_b5_offset(UInt archreg)
1340{
1341 return gpr_offset(archreg) + 5;
1342}
1343
1344/* Write byte #5 of a gpr to the guest state. */
1345static __inline__ void
1346put_gpr_b5(UInt archreg, IRExpr *expr)
1347{
1348 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1349
1350 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1351}
1352
1353/* Read byte #5 of a gpr register. */
1354static __inline__ IRExpr *
1355get_gpr_b5(UInt archreg)
1356{
1357 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1358}
1359
1360/* Return the guest state offset of byte #2 of a gpr register. */
1361static __inline__ UInt
1362gpr_b2_offset(UInt archreg)
1363{
1364 return gpr_offset(archreg) + 2;
1365}
1366
1367/* Write byte #2 of a gpr to the guest state. */
1368static __inline__ void
1369put_gpr_b2(UInt archreg, IRExpr *expr)
1370{
1371 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1372
1373 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1374}
1375
1376/* Read byte #2 of a gpr register. */
1377static __inline__ IRExpr *
1378get_gpr_b2(UInt archreg)
1379{
1380 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1381}
1382
1383/* Return the guest state offset of the counter register. */
1384static UInt
1385counter_offset(void)
1386{
floriane88b3c92011-07-05 02:48:39 +00001387 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001388}
1389
1390/* Return the guest state offset of double word #0 of the counter register. */
1391static __inline__ UInt
1392counter_dw0_offset(void)
1393{
1394 return counter_offset() + 0;
1395}
1396
1397/* Write double word #0 of the counter to the guest state. */
1398static __inline__ void
1399put_counter_dw0(IRExpr *expr)
1400{
1401 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1402
1403 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1404}
1405
1406/* Read double word #0 of the counter register. */
1407static __inline__ IRExpr *
1408get_counter_dw0(void)
1409{
1410 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1411}
1412
1413/* Return the guest state offset of word #0 of the counter register. */
1414static __inline__ UInt
1415counter_w0_offset(void)
1416{
1417 return counter_offset() + 0;
1418}
1419
1420/* Return the guest state offset of word #1 of the counter register. */
1421static __inline__ UInt
1422counter_w1_offset(void)
1423{
1424 return counter_offset() + 4;
1425}
1426
1427/* Write word #0 of the counter to the guest state. */
1428static __inline__ void
1429put_counter_w0(IRExpr *expr)
1430{
1431 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1432
1433 stmt(IRStmt_Put(counter_w0_offset(), expr));
1434}
1435
1436/* Read word #0 of the counter register. */
1437static __inline__ IRExpr *
1438get_counter_w0(void)
1439{
1440 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1441}
1442
1443/* Write word #1 of the counter to the guest state. */
1444static __inline__ void
1445put_counter_w1(IRExpr *expr)
1446{
1447 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1448
1449 stmt(IRStmt_Put(counter_w1_offset(), expr));
1450}
1451
1452/* Read word #1 of the counter register. */
1453static __inline__ IRExpr *
1454get_counter_w1(void)
1455{
1456 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1457}
1458
1459/* Return the guest state offset of the fpc register. */
1460static UInt
1461fpc_offset(void)
1462{
floriane88b3c92011-07-05 02:48:39 +00001463 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001464}
1465
1466/* Return the guest state offset of word #0 of the fpc register. */
1467static __inline__ UInt
1468fpc_w0_offset(void)
1469{
1470 return fpc_offset() + 0;
1471}
1472
1473/* Write word #0 of the fpc to the guest state. */
1474static __inline__ void
1475put_fpc_w0(IRExpr *expr)
1476{
1477 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1478
1479 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1480}
1481
1482/* Read word #0 of the fpc register. */
1483static __inline__ IRExpr *
1484get_fpc_w0(void)
1485{
1486 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1487}
1488
1489
1490/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001491/*--- Rounding modes ---*/
1492/*------------------------------------------------------------*/
1493
florian125e20d2012-10-07 15:42:37 +00001494/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001495 IRRoundingMode:
1496
1497 rounding mode | s390 | IR
1498 -------------------------
1499 to nearest | 00 | 00
1500 to zero | 01 | 11
1501 to +infinity | 10 | 10
1502 to -infinity | 11 | 01
1503
1504 So: IR = (4 - s390) & 3
1505*/
1506static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001507get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001508{
1509 IRTemp fpc_bits = newTemp(Ity_I32);
1510
1511 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1512 Prior to that bits [30:31] contained the bfp rounding mode with
1513 bit 29 being unused and having a value of 0. So we can always
1514 extract the least significant 3 bits. */
1515 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1516
1517 /* fixs390:
1518
1519
1520 if (! s390_host_has_fpext && rounding_mode > 3) {
1521 emulation warning @ runtime and
1522 set fpc to round nearest
1523 }
1524 */
1525
1526 /* For now silently adjust an unsupported rounding mode to "nearest" */
1527 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1528 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001529 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001530
1531 // rm_IR = (4 - rm_s390) & 3;
1532 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1533}
1534
1535/* Encode the s390 rounding mode as it appears in the m3 field of certain
1536 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1537 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1538 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1539 considers the default rounding mode (4.3.3). */
1540static IRTemp
1541encode_bfp_rounding_mode(UChar mode)
1542{
1543 IRExpr *rm;
1544
1545 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001546 case S390_BFP_ROUND_PER_FPC:
1547 rm = get_bfp_rounding_mode_from_fpc();
1548 break;
1549 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1550 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1551 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1552 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1553 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1554 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001555 default:
1556 vpanic("encode_bfp_rounding_mode");
1557 }
1558
1559 return mktemp(Ity_I32, rm);
1560}
1561
florianc8e4f562012-10-27 16:19:31 +00001562/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1563 IRRoundingMode:
1564
1565 rounding mode | s390 | IR
1566 ------------------------------------------------
1567 to nearest, ties to even | 000 | 000
1568 to zero | 001 | 011
1569 to +infinity | 010 | 010
1570 to -infinity | 011 | 001
1571 to nearest, ties away from 0 | 100 | 100
1572 to nearest, ties toward 0 | 101 | 111
1573 to away from 0 | 110 | 110
1574 to prepare for shorter precision | 111 | 101
1575
1576 So: IR = (s390 ^ ((s390 << 1) & 2))
1577*/
florianc8e4f562012-10-27 16:19:31 +00001578static IRExpr *
1579get_dfp_rounding_mode_from_fpc(void)
1580{
1581 IRTemp fpc_bits = newTemp(Ity_I32);
1582
1583 /* The dfp rounding mode is stored in bits [25:27].
1584 extract the bits at 25:27 and right shift 4 times. */
1585 assign(fpc_bits, binop(Iop_Shr32,
1586 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1587 mkU8(4)));
1588
1589 IRExpr *rm_s390 = mkexpr(fpc_bits);
1590 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1591
1592 return binop(Iop_Xor32, rm_s390,
1593 binop( Iop_And32,
1594 binop(Iop_Shl32, rm_s390, mkU8(1)),
1595 mkU32(2)));
1596}
1597
1598/* Encode the s390 rounding mode as it appears in the m3 field of certain
1599 instructions to VEX's IRRoundingMode. */
1600static IRTemp
1601encode_dfp_rounding_mode(UChar mode)
1602{
1603 IRExpr *rm;
1604
1605 switch (mode) {
1606 case S390_DFP_ROUND_PER_FPC_0:
1607 case S390_DFP_ROUND_PER_FPC_2:
1608 rm = get_dfp_rounding_mode_from_fpc(); break;
1609 case S390_DFP_ROUND_NEAREST_EVEN_4:
1610 case S390_DFP_ROUND_NEAREST_EVEN_8:
1611 rm = mkU32(Irrm_DFP_NEAREST); break;
1612 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1613 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1614 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1615 case S390_DFP_ROUND_PREPARE_SHORT_3:
1616 case S390_DFP_ROUND_PREPARE_SHORT_15:
1617 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1618 case S390_DFP_ROUND_ZERO_5:
1619 case S390_DFP_ROUND_ZERO_9:
1620 rm = mkU32(Irrm_DFP_ZERO ); break;
1621 case S390_DFP_ROUND_POSINF_6:
1622 case S390_DFP_ROUND_POSINF_10:
1623 rm = mkU32(Irrm_DFP_PosINF); break;
1624 case S390_DFP_ROUND_NEGINF_7:
1625 case S390_DFP_ROUND_NEGINF_11:
1626 rm = mkU32(Irrm_DFP_NegINF); break;
1627 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1628 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1629 case S390_DFP_ROUND_AWAY_0:
1630 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1631 default:
1632 vpanic("encode_dfp_rounding_mode");
1633 }
1634
1635 return mktemp(Ity_I32, rm);
1636}
florian12390202012-11-10 22:34:14 +00001637
florianc8e4f562012-10-27 16:19:31 +00001638
florian2c74d242012-09-12 19:38:42 +00001639/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001640/*--- Condition code helpers ---*/
1641/*------------------------------------------------------------*/
1642
1643/* The result of a Iop_CmpFxx operation is a condition code. It is
1644 encoded using the values defined in type IRCmpFxxResult.
1645 Before we can store the condition code into the guest state (or do
1646 anything else with it for that matter) we need to convert it to
1647 the encoding that s390 uses. This is what this function does.
1648
1649 s390 VEX b6 b2 b0 cc.1 cc.0
1650 0 0x40 EQ 1 0 0 0 0
1651 1 0x01 LT 0 0 1 0 1
1652 2 0x00 GT 0 0 0 1 0
1653 3 0x45 Unordered 1 1 1 1 1
1654
1655 The following bits from the VEX encoding are interesting:
1656 b0, b2, b6 with b0 being the LSB. We observe:
1657
1658 cc.0 = b0;
1659 cc.1 = b2 | (~b0 & ~b6)
1660
1661 with cc being the s390 condition code.
1662*/
1663static IRExpr *
1664convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1665{
1666 IRTemp cc0 = newTemp(Ity_I32);
1667 IRTemp cc1 = newTemp(Ity_I32);
1668 IRTemp b0 = newTemp(Ity_I32);
1669 IRTemp b2 = newTemp(Ity_I32);
1670 IRTemp b6 = newTemp(Ity_I32);
1671
1672 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1673 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1674 mkU32(1)));
1675 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1676 mkU32(1)));
1677
1678 assign(cc0, mkexpr(b0));
1679 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1680 binop(Iop_And32,
1681 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1682 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1683 )));
1684
1685 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1686}
1687
1688
1689/* The result of a Iop_CmpDxx operation is a condition code. It is
1690 encoded using the values defined in type IRCmpDxxResult.
1691 Before we can store the condition code into the guest state (or do
1692 anything else with it for that matter) we need to convert it to
1693 the encoding that s390 uses. This is what this function does. */
1694static IRExpr *
1695convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1696{
1697 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1698 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001699 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001700}
1701
1702
1703/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001704/*--- Build IR for formats ---*/
1705/*------------------------------------------------------------*/
1706static void
florian55085f82012-11-21 00:36:55 +00001707s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001708 UChar i)
1709{
florian55085f82012-11-21 00:36:55 +00001710 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001711
sewardj7ee97522011-05-09 21:45:04 +00001712 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001713 s390_disasm(ENC2(MNM, UINT), mnm, i);
1714}
1715
1716static void
florian55085f82012-11-21 00:36:55 +00001717s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001718 UChar r1, UShort i2)
1719{
1720 irgen(r1, i2);
1721}
1722
1723static void
florian55085f82012-11-21 00:36:55 +00001724s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001725 UChar r1, UShort i2)
1726{
florian55085f82012-11-21 00:36:55 +00001727 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001728
sewardj7ee97522011-05-09 21:45:04 +00001729 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001730 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1731}
1732
1733static void
florian55085f82012-11-21 00:36:55 +00001734s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001735 UChar r1, UShort i2)
1736{
florian55085f82012-11-21 00:36:55 +00001737 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001738
sewardj7ee97522011-05-09 21:45:04 +00001739 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001740 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1741}
1742
1743static void
florian55085f82012-11-21 00:36:55 +00001744s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001745 UChar r1, UShort i2)
1746{
florian55085f82012-11-21 00:36:55 +00001747 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001748
sewardj7ee97522011-05-09 21:45:04 +00001749 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001750 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1751}
1752
1753static void
florian55085f82012-11-21 00:36:55 +00001754s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001755 UChar r1, UChar r3, UShort i2)
1756{
florian55085f82012-11-21 00:36:55 +00001757 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001758
sewardj7ee97522011-05-09 21:45:04 +00001759 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001760 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1761}
1762
1763static void
florian55085f82012-11-21 00:36:55 +00001764s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001765 UChar r1, UChar r3, UShort i2)
1766{
florian55085f82012-11-21 00:36:55 +00001767 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001768
sewardj7ee97522011-05-09 21:45:04 +00001769 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001770 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1771}
1772
1773static void
florian55085f82012-11-21 00:36:55 +00001774s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1775 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001776 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1777{
florian55085f82012-11-21 00:36:55 +00001778 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001779
sewardj7ee97522011-05-09 21:45:04 +00001780 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001781 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1782 i5);
1783}
1784
1785static void
florian55085f82012-11-21 00:36:55 +00001786s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1787 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001788 UChar r1, UChar r2, UShort i4, UChar m3)
1789{
florian55085f82012-11-21 00:36:55 +00001790 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001791
sewardj7ee97522011-05-09 21:45:04 +00001792 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001793 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1794 r2, m3, (Int)(Short)i4);
1795}
1796
1797static void
florian55085f82012-11-21 00:36:55 +00001798s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1799 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001800 UChar r1, UChar m3, UShort i4, UChar i2)
1801{
florian55085f82012-11-21 00:36:55 +00001802 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001803
sewardj7ee97522011-05-09 21:45:04 +00001804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001805 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1806 r1, i2, m3, (Int)(Short)i4);
1807}
1808
1809static void
florian55085f82012-11-21 00:36:55 +00001810s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1811 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001812 UChar r1, UChar m3, UShort i4, UChar i2)
1813{
florian55085f82012-11-21 00:36:55 +00001814 const HChar *mnm = irgen(r1, m3, i4, 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(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1818 (Int)(Char)i2, m3, (Int)(Short)i4);
1819}
1820
1821static void
florian55085f82012-11-21 00:36:55 +00001822s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001823 UChar r1, UInt i2)
1824{
1825 irgen(r1, i2);
1826}
1827
1828static void
florian55085f82012-11-21 00:36:55 +00001829s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001830 UChar r1, UInt i2)
1831{
florian55085f82012-11-21 00:36:55 +00001832 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001833
sewardj7ee97522011-05-09 21:45:04 +00001834 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001835 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1836}
1837
1838static void
florian55085f82012-11-21 00:36:55 +00001839s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001840 UChar r1, UInt i2)
1841{
florian55085f82012-11-21 00:36:55 +00001842 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001843
sewardj7ee97522011-05-09 21:45:04 +00001844 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001845 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1846}
1847
1848static void
florian55085f82012-11-21 00:36:55 +00001849s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001850 UChar r1, UInt i2)
1851{
florian55085f82012-11-21 00:36:55 +00001852 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001853
sewardj7ee97522011-05-09 21:45:04 +00001854 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001855 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1856}
1857
1858static void
florian55085f82012-11-21 00:36:55 +00001859s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001860 UChar r1, UInt i2)
1861{
florian55085f82012-11-21 00:36:55 +00001862 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001863
sewardj7ee97522011-05-09 21:45:04 +00001864 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001865 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1866}
1867
1868static void
florian55085f82012-11-21 00:36:55 +00001869s390_format_RIS_RURDI(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, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1883 (Int)(Char)i2, m3, d4, 0, b4);
1884}
1885
1886static void
florian55085f82012-11-21 00:36:55 +00001887s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001888 IRTemp op4addr),
1889 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1890{
florian55085f82012-11-21 00:36:55 +00001891 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001892 IRTemp op4addr = newTemp(Ity_I64);
1893
1894 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1895 mkU64(0)));
1896
1897 mnm = irgen(r1, m3, i2, op4addr);
1898
sewardj7ee97522011-05-09 21:45:04 +00001899 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001900 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1901 i2, m3, d4, 0, b4);
1902}
1903
1904static void
florian55085f82012-11-21 00:36:55 +00001905s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001906 UChar r1, UChar r2)
1907{
1908 irgen(r1, r2);
1909}
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001913 UChar r1, UChar r2)
1914{
florian55085f82012-11-21 00:36:55 +00001915 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001916
sewardj7ee97522011-05-09 21:45:04 +00001917 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001918 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1919}
1920
1921static void
florian55085f82012-11-21 00:36:55 +00001922s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001923 UChar r1, UChar r2)
1924{
florian55085f82012-11-21 00:36:55 +00001925 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001926
sewardj7ee97522011-05-09 21:45:04 +00001927 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001928 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1929}
1930
1931static void
florian55085f82012-11-21 00:36:55 +00001932s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001933 UChar r1, UChar r2)
1934{
1935 irgen(r1, r2);
1936}
1937
1938static void
florian55085f82012-11-21 00:36:55 +00001939s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001940 UChar r1, UChar r2)
1941{
florian55085f82012-11-21 00:36:55 +00001942 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001943
sewardj7ee97522011-05-09 21:45:04 +00001944 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001945 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1946}
1947
1948static void
florian55085f82012-11-21 00:36:55 +00001949s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001950 UChar r1, UChar r2)
1951{
florian55085f82012-11-21 00:36:55 +00001952 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001953
sewardj7ee97522011-05-09 21:45:04 +00001954 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001955 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1956}
1957
1958static void
florian55085f82012-11-21 00:36:55 +00001959s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001960 UChar r1, UChar r2)
1961{
florian55085f82012-11-21 00:36:55 +00001962 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001963
sewardj7ee97522011-05-09 21:45:04 +00001964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001965 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1966}
1967
1968static void
florian55085f82012-11-21 00:36:55 +00001969s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001970 UChar r1, UChar r2)
1971{
florian55085f82012-11-21 00:36:55 +00001972 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001973
sewardj7ee97522011-05-09 21:45:04 +00001974 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001975 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1976}
1977
1978static void
florian55085f82012-11-21 00:36:55 +00001979s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001980 UChar r1)
1981{
florian55085f82012-11-21 00:36:55 +00001982 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001983
sewardj7ee97522011-05-09 21:45:04 +00001984 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001985 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1986}
1987
1988static void
florian55085f82012-11-21 00:36:55 +00001989s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001990 UChar r1)
1991{
florian55085f82012-11-21 00:36:55 +00001992 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001993
sewardj7ee97522011-05-09 21:45:04 +00001994 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001995 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1996}
1997
1998static void
florian55085f82012-11-21 00:36:55 +00001999s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002000 UChar m3, UChar r1, UChar r2)
2001{
florian55085f82012-11-21 00:36:55 +00002002 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002003
2004 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002005 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002006}
2007
2008static void
florian55085f82012-11-21 00:36:55 +00002009s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002010 UChar r1, UChar r3, UChar r2)
2011{
florian55085f82012-11-21 00:36:55 +00002012 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002013
sewardj7ee97522011-05-09 21:45:04 +00002014 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002015 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2016}
2017
2018static void
florian55085f82012-11-21 00:36:55 +00002019s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2020 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002021 UChar m3, UChar m4, UChar r1, UChar r2)
2022{
florian55085f82012-11-21 00:36:55 +00002023 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002024
2025 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2026 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2027}
2028
2029static void
floriane38f6412012-12-21 17:32:12 +00002030s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2031 UChar m4, UChar r1, UChar r2)
2032{
2033 const HChar *mnm = irgen(m4, r1, r2);
2034
2035 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2036 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2037}
2038
2039static void
florian55085f82012-11-21 00:36:55 +00002040s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2041 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002042 UChar m3, UChar m4, UChar r1, UChar r2)
2043{
florian55085f82012-11-21 00:36:55 +00002044 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002045
2046 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2047 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2048}
2049
2050static void
florian55085f82012-11-21 00:36:55 +00002051s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2052 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002053 UChar m3, UChar m4, UChar r1, UChar r2)
2054{
florian55085f82012-11-21 00:36:55 +00002055 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002056
2057 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2058 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2059}
2060
2061
2062static void
florian55085f82012-11-21 00:36:55 +00002063s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002064 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2065{
2066 irgen(m3, r1, r2);
2067
sewardj7ee97522011-05-09 21:45:04 +00002068 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002069 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2070}
2071
2072static void
florian55085f82012-11-21 00:36:55 +00002073s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002074 UChar r3, UChar r1, UChar r2)
2075{
florian55085f82012-11-21 00:36:55 +00002076 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002077
sewardj7ee97522011-05-09 21:45:04 +00002078 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002079 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2080}
2081
2082static void
florian55085f82012-11-21 00:36:55 +00002083s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002084 UChar r3, UChar m4, UChar r1, UChar r2)
2085{
florian55085f82012-11-21 00:36:55 +00002086 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002087
2088 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2089 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2090}
2091
2092static void
florian55085f82012-11-21 00:36:55 +00002093s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002094 UChar r3, UChar r1, UChar r2)
2095{
florian55085f82012-11-21 00:36:55 +00002096 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002097
sewardj7ee97522011-05-09 21:45:04 +00002098 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002099 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2100}
2101
2102static void
florian55085f82012-11-21 00:36:55 +00002103s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2104 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002105 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2106{
florian55085f82012-11-21 00:36:55 +00002107 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002108 IRTemp op4addr = newTemp(Ity_I64);
2109
2110 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2111 mkU64(0)));
2112
2113 mnm = irgen(r1, r2, m3, op4addr);
2114
sewardj7ee97522011-05-09 21:45:04 +00002115 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002116 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2117 r2, m3, d4, 0, b4);
2118}
2119
2120static void
florian55085f82012-11-21 00:36:55 +00002121s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002122 UChar r1, UChar b2, UShort d2)
2123{
florian55085f82012-11-21 00:36:55 +00002124 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002125 IRTemp op2addr = newTemp(Ity_I64);
2126
2127 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2128 mkU64(0)));
2129
2130 mnm = irgen(r1, op2addr);
2131
sewardj7ee97522011-05-09 21:45:04 +00002132 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002133 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2134}
2135
2136static void
florian55085f82012-11-21 00:36:55 +00002137s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002138 UChar r1, UChar r3, UChar b2, UShort d2)
2139{
florian55085f82012-11-21 00:36:55 +00002140 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002141 IRTemp op2addr = newTemp(Ity_I64);
2142
2143 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2144 mkU64(0)));
2145
2146 mnm = irgen(r1, r3, op2addr);
2147
sewardj7ee97522011-05-09 21:45:04 +00002148 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002149 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2150}
2151
2152static void
florian55085f82012-11-21 00:36:55 +00002153s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002154 UChar r1, UChar r3, UChar b2, UShort d2)
2155{
florian55085f82012-11-21 00:36:55 +00002156 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002157 IRTemp op2addr = newTemp(Ity_I64);
2158
2159 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2160 mkU64(0)));
2161
2162 mnm = irgen(r1, r3, op2addr);
2163
sewardj7ee97522011-05-09 21:45:04 +00002164 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002165 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2166}
2167
2168static void
florian55085f82012-11-21 00:36:55 +00002169s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002170 UChar r1, UChar r3, UChar b2, UShort d2)
2171{
florian55085f82012-11-21 00:36:55 +00002172 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002173 IRTemp op2addr = newTemp(Ity_I64);
2174
2175 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2176 mkU64(0)));
2177
2178 mnm = irgen(r1, r3, op2addr);
2179
sewardj7ee97522011-05-09 21:45:04 +00002180 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002181 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2182}
2183
2184static void
florian55085f82012-11-21 00:36:55 +00002185s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002186 UChar r1, UChar r3, UShort i2)
2187{
florian55085f82012-11-21 00:36:55 +00002188 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002189
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, PCREL), mnm, r1, r3, (Int)(Short)i2);
2192}
2193
2194static void
florian55085f82012-11-21 00:36:55 +00002195s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
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, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2210}
2211
2212static void
florian55085f82012-11-21 00:36:55 +00002213s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
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, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2228}
2229
2230static void
florian55085f82012-11-21 00:36:55 +00002231s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002232 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2233{
florian55085f82012-11-21 00:36:55 +00002234 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002235 IRTemp op2addr = newTemp(Ity_I64);
2236 IRTemp d2 = newTemp(Ity_I64);
2237
2238 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2239 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2240 mkU64(0)));
2241
2242 mnm = irgen(r1, r3, op2addr);
2243
sewardj7ee97522011-05-09 21:45:04 +00002244 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002245 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2246}
2247
2248static void
florian55085f82012-11-21 00:36:55 +00002249s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002250 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2251 Int xmnm_kind)
2252{
2253 IRTemp op2addr = newTemp(Ity_I64);
2254 IRTemp d2 = newTemp(Ity_I64);
2255
florian6820ba52012-07-26 02:01:50 +00002256 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2257
sewardjd7bde722011-04-05 13:19:33 +00002258 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2259 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2260 mkU64(0)));
2261
2262 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002263
2264 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002265
sewardj7ee97522011-05-09 21:45:04 +00002266 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002267 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2268}
2269
2270static void
florian55085f82012-11-21 00:36:55 +00002271s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002272 IRTemp op2addr),
2273 UChar r1, UChar x2, UChar b2, UShort d2)
2274{
2275 IRTemp op2addr = newTemp(Ity_I64);
2276
2277 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2278 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2279 mkU64(0)));
2280
2281 irgen(r1, x2, b2, d2, op2addr);
2282}
2283
2284static void
florian55085f82012-11-21 00:36:55 +00002285s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002286 UChar r1, UChar x2, UChar b2, UShort d2)
2287{
florian55085f82012-11-21 00:36:55 +00002288 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002289 IRTemp op2addr = newTemp(Ity_I64);
2290
2291 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2292 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2293 mkU64(0)));
2294
2295 mnm = irgen(r1, op2addr);
2296
sewardj7ee97522011-05-09 21:45:04 +00002297 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002298 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2299}
2300
2301static void
florian55085f82012-11-21 00:36:55 +00002302s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002303 UChar r1, UChar x2, UChar b2, UShort d2)
2304{
florian55085f82012-11-21 00:36:55 +00002305 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002306 IRTemp op2addr = newTemp(Ity_I64);
2307
2308 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2309 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2310 mkU64(0)));
2311
2312 mnm = irgen(r1, op2addr);
2313
sewardj7ee97522011-05-09 21:45:04 +00002314 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002315 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2316}
2317
2318static void
florian55085f82012-11-21 00:36:55 +00002319s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002320 UChar r1, UChar x2, UChar b2, UShort d2)
2321{
florian55085f82012-11-21 00:36:55 +00002322 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002323 IRTemp op2addr = newTemp(Ity_I64);
2324
2325 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2326 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2327 mkU64(0)));
2328
2329 mnm = irgen(r1, op2addr);
2330
sewardj7ee97522011-05-09 21:45:04 +00002331 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002332 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2333}
2334
2335static void
florian55085f82012-11-21 00:36:55 +00002336s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002337 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2338{
florian55085f82012-11-21 00:36:55 +00002339 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002340 IRTemp op2addr = newTemp(Ity_I64);
2341
2342 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2343 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2344 mkU64(0)));
2345
2346 mnm = irgen(r3, op2addr, r1);
2347
sewardj7ee97522011-05-09 21:45:04 +00002348 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002349 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2350}
2351
2352static void
florian55085f82012-11-21 00:36:55 +00002353s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002354 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2355{
florian55085f82012-11-21 00:36:55 +00002356 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002357 IRTemp op2addr = newTemp(Ity_I64);
2358 IRTemp d2 = newTemp(Ity_I64);
2359
2360 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2361 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2362 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2363 mkU64(0)));
2364
2365 mnm = irgen(r1, op2addr);
2366
sewardj7ee97522011-05-09 21:45:04 +00002367 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002368 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2369}
2370
2371static void
florian55085f82012-11-21 00:36:55 +00002372s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002373 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2374{
florian55085f82012-11-21 00:36:55 +00002375 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002376 IRTemp op2addr = newTemp(Ity_I64);
2377 IRTemp d2 = newTemp(Ity_I64);
2378
2379 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2380 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2381 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2382 mkU64(0)));
2383
2384 mnm = irgen(r1, op2addr);
2385
sewardj7ee97522011-05-09 21:45:04 +00002386 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002387 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2388}
2389
2390static void
florian55085f82012-11-21 00:36:55 +00002391s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002392 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2393{
florian55085f82012-11-21 00:36:55 +00002394 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002395 IRTemp op2addr = newTemp(Ity_I64);
2396 IRTemp d2 = newTemp(Ity_I64);
2397
2398 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2399 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2400 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2401 mkU64(0)));
2402
2403 mnm = irgen();
2404
sewardj7ee97522011-05-09 21:45:04 +00002405 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002406 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2407}
2408
2409static void
florian55085f82012-11-21 00:36:55 +00002410s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002411 UChar b2, UShort d2)
2412{
florian55085f82012-11-21 00:36:55 +00002413 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002414 IRTemp op2addr = newTemp(Ity_I64);
2415
2416 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2417 mkU64(0)));
2418
2419 mnm = irgen(op2addr);
2420
sewardj7ee97522011-05-09 21:45:04 +00002421 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002422 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2423}
2424
2425static void
florian55085f82012-11-21 00:36:55 +00002426s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002427 UChar i2, UChar b1, UShort d1)
2428{
florian55085f82012-11-21 00:36:55 +00002429 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002430 IRTemp op1addr = newTemp(Ity_I64);
2431
2432 assign(op1addr, binop(Iop_Add64, mkU64(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, UDXB, UINT), mnm, d1, 0, b1, i2);
2439}
2440
2441static void
florian55085f82012-11-21 00:36:55 +00002442s390_format_SIY_URD(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, UINT), mnm, dh1, dl1, 0, b1, i2);
2457}
2458
2459static void
florian55085f82012-11-21 00:36:55 +00002460s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002461 UChar i2, UChar b1, UShort dl1, UChar dh1)
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 d1 = newTemp(Ity_I64);
2466
2467 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2468 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2469 mkU64(0)));
2470
2471 mnm = irgen(i2, op1addr);
2472
sewardj7ee97522011-05-09 21:45:04 +00002473 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002474 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2475}
2476
2477static void
florian55085f82012-11-21 00:36:55 +00002478s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002479 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2480{
florian55085f82012-11-21 00:36:55 +00002481 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002482 IRTemp op1addr = newTemp(Ity_I64);
2483 IRTemp op2addr = newTemp(Ity_I64);
2484
2485 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2486 mkU64(0)));
2487 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2488 mkU64(0)));
2489
2490 mnm = irgen(l, op1addr, op2addr);
2491
sewardj7ee97522011-05-09 21:45:04 +00002492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002493 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2494}
2495
2496static void
florian55085f82012-11-21 00:36:55 +00002497s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002498 UChar b1, UShort d1, UShort i2)
2499{
florian55085f82012-11-21 00:36:55 +00002500 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002501 IRTemp op1addr = newTemp(Ity_I64);
2502
2503 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2504 mkU64(0)));
2505
2506 mnm = irgen(i2, op1addr);
2507
sewardj7ee97522011-05-09 21:45:04 +00002508 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002509 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2510}
2511
2512static void
florian55085f82012-11-21 00:36:55 +00002513s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002514 UChar b1, UShort d1, UShort i2)
2515{
florian55085f82012-11-21 00:36:55 +00002516 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002517 IRTemp op1addr = newTemp(Ity_I64);
2518
2519 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2520 mkU64(0)));
2521
2522 mnm = irgen(i2, op1addr);
2523
sewardj7ee97522011-05-09 21:45:04 +00002524 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002525 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2526}
2527
2528
2529
2530/*------------------------------------------------------------*/
2531/*--- Build IR for opcodes ---*/
2532/*------------------------------------------------------------*/
2533
florian55085f82012-11-21 00:36:55 +00002534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002535s390_irgen_AR(UChar r1, UChar r2)
2536{
2537 IRTemp op1 = newTemp(Ity_I32);
2538 IRTemp op2 = newTemp(Ity_I32);
2539 IRTemp result = newTemp(Ity_I32);
2540
2541 assign(op1, get_gpr_w1(r1));
2542 assign(op2, get_gpr_w1(r2));
2543 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2544 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2545 put_gpr_w1(r1, mkexpr(result));
2546
2547 return "ar";
2548}
2549
florian55085f82012-11-21 00:36:55 +00002550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002551s390_irgen_AGR(UChar r1, UChar r2)
2552{
2553 IRTemp op1 = newTemp(Ity_I64);
2554 IRTemp op2 = newTemp(Ity_I64);
2555 IRTemp result = newTemp(Ity_I64);
2556
2557 assign(op1, get_gpr_dw0(r1));
2558 assign(op2, get_gpr_dw0(r2));
2559 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2560 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2561 put_gpr_dw0(r1, mkexpr(result));
2562
2563 return "agr";
2564}
2565
florian55085f82012-11-21 00:36:55 +00002566static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002567s390_irgen_AGFR(UChar r1, UChar r2)
2568{
2569 IRTemp op1 = newTemp(Ity_I64);
2570 IRTemp op2 = newTemp(Ity_I64);
2571 IRTemp result = newTemp(Ity_I64);
2572
2573 assign(op1, get_gpr_dw0(r1));
2574 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2575 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2576 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2577 put_gpr_dw0(r1, mkexpr(result));
2578
2579 return "agfr";
2580}
2581
florian55085f82012-11-21 00:36:55 +00002582static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002583s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2584{
2585 IRTemp op2 = newTemp(Ity_I32);
2586 IRTemp op3 = newTemp(Ity_I32);
2587 IRTemp result = newTemp(Ity_I32);
2588
2589 assign(op2, get_gpr_w1(r2));
2590 assign(op3, get_gpr_w1(r3));
2591 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2592 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2593 put_gpr_w1(r1, mkexpr(result));
2594
2595 return "ark";
2596}
2597
florian55085f82012-11-21 00:36:55 +00002598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002599s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2600{
2601 IRTemp op2 = newTemp(Ity_I64);
2602 IRTemp op3 = newTemp(Ity_I64);
2603 IRTemp result = newTemp(Ity_I64);
2604
2605 assign(op2, get_gpr_dw0(r2));
2606 assign(op3, get_gpr_dw0(r3));
2607 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2608 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2609 put_gpr_dw0(r1, mkexpr(result));
2610
2611 return "agrk";
2612}
2613
florian55085f82012-11-21 00:36:55 +00002614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002615s390_irgen_A(UChar r1, IRTemp op2addr)
2616{
2617 IRTemp op1 = newTemp(Ity_I32);
2618 IRTemp op2 = newTemp(Ity_I32);
2619 IRTemp result = newTemp(Ity_I32);
2620
2621 assign(op1, get_gpr_w1(r1));
2622 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2623 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2624 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2625 put_gpr_w1(r1, mkexpr(result));
2626
2627 return "a";
2628}
2629
florian55085f82012-11-21 00:36:55 +00002630static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002631s390_irgen_AY(UChar r1, IRTemp op2addr)
2632{
2633 IRTemp op1 = newTemp(Ity_I32);
2634 IRTemp op2 = newTemp(Ity_I32);
2635 IRTemp result = newTemp(Ity_I32);
2636
2637 assign(op1, get_gpr_w1(r1));
2638 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2639 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2640 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2641 put_gpr_w1(r1, mkexpr(result));
2642
2643 return "ay";
2644}
2645
florian55085f82012-11-21 00:36:55 +00002646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002647s390_irgen_AG(UChar r1, IRTemp op2addr)
2648{
2649 IRTemp op1 = newTemp(Ity_I64);
2650 IRTemp op2 = newTemp(Ity_I64);
2651 IRTemp result = newTemp(Ity_I64);
2652
2653 assign(op1, get_gpr_dw0(r1));
2654 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2655 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2656 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2657 put_gpr_dw0(r1, mkexpr(result));
2658
2659 return "ag";
2660}
2661
florian55085f82012-11-21 00:36:55 +00002662static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002663s390_irgen_AGF(UChar r1, IRTemp op2addr)
2664{
2665 IRTemp op1 = newTemp(Ity_I64);
2666 IRTemp op2 = newTemp(Ity_I64);
2667 IRTemp result = newTemp(Ity_I64);
2668
2669 assign(op1, get_gpr_dw0(r1));
2670 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2671 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2672 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2673 put_gpr_dw0(r1, mkexpr(result));
2674
2675 return "agf";
2676}
2677
florian55085f82012-11-21 00:36:55 +00002678static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002679s390_irgen_AFI(UChar r1, UInt i2)
2680{
2681 IRTemp op1 = newTemp(Ity_I32);
2682 Int op2;
2683 IRTemp result = newTemp(Ity_I32);
2684
2685 assign(op1, get_gpr_w1(r1));
2686 op2 = (Int)i2;
2687 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2688 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2689 mkU32((UInt)op2)));
2690 put_gpr_w1(r1, mkexpr(result));
2691
2692 return "afi";
2693}
2694
florian55085f82012-11-21 00:36:55 +00002695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002696s390_irgen_AGFI(UChar r1, UInt i2)
2697{
2698 IRTemp op1 = newTemp(Ity_I64);
2699 Long op2;
2700 IRTemp result = newTemp(Ity_I64);
2701
2702 assign(op1, get_gpr_dw0(r1));
2703 op2 = (Long)(Int)i2;
2704 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2705 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2706 mkU64((ULong)op2)));
2707 put_gpr_dw0(r1, mkexpr(result));
2708
2709 return "agfi";
2710}
2711
florian55085f82012-11-21 00:36:55 +00002712static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002713s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2714{
2715 Int op2;
2716 IRTemp op3 = newTemp(Ity_I32);
2717 IRTemp result = newTemp(Ity_I32);
2718
2719 op2 = (Int)(Short)i2;
2720 assign(op3, get_gpr_w1(r3));
2721 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2722 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2723 op2)), op3);
2724 put_gpr_w1(r1, mkexpr(result));
2725
2726 return "ahik";
2727}
2728
florian55085f82012-11-21 00:36:55 +00002729static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002730s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2731{
2732 Long op2;
2733 IRTemp op3 = newTemp(Ity_I64);
2734 IRTemp result = newTemp(Ity_I64);
2735
2736 op2 = (Long)(Short)i2;
2737 assign(op3, get_gpr_dw0(r3));
2738 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2739 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2740 op2)), op3);
2741 put_gpr_dw0(r1, mkexpr(result));
2742
2743 return "aghik";
2744}
2745
florian55085f82012-11-21 00:36:55 +00002746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002747s390_irgen_ASI(UChar i2, IRTemp op1addr)
2748{
2749 IRTemp op1 = newTemp(Ity_I32);
2750 Int op2;
2751 IRTemp result = newTemp(Ity_I32);
2752
2753 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2754 op2 = (Int)(Char)i2;
2755 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2756 store(mkexpr(op1addr), mkexpr(result));
2757 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2758 mkU32((UInt)op2)));
2759
2760 return "asi";
2761}
2762
florian55085f82012-11-21 00:36:55 +00002763static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002764s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2765{
2766 IRTemp op1 = newTemp(Ity_I64);
2767 Long op2;
2768 IRTemp result = newTemp(Ity_I64);
2769
2770 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2771 op2 = (Long)(Char)i2;
2772 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2773 store(mkexpr(op1addr), mkexpr(result));
2774 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2775 mkU64((ULong)op2)));
2776
2777 return "agsi";
2778}
2779
florian55085f82012-11-21 00:36:55 +00002780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002781s390_irgen_AH(UChar r1, IRTemp op2addr)
2782{
2783 IRTemp op1 = newTemp(Ity_I32);
2784 IRTemp op2 = newTemp(Ity_I32);
2785 IRTemp result = newTemp(Ity_I32);
2786
2787 assign(op1, get_gpr_w1(r1));
2788 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2789 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2790 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2791 put_gpr_w1(r1, mkexpr(result));
2792
2793 return "ah";
2794}
2795
florian55085f82012-11-21 00:36:55 +00002796static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002797s390_irgen_AHY(UChar r1, IRTemp op2addr)
2798{
2799 IRTemp op1 = newTemp(Ity_I32);
2800 IRTemp op2 = newTemp(Ity_I32);
2801 IRTemp result = newTemp(Ity_I32);
2802
2803 assign(op1, get_gpr_w1(r1));
2804 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2805 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2806 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2807 put_gpr_w1(r1, mkexpr(result));
2808
2809 return "ahy";
2810}
2811
florian55085f82012-11-21 00:36:55 +00002812static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002813s390_irgen_AHI(UChar r1, UShort i2)
2814{
2815 IRTemp op1 = newTemp(Ity_I32);
2816 Int op2;
2817 IRTemp result = newTemp(Ity_I32);
2818
2819 assign(op1, get_gpr_w1(r1));
2820 op2 = (Int)(Short)i2;
2821 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2822 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2823 mkU32((UInt)op2)));
2824 put_gpr_w1(r1, mkexpr(result));
2825
2826 return "ahi";
2827}
2828
florian55085f82012-11-21 00:36:55 +00002829static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002830s390_irgen_AGHI(UChar r1, UShort i2)
2831{
2832 IRTemp op1 = newTemp(Ity_I64);
2833 Long op2;
2834 IRTemp result = newTemp(Ity_I64);
2835
2836 assign(op1, get_gpr_dw0(r1));
2837 op2 = (Long)(Short)i2;
2838 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2839 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2840 mkU64((ULong)op2)));
2841 put_gpr_dw0(r1, mkexpr(result));
2842
2843 return "aghi";
2844}
2845
florian55085f82012-11-21 00:36:55 +00002846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002847s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2848{
2849 IRTemp op2 = newTemp(Ity_I32);
2850 IRTemp op3 = newTemp(Ity_I32);
2851 IRTemp result = newTemp(Ity_I32);
2852
2853 assign(op2, get_gpr_w0(r2));
2854 assign(op3, get_gpr_w0(r3));
2855 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2856 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2857 put_gpr_w0(r1, mkexpr(result));
2858
2859 return "ahhhr";
2860}
2861
florian55085f82012-11-21 00:36:55 +00002862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002863s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2864{
2865 IRTemp op2 = newTemp(Ity_I32);
2866 IRTemp op3 = newTemp(Ity_I32);
2867 IRTemp result = newTemp(Ity_I32);
2868
2869 assign(op2, get_gpr_w0(r2));
2870 assign(op3, get_gpr_w1(r3));
2871 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2872 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2873 put_gpr_w0(r1, mkexpr(result));
2874
2875 return "ahhlr";
2876}
2877
florian55085f82012-11-21 00:36:55 +00002878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002879s390_irgen_AIH(UChar r1, UInt i2)
2880{
2881 IRTemp op1 = newTemp(Ity_I32);
2882 Int op2;
2883 IRTemp result = newTemp(Ity_I32);
2884
2885 assign(op1, get_gpr_w0(r1));
2886 op2 = (Int)i2;
2887 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2888 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2889 mkU32((UInt)op2)));
2890 put_gpr_w0(r1, mkexpr(result));
2891
2892 return "aih";
2893}
2894
florian55085f82012-11-21 00:36:55 +00002895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002896s390_irgen_ALR(UChar r1, UChar r2)
2897{
2898 IRTemp op1 = newTemp(Ity_I32);
2899 IRTemp op2 = newTemp(Ity_I32);
2900 IRTemp result = newTemp(Ity_I32);
2901
2902 assign(op1, get_gpr_w1(r1));
2903 assign(op2, get_gpr_w1(r2));
2904 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2905 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2906 put_gpr_w1(r1, mkexpr(result));
2907
2908 return "alr";
2909}
2910
florian55085f82012-11-21 00:36:55 +00002911static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002912s390_irgen_ALGR(UChar r1, UChar r2)
2913{
2914 IRTemp op1 = newTemp(Ity_I64);
2915 IRTemp op2 = newTemp(Ity_I64);
2916 IRTemp result = newTemp(Ity_I64);
2917
2918 assign(op1, get_gpr_dw0(r1));
2919 assign(op2, get_gpr_dw0(r2));
2920 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2921 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2922 put_gpr_dw0(r1, mkexpr(result));
2923
2924 return "algr";
2925}
2926
florian55085f82012-11-21 00:36:55 +00002927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002928s390_irgen_ALGFR(UChar r1, UChar r2)
2929{
2930 IRTemp op1 = newTemp(Ity_I64);
2931 IRTemp op2 = newTemp(Ity_I64);
2932 IRTemp result = newTemp(Ity_I64);
2933
2934 assign(op1, get_gpr_dw0(r1));
2935 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2936 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2937 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2938 put_gpr_dw0(r1, mkexpr(result));
2939
2940 return "algfr";
2941}
2942
florian55085f82012-11-21 00:36:55 +00002943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002944s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2945{
2946 IRTemp op2 = newTemp(Ity_I32);
2947 IRTemp op3 = newTemp(Ity_I32);
2948 IRTemp result = newTemp(Ity_I32);
2949
2950 assign(op2, get_gpr_w1(r2));
2951 assign(op3, get_gpr_w1(r3));
2952 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2953 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2954 put_gpr_w1(r1, mkexpr(result));
2955
2956 return "alrk";
2957}
2958
florian55085f82012-11-21 00:36:55 +00002959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002960s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2961{
2962 IRTemp op2 = newTemp(Ity_I64);
2963 IRTemp op3 = newTemp(Ity_I64);
2964 IRTemp result = newTemp(Ity_I64);
2965
2966 assign(op2, get_gpr_dw0(r2));
2967 assign(op3, get_gpr_dw0(r3));
2968 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2969 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2970 put_gpr_dw0(r1, mkexpr(result));
2971
2972 return "algrk";
2973}
2974
florian55085f82012-11-21 00:36:55 +00002975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002976s390_irgen_AL(UChar r1, IRTemp op2addr)
2977{
2978 IRTemp op1 = newTemp(Ity_I32);
2979 IRTemp op2 = newTemp(Ity_I32);
2980 IRTemp result = newTemp(Ity_I32);
2981
2982 assign(op1, get_gpr_w1(r1));
2983 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2984 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2985 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2986 put_gpr_w1(r1, mkexpr(result));
2987
2988 return "al";
2989}
2990
florian55085f82012-11-21 00:36:55 +00002991static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002992s390_irgen_ALY(UChar r1, IRTemp op2addr)
2993{
2994 IRTemp op1 = newTemp(Ity_I32);
2995 IRTemp op2 = newTemp(Ity_I32);
2996 IRTemp result = newTemp(Ity_I32);
2997
2998 assign(op1, get_gpr_w1(r1));
2999 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3000 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3001 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3002 put_gpr_w1(r1, mkexpr(result));
3003
3004 return "aly";
3005}
3006
florian55085f82012-11-21 00:36:55 +00003007static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003008s390_irgen_ALG(UChar r1, IRTemp op2addr)
3009{
3010 IRTemp op1 = newTemp(Ity_I64);
3011 IRTemp op2 = newTemp(Ity_I64);
3012 IRTemp result = newTemp(Ity_I64);
3013
3014 assign(op1, get_gpr_dw0(r1));
3015 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3016 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3017 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3018 put_gpr_dw0(r1, mkexpr(result));
3019
3020 return "alg";
3021}
3022
florian55085f82012-11-21 00:36:55 +00003023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003024s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3025{
3026 IRTemp op1 = newTemp(Ity_I64);
3027 IRTemp op2 = newTemp(Ity_I64);
3028 IRTemp result = newTemp(Ity_I64);
3029
3030 assign(op1, get_gpr_dw0(r1));
3031 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3032 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3033 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3034 put_gpr_dw0(r1, mkexpr(result));
3035
3036 return "algf";
3037}
3038
florian55085f82012-11-21 00:36:55 +00003039static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003040s390_irgen_ALFI(UChar r1, UInt i2)
3041{
3042 IRTemp op1 = newTemp(Ity_I32);
3043 UInt op2;
3044 IRTemp result = newTemp(Ity_I32);
3045
3046 assign(op1, get_gpr_w1(r1));
3047 op2 = i2;
3048 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3049 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3050 mkU32(op2)));
3051 put_gpr_w1(r1, mkexpr(result));
3052
3053 return "alfi";
3054}
3055
florian55085f82012-11-21 00:36:55 +00003056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003057s390_irgen_ALGFI(UChar r1, UInt i2)
3058{
3059 IRTemp op1 = newTemp(Ity_I64);
3060 ULong op2;
3061 IRTemp result = newTemp(Ity_I64);
3062
3063 assign(op1, get_gpr_dw0(r1));
3064 op2 = (ULong)i2;
3065 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3066 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3067 mkU64(op2)));
3068 put_gpr_dw0(r1, mkexpr(result));
3069
3070 return "algfi";
3071}
3072
florian55085f82012-11-21 00:36:55 +00003073static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003074s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3075{
3076 IRTemp op2 = newTemp(Ity_I32);
3077 IRTemp op3 = newTemp(Ity_I32);
3078 IRTemp result = newTemp(Ity_I32);
3079
3080 assign(op2, get_gpr_w0(r2));
3081 assign(op3, get_gpr_w0(r3));
3082 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3083 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3084 put_gpr_w0(r1, mkexpr(result));
3085
3086 return "alhhhr";
3087}
3088
florian55085f82012-11-21 00:36:55 +00003089static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003090s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3091{
3092 IRTemp op2 = newTemp(Ity_I32);
3093 IRTemp op3 = newTemp(Ity_I32);
3094 IRTemp result = newTemp(Ity_I32);
3095
3096 assign(op2, get_gpr_w0(r2));
3097 assign(op3, get_gpr_w1(r3));
3098 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3099 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3100 put_gpr_w0(r1, mkexpr(result));
3101
3102 return "alhhlr";
3103}
3104
florian55085f82012-11-21 00:36:55 +00003105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003106s390_irgen_ALCR(UChar r1, UChar r2)
3107{
3108 IRTemp op1 = newTemp(Ity_I32);
3109 IRTemp op2 = newTemp(Ity_I32);
3110 IRTemp result = newTemp(Ity_I32);
3111 IRTemp carry_in = newTemp(Ity_I32);
3112
3113 assign(op1, get_gpr_w1(r1));
3114 assign(op2, get_gpr_w1(r2));
3115 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3116 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3117 mkexpr(carry_in)));
3118 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3119 put_gpr_w1(r1, mkexpr(result));
3120
3121 return "alcr";
3122}
3123
florian55085f82012-11-21 00:36:55 +00003124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003125s390_irgen_ALCGR(UChar r1, UChar r2)
3126{
3127 IRTemp op1 = newTemp(Ity_I64);
3128 IRTemp op2 = newTemp(Ity_I64);
3129 IRTemp result = newTemp(Ity_I64);
3130 IRTemp carry_in = newTemp(Ity_I64);
3131
3132 assign(op1, get_gpr_dw0(r1));
3133 assign(op2, get_gpr_dw0(r2));
3134 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3135 mkU8(1))));
3136 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3137 mkexpr(carry_in)));
3138 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3139 put_gpr_dw0(r1, mkexpr(result));
3140
3141 return "alcgr";
3142}
3143
florian55085f82012-11-21 00:36:55 +00003144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003145s390_irgen_ALC(UChar r1, IRTemp op2addr)
3146{
3147 IRTemp op1 = newTemp(Ity_I32);
3148 IRTemp op2 = newTemp(Ity_I32);
3149 IRTemp result = newTemp(Ity_I32);
3150 IRTemp carry_in = newTemp(Ity_I32);
3151
3152 assign(op1, get_gpr_w1(r1));
3153 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3154 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3155 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3156 mkexpr(carry_in)));
3157 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3158 put_gpr_w1(r1, mkexpr(result));
3159
3160 return "alc";
3161}
3162
florian55085f82012-11-21 00:36:55 +00003163static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003164s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3165{
3166 IRTemp op1 = newTemp(Ity_I64);
3167 IRTemp op2 = newTemp(Ity_I64);
3168 IRTemp result = newTemp(Ity_I64);
3169 IRTemp carry_in = newTemp(Ity_I64);
3170
3171 assign(op1, get_gpr_dw0(r1));
3172 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3173 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3174 mkU8(1))));
3175 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3176 mkexpr(carry_in)));
3177 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3178 put_gpr_dw0(r1, mkexpr(result));
3179
3180 return "alcg";
3181}
3182
florian55085f82012-11-21 00:36:55 +00003183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003184s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3185{
3186 IRTemp op1 = newTemp(Ity_I32);
3187 UInt op2;
3188 IRTemp result = newTemp(Ity_I32);
3189
3190 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3191 op2 = (UInt)(Int)(Char)i2;
3192 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3193 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3194 mkU32(op2)));
3195 store(mkexpr(op1addr), mkexpr(result));
3196
3197 return "alsi";
3198}
3199
florian55085f82012-11-21 00:36:55 +00003200static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003201s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3202{
3203 IRTemp op1 = newTemp(Ity_I64);
3204 ULong op2;
3205 IRTemp result = newTemp(Ity_I64);
3206
3207 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3208 op2 = (ULong)(Long)(Char)i2;
3209 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3210 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3211 mkU64(op2)));
3212 store(mkexpr(op1addr), mkexpr(result));
3213
3214 return "algsi";
3215}
3216
florian55085f82012-11-21 00:36:55 +00003217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003218s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3219{
3220 UInt op2;
3221 IRTemp op3 = newTemp(Ity_I32);
3222 IRTemp result = newTemp(Ity_I32);
3223
3224 op2 = (UInt)(Int)(Short)i2;
3225 assign(op3, get_gpr_w1(r3));
3226 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3227 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3228 op3);
3229 put_gpr_w1(r1, mkexpr(result));
3230
3231 return "alhsik";
3232}
3233
florian55085f82012-11-21 00:36:55 +00003234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003235s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3236{
3237 ULong op2;
3238 IRTemp op3 = newTemp(Ity_I64);
3239 IRTemp result = newTemp(Ity_I64);
3240
3241 op2 = (ULong)(Long)(Short)i2;
3242 assign(op3, get_gpr_dw0(r3));
3243 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3244 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3245 op3);
3246 put_gpr_dw0(r1, mkexpr(result));
3247
3248 return "alghsik";
3249}
3250
florian55085f82012-11-21 00:36:55 +00003251static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003252s390_irgen_ALSIH(UChar r1, UInt i2)
3253{
3254 IRTemp op1 = newTemp(Ity_I32);
3255 UInt op2;
3256 IRTemp result = newTemp(Ity_I32);
3257
3258 assign(op1, get_gpr_w0(r1));
3259 op2 = i2;
3260 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3261 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3262 mkU32(op2)));
3263 put_gpr_w0(r1, mkexpr(result));
3264
3265 return "alsih";
3266}
3267
florian55085f82012-11-21 00:36:55 +00003268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003269s390_irgen_ALSIHN(UChar r1, UInt i2)
3270{
3271 IRTemp op1 = newTemp(Ity_I32);
3272 UInt op2;
3273 IRTemp result = newTemp(Ity_I32);
3274
3275 assign(op1, get_gpr_w0(r1));
3276 op2 = i2;
3277 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3278 put_gpr_w0(r1, mkexpr(result));
3279
3280 return "alsihn";
3281}
3282
florian55085f82012-11-21 00:36:55 +00003283static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003284s390_irgen_NR(UChar r1, UChar r2)
3285{
3286 IRTemp op1 = newTemp(Ity_I32);
3287 IRTemp op2 = newTemp(Ity_I32);
3288 IRTemp result = newTemp(Ity_I32);
3289
3290 assign(op1, get_gpr_w1(r1));
3291 assign(op2, get_gpr_w1(r2));
3292 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3293 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3294 put_gpr_w1(r1, mkexpr(result));
3295
3296 return "nr";
3297}
3298
florian55085f82012-11-21 00:36:55 +00003299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003300s390_irgen_NGR(UChar r1, UChar r2)
3301{
3302 IRTemp op1 = newTemp(Ity_I64);
3303 IRTemp op2 = newTemp(Ity_I64);
3304 IRTemp result = newTemp(Ity_I64);
3305
3306 assign(op1, get_gpr_dw0(r1));
3307 assign(op2, get_gpr_dw0(r2));
3308 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3309 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3310 put_gpr_dw0(r1, mkexpr(result));
3311
3312 return "ngr";
3313}
3314
florian55085f82012-11-21 00:36:55 +00003315static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003316s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3317{
3318 IRTemp op2 = newTemp(Ity_I32);
3319 IRTemp op3 = newTemp(Ity_I32);
3320 IRTemp result = newTemp(Ity_I32);
3321
3322 assign(op2, get_gpr_w1(r2));
3323 assign(op3, get_gpr_w1(r3));
3324 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3325 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3326 put_gpr_w1(r1, mkexpr(result));
3327
3328 return "nrk";
3329}
3330
florian55085f82012-11-21 00:36:55 +00003331static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003332s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3333{
3334 IRTemp op2 = newTemp(Ity_I64);
3335 IRTemp op3 = newTemp(Ity_I64);
3336 IRTemp result = newTemp(Ity_I64);
3337
3338 assign(op2, get_gpr_dw0(r2));
3339 assign(op3, get_gpr_dw0(r3));
3340 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3341 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3342 put_gpr_dw0(r1, mkexpr(result));
3343
3344 return "ngrk";
3345}
3346
florian55085f82012-11-21 00:36:55 +00003347static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003348s390_irgen_N(UChar r1, IRTemp op2addr)
3349{
3350 IRTemp op1 = newTemp(Ity_I32);
3351 IRTemp op2 = newTemp(Ity_I32);
3352 IRTemp result = newTemp(Ity_I32);
3353
3354 assign(op1, get_gpr_w1(r1));
3355 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3356 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3357 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3358 put_gpr_w1(r1, mkexpr(result));
3359
3360 return "n";
3361}
3362
florian55085f82012-11-21 00:36:55 +00003363static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003364s390_irgen_NY(UChar r1, IRTemp op2addr)
3365{
3366 IRTemp op1 = newTemp(Ity_I32);
3367 IRTemp op2 = newTemp(Ity_I32);
3368 IRTemp result = newTemp(Ity_I32);
3369
3370 assign(op1, get_gpr_w1(r1));
3371 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3372 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3373 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3374 put_gpr_w1(r1, mkexpr(result));
3375
3376 return "ny";
3377}
3378
florian55085f82012-11-21 00:36:55 +00003379static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003380s390_irgen_NG(UChar r1, IRTemp op2addr)
3381{
3382 IRTemp op1 = newTemp(Ity_I64);
3383 IRTemp op2 = newTemp(Ity_I64);
3384 IRTemp result = newTemp(Ity_I64);
3385
3386 assign(op1, get_gpr_dw0(r1));
3387 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3388 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3389 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3390 put_gpr_dw0(r1, mkexpr(result));
3391
3392 return "ng";
3393}
3394
florian55085f82012-11-21 00:36:55 +00003395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003396s390_irgen_NI(UChar i2, IRTemp op1addr)
3397{
3398 IRTemp op1 = newTemp(Ity_I8);
3399 UChar op2;
3400 IRTemp result = newTemp(Ity_I8);
3401
3402 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3403 op2 = i2;
3404 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3405 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3406 store(mkexpr(op1addr), mkexpr(result));
3407
3408 return "ni";
3409}
3410
florian55085f82012-11-21 00:36:55 +00003411static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003412s390_irgen_NIY(UChar i2, IRTemp op1addr)
3413{
3414 IRTemp op1 = newTemp(Ity_I8);
3415 UChar op2;
3416 IRTemp result = newTemp(Ity_I8);
3417
3418 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3419 op2 = i2;
3420 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3421 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3422 store(mkexpr(op1addr), mkexpr(result));
3423
3424 return "niy";
3425}
3426
florian55085f82012-11-21 00:36:55 +00003427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003428s390_irgen_NIHF(UChar r1, UInt i2)
3429{
3430 IRTemp op1 = newTemp(Ity_I32);
3431 UInt op2;
3432 IRTemp result = newTemp(Ity_I32);
3433
3434 assign(op1, get_gpr_w0(r1));
3435 op2 = i2;
3436 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3437 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3438 put_gpr_w0(r1, mkexpr(result));
3439
3440 return "nihf";
3441}
3442
florian55085f82012-11-21 00:36:55 +00003443static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003444s390_irgen_NIHH(UChar r1, UShort i2)
3445{
3446 IRTemp op1 = newTemp(Ity_I16);
3447 UShort op2;
3448 IRTemp result = newTemp(Ity_I16);
3449
3450 assign(op1, get_gpr_hw0(r1));
3451 op2 = i2;
3452 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3453 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3454 put_gpr_hw0(r1, mkexpr(result));
3455
3456 return "nihh";
3457}
3458
florian55085f82012-11-21 00:36:55 +00003459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003460s390_irgen_NIHL(UChar r1, UShort i2)
3461{
3462 IRTemp op1 = newTemp(Ity_I16);
3463 UShort op2;
3464 IRTemp result = newTemp(Ity_I16);
3465
3466 assign(op1, get_gpr_hw1(r1));
3467 op2 = i2;
3468 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3469 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3470 put_gpr_hw1(r1, mkexpr(result));
3471
3472 return "nihl";
3473}
3474
florian55085f82012-11-21 00:36:55 +00003475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003476s390_irgen_NILF(UChar r1, UInt i2)
3477{
3478 IRTemp op1 = newTemp(Ity_I32);
3479 UInt op2;
3480 IRTemp result = newTemp(Ity_I32);
3481
3482 assign(op1, get_gpr_w1(r1));
3483 op2 = i2;
3484 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3485 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3486 put_gpr_w1(r1, mkexpr(result));
3487
3488 return "nilf";
3489}
3490
florian55085f82012-11-21 00:36:55 +00003491static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003492s390_irgen_NILH(UChar r1, UShort i2)
3493{
3494 IRTemp op1 = newTemp(Ity_I16);
3495 UShort op2;
3496 IRTemp result = newTemp(Ity_I16);
3497
3498 assign(op1, get_gpr_hw2(r1));
3499 op2 = i2;
3500 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3501 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3502 put_gpr_hw2(r1, mkexpr(result));
3503
3504 return "nilh";
3505}
3506
florian55085f82012-11-21 00:36:55 +00003507static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003508s390_irgen_NILL(UChar r1, UShort i2)
3509{
3510 IRTemp op1 = newTemp(Ity_I16);
3511 UShort op2;
3512 IRTemp result = newTemp(Ity_I16);
3513
3514 assign(op1, get_gpr_hw3(r1));
3515 op2 = i2;
3516 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3517 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3518 put_gpr_hw3(r1, mkexpr(result));
3519
3520 return "nill";
3521}
3522
florian55085f82012-11-21 00:36:55 +00003523static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003524s390_irgen_BASR(UChar r1, UChar r2)
3525{
3526 IRTemp target = newTemp(Ity_I64);
3527
3528 if (r2 == 0) {
3529 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3530 } else {
3531 if (r1 != r2) {
3532 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3533 call_function(get_gpr_dw0(r2));
3534 } else {
3535 assign(target, get_gpr_dw0(r2));
3536 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3537 call_function(mkexpr(target));
3538 }
3539 }
3540
3541 return "basr";
3542}
3543
florian55085f82012-11-21 00:36:55 +00003544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003545s390_irgen_BAS(UChar r1, IRTemp op2addr)
3546{
3547 IRTemp target = newTemp(Ity_I64);
3548
3549 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3550 assign(target, mkexpr(op2addr));
3551 call_function(mkexpr(target));
3552
3553 return "bas";
3554}
3555
florian55085f82012-11-21 00:36:55 +00003556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003557s390_irgen_BCR(UChar r1, UChar r2)
3558{
3559 IRTemp cond = newTemp(Ity_I32);
3560
sewardja52e37e2011-04-28 18:48:06 +00003561 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3562 stmt(IRStmt_MBE(Imbe_Fence));
3563 }
3564
sewardj2019a972011-03-07 16:04:07 +00003565 if ((r2 == 0) || (r1 == 0)) {
3566 } else {
3567 if (r1 == 15) {
3568 return_from_function(get_gpr_dw0(r2));
3569 } else {
3570 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003571 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3572 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003573 }
3574 }
sewardj7ee97522011-05-09 21:45:04 +00003575 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003576 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3577
3578 return "bcr";
3579}
3580
florian55085f82012-11-21 00:36:55 +00003581static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003582s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3583{
3584 IRTemp cond = newTemp(Ity_I32);
3585
3586 if (r1 == 0) {
3587 } else {
3588 if (r1 == 15) {
3589 always_goto(mkexpr(op2addr));
3590 } else {
3591 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003592 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3593 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003594 }
3595 }
sewardj7ee97522011-05-09 21:45:04 +00003596 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003597 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3598
3599 return "bc";
3600}
3601
florian55085f82012-11-21 00:36:55 +00003602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003603s390_irgen_BCTR(UChar r1, UChar r2)
3604{
3605 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3606 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003607 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3608 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003609 }
3610
3611 return "bctr";
3612}
3613
florian55085f82012-11-21 00:36:55 +00003614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003615s390_irgen_BCTGR(UChar r1, UChar r2)
3616{
3617 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3618 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003619 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3620 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003621 }
3622
3623 return "bctgr";
3624}
3625
florian55085f82012-11-21 00:36:55 +00003626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003627s390_irgen_BCT(UChar r1, IRTemp op2addr)
3628{
3629 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003630 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3631 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003632
3633 return "bct";
3634}
3635
florian55085f82012-11-21 00:36:55 +00003636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003637s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3638{
3639 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003640 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3641 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003642
3643 return "bctg";
3644}
3645
florian55085f82012-11-21 00:36:55 +00003646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003647s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3648{
3649 IRTemp value = newTemp(Ity_I32);
3650
3651 assign(value, get_gpr_w1(r3 | 1));
3652 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003653 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3654 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003655
3656 return "bxh";
3657}
3658
florian55085f82012-11-21 00:36:55 +00003659static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003660s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3661{
3662 IRTemp value = newTemp(Ity_I64);
3663
3664 assign(value, get_gpr_dw0(r3 | 1));
3665 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003666 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3667 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003668
3669 return "bxhg";
3670}
3671
florian55085f82012-11-21 00:36:55 +00003672static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003673s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3674{
3675 IRTemp value = newTemp(Ity_I32);
3676
3677 assign(value, get_gpr_w1(r3 | 1));
3678 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003679 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3680 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003681
3682 return "bxle";
3683}
3684
florian55085f82012-11-21 00:36:55 +00003685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003686s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3687{
3688 IRTemp value = newTemp(Ity_I64);
3689
3690 assign(value, get_gpr_dw0(r3 | 1));
3691 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003692 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3693 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003694
3695 return "bxleg";
3696}
3697
florian55085f82012-11-21 00:36:55 +00003698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003699s390_irgen_BRAS(UChar r1, UShort i2)
3700{
3701 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003702 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003703
3704 return "bras";
3705}
3706
florian55085f82012-11-21 00:36:55 +00003707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003708s390_irgen_BRASL(UChar r1, UInt i2)
3709{
3710 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003711 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003712
3713 return "brasl";
3714}
3715
florian55085f82012-11-21 00:36:55 +00003716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003717s390_irgen_BRC(UChar r1, UShort i2)
3718{
3719 IRTemp cond = newTemp(Ity_I32);
3720
3721 if (r1 == 0) {
3722 } else {
3723 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003724 always_goto_and_chase(
3725 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003726 } else {
3727 assign(cond, s390_call_calculate_cond(r1));
3728 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3729 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3730
3731 }
3732 }
sewardj7ee97522011-05-09 21:45:04 +00003733 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003734 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3735
3736 return "brc";
3737}
3738
florian55085f82012-11-21 00:36:55 +00003739static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003740s390_irgen_BRCL(UChar r1, UInt i2)
3741{
3742 IRTemp cond = newTemp(Ity_I32);
3743
3744 if (r1 == 0) {
3745 } else {
3746 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003747 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003748 } else {
3749 assign(cond, s390_call_calculate_cond(r1));
3750 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3751 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3752 }
3753 }
sewardj7ee97522011-05-09 21:45:04 +00003754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003755 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3756
3757 return "brcl";
3758}
3759
florian55085f82012-11-21 00:36:55 +00003760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003761s390_irgen_BRCT(UChar r1, UShort i2)
3762{
3763 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3764 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3765 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3766
3767 return "brct";
3768}
3769
florian55085f82012-11-21 00:36:55 +00003770static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003771s390_irgen_BRCTG(UChar r1, UShort i2)
3772{
3773 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3774 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3775 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3776
3777 return "brctg";
3778}
3779
florian55085f82012-11-21 00:36:55 +00003780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003781s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3782{
3783 IRTemp value = newTemp(Ity_I32);
3784
3785 assign(value, get_gpr_w1(r3 | 1));
3786 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3787 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3788 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3789
3790 return "brxh";
3791}
3792
florian55085f82012-11-21 00:36:55 +00003793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003794s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3795{
3796 IRTemp value = newTemp(Ity_I64);
3797
3798 assign(value, get_gpr_dw0(r3 | 1));
3799 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3800 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3801 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3802
3803 return "brxhg";
3804}
3805
florian55085f82012-11-21 00:36:55 +00003806static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003807s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3808{
3809 IRTemp value = newTemp(Ity_I32);
3810
3811 assign(value, get_gpr_w1(r3 | 1));
3812 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3813 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3814 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3815
3816 return "brxle";
3817}
3818
florian55085f82012-11-21 00:36:55 +00003819static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003820s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3821{
3822 IRTemp value = newTemp(Ity_I64);
3823
3824 assign(value, get_gpr_dw0(r3 | 1));
3825 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3826 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3827 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3828
3829 return "brxlg";
3830}
3831
florian55085f82012-11-21 00:36:55 +00003832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003833s390_irgen_CR(UChar r1, UChar r2)
3834{
3835 IRTemp op1 = newTemp(Ity_I32);
3836 IRTemp op2 = newTemp(Ity_I32);
3837
3838 assign(op1, get_gpr_w1(r1));
3839 assign(op2, get_gpr_w1(r2));
3840 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3841
3842 return "cr";
3843}
3844
florian55085f82012-11-21 00:36:55 +00003845static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003846s390_irgen_CGR(UChar r1, UChar r2)
3847{
3848 IRTemp op1 = newTemp(Ity_I64);
3849 IRTemp op2 = newTemp(Ity_I64);
3850
3851 assign(op1, get_gpr_dw0(r1));
3852 assign(op2, get_gpr_dw0(r2));
3853 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3854
3855 return "cgr";
3856}
3857
florian55085f82012-11-21 00:36:55 +00003858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003859s390_irgen_CGFR(UChar r1, UChar r2)
3860{
3861 IRTemp op1 = newTemp(Ity_I64);
3862 IRTemp op2 = newTemp(Ity_I64);
3863
3864 assign(op1, get_gpr_dw0(r1));
3865 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3866 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3867
3868 return "cgfr";
3869}
3870
florian55085f82012-11-21 00:36:55 +00003871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003872s390_irgen_C(UChar r1, IRTemp op2addr)
3873{
3874 IRTemp op1 = newTemp(Ity_I32);
3875 IRTemp op2 = newTemp(Ity_I32);
3876
3877 assign(op1, get_gpr_w1(r1));
3878 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3879 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3880
3881 return "c";
3882}
3883
florian55085f82012-11-21 00:36:55 +00003884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003885s390_irgen_CY(UChar r1, IRTemp op2addr)
3886{
3887 IRTemp op1 = newTemp(Ity_I32);
3888 IRTemp op2 = newTemp(Ity_I32);
3889
3890 assign(op1, get_gpr_w1(r1));
3891 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3892 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3893
3894 return "cy";
3895}
3896
florian55085f82012-11-21 00:36:55 +00003897static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003898s390_irgen_CG(UChar r1, IRTemp op2addr)
3899{
3900 IRTemp op1 = newTemp(Ity_I64);
3901 IRTemp op2 = newTemp(Ity_I64);
3902
3903 assign(op1, get_gpr_dw0(r1));
3904 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3905 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3906
3907 return "cg";
3908}
3909
florian55085f82012-11-21 00:36:55 +00003910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003911s390_irgen_CGF(UChar r1, IRTemp op2addr)
3912{
3913 IRTemp op1 = newTemp(Ity_I64);
3914 IRTemp op2 = newTemp(Ity_I64);
3915
3916 assign(op1, get_gpr_dw0(r1));
3917 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3918 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3919
3920 return "cgf";
3921}
3922
florian55085f82012-11-21 00:36:55 +00003923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003924s390_irgen_CFI(UChar r1, UInt i2)
3925{
3926 IRTemp op1 = newTemp(Ity_I32);
3927 Int op2;
3928
3929 assign(op1, get_gpr_w1(r1));
3930 op2 = (Int)i2;
3931 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3932 mkU32((UInt)op2)));
3933
3934 return "cfi";
3935}
3936
florian55085f82012-11-21 00:36:55 +00003937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003938s390_irgen_CGFI(UChar r1, UInt i2)
3939{
3940 IRTemp op1 = newTemp(Ity_I64);
3941 Long op2;
3942
3943 assign(op1, get_gpr_dw0(r1));
3944 op2 = (Long)(Int)i2;
3945 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3946 mkU64((ULong)op2)));
3947
3948 return "cgfi";
3949}
3950
florian55085f82012-11-21 00:36:55 +00003951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003952s390_irgen_CRL(UChar r1, UInt i2)
3953{
3954 IRTemp op1 = newTemp(Ity_I32);
3955 IRTemp op2 = newTemp(Ity_I32);
3956
3957 assign(op1, get_gpr_w1(r1));
3958 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3959 i2 << 1))));
3960 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3961
3962 return "crl";
3963}
3964
florian55085f82012-11-21 00:36:55 +00003965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003966s390_irgen_CGRL(UChar r1, UInt i2)
3967{
3968 IRTemp op1 = newTemp(Ity_I64);
3969 IRTemp op2 = newTemp(Ity_I64);
3970
3971 assign(op1, get_gpr_dw0(r1));
3972 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3973 i2 << 1))));
3974 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3975
3976 return "cgrl";
3977}
3978
florian55085f82012-11-21 00:36:55 +00003979static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003980s390_irgen_CGFRL(UChar r1, UInt i2)
3981{
3982 IRTemp op1 = newTemp(Ity_I64);
3983 IRTemp op2 = newTemp(Ity_I64);
3984
3985 assign(op1, get_gpr_dw0(r1));
3986 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3987 ((ULong)(Long)(Int)i2 << 1)))));
3988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3989
3990 return "cgfrl";
3991}
3992
florian55085f82012-11-21 00:36:55 +00003993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003994s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3995{
3996 IRTemp op1 = newTemp(Ity_I32);
3997 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003998 IRTemp cond = newTemp(Ity_I32);
3999
4000 if (m3 == 0) {
4001 } else {
4002 if (m3 == 14) {
4003 always_goto(mkexpr(op4addr));
4004 } else {
4005 assign(op1, get_gpr_w1(r1));
4006 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004007 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4008 op1, op2));
florianf321da72012-07-21 20:32:57 +00004009 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4010 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004011 }
4012 }
4013
4014 return "crb";
4015}
4016
florian55085f82012-11-21 00:36:55 +00004017static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004018s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4019{
4020 IRTemp op1 = newTemp(Ity_I64);
4021 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004022 IRTemp cond = newTemp(Ity_I32);
4023
4024 if (m3 == 0) {
4025 } else {
4026 if (m3 == 14) {
4027 always_goto(mkexpr(op4addr));
4028 } else {
4029 assign(op1, get_gpr_dw0(r1));
4030 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004031 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4032 op1, op2));
florianf321da72012-07-21 20:32:57 +00004033 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4034 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004035 }
4036 }
4037
4038 return "cgrb";
4039}
4040
florian55085f82012-11-21 00:36:55 +00004041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004042s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4043{
4044 IRTemp op1 = newTemp(Ity_I32);
4045 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004046 IRTemp cond = newTemp(Ity_I32);
4047
4048 if (m3 == 0) {
4049 } else {
4050 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004051 always_goto_and_chase(
4052 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004053 } else {
4054 assign(op1, get_gpr_w1(r1));
4055 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004056 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4057 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004058 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4059 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4060
4061 }
4062 }
4063
4064 return "crj";
4065}
4066
florian55085f82012-11-21 00:36:55 +00004067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004068s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4069{
4070 IRTemp op1 = newTemp(Ity_I64);
4071 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004072 IRTemp cond = newTemp(Ity_I32);
4073
4074 if (m3 == 0) {
4075 } else {
4076 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004077 always_goto_and_chase(
4078 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004079 } else {
4080 assign(op1, get_gpr_dw0(r1));
4081 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004082 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4083 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004084 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4085 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4086
4087 }
4088 }
4089
4090 return "cgrj";
4091}
4092
florian55085f82012-11-21 00:36:55 +00004093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004094s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4095{
4096 IRTemp op1 = newTemp(Ity_I32);
4097 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004098 IRTemp cond = newTemp(Ity_I32);
4099
4100 if (m3 == 0) {
4101 } else {
4102 if (m3 == 14) {
4103 always_goto(mkexpr(op4addr));
4104 } else {
4105 assign(op1, get_gpr_w1(r1));
4106 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004107 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4108 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004109 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4110 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004111 }
4112 }
4113
4114 return "cib";
4115}
4116
florian55085f82012-11-21 00:36:55 +00004117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004118s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4119{
4120 IRTemp op1 = newTemp(Ity_I64);
4121 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004122 IRTemp cond = newTemp(Ity_I32);
4123
4124 if (m3 == 0) {
4125 } else {
4126 if (m3 == 14) {
4127 always_goto(mkexpr(op4addr));
4128 } else {
4129 assign(op1, get_gpr_dw0(r1));
4130 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004131 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4132 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004133 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4134 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004135 }
4136 }
4137
4138 return "cgib";
4139}
4140
florian55085f82012-11-21 00:36:55 +00004141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004142s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4143{
4144 IRTemp op1 = newTemp(Ity_I32);
4145 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004146 IRTemp cond = newTemp(Ity_I32);
4147
4148 if (m3 == 0) {
4149 } else {
4150 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004151 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004152 } else {
4153 assign(op1, get_gpr_w1(r1));
4154 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004155 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4156 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004157 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4158 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4159
4160 }
4161 }
4162
4163 return "cij";
4164}
4165
florian55085f82012-11-21 00:36:55 +00004166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004167s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4168{
4169 IRTemp op1 = newTemp(Ity_I64);
4170 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004171 IRTemp cond = newTemp(Ity_I32);
4172
4173 if (m3 == 0) {
4174 } else {
4175 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004176 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004177 } else {
4178 assign(op1, get_gpr_dw0(r1));
4179 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004180 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4181 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004182 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4183 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4184
4185 }
4186 }
4187
4188 return "cgij";
4189}
4190
florian55085f82012-11-21 00:36:55 +00004191static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004192s390_irgen_CH(UChar r1, IRTemp op2addr)
4193{
4194 IRTemp op1 = newTemp(Ity_I32);
4195 IRTemp op2 = newTemp(Ity_I32);
4196
4197 assign(op1, get_gpr_w1(r1));
4198 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4199 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4200
4201 return "ch";
4202}
4203
florian55085f82012-11-21 00:36:55 +00004204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004205s390_irgen_CHY(UChar r1, IRTemp op2addr)
4206{
4207 IRTemp op1 = newTemp(Ity_I32);
4208 IRTemp op2 = newTemp(Ity_I32);
4209
4210 assign(op1, get_gpr_w1(r1));
4211 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4212 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4213
4214 return "chy";
4215}
4216
florian55085f82012-11-21 00:36:55 +00004217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004218s390_irgen_CGH(UChar r1, IRTemp op2addr)
4219{
4220 IRTemp op1 = newTemp(Ity_I64);
4221 IRTemp op2 = newTemp(Ity_I64);
4222
4223 assign(op1, get_gpr_dw0(r1));
4224 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4225 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4226
4227 return "cgh";
4228}
4229
florian55085f82012-11-21 00:36:55 +00004230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004231s390_irgen_CHI(UChar r1, UShort i2)
4232{
4233 IRTemp op1 = newTemp(Ity_I32);
4234 Int op2;
4235
4236 assign(op1, get_gpr_w1(r1));
4237 op2 = (Int)(Short)i2;
4238 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4239 mkU32((UInt)op2)));
4240
4241 return "chi";
4242}
4243
florian55085f82012-11-21 00:36:55 +00004244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004245s390_irgen_CGHI(UChar r1, UShort i2)
4246{
4247 IRTemp op1 = newTemp(Ity_I64);
4248 Long op2;
4249
4250 assign(op1, get_gpr_dw0(r1));
4251 op2 = (Long)(Short)i2;
4252 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4253 mkU64((ULong)op2)));
4254
4255 return "cghi";
4256}
4257
florian55085f82012-11-21 00:36:55 +00004258static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004259s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4260{
4261 IRTemp op1 = newTemp(Ity_I16);
4262 Short op2;
4263
4264 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4265 op2 = (Short)i2;
4266 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4267 mkU16((UShort)op2)));
4268
4269 return "chhsi";
4270}
4271
florian55085f82012-11-21 00:36:55 +00004272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004273s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4274{
4275 IRTemp op1 = newTemp(Ity_I32);
4276 Int op2;
4277
4278 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4279 op2 = (Int)(Short)i2;
4280 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4281 mkU32((UInt)op2)));
4282
4283 return "chsi";
4284}
4285
florian55085f82012-11-21 00:36:55 +00004286static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004287s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4288{
4289 IRTemp op1 = newTemp(Ity_I64);
4290 Long op2;
4291
4292 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4293 op2 = (Long)(Short)i2;
4294 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4295 mkU64((ULong)op2)));
4296
4297 return "cghsi";
4298}
4299
florian55085f82012-11-21 00:36:55 +00004300static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004301s390_irgen_CHRL(UChar r1, UInt i2)
4302{
4303 IRTemp op1 = newTemp(Ity_I32);
4304 IRTemp op2 = newTemp(Ity_I32);
4305
4306 assign(op1, get_gpr_w1(r1));
4307 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4308 ((ULong)(Long)(Int)i2 << 1)))));
4309 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4310
4311 return "chrl";
4312}
4313
florian55085f82012-11-21 00:36:55 +00004314static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004315s390_irgen_CGHRL(UChar r1, UInt i2)
4316{
4317 IRTemp op1 = newTemp(Ity_I64);
4318 IRTemp op2 = newTemp(Ity_I64);
4319
4320 assign(op1, get_gpr_dw0(r1));
4321 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4322 ((ULong)(Long)(Int)i2 << 1)))));
4323 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4324
4325 return "cghrl";
4326}
4327
florian55085f82012-11-21 00:36:55 +00004328static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004329s390_irgen_CHHR(UChar r1, UChar r2)
4330{
4331 IRTemp op1 = newTemp(Ity_I32);
4332 IRTemp op2 = newTemp(Ity_I32);
4333
4334 assign(op1, get_gpr_w0(r1));
4335 assign(op2, get_gpr_w0(r2));
4336 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4337
4338 return "chhr";
4339}
4340
florian55085f82012-11-21 00:36:55 +00004341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004342s390_irgen_CHLR(UChar r1, UChar r2)
4343{
4344 IRTemp op1 = newTemp(Ity_I32);
4345 IRTemp op2 = newTemp(Ity_I32);
4346
4347 assign(op1, get_gpr_w0(r1));
4348 assign(op2, get_gpr_w1(r2));
4349 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4350
4351 return "chlr";
4352}
4353
florian55085f82012-11-21 00:36:55 +00004354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004355s390_irgen_CHF(UChar r1, IRTemp op2addr)
4356{
4357 IRTemp op1 = newTemp(Ity_I32);
4358 IRTemp op2 = newTemp(Ity_I32);
4359
4360 assign(op1, get_gpr_w0(r1));
4361 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4362 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4363
4364 return "chf";
4365}
4366
florian55085f82012-11-21 00:36:55 +00004367static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004368s390_irgen_CIH(UChar r1, UInt i2)
4369{
4370 IRTemp op1 = newTemp(Ity_I32);
4371 Int op2;
4372
4373 assign(op1, get_gpr_w0(r1));
4374 op2 = (Int)i2;
4375 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4376 mkU32((UInt)op2)));
4377
4378 return "cih";
4379}
4380
florian55085f82012-11-21 00:36:55 +00004381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004382s390_irgen_CLR(UChar r1, UChar r2)
4383{
4384 IRTemp op1 = newTemp(Ity_I32);
4385 IRTemp op2 = newTemp(Ity_I32);
4386
4387 assign(op1, get_gpr_w1(r1));
4388 assign(op2, get_gpr_w1(r2));
4389 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4390
4391 return "clr";
4392}
4393
florian55085f82012-11-21 00:36:55 +00004394static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004395s390_irgen_CLGR(UChar r1, UChar r2)
4396{
4397 IRTemp op1 = newTemp(Ity_I64);
4398 IRTemp op2 = newTemp(Ity_I64);
4399
4400 assign(op1, get_gpr_dw0(r1));
4401 assign(op2, get_gpr_dw0(r2));
4402 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4403
4404 return "clgr";
4405}
4406
florian55085f82012-11-21 00:36:55 +00004407static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004408s390_irgen_CLGFR(UChar r1, UChar r2)
4409{
4410 IRTemp op1 = newTemp(Ity_I64);
4411 IRTemp op2 = newTemp(Ity_I64);
4412
4413 assign(op1, get_gpr_dw0(r1));
4414 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4415 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4416
4417 return "clgfr";
4418}
4419
florian55085f82012-11-21 00:36:55 +00004420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004421s390_irgen_CL(UChar r1, IRTemp op2addr)
4422{
4423 IRTemp op1 = newTemp(Ity_I32);
4424 IRTemp op2 = newTemp(Ity_I32);
4425
4426 assign(op1, get_gpr_w1(r1));
4427 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4428 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4429
4430 return "cl";
4431}
4432
florian55085f82012-11-21 00:36:55 +00004433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004434s390_irgen_CLY(UChar r1, IRTemp op2addr)
4435{
4436 IRTemp op1 = newTemp(Ity_I32);
4437 IRTemp op2 = newTemp(Ity_I32);
4438
4439 assign(op1, get_gpr_w1(r1));
4440 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4441 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4442
4443 return "cly";
4444}
4445
florian55085f82012-11-21 00:36:55 +00004446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004447s390_irgen_CLG(UChar r1, IRTemp op2addr)
4448{
4449 IRTemp op1 = newTemp(Ity_I64);
4450 IRTemp op2 = newTemp(Ity_I64);
4451
4452 assign(op1, get_gpr_dw0(r1));
4453 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4454 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4455
4456 return "clg";
4457}
4458
florian55085f82012-11-21 00:36:55 +00004459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004460s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4461{
4462 IRTemp op1 = newTemp(Ity_I64);
4463 IRTemp op2 = newTemp(Ity_I64);
4464
4465 assign(op1, get_gpr_dw0(r1));
4466 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4467 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4468
4469 return "clgf";
4470}
4471
florian55085f82012-11-21 00:36:55 +00004472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004473s390_irgen_CLFI(UChar r1, UInt i2)
4474{
4475 IRTemp op1 = newTemp(Ity_I32);
4476 UInt op2;
4477
4478 assign(op1, get_gpr_w1(r1));
4479 op2 = i2;
4480 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4481 mkU32(op2)));
4482
4483 return "clfi";
4484}
4485
florian55085f82012-11-21 00:36:55 +00004486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004487s390_irgen_CLGFI(UChar r1, UInt i2)
4488{
4489 IRTemp op1 = newTemp(Ity_I64);
4490 ULong op2;
4491
4492 assign(op1, get_gpr_dw0(r1));
4493 op2 = (ULong)i2;
4494 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4495 mkU64(op2)));
4496
4497 return "clgfi";
4498}
4499
florian55085f82012-11-21 00:36:55 +00004500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004501s390_irgen_CLI(UChar i2, IRTemp op1addr)
4502{
4503 IRTemp op1 = newTemp(Ity_I8);
4504 UChar op2;
4505
4506 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4507 op2 = i2;
4508 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4509 mkU8(op2)));
4510
4511 return "cli";
4512}
4513
florian55085f82012-11-21 00:36:55 +00004514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004515s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4516{
4517 IRTemp op1 = newTemp(Ity_I8);
4518 UChar op2;
4519
4520 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4521 op2 = i2;
4522 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4523 mkU8(op2)));
4524
4525 return "cliy";
4526}
4527
florian55085f82012-11-21 00:36:55 +00004528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004529s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4530{
4531 IRTemp op1 = newTemp(Ity_I32);
4532 UInt op2;
4533
4534 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4535 op2 = (UInt)i2;
4536 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4537 mkU32(op2)));
4538
4539 return "clfhsi";
4540}
4541
florian55085f82012-11-21 00:36:55 +00004542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004543s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4544{
4545 IRTemp op1 = newTemp(Ity_I64);
4546 ULong op2;
4547
4548 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4549 op2 = (ULong)i2;
4550 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4551 mkU64(op2)));
4552
4553 return "clghsi";
4554}
4555
florian55085f82012-11-21 00:36:55 +00004556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004557s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4558{
4559 IRTemp op1 = newTemp(Ity_I16);
4560 UShort op2;
4561
4562 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4563 op2 = i2;
4564 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4565 mkU16(op2)));
4566
4567 return "clhhsi";
4568}
4569
florian55085f82012-11-21 00:36:55 +00004570static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004571s390_irgen_CLRL(UChar r1, UInt i2)
4572{
4573 IRTemp op1 = newTemp(Ity_I32);
4574 IRTemp op2 = newTemp(Ity_I32);
4575
4576 assign(op1, get_gpr_w1(r1));
4577 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4578 i2 << 1))));
4579 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4580
4581 return "clrl";
4582}
4583
florian55085f82012-11-21 00:36:55 +00004584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004585s390_irgen_CLGRL(UChar r1, UInt i2)
4586{
4587 IRTemp op1 = newTemp(Ity_I64);
4588 IRTemp op2 = newTemp(Ity_I64);
4589
4590 assign(op1, get_gpr_dw0(r1));
4591 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4592 i2 << 1))));
4593 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4594
4595 return "clgrl";
4596}
4597
florian55085f82012-11-21 00:36:55 +00004598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004599s390_irgen_CLGFRL(UChar r1, UInt i2)
4600{
4601 IRTemp op1 = newTemp(Ity_I64);
4602 IRTemp op2 = newTemp(Ity_I64);
4603
4604 assign(op1, get_gpr_dw0(r1));
4605 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4606 ((ULong)(Long)(Int)i2 << 1)))));
4607 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4608
4609 return "clgfrl";
4610}
4611
florian55085f82012-11-21 00:36:55 +00004612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004613s390_irgen_CLHRL(UChar r1, UInt i2)
4614{
4615 IRTemp op1 = newTemp(Ity_I32);
4616 IRTemp op2 = newTemp(Ity_I32);
4617
4618 assign(op1, get_gpr_w1(r1));
4619 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4620 ((ULong)(Long)(Int)i2 << 1)))));
4621 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4622
4623 return "clhrl";
4624}
4625
florian55085f82012-11-21 00:36:55 +00004626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004627s390_irgen_CLGHRL(UChar r1, UInt i2)
4628{
4629 IRTemp op1 = newTemp(Ity_I64);
4630 IRTemp op2 = newTemp(Ity_I64);
4631
4632 assign(op1, get_gpr_dw0(r1));
4633 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4634 ((ULong)(Long)(Int)i2 << 1)))));
4635 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4636
4637 return "clghrl";
4638}
4639
florian55085f82012-11-21 00:36:55 +00004640static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004641s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4642{
4643 IRTemp op1 = newTemp(Ity_I32);
4644 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004645 IRTemp cond = newTemp(Ity_I32);
4646
4647 if (m3 == 0) {
4648 } else {
4649 if (m3 == 14) {
4650 always_goto(mkexpr(op4addr));
4651 } else {
4652 assign(op1, get_gpr_w1(r1));
4653 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004654 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4655 op1, op2));
florianf321da72012-07-21 20:32:57 +00004656 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4657 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004658 }
4659 }
4660
4661 return "clrb";
4662}
4663
florian55085f82012-11-21 00:36:55 +00004664static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004665s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4666{
4667 IRTemp op1 = newTemp(Ity_I64);
4668 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004669 IRTemp cond = newTemp(Ity_I32);
4670
4671 if (m3 == 0) {
4672 } else {
4673 if (m3 == 14) {
4674 always_goto(mkexpr(op4addr));
4675 } else {
4676 assign(op1, get_gpr_dw0(r1));
4677 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004678 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4679 op1, op2));
florianf321da72012-07-21 20:32:57 +00004680 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4681 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004682 }
4683 }
4684
4685 return "clgrb";
4686}
4687
florian55085f82012-11-21 00:36:55 +00004688static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004689s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4690{
4691 IRTemp op1 = newTemp(Ity_I32);
4692 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004693 IRTemp cond = newTemp(Ity_I32);
4694
4695 if (m3 == 0) {
4696 } else {
4697 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004698 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004699 } else {
4700 assign(op1, get_gpr_w1(r1));
4701 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004702 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4703 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004704 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4705 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4706
4707 }
4708 }
4709
4710 return "clrj";
4711}
4712
florian55085f82012-11-21 00:36:55 +00004713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004714s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4715{
4716 IRTemp op1 = newTemp(Ity_I64);
4717 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004718 IRTemp cond = newTemp(Ity_I32);
4719
4720 if (m3 == 0) {
4721 } else {
4722 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004723 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004724 } else {
4725 assign(op1, get_gpr_dw0(r1));
4726 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004727 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4728 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004729 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4730 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4731
4732 }
4733 }
4734
4735 return "clgrj";
4736}
4737
florian55085f82012-11-21 00:36:55 +00004738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004739s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4740{
4741 IRTemp op1 = newTemp(Ity_I32);
4742 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004743 IRTemp cond = newTemp(Ity_I32);
4744
4745 if (m3 == 0) {
4746 } else {
4747 if (m3 == 14) {
4748 always_goto(mkexpr(op4addr));
4749 } else {
4750 assign(op1, get_gpr_w1(r1));
4751 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004752 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4753 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004754 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4755 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004756 }
4757 }
4758
4759 return "clib";
4760}
4761
florian55085f82012-11-21 00:36:55 +00004762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004763s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4764{
4765 IRTemp op1 = newTemp(Ity_I64);
4766 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004767 IRTemp cond = newTemp(Ity_I32);
4768
4769 if (m3 == 0) {
4770 } else {
4771 if (m3 == 14) {
4772 always_goto(mkexpr(op4addr));
4773 } else {
4774 assign(op1, get_gpr_dw0(r1));
4775 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004776 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4777 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004778 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4779 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004780 }
4781 }
4782
4783 return "clgib";
4784}
4785
florian55085f82012-11-21 00:36:55 +00004786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004787s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4788{
4789 IRTemp op1 = newTemp(Ity_I32);
4790 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004791 IRTemp cond = newTemp(Ity_I32);
4792
4793 if (m3 == 0) {
4794 } else {
4795 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004796 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004797 } else {
4798 assign(op1, get_gpr_w1(r1));
4799 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004800 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4801 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004802 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4803 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4804
4805 }
4806 }
4807
4808 return "clij";
4809}
4810
florian55085f82012-11-21 00:36:55 +00004811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004812s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4813{
4814 IRTemp op1 = newTemp(Ity_I64);
4815 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004816 IRTemp cond = newTemp(Ity_I32);
4817
4818 if (m3 == 0) {
4819 } else {
4820 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004821 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004822 } else {
4823 assign(op1, get_gpr_dw0(r1));
4824 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004825 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4826 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004827 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4828 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4829
4830 }
4831 }
4832
4833 return "clgij";
4834}
4835
florian55085f82012-11-21 00:36:55 +00004836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004837s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4838{
4839 IRTemp op1 = newTemp(Ity_I32);
4840 IRTemp op2 = newTemp(Ity_I32);
4841 IRTemp b0 = newTemp(Ity_I32);
4842 IRTemp b1 = newTemp(Ity_I32);
4843 IRTemp b2 = newTemp(Ity_I32);
4844 IRTemp b3 = newTemp(Ity_I32);
4845 IRTemp c0 = newTemp(Ity_I32);
4846 IRTemp c1 = newTemp(Ity_I32);
4847 IRTemp c2 = newTemp(Ity_I32);
4848 IRTemp c3 = newTemp(Ity_I32);
4849 UChar n;
4850
4851 n = 0;
4852 if ((r3 & 8) != 0) {
4853 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4854 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4855 n = n + 1;
4856 } else {
4857 assign(b0, mkU32(0));
4858 assign(c0, mkU32(0));
4859 }
4860 if ((r3 & 4) != 0) {
4861 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4862 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4863 mkU64(n)))));
4864 n = n + 1;
4865 } else {
4866 assign(b1, mkU32(0));
4867 assign(c1, mkU32(0));
4868 }
4869 if ((r3 & 2) != 0) {
4870 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4871 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4872 mkU64(n)))));
4873 n = n + 1;
4874 } else {
4875 assign(b2, mkU32(0));
4876 assign(c2, mkU32(0));
4877 }
4878 if ((r3 & 1) != 0) {
4879 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4880 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4881 mkU64(n)))));
4882 n = n + 1;
4883 } else {
4884 assign(b3, mkU32(0));
4885 assign(c3, mkU32(0));
4886 }
4887 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4888 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4889 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4890 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4891 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4892 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4893 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4894
4895 return "clm";
4896}
4897
florian55085f82012-11-21 00:36:55 +00004898static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004899s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4900{
4901 IRTemp op1 = newTemp(Ity_I32);
4902 IRTemp op2 = newTemp(Ity_I32);
4903 IRTemp b0 = newTemp(Ity_I32);
4904 IRTemp b1 = newTemp(Ity_I32);
4905 IRTemp b2 = newTemp(Ity_I32);
4906 IRTemp b3 = newTemp(Ity_I32);
4907 IRTemp c0 = newTemp(Ity_I32);
4908 IRTemp c1 = newTemp(Ity_I32);
4909 IRTemp c2 = newTemp(Ity_I32);
4910 IRTemp c3 = newTemp(Ity_I32);
4911 UChar n;
4912
4913 n = 0;
4914 if ((r3 & 8) != 0) {
4915 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4916 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4917 n = n + 1;
4918 } else {
4919 assign(b0, mkU32(0));
4920 assign(c0, mkU32(0));
4921 }
4922 if ((r3 & 4) != 0) {
4923 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4924 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4925 mkU64(n)))));
4926 n = n + 1;
4927 } else {
4928 assign(b1, mkU32(0));
4929 assign(c1, mkU32(0));
4930 }
4931 if ((r3 & 2) != 0) {
4932 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4933 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4934 mkU64(n)))));
4935 n = n + 1;
4936 } else {
4937 assign(b2, mkU32(0));
4938 assign(c2, mkU32(0));
4939 }
4940 if ((r3 & 1) != 0) {
4941 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4942 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4943 mkU64(n)))));
4944 n = n + 1;
4945 } else {
4946 assign(b3, mkU32(0));
4947 assign(c3, mkU32(0));
4948 }
4949 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4950 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4951 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4952 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4953 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4954 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4955 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4956
4957 return "clmy";
4958}
4959
florian55085f82012-11-21 00:36:55 +00004960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004961s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4962{
4963 IRTemp op1 = newTemp(Ity_I32);
4964 IRTemp op2 = newTemp(Ity_I32);
4965 IRTemp b0 = newTemp(Ity_I32);
4966 IRTemp b1 = newTemp(Ity_I32);
4967 IRTemp b2 = newTemp(Ity_I32);
4968 IRTemp b3 = newTemp(Ity_I32);
4969 IRTemp c0 = newTemp(Ity_I32);
4970 IRTemp c1 = newTemp(Ity_I32);
4971 IRTemp c2 = newTemp(Ity_I32);
4972 IRTemp c3 = newTemp(Ity_I32);
4973 UChar n;
4974
4975 n = 0;
4976 if ((r3 & 8) != 0) {
4977 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4978 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4979 n = n + 1;
4980 } else {
4981 assign(b0, mkU32(0));
4982 assign(c0, mkU32(0));
4983 }
4984 if ((r3 & 4) != 0) {
4985 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4986 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4987 mkU64(n)))));
4988 n = n + 1;
4989 } else {
4990 assign(b1, mkU32(0));
4991 assign(c1, mkU32(0));
4992 }
4993 if ((r3 & 2) != 0) {
4994 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4995 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4996 mkU64(n)))));
4997 n = n + 1;
4998 } else {
4999 assign(b2, mkU32(0));
5000 assign(c2, mkU32(0));
5001 }
5002 if ((r3 & 1) != 0) {
5003 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5004 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5005 mkU64(n)))));
5006 n = n + 1;
5007 } else {
5008 assign(b3, mkU32(0));
5009 assign(c3, mkU32(0));
5010 }
5011 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5012 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5013 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5014 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5015 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5016 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5017 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5018
5019 return "clmh";
5020}
5021
florian55085f82012-11-21 00:36:55 +00005022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005023s390_irgen_CLHHR(UChar r1, UChar r2)
5024{
5025 IRTemp op1 = newTemp(Ity_I32);
5026 IRTemp op2 = newTemp(Ity_I32);
5027
5028 assign(op1, get_gpr_w0(r1));
5029 assign(op2, get_gpr_w0(r2));
5030 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5031
5032 return "clhhr";
5033}
5034
florian55085f82012-11-21 00:36:55 +00005035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005036s390_irgen_CLHLR(UChar r1, UChar r2)
5037{
5038 IRTemp op1 = newTemp(Ity_I32);
5039 IRTemp op2 = newTemp(Ity_I32);
5040
5041 assign(op1, get_gpr_w0(r1));
5042 assign(op2, get_gpr_w1(r2));
5043 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5044
5045 return "clhlr";
5046}
5047
florian55085f82012-11-21 00:36:55 +00005048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005049s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5050{
5051 IRTemp op1 = newTemp(Ity_I32);
5052 IRTemp op2 = newTemp(Ity_I32);
5053
5054 assign(op1, get_gpr_w0(r1));
5055 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5056 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5057
5058 return "clhf";
5059}
5060
florian55085f82012-11-21 00:36:55 +00005061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005062s390_irgen_CLIH(UChar r1, UInt i2)
5063{
5064 IRTemp op1 = newTemp(Ity_I32);
5065 UInt op2;
5066
5067 assign(op1, get_gpr_w0(r1));
5068 op2 = i2;
5069 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5070 mkU32(op2)));
5071
5072 return "clih";
5073}
5074
florian55085f82012-11-21 00:36:55 +00005075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005076s390_irgen_CPYA(UChar r1, UChar r2)
5077{
5078 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005079 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005080 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5081
5082 return "cpya";
5083}
5084
florian55085f82012-11-21 00:36:55 +00005085static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005086s390_irgen_XR(UChar r1, UChar r2)
5087{
5088 IRTemp op1 = newTemp(Ity_I32);
5089 IRTemp op2 = newTemp(Ity_I32);
5090 IRTemp result = newTemp(Ity_I32);
5091
5092 if (r1 == r2) {
5093 assign(result, mkU32(0));
5094 } else {
5095 assign(op1, get_gpr_w1(r1));
5096 assign(op2, get_gpr_w1(r2));
5097 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5098 }
5099 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5100 put_gpr_w1(r1, mkexpr(result));
5101
5102 return "xr";
5103}
5104
florian55085f82012-11-21 00:36:55 +00005105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005106s390_irgen_XGR(UChar r1, UChar r2)
5107{
5108 IRTemp op1 = newTemp(Ity_I64);
5109 IRTemp op2 = newTemp(Ity_I64);
5110 IRTemp result = newTemp(Ity_I64);
5111
5112 if (r1 == r2) {
5113 assign(result, mkU64(0));
5114 } else {
5115 assign(op1, get_gpr_dw0(r1));
5116 assign(op2, get_gpr_dw0(r2));
5117 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5118 }
5119 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5120 put_gpr_dw0(r1, mkexpr(result));
5121
5122 return "xgr";
5123}
5124
florian55085f82012-11-21 00:36:55 +00005125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005126s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5127{
5128 IRTemp op2 = newTemp(Ity_I32);
5129 IRTemp op3 = newTemp(Ity_I32);
5130 IRTemp result = newTemp(Ity_I32);
5131
5132 assign(op2, get_gpr_w1(r2));
5133 assign(op3, get_gpr_w1(r3));
5134 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5135 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5136 put_gpr_w1(r1, mkexpr(result));
5137
5138 return "xrk";
5139}
5140
florian55085f82012-11-21 00:36:55 +00005141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005142s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5143{
5144 IRTemp op2 = newTemp(Ity_I64);
5145 IRTemp op3 = newTemp(Ity_I64);
5146 IRTemp result = newTemp(Ity_I64);
5147
5148 assign(op2, get_gpr_dw0(r2));
5149 assign(op3, get_gpr_dw0(r3));
5150 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5151 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5152 put_gpr_dw0(r1, mkexpr(result));
5153
5154 return "xgrk";
5155}
5156
florian55085f82012-11-21 00:36:55 +00005157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005158s390_irgen_X(UChar r1, IRTemp op2addr)
5159{
5160 IRTemp op1 = newTemp(Ity_I32);
5161 IRTemp op2 = newTemp(Ity_I32);
5162 IRTemp result = newTemp(Ity_I32);
5163
5164 assign(op1, get_gpr_w1(r1));
5165 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5166 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5167 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5168 put_gpr_w1(r1, mkexpr(result));
5169
5170 return "x";
5171}
5172
florian55085f82012-11-21 00:36:55 +00005173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005174s390_irgen_XY(UChar r1, IRTemp op2addr)
5175{
5176 IRTemp op1 = newTemp(Ity_I32);
5177 IRTemp op2 = newTemp(Ity_I32);
5178 IRTemp result = newTemp(Ity_I32);
5179
5180 assign(op1, get_gpr_w1(r1));
5181 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5182 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5183 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5184 put_gpr_w1(r1, mkexpr(result));
5185
5186 return "xy";
5187}
5188
florian55085f82012-11-21 00:36:55 +00005189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005190s390_irgen_XG(UChar r1, IRTemp op2addr)
5191{
5192 IRTemp op1 = newTemp(Ity_I64);
5193 IRTemp op2 = newTemp(Ity_I64);
5194 IRTemp result = newTemp(Ity_I64);
5195
5196 assign(op1, get_gpr_dw0(r1));
5197 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5198 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5199 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5200 put_gpr_dw0(r1, mkexpr(result));
5201
5202 return "xg";
5203}
5204
florian55085f82012-11-21 00:36:55 +00005205static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005206s390_irgen_XI(UChar i2, IRTemp op1addr)
5207{
5208 IRTemp op1 = newTemp(Ity_I8);
5209 UChar op2;
5210 IRTemp result = newTemp(Ity_I8);
5211
5212 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5213 op2 = i2;
5214 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5215 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5216 store(mkexpr(op1addr), mkexpr(result));
5217
5218 return "xi";
5219}
5220
florian55085f82012-11-21 00:36:55 +00005221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005222s390_irgen_XIY(UChar i2, IRTemp op1addr)
5223{
5224 IRTemp op1 = newTemp(Ity_I8);
5225 UChar op2;
5226 IRTemp result = newTemp(Ity_I8);
5227
5228 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5229 op2 = i2;
5230 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5231 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5232 store(mkexpr(op1addr), mkexpr(result));
5233
5234 return "xiy";
5235}
5236
florian55085f82012-11-21 00:36:55 +00005237static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005238s390_irgen_XIHF(UChar r1, UInt i2)
5239{
5240 IRTemp op1 = newTemp(Ity_I32);
5241 UInt op2;
5242 IRTemp result = newTemp(Ity_I32);
5243
5244 assign(op1, get_gpr_w0(r1));
5245 op2 = i2;
5246 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5247 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5248 put_gpr_w0(r1, mkexpr(result));
5249
5250 return "xihf";
5251}
5252
florian55085f82012-11-21 00:36:55 +00005253static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005254s390_irgen_XILF(UChar r1, UInt i2)
5255{
5256 IRTemp op1 = newTemp(Ity_I32);
5257 UInt op2;
5258 IRTemp result = newTemp(Ity_I32);
5259
5260 assign(op1, get_gpr_w1(r1));
5261 op2 = i2;
5262 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5263 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5264 put_gpr_w1(r1, mkexpr(result));
5265
5266 return "xilf";
5267}
5268
florian55085f82012-11-21 00:36:55 +00005269static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005270s390_irgen_EAR(UChar r1, UChar r2)
5271{
5272 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005273 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005274 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5275
5276 return "ear";
5277}
5278
florian55085f82012-11-21 00:36:55 +00005279static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005280s390_irgen_IC(UChar r1, IRTemp op2addr)
5281{
5282 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5283
5284 return "ic";
5285}
5286
florian55085f82012-11-21 00:36:55 +00005287static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005288s390_irgen_ICY(UChar r1, IRTemp op2addr)
5289{
5290 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5291
5292 return "icy";
5293}
5294
florian55085f82012-11-21 00:36:55 +00005295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005296s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5297{
5298 UChar n;
5299 IRTemp result = newTemp(Ity_I32);
5300 UInt mask;
5301
5302 n = 0;
5303 mask = (UInt)r3;
5304 if ((mask & 8) != 0) {
5305 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5306 n = n + 1;
5307 }
5308 if ((mask & 4) != 0) {
5309 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5310
5311 n = n + 1;
5312 }
5313 if ((mask & 2) != 0) {
5314 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5315
5316 n = n + 1;
5317 }
5318 if ((mask & 1) != 0) {
5319 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5320
5321 n = n + 1;
5322 }
5323 assign(result, get_gpr_w1(r1));
5324 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5325 mkU32(mask)));
5326
5327 return "icm";
5328}
5329
florian55085f82012-11-21 00:36:55 +00005330static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005331s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5332{
5333 UChar n;
5334 IRTemp result = newTemp(Ity_I32);
5335 UInt mask;
5336
5337 n = 0;
5338 mask = (UInt)r3;
5339 if ((mask & 8) != 0) {
5340 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5341 n = n + 1;
5342 }
5343 if ((mask & 4) != 0) {
5344 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5345
5346 n = n + 1;
5347 }
5348 if ((mask & 2) != 0) {
5349 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5350
5351 n = n + 1;
5352 }
5353 if ((mask & 1) != 0) {
5354 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5355
5356 n = n + 1;
5357 }
5358 assign(result, get_gpr_w1(r1));
5359 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5360 mkU32(mask)));
5361
5362 return "icmy";
5363}
5364
florian55085f82012-11-21 00:36:55 +00005365static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005366s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5367{
5368 UChar n;
5369 IRTemp result = newTemp(Ity_I32);
5370 UInt mask;
5371
5372 n = 0;
5373 mask = (UInt)r3;
5374 if ((mask & 8) != 0) {
5375 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5376 n = n + 1;
5377 }
5378 if ((mask & 4) != 0) {
5379 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5380
5381 n = n + 1;
5382 }
5383 if ((mask & 2) != 0) {
5384 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5385
5386 n = n + 1;
5387 }
5388 if ((mask & 1) != 0) {
5389 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5390
5391 n = n + 1;
5392 }
5393 assign(result, get_gpr_w0(r1));
5394 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5395 mkU32(mask)));
5396
5397 return "icmh";
5398}
5399
florian55085f82012-11-21 00:36:55 +00005400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005401s390_irgen_IIHF(UChar r1, UInt i2)
5402{
5403 put_gpr_w0(r1, mkU32(i2));
5404
5405 return "iihf";
5406}
5407
florian55085f82012-11-21 00:36:55 +00005408static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005409s390_irgen_IIHH(UChar r1, UShort i2)
5410{
5411 put_gpr_hw0(r1, mkU16(i2));
5412
5413 return "iihh";
5414}
5415
florian55085f82012-11-21 00:36:55 +00005416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005417s390_irgen_IIHL(UChar r1, UShort i2)
5418{
5419 put_gpr_hw1(r1, mkU16(i2));
5420
5421 return "iihl";
5422}
5423
florian55085f82012-11-21 00:36:55 +00005424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005425s390_irgen_IILF(UChar r1, UInt i2)
5426{
5427 put_gpr_w1(r1, mkU32(i2));
5428
5429 return "iilf";
5430}
5431
florian55085f82012-11-21 00:36:55 +00005432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005433s390_irgen_IILH(UChar r1, UShort i2)
5434{
5435 put_gpr_hw2(r1, mkU16(i2));
5436
5437 return "iilh";
5438}
5439
florian55085f82012-11-21 00:36:55 +00005440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005441s390_irgen_IILL(UChar r1, UShort i2)
5442{
5443 put_gpr_hw3(r1, mkU16(i2));
5444
5445 return "iill";
5446}
5447
florian55085f82012-11-21 00:36:55 +00005448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005449s390_irgen_LR(UChar r1, UChar r2)
5450{
5451 put_gpr_w1(r1, get_gpr_w1(r2));
5452
5453 return "lr";
5454}
5455
florian55085f82012-11-21 00:36:55 +00005456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005457s390_irgen_LGR(UChar r1, UChar r2)
5458{
5459 put_gpr_dw0(r1, get_gpr_dw0(r2));
5460
5461 return "lgr";
5462}
5463
florian55085f82012-11-21 00:36:55 +00005464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005465s390_irgen_LGFR(UChar r1, UChar r2)
5466{
5467 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5468
5469 return "lgfr";
5470}
5471
florian55085f82012-11-21 00:36:55 +00005472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005473s390_irgen_L(UChar r1, IRTemp op2addr)
5474{
5475 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5476
5477 return "l";
5478}
5479
florian55085f82012-11-21 00:36:55 +00005480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005481s390_irgen_LY(UChar r1, IRTemp op2addr)
5482{
5483 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5484
5485 return "ly";
5486}
5487
florian55085f82012-11-21 00:36:55 +00005488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005489s390_irgen_LG(UChar r1, IRTemp op2addr)
5490{
5491 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5492
5493 return "lg";
5494}
5495
florian55085f82012-11-21 00:36:55 +00005496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005497s390_irgen_LGF(UChar r1, IRTemp op2addr)
5498{
5499 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5500
5501 return "lgf";
5502}
5503
florian55085f82012-11-21 00:36:55 +00005504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005505s390_irgen_LGFI(UChar r1, UInt i2)
5506{
5507 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5508
5509 return "lgfi";
5510}
5511
florian55085f82012-11-21 00:36:55 +00005512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005513s390_irgen_LRL(UChar r1, UInt i2)
5514{
5515 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5516 i2 << 1))));
5517
5518 return "lrl";
5519}
5520
florian55085f82012-11-21 00:36:55 +00005521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005522s390_irgen_LGRL(UChar r1, UInt i2)
5523{
5524 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5525 i2 << 1))));
5526
5527 return "lgrl";
5528}
5529
florian55085f82012-11-21 00:36:55 +00005530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005531s390_irgen_LGFRL(UChar r1, UInt i2)
5532{
5533 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5534 ((ULong)(Long)(Int)i2 << 1)))));
5535
5536 return "lgfrl";
5537}
5538
florian55085f82012-11-21 00:36:55 +00005539static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005540s390_irgen_LA(UChar r1, IRTemp op2addr)
5541{
5542 put_gpr_dw0(r1, mkexpr(op2addr));
5543
5544 return "la";
5545}
5546
florian55085f82012-11-21 00:36:55 +00005547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005548s390_irgen_LAY(UChar r1, IRTemp op2addr)
5549{
5550 put_gpr_dw0(r1, mkexpr(op2addr));
5551
5552 return "lay";
5553}
5554
florian55085f82012-11-21 00:36:55 +00005555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005556s390_irgen_LAE(UChar r1, IRTemp op2addr)
5557{
5558 put_gpr_dw0(r1, mkexpr(op2addr));
5559
5560 return "lae";
5561}
5562
florian55085f82012-11-21 00:36:55 +00005563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005564s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5565{
5566 put_gpr_dw0(r1, mkexpr(op2addr));
5567
5568 return "laey";
5569}
5570
florian55085f82012-11-21 00:36:55 +00005571static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005572s390_irgen_LARL(UChar r1, UInt i2)
5573{
5574 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5575
5576 return "larl";
5577}
5578
floriana265ee72012-12-02 20:58:17 +00005579/* The IR representation of LAA and friends is an approximation of what
5580 happens natively. Essentially a loop containing a compare-and-swap is
5581 constructed which will iterate until the CAS succeeds. As a consequence,
5582 instrumenters may see more memory accesses than happen natively. See also
5583 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005584static void
5585s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005586{
floriana265ee72012-12-02 20:58:17 +00005587 IRCAS *cas;
5588 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005589 IRTemp op2 = newTemp(Ity_I32);
5590 IRTemp op3 = newTemp(Ity_I32);
5591 IRTemp result = newTemp(Ity_I32);
5592
5593 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5594 assign(op3, get_gpr_w1(r3));
5595 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005596
5597 /* Place the addition of second operand and third operand at the
5598 second-operand location everytime */
5599 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5600 Iend_BE, mkexpr(op2addr),
5601 NULL, mkexpr(op2), /* expected value */
5602 NULL, mkexpr(result) /* new value */);
5603 stmt(IRStmt_CAS(cas));
5604
florianffc94012012-12-02 21:31:15 +00005605 /* Set CC according to 32-bit addition */
5606 if (is_signed) {
5607 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5608 } else {
5609 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5610 }
floriana265ee72012-12-02 20:58:17 +00005611
5612 /* If old_mem contains the expected value, then the CAS succeeded.
5613 Otherwise, it did not */
5614 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5615 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005616}
5617
5618static void
5619s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5620{
5621 IRCAS *cas;
5622 IRTemp old_mem = newTemp(Ity_I64);
5623 IRTemp op2 = newTemp(Ity_I64);
5624 IRTemp op3 = newTemp(Ity_I64);
5625 IRTemp result = newTemp(Ity_I64);
5626
5627 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5628 assign(op3, get_gpr_dw0(r3));
5629 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5630
5631 /* Place the addition of second operand and third operand at the
5632 second-operand location everytime */
5633 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5634 Iend_BE, mkexpr(op2addr),
5635 NULL, mkexpr(op2), /* expected value */
5636 NULL, mkexpr(result) /* new value */);
5637 stmt(IRStmt_CAS(cas));
5638
5639 /* Set CC according to 64-bit addition */
5640 if (is_signed) {
5641 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5642 } else {
5643 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5644 }
5645
5646 /* If old_mem contains the expected value, then the CAS succeeded.
5647 Otherwise, it did not */
5648 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5649 put_gpr_dw0(r1, mkexpr(old_mem));
5650}
5651
5652static void
5653s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5654{
5655 IRCAS *cas;
5656 IRTemp old_mem = newTemp(Ity_I32);
5657 IRTemp op2 = newTemp(Ity_I32);
5658 IRTemp op3 = newTemp(Ity_I32);
5659 IRTemp result = newTemp(Ity_I32);
5660
5661 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5662 assign(op3, get_gpr_w1(r3));
5663 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5664
5665 /* Place the addition of second operand and third operand at the
5666 second-operand location everytime */
5667 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5668 Iend_BE, mkexpr(op2addr),
5669 NULL, mkexpr(op2), /* expected value */
5670 NULL, mkexpr(result) /* new value */);
5671 stmt(IRStmt_CAS(cas));
5672
5673 /* Set CC according to bitwise operation */
5674 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5675
5676 /* If old_mem contains the expected value, then the CAS succeeded.
5677 Otherwise, it did not */
5678 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5679 put_gpr_w1(r1, mkexpr(old_mem));
5680}
5681
5682static void
5683s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5684{
5685 IRCAS *cas;
5686 IRTemp old_mem = newTemp(Ity_I64);
5687 IRTemp op2 = newTemp(Ity_I64);
5688 IRTemp op3 = newTemp(Ity_I64);
5689 IRTemp result = newTemp(Ity_I64);
5690
5691 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5692 assign(op3, get_gpr_dw0(r3));
5693 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5694
5695 /* Place the addition of second operand and third operand at the
5696 second-operand location everytime */
5697 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5698 Iend_BE, mkexpr(op2addr),
5699 NULL, mkexpr(op2), /* expected value */
5700 NULL, mkexpr(result) /* new value */);
5701 stmt(IRStmt_CAS(cas));
5702
5703 /* Set CC according to bitwise operation */
5704 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5705
5706 /* If old_mem contains the expected value, then the CAS succeeded.
5707 Otherwise, it did not */
5708 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5709 put_gpr_dw0(r1, mkexpr(old_mem));
5710}
5711
5712static const HChar *
5713s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5714{
5715 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005716
5717 return "laa";
5718}
5719
florian55085f82012-11-21 00:36:55 +00005720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005721s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5722{
florianffc94012012-12-02 21:31:15 +00005723 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005724
5725 return "laag";
5726}
5727
florian55085f82012-11-21 00:36:55 +00005728static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005729s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5730{
florianffc94012012-12-02 21:31:15 +00005731 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005732
5733 return "laal";
5734}
5735
florian55085f82012-11-21 00:36:55 +00005736static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005737s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5738{
florianffc94012012-12-02 21:31:15 +00005739 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005740
5741 return "laalg";
5742}
5743
florian55085f82012-11-21 00:36:55 +00005744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005745s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5746{
florianffc94012012-12-02 21:31:15 +00005747 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005748
5749 return "lan";
5750}
5751
florian55085f82012-11-21 00:36:55 +00005752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005753s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5754{
florianffc94012012-12-02 21:31:15 +00005755 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005756
5757 return "lang";
5758}
5759
florian55085f82012-11-21 00:36:55 +00005760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005761s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5762{
florianffc94012012-12-02 21:31:15 +00005763 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005764
5765 return "lax";
5766}
5767
florian55085f82012-11-21 00:36:55 +00005768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005769s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5770{
florianffc94012012-12-02 21:31:15 +00005771 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005772
5773 return "laxg";
5774}
5775
florian55085f82012-11-21 00:36:55 +00005776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005777s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5778{
florianffc94012012-12-02 21:31:15 +00005779 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005780
5781 return "lao";
5782}
5783
florian55085f82012-11-21 00:36:55 +00005784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005785s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5786{
florianffc94012012-12-02 21:31:15 +00005787 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005788
5789 return "laog";
5790}
5791
florian55085f82012-11-21 00:36:55 +00005792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005793s390_irgen_LTR(UChar r1, UChar r2)
5794{
5795 IRTemp op2 = newTemp(Ity_I32);
5796
5797 assign(op2, get_gpr_w1(r2));
5798 put_gpr_w1(r1, mkexpr(op2));
5799 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5800
5801 return "ltr";
5802}
5803
florian55085f82012-11-21 00:36:55 +00005804static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005805s390_irgen_LTGR(UChar r1, UChar r2)
5806{
5807 IRTemp op2 = newTemp(Ity_I64);
5808
5809 assign(op2, get_gpr_dw0(r2));
5810 put_gpr_dw0(r1, mkexpr(op2));
5811 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5812
5813 return "ltgr";
5814}
5815
florian55085f82012-11-21 00:36:55 +00005816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005817s390_irgen_LTGFR(UChar r1, UChar r2)
5818{
5819 IRTemp op2 = newTemp(Ity_I64);
5820
5821 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5822 put_gpr_dw0(r1, mkexpr(op2));
5823 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5824
5825 return "ltgfr";
5826}
5827
florian55085f82012-11-21 00:36:55 +00005828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005829s390_irgen_LT(UChar r1, IRTemp op2addr)
5830{
5831 IRTemp op2 = newTemp(Ity_I32);
5832
5833 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5834 put_gpr_w1(r1, mkexpr(op2));
5835 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5836
5837 return "lt";
5838}
5839
florian55085f82012-11-21 00:36:55 +00005840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005841s390_irgen_LTG(UChar r1, IRTemp op2addr)
5842{
5843 IRTemp op2 = newTemp(Ity_I64);
5844
5845 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5846 put_gpr_dw0(r1, mkexpr(op2));
5847 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5848
5849 return "ltg";
5850}
5851
florian55085f82012-11-21 00:36:55 +00005852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005853s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5854{
5855 IRTemp op2 = newTemp(Ity_I64);
5856
5857 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5858 put_gpr_dw0(r1, mkexpr(op2));
5859 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5860
5861 return "ltgf";
5862}
5863
florian55085f82012-11-21 00:36:55 +00005864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005865s390_irgen_LBR(UChar r1, UChar r2)
5866{
5867 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5868
5869 return "lbr";
5870}
5871
florian55085f82012-11-21 00:36:55 +00005872static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005873s390_irgen_LGBR(UChar r1, UChar r2)
5874{
5875 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5876
5877 return "lgbr";
5878}
5879
florian55085f82012-11-21 00:36:55 +00005880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005881s390_irgen_LB(UChar r1, IRTemp op2addr)
5882{
5883 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5884
5885 return "lb";
5886}
5887
florian55085f82012-11-21 00:36:55 +00005888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005889s390_irgen_LGB(UChar r1, IRTemp op2addr)
5890{
5891 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5892
5893 return "lgb";
5894}
5895
florian55085f82012-11-21 00:36:55 +00005896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005897s390_irgen_LBH(UChar r1, IRTemp op2addr)
5898{
5899 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5900
5901 return "lbh";
5902}
5903
florian55085f82012-11-21 00:36:55 +00005904static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005905s390_irgen_LCR(UChar r1, UChar r2)
5906{
5907 Int op1;
5908 IRTemp op2 = newTemp(Ity_I32);
5909 IRTemp result = newTemp(Ity_I32);
5910
5911 op1 = 0;
5912 assign(op2, get_gpr_w1(r2));
5913 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5914 put_gpr_w1(r1, mkexpr(result));
5915 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5916 op1)), op2);
5917
5918 return "lcr";
5919}
5920
florian55085f82012-11-21 00:36:55 +00005921static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005922s390_irgen_LCGR(UChar r1, UChar r2)
5923{
5924 Long op1;
5925 IRTemp op2 = newTemp(Ity_I64);
5926 IRTemp result = newTemp(Ity_I64);
5927
5928 op1 = 0ULL;
5929 assign(op2, get_gpr_dw0(r2));
5930 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5931 put_gpr_dw0(r1, mkexpr(result));
5932 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5933 op1)), op2);
5934
5935 return "lcgr";
5936}
5937
florian55085f82012-11-21 00:36:55 +00005938static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005939s390_irgen_LCGFR(UChar r1, UChar r2)
5940{
5941 Long op1;
5942 IRTemp op2 = newTemp(Ity_I64);
5943 IRTemp result = newTemp(Ity_I64);
5944
5945 op1 = 0ULL;
5946 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5947 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5948 put_gpr_dw0(r1, mkexpr(result));
5949 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5950 op1)), op2);
5951
5952 return "lcgfr";
5953}
5954
florian55085f82012-11-21 00:36:55 +00005955static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005956s390_irgen_LHR(UChar r1, UChar r2)
5957{
5958 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5959
5960 return "lhr";
5961}
5962
florian55085f82012-11-21 00:36:55 +00005963static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005964s390_irgen_LGHR(UChar r1, UChar r2)
5965{
5966 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5967
5968 return "lghr";
5969}
5970
florian55085f82012-11-21 00:36:55 +00005971static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005972s390_irgen_LH(UChar r1, IRTemp op2addr)
5973{
5974 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5975
5976 return "lh";
5977}
5978
florian55085f82012-11-21 00:36:55 +00005979static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005980s390_irgen_LHY(UChar r1, IRTemp op2addr)
5981{
5982 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5983
5984 return "lhy";
5985}
5986
florian55085f82012-11-21 00:36:55 +00005987static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005988s390_irgen_LGH(UChar r1, IRTemp op2addr)
5989{
5990 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5991
5992 return "lgh";
5993}
5994
florian55085f82012-11-21 00:36:55 +00005995static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005996s390_irgen_LHI(UChar r1, UShort i2)
5997{
5998 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5999
6000 return "lhi";
6001}
6002
florian55085f82012-11-21 00:36:55 +00006003static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006004s390_irgen_LGHI(UChar r1, UShort i2)
6005{
6006 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6007
6008 return "lghi";
6009}
6010
florian55085f82012-11-21 00:36:55 +00006011static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006012s390_irgen_LHRL(UChar r1, UInt i2)
6013{
6014 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6015 ((ULong)(Long)(Int)i2 << 1)))));
6016
6017 return "lhrl";
6018}
6019
florian55085f82012-11-21 00:36:55 +00006020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006021s390_irgen_LGHRL(UChar r1, UInt i2)
6022{
6023 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6024 ((ULong)(Long)(Int)i2 << 1)))));
6025
6026 return "lghrl";
6027}
6028
florian55085f82012-11-21 00:36:55 +00006029static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006030s390_irgen_LHH(UChar r1, IRTemp op2addr)
6031{
6032 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6033
6034 return "lhh";
6035}
6036
florian55085f82012-11-21 00:36:55 +00006037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006038s390_irgen_LFH(UChar r1, IRTemp op2addr)
6039{
6040 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6041
6042 return "lfh";
6043}
6044
florian55085f82012-11-21 00:36:55 +00006045static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006046s390_irgen_LLGFR(UChar r1, UChar r2)
6047{
6048 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6049
6050 return "llgfr";
6051}
6052
florian55085f82012-11-21 00:36:55 +00006053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006054s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6055{
6056 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6057
6058 return "llgf";
6059}
6060
florian55085f82012-11-21 00:36:55 +00006061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006062s390_irgen_LLGFRL(UChar r1, UInt i2)
6063{
6064 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6065 ((ULong)(Long)(Int)i2 << 1)))));
6066
6067 return "llgfrl";
6068}
6069
florian55085f82012-11-21 00:36:55 +00006070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006071s390_irgen_LLCR(UChar r1, UChar r2)
6072{
6073 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6074
6075 return "llcr";
6076}
6077
florian55085f82012-11-21 00:36:55 +00006078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006079s390_irgen_LLGCR(UChar r1, UChar r2)
6080{
6081 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6082
6083 return "llgcr";
6084}
6085
florian55085f82012-11-21 00:36:55 +00006086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006087s390_irgen_LLC(UChar r1, IRTemp op2addr)
6088{
6089 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6090
6091 return "llc";
6092}
6093
florian55085f82012-11-21 00:36:55 +00006094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006095s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6096{
6097 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6098
6099 return "llgc";
6100}
6101
florian55085f82012-11-21 00:36:55 +00006102static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006103s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6104{
6105 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6106
6107 return "llch";
6108}
6109
florian55085f82012-11-21 00:36:55 +00006110static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006111s390_irgen_LLHR(UChar r1, UChar r2)
6112{
6113 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6114
6115 return "llhr";
6116}
6117
florian55085f82012-11-21 00:36:55 +00006118static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006119s390_irgen_LLGHR(UChar r1, UChar r2)
6120{
6121 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6122
6123 return "llghr";
6124}
6125
florian55085f82012-11-21 00:36:55 +00006126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006127s390_irgen_LLH(UChar r1, IRTemp op2addr)
6128{
6129 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6130
6131 return "llh";
6132}
6133
florian55085f82012-11-21 00:36:55 +00006134static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006135s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6136{
6137 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6138
6139 return "llgh";
6140}
6141
florian55085f82012-11-21 00:36:55 +00006142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006143s390_irgen_LLHRL(UChar r1, UInt i2)
6144{
6145 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6146 ((ULong)(Long)(Int)i2 << 1)))));
6147
6148 return "llhrl";
6149}
6150
florian55085f82012-11-21 00:36:55 +00006151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006152s390_irgen_LLGHRL(UChar r1, UInt i2)
6153{
6154 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6155 ((ULong)(Long)(Int)i2 << 1)))));
6156
6157 return "llghrl";
6158}
6159
florian55085f82012-11-21 00:36:55 +00006160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006161s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6162{
6163 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6164
6165 return "llhh";
6166}
6167
florian55085f82012-11-21 00:36:55 +00006168static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006169s390_irgen_LLIHF(UChar r1, UInt i2)
6170{
6171 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6172
6173 return "llihf";
6174}
6175
florian55085f82012-11-21 00:36:55 +00006176static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006177s390_irgen_LLIHH(UChar r1, UShort i2)
6178{
6179 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6180
6181 return "llihh";
6182}
6183
florian55085f82012-11-21 00:36:55 +00006184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006185s390_irgen_LLIHL(UChar r1, UShort i2)
6186{
6187 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6188
6189 return "llihl";
6190}
6191
florian55085f82012-11-21 00:36:55 +00006192static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006193s390_irgen_LLILF(UChar r1, UInt i2)
6194{
6195 put_gpr_dw0(r1, mkU64(i2));
6196
6197 return "llilf";
6198}
6199
florian55085f82012-11-21 00:36:55 +00006200static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006201s390_irgen_LLILH(UChar r1, UShort i2)
6202{
6203 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6204
6205 return "llilh";
6206}
6207
florian55085f82012-11-21 00:36:55 +00006208static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006209s390_irgen_LLILL(UChar r1, UShort i2)
6210{
6211 put_gpr_dw0(r1, mkU64(i2));
6212
6213 return "llill";
6214}
6215
florian55085f82012-11-21 00:36:55 +00006216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006217s390_irgen_LLGTR(UChar r1, UChar r2)
6218{
6219 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6220 mkU32(2147483647))));
6221
6222 return "llgtr";
6223}
6224
florian55085f82012-11-21 00:36:55 +00006225static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006226s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6227{
6228 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6229 mkexpr(op2addr)), mkU32(2147483647))));
6230
6231 return "llgt";
6232}
6233
florian55085f82012-11-21 00:36:55 +00006234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006235s390_irgen_LNR(UChar r1, UChar r2)
6236{
6237 IRTemp op2 = newTemp(Ity_I32);
6238 IRTemp result = newTemp(Ity_I32);
6239
6240 assign(op2, get_gpr_w1(r2));
6241 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6242 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6243 put_gpr_w1(r1, mkexpr(result));
6244 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6245
6246 return "lnr";
6247}
6248
florian55085f82012-11-21 00:36:55 +00006249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006250s390_irgen_LNGR(UChar r1, UChar r2)
6251{
6252 IRTemp op2 = newTemp(Ity_I64);
6253 IRTemp result = newTemp(Ity_I64);
6254
6255 assign(op2, get_gpr_dw0(r2));
6256 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6257 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6258 put_gpr_dw0(r1, mkexpr(result));
6259 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6260
6261 return "lngr";
6262}
6263
florian55085f82012-11-21 00:36:55 +00006264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006265s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6266{
6267 IRTemp op2 = newTemp(Ity_I64);
6268 IRTemp result = newTemp(Ity_I64);
6269
6270 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6271 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6272 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6273 put_gpr_dw0(r1, mkexpr(result));
6274 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6275
6276 return "lngfr";
6277}
6278
florian55085f82012-11-21 00:36:55 +00006279static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006280s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6281{
florian6820ba52012-07-26 02:01:50 +00006282 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006283 put_gpr_w1(r1, get_gpr_w1(r2));
6284
6285 return "locr";
6286}
6287
florian55085f82012-11-21 00:36:55 +00006288static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006289s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6290{
florian6820ba52012-07-26 02:01:50 +00006291 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006292 put_gpr_dw0(r1, get_gpr_dw0(r2));
6293
6294 return "locgr";
6295}
6296
florian55085f82012-11-21 00:36:55 +00006297static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006298s390_irgen_LOC(UChar r1, IRTemp op2addr)
6299{
6300 /* condition is checked in format handler */
6301 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6302
6303 return "loc";
6304}
6305
florian55085f82012-11-21 00:36:55 +00006306static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006307s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6308{
6309 /* condition is checked in format handler */
6310 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6311
6312 return "locg";
6313}
6314
florian55085f82012-11-21 00:36:55 +00006315static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006316s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6317{
6318 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6319 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6320 ));
6321
6322 return "lpq";
6323}
6324
florian55085f82012-11-21 00:36:55 +00006325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006326s390_irgen_LPR(UChar r1, UChar r2)
6327{
6328 IRTemp op2 = newTemp(Ity_I32);
6329 IRTemp result = newTemp(Ity_I32);
6330
6331 assign(op2, get_gpr_w1(r2));
6332 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6333 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6334 put_gpr_w1(r1, mkexpr(result));
6335 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6336
6337 return "lpr";
6338}
6339
florian55085f82012-11-21 00:36:55 +00006340static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006341s390_irgen_LPGR(UChar r1, UChar r2)
6342{
6343 IRTemp op2 = newTemp(Ity_I64);
6344 IRTemp result = newTemp(Ity_I64);
6345
6346 assign(op2, get_gpr_dw0(r2));
6347 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6348 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6349 put_gpr_dw0(r1, mkexpr(result));
6350 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6351
6352 return "lpgr";
6353}
6354
florian55085f82012-11-21 00:36:55 +00006355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006356s390_irgen_LPGFR(UChar r1, UChar r2)
6357{
6358 IRTemp op2 = newTemp(Ity_I64);
6359 IRTemp result = newTemp(Ity_I64);
6360
6361 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6362 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6363 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6364 put_gpr_dw0(r1, mkexpr(result));
6365 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6366
6367 return "lpgfr";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006371s390_irgen_LRVR(UChar r1, UChar r2)
6372{
6373 IRTemp b0 = newTemp(Ity_I8);
6374 IRTemp b1 = newTemp(Ity_I8);
6375 IRTemp b2 = newTemp(Ity_I8);
6376 IRTemp b3 = newTemp(Ity_I8);
6377
6378 assign(b3, get_gpr_b7(r2));
6379 assign(b2, get_gpr_b6(r2));
6380 assign(b1, get_gpr_b5(r2));
6381 assign(b0, get_gpr_b4(r2));
6382 put_gpr_b4(r1, mkexpr(b3));
6383 put_gpr_b5(r1, mkexpr(b2));
6384 put_gpr_b6(r1, mkexpr(b1));
6385 put_gpr_b7(r1, mkexpr(b0));
6386
6387 return "lrvr";
6388}
6389
florian55085f82012-11-21 00:36:55 +00006390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006391s390_irgen_LRVGR(UChar r1, UChar r2)
6392{
6393 IRTemp b0 = newTemp(Ity_I8);
6394 IRTemp b1 = newTemp(Ity_I8);
6395 IRTemp b2 = newTemp(Ity_I8);
6396 IRTemp b3 = newTemp(Ity_I8);
6397 IRTemp b4 = newTemp(Ity_I8);
6398 IRTemp b5 = newTemp(Ity_I8);
6399 IRTemp b6 = newTemp(Ity_I8);
6400 IRTemp b7 = newTemp(Ity_I8);
6401
6402 assign(b7, get_gpr_b7(r2));
6403 assign(b6, get_gpr_b6(r2));
6404 assign(b5, get_gpr_b5(r2));
6405 assign(b4, get_gpr_b4(r2));
6406 assign(b3, get_gpr_b3(r2));
6407 assign(b2, get_gpr_b2(r2));
6408 assign(b1, get_gpr_b1(r2));
6409 assign(b0, get_gpr_b0(r2));
6410 put_gpr_b0(r1, mkexpr(b7));
6411 put_gpr_b1(r1, mkexpr(b6));
6412 put_gpr_b2(r1, mkexpr(b5));
6413 put_gpr_b3(r1, mkexpr(b4));
6414 put_gpr_b4(r1, mkexpr(b3));
6415 put_gpr_b5(r1, mkexpr(b2));
6416 put_gpr_b6(r1, mkexpr(b1));
6417 put_gpr_b7(r1, mkexpr(b0));
6418
6419 return "lrvgr";
6420}
6421
florian55085f82012-11-21 00:36:55 +00006422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006423s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6424{
6425 IRTemp op2 = newTemp(Ity_I16);
6426
6427 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6428 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6429 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6430
6431 return "lrvh";
6432}
6433
florian55085f82012-11-21 00:36:55 +00006434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006435s390_irgen_LRV(UChar r1, IRTemp op2addr)
6436{
6437 IRTemp op2 = newTemp(Ity_I32);
6438
6439 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6440 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6441 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6442 mkU8(8)), mkU32(255))));
6443 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6444 mkU8(16)), mkU32(255))));
6445 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6446 mkU8(24)), mkU32(255))));
6447
6448 return "lrv";
6449}
6450
florian55085f82012-11-21 00:36:55 +00006451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006452s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6453{
6454 IRTemp op2 = newTemp(Ity_I64);
6455
6456 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6457 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6458 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6459 mkU8(8)), mkU64(255))));
6460 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6461 mkU8(16)), mkU64(255))));
6462 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6463 mkU8(24)), mkU64(255))));
6464 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6465 mkU8(32)), mkU64(255))));
6466 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6467 mkU8(40)), mkU64(255))));
6468 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6469 mkU8(48)), mkU64(255))));
6470 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6471 mkU8(56)), mkU64(255))));
6472
6473 return "lrvg";
6474}
6475
florian55085f82012-11-21 00:36:55 +00006476static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006477s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6478{
6479 store(mkexpr(op1addr), mkU16(i2));
6480
6481 return "mvhhi";
6482}
6483
florian55085f82012-11-21 00:36:55 +00006484static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006485s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6486{
6487 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6488
6489 return "mvhi";
6490}
6491
florian55085f82012-11-21 00:36:55 +00006492static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006493s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6494{
6495 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6496
6497 return "mvghi";
6498}
6499
florian55085f82012-11-21 00:36:55 +00006500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006501s390_irgen_MVI(UChar i2, IRTemp op1addr)
6502{
6503 store(mkexpr(op1addr), mkU8(i2));
6504
6505 return "mvi";
6506}
6507
florian55085f82012-11-21 00:36:55 +00006508static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006509s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6510{
6511 store(mkexpr(op1addr), mkU8(i2));
6512
6513 return "mviy";
6514}
6515
florian55085f82012-11-21 00:36:55 +00006516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006517s390_irgen_MR(UChar r1, UChar r2)
6518{
6519 IRTemp op1 = newTemp(Ity_I32);
6520 IRTemp op2 = newTemp(Ity_I32);
6521 IRTemp result = newTemp(Ity_I64);
6522
6523 assign(op1, get_gpr_w1(r1 + 1));
6524 assign(op2, get_gpr_w1(r2));
6525 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6526 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6527 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6528
6529 return "mr";
6530}
6531
florian55085f82012-11-21 00:36:55 +00006532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006533s390_irgen_M(UChar r1, IRTemp op2addr)
6534{
6535 IRTemp op1 = newTemp(Ity_I32);
6536 IRTemp op2 = newTemp(Ity_I32);
6537 IRTemp result = newTemp(Ity_I64);
6538
6539 assign(op1, get_gpr_w1(r1 + 1));
6540 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6541 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6542 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6543 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6544
6545 return "m";
6546}
6547
florian55085f82012-11-21 00:36:55 +00006548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006549s390_irgen_MFY(UChar r1, IRTemp op2addr)
6550{
6551 IRTemp op1 = newTemp(Ity_I32);
6552 IRTemp op2 = newTemp(Ity_I32);
6553 IRTemp result = newTemp(Ity_I64);
6554
6555 assign(op1, get_gpr_w1(r1 + 1));
6556 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6557 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6558 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6559 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6560
6561 return "mfy";
6562}
6563
florian55085f82012-11-21 00:36:55 +00006564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006565s390_irgen_MH(UChar r1, IRTemp op2addr)
6566{
6567 IRTemp op1 = newTemp(Ity_I32);
6568 IRTemp op2 = newTemp(Ity_I16);
6569 IRTemp result = newTemp(Ity_I64);
6570
6571 assign(op1, get_gpr_w1(r1));
6572 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6573 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6574 ));
6575 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6576
6577 return "mh";
6578}
6579
florian55085f82012-11-21 00:36:55 +00006580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006581s390_irgen_MHY(UChar r1, IRTemp op2addr)
6582{
6583 IRTemp op1 = newTemp(Ity_I32);
6584 IRTemp op2 = newTemp(Ity_I16);
6585 IRTemp result = newTemp(Ity_I64);
6586
6587 assign(op1, get_gpr_w1(r1));
6588 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6589 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6590 ));
6591 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6592
6593 return "mhy";
6594}
6595
florian55085f82012-11-21 00:36:55 +00006596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006597s390_irgen_MHI(UChar r1, UShort i2)
6598{
6599 IRTemp op1 = newTemp(Ity_I32);
6600 Short op2;
6601 IRTemp result = newTemp(Ity_I64);
6602
6603 assign(op1, get_gpr_w1(r1));
6604 op2 = (Short)i2;
6605 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6606 mkU16((UShort)op2))));
6607 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6608
6609 return "mhi";
6610}
6611
florian55085f82012-11-21 00:36:55 +00006612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006613s390_irgen_MGHI(UChar r1, UShort i2)
6614{
6615 IRTemp op1 = newTemp(Ity_I64);
6616 Short op2;
6617 IRTemp result = newTemp(Ity_I128);
6618
6619 assign(op1, get_gpr_dw0(r1));
6620 op2 = (Short)i2;
6621 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6622 mkU16((UShort)op2))));
6623 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6624
6625 return "mghi";
6626}
6627
florian55085f82012-11-21 00:36:55 +00006628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006629s390_irgen_MLR(UChar r1, UChar r2)
6630{
6631 IRTemp op1 = newTemp(Ity_I32);
6632 IRTemp op2 = newTemp(Ity_I32);
6633 IRTemp result = newTemp(Ity_I64);
6634
6635 assign(op1, get_gpr_w1(r1 + 1));
6636 assign(op2, get_gpr_w1(r2));
6637 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6638 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6639 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6640
6641 return "mlr";
6642}
6643
florian55085f82012-11-21 00:36:55 +00006644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006645s390_irgen_MLGR(UChar r1, UChar r2)
6646{
6647 IRTemp op1 = newTemp(Ity_I64);
6648 IRTemp op2 = newTemp(Ity_I64);
6649 IRTemp result = newTemp(Ity_I128);
6650
6651 assign(op1, get_gpr_dw0(r1 + 1));
6652 assign(op2, get_gpr_dw0(r2));
6653 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6654 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6655 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6656
6657 return "mlgr";
6658}
6659
florian55085f82012-11-21 00:36:55 +00006660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006661s390_irgen_ML(UChar r1, IRTemp op2addr)
6662{
6663 IRTemp op1 = newTemp(Ity_I32);
6664 IRTemp op2 = newTemp(Ity_I32);
6665 IRTemp result = newTemp(Ity_I64);
6666
6667 assign(op1, get_gpr_w1(r1 + 1));
6668 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6669 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6670 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6671 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6672
6673 return "ml";
6674}
6675
florian55085f82012-11-21 00:36:55 +00006676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006677s390_irgen_MLG(UChar r1, IRTemp op2addr)
6678{
6679 IRTemp op1 = newTemp(Ity_I64);
6680 IRTemp op2 = newTemp(Ity_I64);
6681 IRTemp result = newTemp(Ity_I128);
6682
6683 assign(op1, get_gpr_dw0(r1 + 1));
6684 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6685 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6686 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6687 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6688
6689 return "mlg";
6690}
6691
florian55085f82012-11-21 00:36:55 +00006692static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006693s390_irgen_MSR(UChar r1, UChar r2)
6694{
6695 IRTemp op1 = newTemp(Ity_I32);
6696 IRTemp op2 = newTemp(Ity_I32);
6697 IRTemp result = newTemp(Ity_I64);
6698
6699 assign(op1, get_gpr_w1(r1));
6700 assign(op2, get_gpr_w1(r2));
6701 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6702 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6703
6704 return "msr";
6705}
6706
florian55085f82012-11-21 00:36:55 +00006707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006708s390_irgen_MSGR(UChar r1, UChar r2)
6709{
6710 IRTemp op1 = newTemp(Ity_I64);
6711 IRTemp op2 = newTemp(Ity_I64);
6712 IRTemp result = newTemp(Ity_I128);
6713
6714 assign(op1, get_gpr_dw0(r1));
6715 assign(op2, get_gpr_dw0(r2));
6716 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6717 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6718
6719 return "msgr";
6720}
6721
florian55085f82012-11-21 00:36:55 +00006722static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006723s390_irgen_MSGFR(UChar r1, UChar r2)
6724{
6725 IRTemp op1 = newTemp(Ity_I64);
6726 IRTemp op2 = newTemp(Ity_I32);
6727 IRTemp result = newTemp(Ity_I128);
6728
6729 assign(op1, get_gpr_dw0(r1));
6730 assign(op2, get_gpr_w1(r2));
6731 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6732 ));
6733 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6734
6735 return "msgfr";
6736}
6737
florian55085f82012-11-21 00:36:55 +00006738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006739s390_irgen_MS(UChar r1, IRTemp op2addr)
6740{
6741 IRTemp op1 = newTemp(Ity_I32);
6742 IRTemp op2 = newTemp(Ity_I32);
6743 IRTemp result = newTemp(Ity_I64);
6744
6745 assign(op1, get_gpr_w1(r1));
6746 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6747 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6748 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6749
6750 return "ms";
6751}
6752
florian55085f82012-11-21 00:36:55 +00006753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006754s390_irgen_MSY(UChar r1, IRTemp op2addr)
6755{
6756 IRTemp op1 = newTemp(Ity_I32);
6757 IRTemp op2 = newTemp(Ity_I32);
6758 IRTemp result = newTemp(Ity_I64);
6759
6760 assign(op1, get_gpr_w1(r1));
6761 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6762 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6763 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6764
6765 return "msy";
6766}
6767
florian55085f82012-11-21 00:36:55 +00006768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006769s390_irgen_MSG(UChar r1, IRTemp op2addr)
6770{
6771 IRTemp op1 = newTemp(Ity_I64);
6772 IRTemp op2 = newTemp(Ity_I64);
6773 IRTemp result = newTemp(Ity_I128);
6774
6775 assign(op1, get_gpr_dw0(r1));
6776 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6777 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6778 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6779
6780 return "msg";
6781}
6782
florian55085f82012-11-21 00:36:55 +00006783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006784s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6785{
6786 IRTemp op1 = newTemp(Ity_I64);
6787 IRTemp op2 = newTemp(Ity_I32);
6788 IRTemp result = newTemp(Ity_I128);
6789
6790 assign(op1, get_gpr_dw0(r1));
6791 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6792 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6793 ));
6794 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6795
6796 return "msgf";
6797}
6798
florian55085f82012-11-21 00:36:55 +00006799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006800s390_irgen_MSFI(UChar r1, UInt i2)
6801{
6802 IRTemp op1 = newTemp(Ity_I32);
6803 Int op2;
6804 IRTemp result = newTemp(Ity_I64);
6805
6806 assign(op1, get_gpr_w1(r1));
6807 op2 = (Int)i2;
6808 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6809 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6810
6811 return "msfi";
6812}
6813
florian55085f82012-11-21 00:36:55 +00006814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006815s390_irgen_MSGFI(UChar r1, UInt i2)
6816{
6817 IRTemp op1 = newTemp(Ity_I64);
6818 Int op2;
6819 IRTemp result = newTemp(Ity_I128);
6820
6821 assign(op1, get_gpr_dw0(r1));
6822 op2 = (Int)i2;
6823 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6824 op2))));
6825 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6826
6827 return "msgfi";
6828}
6829
florian55085f82012-11-21 00:36:55 +00006830static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006831s390_irgen_OR(UChar r1, UChar r2)
6832{
6833 IRTemp op1 = newTemp(Ity_I32);
6834 IRTemp op2 = newTemp(Ity_I32);
6835 IRTemp result = newTemp(Ity_I32);
6836
6837 assign(op1, get_gpr_w1(r1));
6838 assign(op2, get_gpr_w1(r2));
6839 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6840 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6841 put_gpr_w1(r1, mkexpr(result));
6842
6843 return "or";
6844}
6845
florian55085f82012-11-21 00:36:55 +00006846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006847s390_irgen_OGR(UChar r1, UChar r2)
6848{
6849 IRTemp op1 = newTemp(Ity_I64);
6850 IRTemp op2 = newTemp(Ity_I64);
6851 IRTemp result = newTemp(Ity_I64);
6852
6853 assign(op1, get_gpr_dw0(r1));
6854 assign(op2, get_gpr_dw0(r2));
6855 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6856 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6857 put_gpr_dw0(r1, mkexpr(result));
6858
6859 return "ogr";
6860}
6861
florian55085f82012-11-21 00:36:55 +00006862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006863s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6864{
6865 IRTemp op2 = newTemp(Ity_I32);
6866 IRTemp op3 = newTemp(Ity_I32);
6867 IRTemp result = newTemp(Ity_I32);
6868
6869 assign(op2, get_gpr_w1(r2));
6870 assign(op3, get_gpr_w1(r3));
6871 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6872 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6873 put_gpr_w1(r1, mkexpr(result));
6874
6875 return "ork";
6876}
6877
florian55085f82012-11-21 00:36:55 +00006878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006879s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6880{
6881 IRTemp op2 = newTemp(Ity_I64);
6882 IRTemp op3 = newTemp(Ity_I64);
6883 IRTemp result = newTemp(Ity_I64);
6884
6885 assign(op2, get_gpr_dw0(r2));
6886 assign(op3, get_gpr_dw0(r3));
6887 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6888 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6889 put_gpr_dw0(r1, mkexpr(result));
6890
6891 return "ogrk";
6892}
6893
florian55085f82012-11-21 00:36:55 +00006894static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006895s390_irgen_O(UChar r1, IRTemp op2addr)
6896{
6897 IRTemp op1 = newTemp(Ity_I32);
6898 IRTemp op2 = newTemp(Ity_I32);
6899 IRTemp result = newTemp(Ity_I32);
6900
6901 assign(op1, get_gpr_w1(r1));
6902 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6903 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6904 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6905 put_gpr_w1(r1, mkexpr(result));
6906
6907 return "o";
6908}
6909
florian55085f82012-11-21 00:36:55 +00006910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006911s390_irgen_OY(UChar r1, IRTemp op2addr)
6912{
6913 IRTemp op1 = newTemp(Ity_I32);
6914 IRTemp op2 = newTemp(Ity_I32);
6915 IRTemp result = newTemp(Ity_I32);
6916
6917 assign(op1, get_gpr_w1(r1));
6918 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6919 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6920 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6921 put_gpr_w1(r1, mkexpr(result));
6922
6923 return "oy";
6924}
6925
florian55085f82012-11-21 00:36:55 +00006926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006927s390_irgen_OG(UChar r1, IRTemp op2addr)
6928{
6929 IRTemp op1 = newTemp(Ity_I64);
6930 IRTemp op2 = newTemp(Ity_I64);
6931 IRTemp result = newTemp(Ity_I64);
6932
6933 assign(op1, get_gpr_dw0(r1));
6934 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6935 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6936 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6937 put_gpr_dw0(r1, mkexpr(result));
6938
6939 return "og";
6940}
6941
florian55085f82012-11-21 00:36:55 +00006942static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006943s390_irgen_OI(UChar i2, IRTemp op1addr)
6944{
6945 IRTemp op1 = newTemp(Ity_I8);
6946 UChar op2;
6947 IRTemp result = newTemp(Ity_I8);
6948
6949 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6950 op2 = i2;
6951 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6952 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6953 store(mkexpr(op1addr), mkexpr(result));
6954
6955 return "oi";
6956}
6957
florian55085f82012-11-21 00:36:55 +00006958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006959s390_irgen_OIY(UChar i2, IRTemp op1addr)
6960{
6961 IRTemp op1 = newTemp(Ity_I8);
6962 UChar op2;
6963 IRTemp result = newTemp(Ity_I8);
6964
6965 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6966 op2 = i2;
6967 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6968 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6969 store(mkexpr(op1addr), mkexpr(result));
6970
6971 return "oiy";
6972}
6973
florian55085f82012-11-21 00:36:55 +00006974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006975s390_irgen_OIHF(UChar r1, UInt i2)
6976{
6977 IRTemp op1 = newTemp(Ity_I32);
6978 UInt op2;
6979 IRTemp result = newTemp(Ity_I32);
6980
6981 assign(op1, get_gpr_w0(r1));
6982 op2 = i2;
6983 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6984 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6985 put_gpr_w0(r1, mkexpr(result));
6986
6987 return "oihf";
6988}
6989
florian55085f82012-11-21 00:36:55 +00006990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006991s390_irgen_OIHH(UChar r1, UShort i2)
6992{
6993 IRTemp op1 = newTemp(Ity_I16);
6994 UShort op2;
6995 IRTemp result = newTemp(Ity_I16);
6996
6997 assign(op1, get_gpr_hw0(r1));
6998 op2 = i2;
6999 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7000 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7001 put_gpr_hw0(r1, mkexpr(result));
7002
7003 return "oihh";
7004}
7005
florian55085f82012-11-21 00:36:55 +00007006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007007s390_irgen_OIHL(UChar r1, UShort i2)
7008{
7009 IRTemp op1 = newTemp(Ity_I16);
7010 UShort op2;
7011 IRTemp result = newTemp(Ity_I16);
7012
7013 assign(op1, get_gpr_hw1(r1));
7014 op2 = i2;
7015 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7016 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7017 put_gpr_hw1(r1, mkexpr(result));
7018
7019 return "oihl";
7020}
7021
florian55085f82012-11-21 00:36:55 +00007022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007023s390_irgen_OILF(UChar r1, UInt i2)
7024{
7025 IRTemp op1 = newTemp(Ity_I32);
7026 UInt op2;
7027 IRTemp result = newTemp(Ity_I32);
7028
7029 assign(op1, get_gpr_w1(r1));
7030 op2 = i2;
7031 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7032 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7033 put_gpr_w1(r1, mkexpr(result));
7034
7035 return "oilf";
7036}
7037
florian55085f82012-11-21 00:36:55 +00007038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007039s390_irgen_OILH(UChar r1, UShort i2)
7040{
7041 IRTemp op1 = newTemp(Ity_I16);
7042 UShort op2;
7043 IRTemp result = newTemp(Ity_I16);
7044
7045 assign(op1, get_gpr_hw2(r1));
7046 op2 = i2;
7047 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7048 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7049 put_gpr_hw2(r1, mkexpr(result));
7050
7051 return "oilh";
7052}
7053
florian55085f82012-11-21 00:36:55 +00007054static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007055s390_irgen_OILL(UChar r1, UShort i2)
7056{
7057 IRTemp op1 = newTemp(Ity_I16);
7058 UShort op2;
7059 IRTemp result = newTemp(Ity_I16);
7060
7061 assign(op1, get_gpr_hw3(r1));
7062 op2 = i2;
7063 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7064 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7065 put_gpr_hw3(r1, mkexpr(result));
7066
7067 return "oill";
7068}
7069
florian55085f82012-11-21 00:36:55 +00007070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007071s390_irgen_PFD(void)
7072{
7073
7074 return "pfd";
7075}
7076
florian55085f82012-11-21 00:36:55 +00007077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007078s390_irgen_PFDRL(void)
7079{
7080
7081 return "pfdrl";
7082}
7083
florian55085f82012-11-21 00:36:55 +00007084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007085s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7086{
7087 IRTemp amount = newTemp(Ity_I64);
7088 IRTemp op = newTemp(Ity_I32);
7089
7090 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7091 assign(op, get_gpr_w1(r3));
7092 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7093 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7094 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7095
7096 return "rll";
7097}
7098
florian55085f82012-11-21 00:36:55 +00007099static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007100s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7101{
7102 IRTemp amount = newTemp(Ity_I64);
7103 IRTemp op = newTemp(Ity_I64);
7104
7105 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7106 assign(op, get_gpr_dw0(r3));
7107 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7108 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7109 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7110
7111 return "rllg";
7112}
7113
florian55085f82012-11-21 00:36:55 +00007114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007115s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7116{
7117 UChar from;
7118 UChar to;
7119 UChar rot;
7120 UChar t_bit;
7121 ULong mask;
7122 ULong maskc;
7123 IRTemp result = newTemp(Ity_I64);
7124 IRTemp op2 = newTemp(Ity_I64);
7125
7126 from = i3 & 63;
7127 to = i4 & 63;
7128 rot = i5 & 63;
7129 t_bit = i3 & 128;
7130 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7131 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7132 mkU8(64 - rot))));
7133 if (from <= to) {
7134 mask = ~0ULL;
7135 mask = (mask >> from) & (mask << (63 - to));
7136 maskc = ~mask;
7137 } else {
7138 maskc = ~0ULL;
7139 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7140 mask = ~maskc;
7141 }
7142 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7143 ), mkU64(mask)));
7144 if (t_bit == 0) {
7145 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7146 mkU64(maskc)), mkexpr(result)));
7147 }
7148 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7149
7150 return "rnsbg";
7151}
7152
florian55085f82012-11-21 00:36:55 +00007153static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007154s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7155{
7156 UChar from;
7157 UChar to;
7158 UChar rot;
7159 UChar t_bit;
7160 ULong mask;
7161 ULong maskc;
7162 IRTemp result = newTemp(Ity_I64);
7163 IRTemp op2 = newTemp(Ity_I64);
7164
7165 from = i3 & 63;
7166 to = i4 & 63;
7167 rot = i5 & 63;
7168 t_bit = i3 & 128;
7169 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7170 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7171 mkU8(64 - rot))));
7172 if (from <= to) {
7173 mask = ~0ULL;
7174 mask = (mask >> from) & (mask << (63 - to));
7175 maskc = ~mask;
7176 } else {
7177 maskc = ~0ULL;
7178 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7179 mask = ~maskc;
7180 }
7181 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7182 ), mkU64(mask)));
7183 if (t_bit == 0) {
7184 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7185 mkU64(maskc)), mkexpr(result)));
7186 }
7187 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7188
7189 return "rxsbg";
7190}
7191
florian55085f82012-11-21 00:36:55 +00007192static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007193s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7194{
7195 UChar from;
7196 UChar to;
7197 UChar rot;
7198 UChar t_bit;
7199 ULong mask;
7200 ULong maskc;
7201 IRTemp result = newTemp(Ity_I64);
7202 IRTemp op2 = newTemp(Ity_I64);
7203
7204 from = i3 & 63;
7205 to = i4 & 63;
7206 rot = i5 & 63;
7207 t_bit = i3 & 128;
7208 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7209 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7210 mkU8(64 - rot))));
7211 if (from <= to) {
7212 mask = ~0ULL;
7213 mask = (mask >> from) & (mask << (63 - to));
7214 maskc = ~mask;
7215 } else {
7216 maskc = ~0ULL;
7217 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7218 mask = ~maskc;
7219 }
7220 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7221 ), mkU64(mask)));
7222 if (t_bit == 0) {
7223 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7224 mkU64(maskc)), mkexpr(result)));
7225 }
7226 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7227
7228 return "rosbg";
7229}
7230
florian55085f82012-11-21 00:36:55 +00007231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007232s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7233{
7234 UChar from;
7235 UChar to;
7236 UChar rot;
7237 UChar z_bit;
7238 ULong mask;
7239 ULong maskc;
7240 IRTemp op2 = newTemp(Ity_I64);
7241 IRTemp result = newTemp(Ity_I64);
7242
7243 from = i3 & 63;
7244 to = i4 & 63;
7245 rot = i5 & 63;
7246 z_bit = i4 & 128;
7247 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7248 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7249 mkU8(64 - rot))));
7250 if (from <= to) {
7251 mask = ~0ULL;
7252 mask = (mask >> from) & (mask << (63 - to));
7253 maskc = ~mask;
7254 } else {
7255 maskc = ~0ULL;
7256 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7257 mask = ~maskc;
7258 }
7259 if (z_bit == 0) {
7260 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7261 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7262 } else {
7263 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7264 }
7265 assign(result, get_gpr_dw0(r1));
7266 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7267
7268 return "risbg";
7269}
7270
florian55085f82012-11-21 00:36:55 +00007271static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007272s390_irgen_SAR(UChar r1, UChar r2)
7273{
7274 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007275 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007276 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7277
7278 return "sar";
7279}
7280
florian55085f82012-11-21 00:36:55 +00007281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007282s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7283{
7284 IRTemp p1 = newTemp(Ity_I64);
7285 IRTemp p2 = newTemp(Ity_I64);
7286 IRTemp op = newTemp(Ity_I64);
7287 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007288 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007289 IRTemp shift_amount = newTemp(Ity_I64);
7290
7291 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7292 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7293 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7294 ));
7295 sign_mask = 1ULL << 63;
7296 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7297 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007298 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7299 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007300 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7301 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7302 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7303
7304 return "slda";
7305}
7306
florian55085f82012-11-21 00:36:55 +00007307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007308s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7309{
7310 IRTemp p1 = newTemp(Ity_I64);
7311 IRTemp p2 = newTemp(Ity_I64);
7312 IRTemp result = newTemp(Ity_I64);
7313
7314 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7315 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7316 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7317 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7318 mkexpr(op2addr), mkU64(63)))));
7319 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7320 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7321
7322 return "sldl";
7323}
7324
florian55085f82012-11-21 00:36:55 +00007325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007326s390_irgen_SLA(UChar r1, IRTemp op2addr)
7327{
7328 IRTemp uop = newTemp(Ity_I32);
7329 IRTemp result = newTemp(Ity_I32);
7330 UInt sign_mask;
7331 IRTemp shift_amount = newTemp(Ity_I64);
7332 IRTemp op = newTemp(Ity_I32);
7333
7334 assign(op, get_gpr_w1(r1));
7335 assign(uop, get_gpr_w1(r1));
7336 sign_mask = 2147483648U;
7337 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7338 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7339 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7340 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7341 put_gpr_w1(r1, mkexpr(result));
7342 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7343
7344 return "sla";
7345}
7346
florian55085f82012-11-21 00:36:55 +00007347static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007348s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7349{
7350 IRTemp uop = newTemp(Ity_I32);
7351 IRTemp result = newTemp(Ity_I32);
7352 UInt sign_mask;
7353 IRTemp shift_amount = newTemp(Ity_I64);
7354 IRTemp op = newTemp(Ity_I32);
7355
7356 assign(op, get_gpr_w1(r3));
7357 assign(uop, get_gpr_w1(r3));
7358 sign_mask = 2147483648U;
7359 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7360 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7361 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7362 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7363 put_gpr_w1(r1, mkexpr(result));
7364 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7365
7366 return "slak";
7367}
7368
florian55085f82012-11-21 00:36:55 +00007369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007370s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7371{
7372 IRTemp uop = newTemp(Ity_I64);
7373 IRTemp result = newTemp(Ity_I64);
7374 ULong sign_mask;
7375 IRTemp shift_amount = newTemp(Ity_I64);
7376 IRTemp op = newTemp(Ity_I64);
7377
7378 assign(op, get_gpr_dw0(r3));
7379 assign(uop, get_gpr_dw0(r3));
7380 sign_mask = 9223372036854775808ULL;
7381 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7382 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7383 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7384 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7385 put_gpr_dw0(r1, mkexpr(result));
7386 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7387
7388 return "slag";
7389}
7390
florian55085f82012-11-21 00:36:55 +00007391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007392s390_irgen_SLL(UChar r1, IRTemp op2addr)
7393{
7394 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7395 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7396
7397 return "sll";
7398}
7399
florian55085f82012-11-21 00:36:55 +00007400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007401s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7402{
7403 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7404 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7405
7406 return "sllk";
7407}
7408
florian55085f82012-11-21 00:36:55 +00007409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007410s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7411{
7412 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7413 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7414
7415 return "sllg";
7416}
7417
florian55085f82012-11-21 00:36:55 +00007418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007419s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7420{
7421 IRTemp p1 = newTemp(Ity_I64);
7422 IRTemp p2 = newTemp(Ity_I64);
7423 IRTemp result = newTemp(Ity_I64);
7424
7425 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7426 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7427 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7428 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7429 mkexpr(op2addr), mkU64(63)))));
7430 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7431 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7432 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7433
7434 return "srda";
7435}
7436
florian55085f82012-11-21 00:36:55 +00007437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007438s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7439{
7440 IRTemp p1 = newTemp(Ity_I64);
7441 IRTemp p2 = newTemp(Ity_I64);
7442 IRTemp result = newTemp(Ity_I64);
7443
7444 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7445 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7446 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7447 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7448 mkexpr(op2addr), mkU64(63)))));
7449 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7450 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7451
7452 return "srdl";
7453}
7454
florian55085f82012-11-21 00:36:55 +00007455static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007456s390_irgen_SRA(UChar r1, IRTemp op2addr)
7457{
7458 IRTemp result = newTemp(Ity_I32);
7459 IRTemp op = newTemp(Ity_I32);
7460
7461 assign(op, get_gpr_w1(r1));
7462 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7463 mkexpr(op2addr), mkU64(63)))));
7464 put_gpr_w1(r1, mkexpr(result));
7465 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7466
7467 return "sra";
7468}
7469
florian55085f82012-11-21 00:36:55 +00007470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007471s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7472{
7473 IRTemp result = newTemp(Ity_I32);
7474 IRTemp op = newTemp(Ity_I32);
7475
7476 assign(op, get_gpr_w1(r3));
7477 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7478 mkexpr(op2addr), mkU64(63)))));
7479 put_gpr_w1(r1, mkexpr(result));
7480 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7481
7482 return "srak";
7483}
7484
florian55085f82012-11-21 00:36:55 +00007485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007486s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7487{
7488 IRTemp result = newTemp(Ity_I64);
7489 IRTemp op = newTemp(Ity_I64);
7490
7491 assign(op, get_gpr_dw0(r3));
7492 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7493 mkexpr(op2addr), mkU64(63)))));
7494 put_gpr_dw0(r1, mkexpr(result));
7495 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7496
7497 return "srag";
7498}
7499
florian55085f82012-11-21 00:36:55 +00007500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007501s390_irgen_SRL(UChar r1, IRTemp op2addr)
7502{
7503 IRTemp op = newTemp(Ity_I32);
7504
7505 assign(op, get_gpr_w1(r1));
7506 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7507 mkexpr(op2addr), mkU64(63)))));
7508
7509 return "srl";
7510}
7511
florian55085f82012-11-21 00:36:55 +00007512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007513s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7514{
7515 IRTemp op = newTemp(Ity_I32);
7516
7517 assign(op, get_gpr_w1(r3));
7518 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7519 mkexpr(op2addr), mkU64(63)))));
7520
7521 return "srlk";
7522}
7523
florian55085f82012-11-21 00:36:55 +00007524static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007525s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7526{
7527 IRTemp op = newTemp(Ity_I64);
7528
7529 assign(op, get_gpr_dw0(r3));
7530 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7531 mkexpr(op2addr), mkU64(63)))));
7532
7533 return "srlg";
7534}
7535
florian55085f82012-11-21 00:36:55 +00007536static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007537s390_irgen_ST(UChar r1, IRTemp op2addr)
7538{
7539 store(mkexpr(op2addr), get_gpr_w1(r1));
7540
7541 return "st";
7542}
7543
florian55085f82012-11-21 00:36:55 +00007544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007545s390_irgen_STY(UChar r1, IRTemp op2addr)
7546{
7547 store(mkexpr(op2addr), get_gpr_w1(r1));
7548
7549 return "sty";
7550}
7551
florian55085f82012-11-21 00:36:55 +00007552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007553s390_irgen_STG(UChar r1, IRTemp op2addr)
7554{
7555 store(mkexpr(op2addr), get_gpr_dw0(r1));
7556
7557 return "stg";
7558}
7559
florian55085f82012-11-21 00:36:55 +00007560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007561s390_irgen_STRL(UChar r1, UInt i2)
7562{
7563 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7564 get_gpr_w1(r1));
7565
7566 return "strl";
7567}
7568
florian55085f82012-11-21 00:36:55 +00007569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007570s390_irgen_STGRL(UChar r1, UInt i2)
7571{
7572 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7573 get_gpr_dw0(r1));
7574
7575 return "stgrl";
7576}
7577
florian55085f82012-11-21 00:36:55 +00007578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007579s390_irgen_STC(UChar r1, IRTemp op2addr)
7580{
7581 store(mkexpr(op2addr), get_gpr_b7(r1));
7582
7583 return "stc";
7584}
7585
florian55085f82012-11-21 00:36:55 +00007586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007587s390_irgen_STCY(UChar r1, IRTemp op2addr)
7588{
7589 store(mkexpr(op2addr), get_gpr_b7(r1));
7590
7591 return "stcy";
7592}
7593
florian55085f82012-11-21 00:36:55 +00007594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007595s390_irgen_STCH(UChar r1, IRTemp op2addr)
7596{
7597 store(mkexpr(op2addr), get_gpr_b3(r1));
7598
7599 return "stch";
7600}
7601
florian55085f82012-11-21 00:36:55 +00007602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007603s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7604{
7605 UChar mask;
7606 UChar n;
7607
7608 mask = (UChar)r3;
7609 n = 0;
7610 if ((mask & 8) != 0) {
7611 store(mkexpr(op2addr), get_gpr_b4(r1));
7612 n = n + 1;
7613 }
7614 if ((mask & 4) != 0) {
7615 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7616 n = n + 1;
7617 }
7618 if ((mask & 2) != 0) {
7619 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7620 n = n + 1;
7621 }
7622 if ((mask & 1) != 0) {
7623 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7624 }
7625
7626 return "stcm";
7627}
7628
florian55085f82012-11-21 00:36:55 +00007629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007630s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7631{
7632 UChar mask;
7633 UChar n;
7634
7635 mask = (UChar)r3;
7636 n = 0;
7637 if ((mask & 8) != 0) {
7638 store(mkexpr(op2addr), get_gpr_b4(r1));
7639 n = n + 1;
7640 }
7641 if ((mask & 4) != 0) {
7642 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7643 n = n + 1;
7644 }
7645 if ((mask & 2) != 0) {
7646 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7647 n = n + 1;
7648 }
7649 if ((mask & 1) != 0) {
7650 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7651 }
7652
7653 return "stcmy";
7654}
7655
florian55085f82012-11-21 00:36:55 +00007656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007657s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7658{
7659 UChar mask;
7660 UChar n;
7661
7662 mask = (UChar)r3;
7663 n = 0;
7664 if ((mask & 8) != 0) {
7665 store(mkexpr(op2addr), get_gpr_b0(r1));
7666 n = n + 1;
7667 }
7668 if ((mask & 4) != 0) {
7669 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7670 n = n + 1;
7671 }
7672 if ((mask & 2) != 0) {
7673 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7674 n = n + 1;
7675 }
7676 if ((mask & 1) != 0) {
7677 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7678 }
7679
7680 return "stcmh";
7681}
7682
florian55085f82012-11-21 00:36:55 +00007683static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007684s390_irgen_STH(UChar r1, IRTemp op2addr)
7685{
7686 store(mkexpr(op2addr), get_gpr_hw3(r1));
7687
7688 return "sth";
7689}
7690
florian55085f82012-11-21 00:36:55 +00007691static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007692s390_irgen_STHY(UChar r1, IRTemp op2addr)
7693{
7694 store(mkexpr(op2addr), get_gpr_hw3(r1));
7695
7696 return "sthy";
7697}
7698
florian55085f82012-11-21 00:36:55 +00007699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007700s390_irgen_STHRL(UChar r1, UInt i2)
7701{
7702 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7703 get_gpr_hw3(r1));
7704
7705 return "sthrl";
7706}
7707
florian55085f82012-11-21 00:36:55 +00007708static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007709s390_irgen_STHH(UChar r1, IRTemp op2addr)
7710{
7711 store(mkexpr(op2addr), get_gpr_hw1(r1));
7712
7713 return "sthh";
7714}
7715
florian55085f82012-11-21 00:36:55 +00007716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007717s390_irgen_STFH(UChar r1, IRTemp op2addr)
7718{
7719 store(mkexpr(op2addr), get_gpr_w0(r1));
7720
7721 return "stfh";
7722}
7723
florian55085f82012-11-21 00:36:55 +00007724static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007725s390_irgen_STOC(UChar r1, IRTemp op2addr)
7726{
7727 /* condition is checked in format handler */
7728 store(mkexpr(op2addr), get_gpr_w1(r1));
7729
7730 return "stoc";
7731}
7732
florian55085f82012-11-21 00:36:55 +00007733static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007734s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7735{
7736 /* condition is checked in format handler */
7737 store(mkexpr(op2addr), get_gpr_dw0(r1));
7738
7739 return "stocg";
7740}
7741
florian55085f82012-11-21 00:36:55 +00007742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007743s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7744{
7745 store(mkexpr(op2addr), get_gpr_dw0(r1));
7746 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7747
7748 return "stpq";
7749}
7750
florian55085f82012-11-21 00:36:55 +00007751static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007752s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7753{
7754 store(mkexpr(op2addr), get_gpr_b7(r1));
7755 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7756
7757 return "strvh";
7758}
7759
florian55085f82012-11-21 00:36:55 +00007760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007761s390_irgen_STRV(UChar r1, IRTemp op2addr)
7762{
7763 store(mkexpr(op2addr), get_gpr_b7(r1));
7764 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7765 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7766 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7767
7768 return "strv";
7769}
7770
florian55085f82012-11-21 00:36:55 +00007771static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007772s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7773{
7774 store(mkexpr(op2addr), get_gpr_b7(r1));
7775 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7776 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7777 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7778 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7779 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7780 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7781 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7782
7783 return "strvg";
7784}
7785
florian55085f82012-11-21 00:36:55 +00007786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007787s390_irgen_SR(UChar r1, UChar r2)
7788{
7789 IRTemp op1 = newTemp(Ity_I32);
7790 IRTemp op2 = newTemp(Ity_I32);
7791 IRTemp result = newTemp(Ity_I32);
7792
7793 assign(op1, get_gpr_w1(r1));
7794 assign(op2, get_gpr_w1(r2));
7795 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7796 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7797 put_gpr_w1(r1, mkexpr(result));
7798
7799 return "sr";
7800}
7801
florian55085f82012-11-21 00:36:55 +00007802static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007803s390_irgen_SGR(UChar r1, UChar r2)
7804{
7805 IRTemp op1 = newTemp(Ity_I64);
7806 IRTemp op2 = newTemp(Ity_I64);
7807 IRTemp result = newTemp(Ity_I64);
7808
7809 assign(op1, get_gpr_dw0(r1));
7810 assign(op2, get_gpr_dw0(r2));
7811 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7812 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7813 put_gpr_dw0(r1, mkexpr(result));
7814
7815 return "sgr";
7816}
7817
florian55085f82012-11-21 00:36:55 +00007818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007819s390_irgen_SGFR(UChar r1, UChar r2)
7820{
7821 IRTemp op1 = newTemp(Ity_I64);
7822 IRTemp op2 = newTemp(Ity_I64);
7823 IRTemp result = newTemp(Ity_I64);
7824
7825 assign(op1, get_gpr_dw0(r1));
7826 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7827 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7828 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7829 put_gpr_dw0(r1, mkexpr(result));
7830
7831 return "sgfr";
7832}
7833
florian55085f82012-11-21 00:36:55 +00007834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007835s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7836{
7837 IRTemp op2 = newTemp(Ity_I32);
7838 IRTemp op3 = newTemp(Ity_I32);
7839 IRTemp result = newTemp(Ity_I32);
7840
7841 assign(op2, get_gpr_w1(r2));
7842 assign(op3, get_gpr_w1(r3));
7843 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7844 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7845 put_gpr_w1(r1, mkexpr(result));
7846
7847 return "srk";
7848}
7849
florian55085f82012-11-21 00:36:55 +00007850static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007851s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7852{
7853 IRTemp op2 = newTemp(Ity_I64);
7854 IRTemp op3 = newTemp(Ity_I64);
7855 IRTemp result = newTemp(Ity_I64);
7856
7857 assign(op2, get_gpr_dw0(r2));
7858 assign(op3, get_gpr_dw0(r3));
7859 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7860 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7861 put_gpr_dw0(r1, mkexpr(result));
7862
7863 return "sgrk";
7864}
7865
florian55085f82012-11-21 00:36:55 +00007866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007867s390_irgen_S(UChar r1, IRTemp op2addr)
7868{
7869 IRTemp op1 = newTemp(Ity_I32);
7870 IRTemp op2 = newTemp(Ity_I32);
7871 IRTemp result = newTemp(Ity_I32);
7872
7873 assign(op1, get_gpr_w1(r1));
7874 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7875 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7876 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7877 put_gpr_w1(r1, mkexpr(result));
7878
7879 return "s";
7880}
7881
florian55085f82012-11-21 00:36:55 +00007882static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007883s390_irgen_SY(UChar r1, IRTemp op2addr)
7884{
7885 IRTemp op1 = newTemp(Ity_I32);
7886 IRTemp op2 = newTemp(Ity_I32);
7887 IRTemp result = newTemp(Ity_I32);
7888
7889 assign(op1, get_gpr_w1(r1));
7890 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7891 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7892 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7893 put_gpr_w1(r1, mkexpr(result));
7894
7895 return "sy";
7896}
7897
florian55085f82012-11-21 00:36:55 +00007898static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007899s390_irgen_SG(UChar r1, IRTemp op2addr)
7900{
7901 IRTemp op1 = newTemp(Ity_I64);
7902 IRTemp op2 = newTemp(Ity_I64);
7903 IRTemp result = newTemp(Ity_I64);
7904
7905 assign(op1, get_gpr_dw0(r1));
7906 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7907 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7908 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7909 put_gpr_dw0(r1, mkexpr(result));
7910
7911 return "sg";
7912}
7913
florian55085f82012-11-21 00:36:55 +00007914static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007915s390_irgen_SGF(UChar r1, IRTemp op2addr)
7916{
7917 IRTemp op1 = newTemp(Ity_I64);
7918 IRTemp op2 = newTemp(Ity_I64);
7919 IRTemp result = newTemp(Ity_I64);
7920
7921 assign(op1, get_gpr_dw0(r1));
7922 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7923 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7924 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7925 put_gpr_dw0(r1, mkexpr(result));
7926
7927 return "sgf";
7928}
7929
florian55085f82012-11-21 00:36:55 +00007930static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007931s390_irgen_SH(UChar r1, IRTemp op2addr)
7932{
7933 IRTemp op1 = newTemp(Ity_I32);
7934 IRTemp op2 = newTemp(Ity_I32);
7935 IRTemp result = newTemp(Ity_I32);
7936
7937 assign(op1, get_gpr_w1(r1));
7938 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7939 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7940 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7941 put_gpr_w1(r1, mkexpr(result));
7942
7943 return "sh";
7944}
7945
florian55085f82012-11-21 00:36:55 +00007946static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007947s390_irgen_SHY(UChar r1, IRTemp op2addr)
7948{
7949 IRTemp op1 = newTemp(Ity_I32);
7950 IRTemp op2 = newTemp(Ity_I32);
7951 IRTemp result = newTemp(Ity_I32);
7952
7953 assign(op1, get_gpr_w1(r1));
7954 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7955 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7956 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7957 put_gpr_w1(r1, mkexpr(result));
7958
7959 return "shy";
7960}
7961
florian55085f82012-11-21 00:36:55 +00007962static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007963s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7964{
7965 IRTemp op2 = newTemp(Ity_I32);
7966 IRTemp op3 = newTemp(Ity_I32);
7967 IRTemp result = newTemp(Ity_I32);
7968
7969 assign(op2, get_gpr_w0(r1));
7970 assign(op3, get_gpr_w0(r2));
7971 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7972 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7973 put_gpr_w0(r1, mkexpr(result));
7974
7975 return "shhhr";
7976}
7977
florian55085f82012-11-21 00:36:55 +00007978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007979s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7980{
7981 IRTemp op2 = newTemp(Ity_I32);
7982 IRTemp op3 = newTemp(Ity_I32);
7983 IRTemp result = newTemp(Ity_I32);
7984
7985 assign(op2, get_gpr_w0(r1));
7986 assign(op3, get_gpr_w1(r2));
7987 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7989 put_gpr_w0(r1, mkexpr(result));
7990
7991 return "shhlr";
7992}
7993
florian55085f82012-11-21 00:36:55 +00007994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007995s390_irgen_SLR(UChar r1, UChar r2)
7996{
7997 IRTemp op1 = newTemp(Ity_I32);
7998 IRTemp op2 = newTemp(Ity_I32);
7999 IRTemp result = newTemp(Ity_I32);
8000
8001 assign(op1, get_gpr_w1(r1));
8002 assign(op2, get_gpr_w1(r2));
8003 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8004 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8005 put_gpr_w1(r1, mkexpr(result));
8006
8007 return "slr";
8008}
8009
florian55085f82012-11-21 00:36:55 +00008010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008011s390_irgen_SLGR(UChar r1, UChar r2)
8012{
8013 IRTemp op1 = newTemp(Ity_I64);
8014 IRTemp op2 = newTemp(Ity_I64);
8015 IRTemp result = newTemp(Ity_I64);
8016
8017 assign(op1, get_gpr_dw0(r1));
8018 assign(op2, get_gpr_dw0(r2));
8019 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8020 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8021 put_gpr_dw0(r1, mkexpr(result));
8022
8023 return "slgr";
8024}
8025
florian55085f82012-11-21 00:36:55 +00008026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008027s390_irgen_SLGFR(UChar r1, UChar r2)
8028{
8029 IRTemp op1 = newTemp(Ity_I64);
8030 IRTemp op2 = newTemp(Ity_I64);
8031 IRTemp result = newTemp(Ity_I64);
8032
8033 assign(op1, get_gpr_dw0(r1));
8034 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8035 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8036 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8037 put_gpr_dw0(r1, mkexpr(result));
8038
8039 return "slgfr";
8040}
8041
florian55085f82012-11-21 00:36:55 +00008042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008043s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8044{
8045 IRTemp op2 = newTemp(Ity_I32);
8046 IRTemp op3 = newTemp(Ity_I32);
8047 IRTemp result = newTemp(Ity_I32);
8048
8049 assign(op2, get_gpr_w1(r2));
8050 assign(op3, get_gpr_w1(r3));
8051 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8052 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8053 put_gpr_w1(r1, mkexpr(result));
8054
8055 return "slrk";
8056}
8057
florian55085f82012-11-21 00:36:55 +00008058static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008059s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8060{
8061 IRTemp op2 = newTemp(Ity_I64);
8062 IRTemp op3 = newTemp(Ity_I64);
8063 IRTemp result = newTemp(Ity_I64);
8064
8065 assign(op2, get_gpr_dw0(r2));
8066 assign(op3, get_gpr_dw0(r3));
8067 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8068 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8069 put_gpr_dw0(r1, mkexpr(result));
8070
8071 return "slgrk";
8072}
8073
florian55085f82012-11-21 00:36:55 +00008074static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008075s390_irgen_SL(UChar r1, IRTemp op2addr)
8076{
8077 IRTemp op1 = newTemp(Ity_I32);
8078 IRTemp op2 = newTemp(Ity_I32);
8079 IRTemp result = newTemp(Ity_I32);
8080
8081 assign(op1, get_gpr_w1(r1));
8082 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8083 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8084 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8085 put_gpr_w1(r1, mkexpr(result));
8086
8087 return "sl";
8088}
8089
florian55085f82012-11-21 00:36:55 +00008090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008091s390_irgen_SLY(UChar r1, IRTemp op2addr)
8092{
8093 IRTemp op1 = newTemp(Ity_I32);
8094 IRTemp op2 = newTemp(Ity_I32);
8095 IRTemp result = newTemp(Ity_I32);
8096
8097 assign(op1, get_gpr_w1(r1));
8098 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8099 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8100 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8101 put_gpr_w1(r1, mkexpr(result));
8102
8103 return "sly";
8104}
8105
florian55085f82012-11-21 00:36:55 +00008106static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008107s390_irgen_SLG(UChar r1, IRTemp op2addr)
8108{
8109 IRTemp op1 = newTemp(Ity_I64);
8110 IRTemp op2 = newTemp(Ity_I64);
8111 IRTemp result = newTemp(Ity_I64);
8112
8113 assign(op1, get_gpr_dw0(r1));
8114 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8115 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8116 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8117 put_gpr_dw0(r1, mkexpr(result));
8118
8119 return "slg";
8120}
8121
florian55085f82012-11-21 00:36:55 +00008122static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008123s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8124{
8125 IRTemp op1 = newTemp(Ity_I64);
8126 IRTemp op2 = newTemp(Ity_I64);
8127 IRTemp result = newTemp(Ity_I64);
8128
8129 assign(op1, get_gpr_dw0(r1));
8130 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8131 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8132 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8133 put_gpr_dw0(r1, mkexpr(result));
8134
8135 return "slgf";
8136}
8137
florian55085f82012-11-21 00:36:55 +00008138static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008139s390_irgen_SLFI(UChar r1, UInt i2)
8140{
8141 IRTemp op1 = newTemp(Ity_I32);
8142 UInt op2;
8143 IRTemp result = newTemp(Ity_I32);
8144
8145 assign(op1, get_gpr_w1(r1));
8146 op2 = i2;
8147 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8148 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8149 mkU32(op2)));
8150 put_gpr_w1(r1, mkexpr(result));
8151
8152 return "slfi";
8153}
8154
florian55085f82012-11-21 00:36:55 +00008155static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008156s390_irgen_SLGFI(UChar r1, UInt i2)
8157{
8158 IRTemp op1 = newTemp(Ity_I64);
8159 ULong op2;
8160 IRTemp result = newTemp(Ity_I64);
8161
8162 assign(op1, get_gpr_dw0(r1));
8163 op2 = (ULong)i2;
8164 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8165 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8166 mkU64(op2)));
8167 put_gpr_dw0(r1, mkexpr(result));
8168
8169 return "slgfi";
8170}
8171
florian55085f82012-11-21 00:36:55 +00008172static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008173s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8174{
8175 IRTemp op2 = newTemp(Ity_I32);
8176 IRTemp op3 = newTemp(Ity_I32);
8177 IRTemp result = newTemp(Ity_I32);
8178
8179 assign(op2, get_gpr_w0(r1));
8180 assign(op3, get_gpr_w0(r2));
8181 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8182 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8183 put_gpr_w0(r1, mkexpr(result));
8184
8185 return "slhhhr";
8186}
8187
florian55085f82012-11-21 00:36:55 +00008188static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008189s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8190{
8191 IRTemp op2 = newTemp(Ity_I32);
8192 IRTemp op3 = newTemp(Ity_I32);
8193 IRTemp result = newTemp(Ity_I32);
8194
8195 assign(op2, get_gpr_w0(r1));
8196 assign(op3, get_gpr_w1(r2));
8197 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8198 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8199 put_gpr_w0(r1, mkexpr(result));
8200
8201 return "slhhlr";
8202}
8203
florian55085f82012-11-21 00:36:55 +00008204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008205s390_irgen_SLBR(UChar r1, UChar r2)
8206{
8207 IRTemp op1 = newTemp(Ity_I32);
8208 IRTemp op2 = newTemp(Ity_I32);
8209 IRTemp result = newTemp(Ity_I32);
8210 IRTemp borrow_in = newTemp(Ity_I32);
8211
8212 assign(op1, get_gpr_w1(r1));
8213 assign(op2, get_gpr_w1(r2));
8214 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8215 s390_call_calculate_cc(), mkU8(1))));
8216 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8217 mkexpr(borrow_in)));
8218 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8219 put_gpr_w1(r1, mkexpr(result));
8220
8221 return "slbr";
8222}
8223
florian55085f82012-11-21 00:36:55 +00008224static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008225s390_irgen_SLBGR(UChar r1, UChar r2)
8226{
8227 IRTemp op1 = newTemp(Ity_I64);
8228 IRTemp op2 = newTemp(Ity_I64);
8229 IRTemp result = newTemp(Ity_I64);
8230 IRTemp borrow_in = newTemp(Ity_I64);
8231
8232 assign(op1, get_gpr_dw0(r1));
8233 assign(op2, get_gpr_dw0(r2));
8234 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8235 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8236 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8237 mkexpr(borrow_in)));
8238 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8239 put_gpr_dw0(r1, mkexpr(result));
8240
8241 return "slbgr";
8242}
8243
florian55085f82012-11-21 00:36:55 +00008244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008245s390_irgen_SLB(UChar r1, IRTemp op2addr)
8246{
8247 IRTemp op1 = newTemp(Ity_I32);
8248 IRTemp op2 = newTemp(Ity_I32);
8249 IRTemp result = newTemp(Ity_I32);
8250 IRTemp borrow_in = newTemp(Ity_I32);
8251
8252 assign(op1, get_gpr_w1(r1));
8253 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8254 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8255 s390_call_calculate_cc(), mkU8(1))));
8256 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8257 mkexpr(borrow_in)));
8258 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8259 put_gpr_w1(r1, mkexpr(result));
8260
8261 return "slb";
8262}
8263
florian55085f82012-11-21 00:36:55 +00008264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008265s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8266{
8267 IRTemp op1 = newTemp(Ity_I64);
8268 IRTemp op2 = newTemp(Ity_I64);
8269 IRTemp result = newTemp(Ity_I64);
8270 IRTemp borrow_in = newTemp(Ity_I64);
8271
8272 assign(op1, get_gpr_dw0(r1));
8273 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8274 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8275 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8276 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8277 mkexpr(borrow_in)));
8278 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8279 put_gpr_dw0(r1, mkexpr(result));
8280
8281 return "slbg";
8282}
8283
florian55085f82012-11-21 00:36:55 +00008284static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008285s390_irgen_SVC(UChar i)
8286{
8287 IRTemp sysno = newTemp(Ity_I64);
8288
8289 if (i != 0) {
8290 assign(sysno, mkU64(i));
8291 } else {
8292 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8293 }
8294 system_call(mkexpr(sysno));
8295
8296 return "svc";
8297}
8298
florian55085f82012-11-21 00:36:55 +00008299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008300s390_irgen_TM(UChar i2, IRTemp op1addr)
8301{
8302 UChar mask;
8303 IRTemp value = newTemp(Ity_I8);
8304
8305 mask = i2;
8306 assign(value, load(Ity_I8, mkexpr(op1addr)));
8307 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8308 mkU8(mask)));
8309
8310 return "tm";
8311}
8312
florian55085f82012-11-21 00:36:55 +00008313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008314s390_irgen_TMY(UChar i2, IRTemp op1addr)
8315{
8316 UChar mask;
8317 IRTemp value = newTemp(Ity_I8);
8318
8319 mask = i2;
8320 assign(value, load(Ity_I8, mkexpr(op1addr)));
8321 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8322 mkU8(mask)));
8323
8324 return "tmy";
8325}
8326
florian55085f82012-11-21 00:36:55 +00008327static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008328s390_irgen_TMHH(UChar r1, UShort i2)
8329{
8330 UShort mask;
8331 IRTemp value = newTemp(Ity_I16);
8332
8333 mask = i2;
8334 assign(value, get_gpr_hw0(r1));
8335 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8336 mkU16(mask)));
8337
8338 return "tmhh";
8339}
8340
florian55085f82012-11-21 00:36:55 +00008341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008342s390_irgen_TMHL(UChar r1, UShort i2)
8343{
8344 UShort mask;
8345 IRTemp value = newTemp(Ity_I16);
8346
8347 mask = i2;
8348 assign(value, get_gpr_hw1(r1));
8349 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8350 mkU16(mask)));
8351
8352 return "tmhl";
8353}
8354
florian55085f82012-11-21 00:36:55 +00008355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008356s390_irgen_TMLH(UChar r1, UShort i2)
8357{
8358 UShort mask;
8359 IRTemp value = newTemp(Ity_I16);
8360
8361 mask = i2;
8362 assign(value, get_gpr_hw2(r1));
8363 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8364 mkU16(mask)));
8365
8366 return "tmlh";
8367}
8368
florian55085f82012-11-21 00:36:55 +00008369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008370s390_irgen_TMLL(UChar r1, UShort i2)
8371{
8372 UShort mask;
8373 IRTemp value = newTemp(Ity_I16);
8374
8375 mask = i2;
8376 assign(value, get_gpr_hw3(r1));
8377 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8378 mkU16(mask)));
8379
8380 return "tmll";
8381}
8382
florian55085f82012-11-21 00:36:55 +00008383static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008384s390_irgen_EFPC(UChar r1)
8385{
8386 put_gpr_w1(r1, get_fpc_w0());
8387
8388 return "efpc";
8389}
8390
florian55085f82012-11-21 00:36:55 +00008391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008392s390_irgen_LER(UChar r1, UChar r2)
8393{
8394 put_fpr_w0(r1, get_fpr_w0(r2));
8395
8396 return "ler";
8397}
8398
florian55085f82012-11-21 00:36:55 +00008399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008400s390_irgen_LDR(UChar r1, UChar r2)
8401{
8402 put_fpr_dw0(r1, get_fpr_dw0(r2));
8403
8404 return "ldr";
8405}
8406
florian55085f82012-11-21 00:36:55 +00008407static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008408s390_irgen_LXR(UChar r1, UChar r2)
8409{
8410 put_fpr_dw0(r1, get_fpr_dw0(r2));
8411 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8412
8413 return "lxr";
8414}
8415
florian55085f82012-11-21 00:36:55 +00008416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008417s390_irgen_LE(UChar r1, IRTemp op2addr)
8418{
8419 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8420
8421 return "le";
8422}
8423
florian55085f82012-11-21 00:36:55 +00008424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008425s390_irgen_LD(UChar r1, IRTemp op2addr)
8426{
8427 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8428
8429 return "ld";
8430}
8431
florian55085f82012-11-21 00:36:55 +00008432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008433s390_irgen_LEY(UChar r1, IRTemp op2addr)
8434{
8435 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8436
8437 return "ley";
8438}
8439
florian55085f82012-11-21 00:36:55 +00008440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008441s390_irgen_LDY(UChar r1, IRTemp op2addr)
8442{
8443 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8444
8445 return "ldy";
8446}
8447
florian55085f82012-11-21 00:36:55 +00008448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008449s390_irgen_LFPC(IRTemp op2addr)
8450{
8451 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8452
8453 return "lfpc";
8454}
8455
florian55085f82012-11-21 00:36:55 +00008456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008457s390_irgen_LZER(UChar r1)
8458{
8459 put_fpr_w0(r1, mkF32i(0x0));
8460
8461 return "lzer";
8462}
8463
florian55085f82012-11-21 00:36:55 +00008464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008465s390_irgen_LZDR(UChar r1)
8466{
8467 put_fpr_dw0(r1, mkF64i(0x0));
8468
8469 return "lzdr";
8470}
8471
florian55085f82012-11-21 00:36:55 +00008472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008473s390_irgen_LZXR(UChar r1)
8474{
8475 put_fpr_dw0(r1, mkF64i(0x0));
8476 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8477
8478 return "lzxr";
8479}
8480
florian55085f82012-11-21 00:36:55 +00008481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008482s390_irgen_SRNM(IRTemp op2addr)
8483{
florianf0fa1be2012-09-18 20:24:38 +00008484 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008485
florianf0fa1be2012-09-18 20:24:38 +00008486 input_mask = 3;
8487 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008488
florianf0fa1be2012-09-18 20:24:38 +00008489 put_fpc_w0(binop(Iop_Or32,
8490 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8491 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8492 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008493 return "srnm";
8494}
8495
florian55085f82012-11-21 00:36:55 +00008496static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008497s390_irgen_SRNMB(IRTemp op2addr)
8498{
8499 UInt input_mask, fpc_mask;
8500
8501 input_mask = 7;
8502 fpc_mask = 7;
8503
8504 put_fpc_w0(binop(Iop_Or32,
8505 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8506 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8507 mkU32(input_mask))));
8508 return "srnmb";
8509}
8510
florian81a4bfe2012-09-20 01:25:28 +00008511static void
florianf0fa1be2012-09-18 20:24:38 +00008512s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8513{
8514 if (b2 == 0) { /* This is the typical case */
8515 if (d2 > 3) {
8516 if (s390_host_has_fpext && d2 == 7) {
8517 /* ok */
8518 } else {
8519 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008520 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008521 }
8522 }
8523 }
8524
8525 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8526}
8527
8528
florian55085f82012-11-21 00:36:55 +00008529static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008530s390_irgen_SFPC(UChar r1)
8531{
8532 put_fpc_w0(get_gpr_w1(r1));
8533
8534 return "sfpc";
8535}
8536
florian55085f82012-11-21 00:36:55 +00008537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008538s390_irgen_STE(UChar r1, IRTemp op2addr)
8539{
8540 store(mkexpr(op2addr), get_fpr_w0(r1));
8541
8542 return "ste";
8543}
8544
florian55085f82012-11-21 00:36:55 +00008545static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008546s390_irgen_STD(UChar r1, IRTemp op2addr)
8547{
8548 store(mkexpr(op2addr), get_fpr_dw0(r1));
8549
8550 return "std";
8551}
8552
florian55085f82012-11-21 00:36:55 +00008553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008554s390_irgen_STEY(UChar r1, IRTemp op2addr)
8555{
8556 store(mkexpr(op2addr), get_fpr_w0(r1));
8557
8558 return "stey";
8559}
8560
florian55085f82012-11-21 00:36:55 +00008561static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008562s390_irgen_STDY(UChar r1, IRTemp op2addr)
8563{
8564 store(mkexpr(op2addr), get_fpr_dw0(r1));
8565
8566 return "stdy";
8567}
8568
florian55085f82012-11-21 00:36:55 +00008569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008570s390_irgen_STFPC(IRTemp op2addr)
8571{
8572 store(mkexpr(op2addr), get_fpc_w0());
8573
8574 return "stfpc";
8575}
8576
florian55085f82012-11-21 00:36:55 +00008577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008578s390_irgen_AEBR(UChar r1, UChar r2)
8579{
8580 IRTemp op1 = newTemp(Ity_F32);
8581 IRTemp op2 = newTemp(Ity_F32);
8582 IRTemp result = newTemp(Ity_F32);
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_w0(r1));
8586 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008587 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008588 mkexpr(op2)));
8589 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8590 put_fpr_w0(r1, mkexpr(result));
8591
8592 return "aebr";
8593}
8594
florian55085f82012-11-21 00:36:55 +00008595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008596s390_irgen_ADBR(UChar r1, UChar r2)
8597{
8598 IRTemp op1 = newTemp(Ity_F64);
8599 IRTemp op2 = newTemp(Ity_F64);
8600 IRTemp result = newTemp(Ity_F64);
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_dw0(r1));
8604 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008605 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008606 mkexpr(op2)));
8607 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8608 put_fpr_dw0(r1, mkexpr(result));
8609
8610 return "adbr";
8611}
8612
florian55085f82012-11-21 00:36:55 +00008613static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008614s390_irgen_AEB(UChar r1, IRTemp op2addr)
8615{
8616 IRTemp op1 = newTemp(Ity_F32);
8617 IRTemp op2 = newTemp(Ity_F32);
8618 IRTemp result = newTemp(Ity_F32);
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_w0(r1));
8622 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008623 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008624 mkexpr(op2)));
8625 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8626 put_fpr_w0(r1, mkexpr(result));
8627
8628 return "aeb";
8629}
8630
florian55085f82012-11-21 00:36:55 +00008631static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008632s390_irgen_ADB(UChar r1, IRTemp op2addr)
8633{
8634 IRTemp op1 = newTemp(Ity_F64);
8635 IRTemp op2 = newTemp(Ity_F64);
8636 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008637 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008638
8639 assign(op1, get_fpr_dw0(r1));
8640 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008641 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008642 mkexpr(op2)));
8643 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8644 put_fpr_dw0(r1, mkexpr(result));
8645
8646 return "adb";
8647}
8648
florian55085f82012-11-21 00:36:55 +00008649static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008650s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8651 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008652{
florian125e20d2012-10-07 15:42:37 +00008653 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008654 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008655 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008656 }
sewardj2019a972011-03-07 16:04:07 +00008657 IRTemp op2 = newTemp(Ity_I32);
8658
8659 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008660 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008661 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008662
8663 return "cefbr";
8664}
8665
florian55085f82012-11-21 00:36:55 +00008666static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008667s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8668 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008669{
8670 IRTemp op2 = newTemp(Ity_I32);
8671
8672 assign(op2, get_gpr_w1(r2));
8673 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8674
8675 return "cdfbr";
8676}
8677
florian55085f82012-11-21 00:36:55 +00008678static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008679s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8680 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008681{
florian125e20d2012-10-07 15:42:37 +00008682 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008683 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008684 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008685 }
sewardj2019a972011-03-07 16:04:07 +00008686 IRTemp op2 = newTemp(Ity_I64);
8687
8688 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008689 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008690 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008691
8692 return "cegbr";
8693}
8694
florian55085f82012-11-21 00:36:55 +00008695static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008696s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8697 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008698{
florian125e20d2012-10-07 15:42:37 +00008699 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008700 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008701 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008702 }
sewardj2019a972011-03-07 16:04:07 +00008703 IRTemp op2 = newTemp(Ity_I64);
8704
8705 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008706 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008707 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008708
8709 return "cdgbr";
8710}
8711
florian55085f82012-11-21 00:36:55 +00008712static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008713s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8714 UChar r1, UChar r2)
8715{
floriane75dafa2012-09-01 17:54:09 +00008716 if (! s390_host_has_fpext) {
8717 emulation_failure(EmFail_S390X_fpext);
8718 } else {
8719 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008720
floriane75dafa2012-09-01 17:54:09 +00008721 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008722 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008723 mkexpr(op2)));
8724 }
florian1c8f7ff2012-09-01 00:12:11 +00008725 return "celfbr";
8726}
8727
florian55085f82012-11-21 00:36:55 +00008728static const HChar *
floriand2129202012-09-01 20:01:39 +00008729s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8730 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008731{
floriane75dafa2012-09-01 17:54:09 +00008732 if (! s390_host_has_fpext) {
8733 emulation_failure(EmFail_S390X_fpext);
8734 } else {
8735 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008736
floriane75dafa2012-09-01 17:54:09 +00008737 assign(op2, get_gpr_w1(r2));
8738 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8739 }
florian1c8f7ff2012-09-01 00:12:11 +00008740 return "cdlfbr";
8741}
8742
florian55085f82012-11-21 00:36:55 +00008743static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008744s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8745 UChar r1, UChar r2)
8746{
floriane75dafa2012-09-01 17:54:09 +00008747 if (! s390_host_has_fpext) {
8748 emulation_failure(EmFail_S390X_fpext);
8749 } else {
8750 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008751
floriane75dafa2012-09-01 17:54:09 +00008752 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008753 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008754 mkexpr(op2)));
8755 }
florian1c8f7ff2012-09-01 00:12:11 +00008756 return "celgbr";
8757}
8758
florian55085f82012-11-21 00:36:55 +00008759static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008760s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8761 UChar r1, UChar r2)
8762{
floriane75dafa2012-09-01 17:54:09 +00008763 if (! s390_host_has_fpext) {
8764 emulation_failure(EmFail_S390X_fpext);
8765 } else {
8766 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008767
floriane75dafa2012-09-01 17:54:09 +00008768 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008769 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8770 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008771 mkexpr(op2)));
8772 }
florian1c8f7ff2012-09-01 00:12:11 +00008773 return "cdlgbr";
8774}
8775
florian55085f82012-11-21 00:36:55 +00008776static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008777s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8778 UChar r1, UChar r2)
8779{
floriane75dafa2012-09-01 17:54:09 +00008780 if (! s390_host_has_fpext) {
8781 emulation_failure(EmFail_S390X_fpext);
8782 } else {
8783 IRTemp op = newTemp(Ity_F32);
8784 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008785 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008786
floriane75dafa2012-09-01 17:54:09 +00008787 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008788 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008789 mkexpr(op)));
8790 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008791 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008792 }
florian1c8f7ff2012-09-01 00:12:11 +00008793 return "clfebr";
8794}
8795
florian55085f82012-11-21 00:36:55 +00008796static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008797s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8798 UChar r1, UChar r2)
8799{
floriane75dafa2012-09-01 17:54:09 +00008800 if (! s390_host_has_fpext) {
8801 emulation_failure(EmFail_S390X_fpext);
8802 } else {
8803 IRTemp op = newTemp(Ity_F64);
8804 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008805 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008806
floriane75dafa2012-09-01 17:54:09 +00008807 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008808 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008809 mkexpr(op)));
8810 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008811 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008812 }
florian1c8f7ff2012-09-01 00:12:11 +00008813 return "clfdbr";
8814}
8815
florian55085f82012-11-21 00:36:55 +00008816static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008817s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8818 UChar r1, UChar r2)
8819{
floriane75dafa2012-09-01 17:54:09 +00008820 if (! s390_host_has_fpext) {
8821 emulation_failure(EmFail_S390X_fpext);
8822 } else {
8823 IRTemp op = newTemp(Ity_F32);
8824 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008825 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008826
floriane75dafa2012-09-01 17:54:09 +00008827 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008828 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008829 mkexpr(op)));
8830 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008831 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008832 }
florian1c8f7ff2012-09-01 00:12:11 +00008833 return "clgebr";
8834}
8835
florian55085f82012-11-21 00:36:55 +00008836static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008837s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8838 UChar r1, UChar r2)
8839{
floriane75dafa2012-09-01 17:54:09 +00008840 if (! s390_host_has_fpext) {
8841 emulation_failure(EmFail_S390X_fpext);
8842 } else {
8843 IRTemp op = newTemp(Ity_F64);
8844 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008845 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008846
floriane75dafa2012-09-01 17:54:09 +00008847 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008848 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008849 mkexpr(op)));
8850 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008851 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008852 }
florian1c8f7ff2012-09-01 00:12:11 +00008853 return "clgdbr";
8854}
8855
florian55085f82012-11-21 00:36:55 +00008856static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008857s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8858 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008859{
8860 IRTemp op = newTemp(Ity_F32);
8861 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008862 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008863
8864 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008865 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008866 mkexpr(op)));
8867 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008868 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008869
8870 return "cfebr";
8871}
8872
florian55085f82012-11-21 00:36:55 +00008873static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008874s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8875 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008876{
8877 IRTemp op = newTemp(Ity_F64);
8878 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008879 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008880
8881 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008882 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008883 mkexpr(op)));
8884 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008885 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008886
8887 return "cfdbr";
8888}
8889
florian55085f82012-11-21 00:36:55 +00008890static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008891s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8892 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008893{
8894 IRTemp op = newTemp(Ity_F32);
8895 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008896 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008897
8898 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008899 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008900 mkexpr(op)));
8901 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008902 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008903
8904 return "cgebr";
8905}
8906
florian55085f82012-11-21 00:36:55 +00008907static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008908s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8909 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008910{
8911 IRTemp op = newTemp(Ity_F64);
8912 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008913 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008914
8915 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008916 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008917 mkexpr(op)));
8918 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008919 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008920
8921 return "cgdbr";
8922}
8923
florian55085f82012-11-21 00:36:55 +00008924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008925s390_irgen_DEBR(UChar r1, UChar r2)
8926{
8927 IRTemp op1 = newTemp(Ity_F32);
8928 IRTemp op2 = newTemp(Ity_F32);
8929 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008930 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008931
8932 assign(op1, get_fpr_w0(r1));
8933 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008934 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008935 mkexpr(op2)));
8936 put_fpr_w0(r1, mkexpr(result));
8937
8938 return "debr";
8939}
8940
florian55085f82012-11-21 00:36:55 +00008941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008942s390_irgen_DDBR(UChar r1, UChar r2)
8943{
8944 IRTemp op1 = newTemp(Ity_F64);
8945 IRTemp op2 = newTemp(Ity_F64);
8946 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008947 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008948
8949 assign(op1, get_fpr_dw0(r1));
8950 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008951 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008952 mkexpr(op2)));
8953 put_fpr_dw0(r1, mkexpr(result));
8954
8955 return "ddbr";
8956}
8957
florian55085f82012-11-21 00:36:55 +00008958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008959s390_irgen_DEB(UChar r1, IRTemp op2addr)
8960{
8961 IRTemp op1 = newTemp(Ity_F32);
8962 IRTemp op2 = newTemp(Ity_F32);
8963 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008964 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008965
8966 assign(op1, get_fpr_w0(r1));
8967 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008968 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008969 mkexpr(op2)));
8970 put_fpr_w0(r1, mkexpr(result));
8971
8972 return "deb";
8973}
8974
florian55085f82012-11-21 00:36:55 +00008975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008976s390_irgen_DDB(UChar r1, IRTemp op2addr)
8977{
8978 IRTemp op1 = newTemp(Ity_F64);
8979 IRTemp op2 = newTemp(Ity_F64);
8980 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008981 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008982
8983 assign(op1, get_fpr_dw0(r1));
8984 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008985 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008986 mkexpr(op2)));
8987 put_fpr_dw0(r1, mkexpr(result));
8988
8989 return "ddb";
8990}
8991
florian55085f82012-11-21 00:36:55 +00008992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008993s390_irgen_LTEBR(UChar r1, UChar r2)
8994{
8995 IRTemp result = newTemp(Ity_F32);
8996
8997 assign(result, get_fpr_w0(r2));
8998 put_fpr_w0(r1, mkexpr(result));
8999 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9000
9001 return "ltebr";
9002}
9003
florian55085f82012-11-21 00:36:55 +00009004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009005s390_irgen_LTDBR(UChar r1, UChar r2)
9006{
9007 IRTemp result = newTemp(Ity_F64);
9008
9009 assign(result, get_fpr_dw0(r2));
9010 put_fpr_dw0(r1, mkexpr(result));
9011 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9012
9013 return "ltdbr";
9014}
9015
florian55085f82012-11-21 00:36:55 +00009016static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009017s390_irgen_LCEBR(UChar r1, UChar r2)
9018{
9019 IRTemp result = newTemp(Ity_F32);
9020
9021 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9022 put_fpr_w0(r1, mkexpr(result));
9023 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9024
9025 return "lcebr";
9026}
9027
florian55085f82012-11-21 00:36:55 +00009028static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009029s390_irgen_LCDBR(UChar r1, UChar r2)
9030{
9031 IRTemp result = newTemp(Ity_F64);
9032
9033 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9034 put_fpr_dw0(r1, mkexpr(result));
9035 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9036
9037 return "lcdbr";
9038}
9039
florian55085f82012-11-21 00:36:55 +00009040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009041s390_irgen_LDEBR(UChar r1, UChar r2)
9042{
9043 IRTemp op = newTemp(Ity_F32);
9044
9045 assign(op, get_fpr_w0(r2));
9046 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9047
9048 return "ldebr";
9049}
9050
florian55085f82012-11-21 00:36:55 +00009051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009052s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9053{
9054 IRTemp op = newTemp(Ity_F32);
9055
9056 assign(op, load(Ity_F32, mkexpr(op2addr)));
9057 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9058
9059 return "ldeb";
9060}
9061
florian55085f82012-11-21 00:36:55 +00009062static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009063s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9064 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009065{
florian125e20d2012-10-07 15:42:37 +00009066 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009067 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009068 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009069 }
sewardj2019a972011-03-07 16:04:07 +00009070 IRTemp op = newTemp(Ity_F64);
9071
9072 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009073 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009074 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009075
9076 return "ledbr";
9077}
9078
florian55085f82012-11-21 00:36:55 +00009079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009080s390_irgen_MEEBR(UChar r1, UChar r2)
9081{
9082 IRTemp op1 = newTemp(Ity_F32);
9083 IRTemp op2 = newTemp(Ity_F32);
9084 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009085 IRRoundingMode rounding_mode =
9086 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009087
9088 assign(op1, get_fpr_w0(r1));
9089 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009090 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009091 mkexpr(op2)));
9092 put_fpr_w0(r1, mkexpr(result));
9093
9094 return "meebr";
9095}
9096
florian55085f82012-11-21 00:36:55 +00009097static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009098s390_irgen_MDBR(UChar r1, UChar r2)
9099{
9100 IRTemp op1 = newTemp(Ity_F64);
9101 IRTemp op2 = newTemp(Ity_F64);
9102 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009103 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009104
9105 assign(op1, get_fpr_dw0(r1));
9106 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009107 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009108 mkexpr(op2)));
9109 put_fpr_dw0(r1, mkexpr(result));
9110
9111 return "mdbr";
9112}
9113
florian55085f82012-11-21 00:36:55 +00009114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009115s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9116{
9117 IRTemp op1 = newTemp(Ity_F32);
9118 IRTemp op2 = newTemp(Ity_F32);
9119 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009120 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009121
9122 assign(op1, get_fpr_w0(r1));
9123 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009124 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009125 mkexpr(op2)));
9126 put_fpr_w0(r1, mkexpr(result));
9127
9128 return "meeb";
9129}
9130
florian55085f82012-11-21 00:36:55 +00009131static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009132s390_irgen_MDB(UChar r1, IRTemp op2addr)
9133{
9134 IRTemp op1 = newTemp(Ity_F64);
9135 IRTemp op2 = newTemp(Ity_F64);
9136 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009137 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009138
9139 assign(op1, get_fpr_dw0(r1));
9140 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009141 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009142 mkexpr(op2)));
9143 put_fpr_dw0(r1, mkexpr(result));
9144
9145 return "mdb";
9146}
9147
florian55085f82012-11-21 00:36:55 +00009148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009149s390_irgen_SEBR(UChar r1, UChar r2)
9150{
9151 IRTemp op1 = newTemp(Ity_F32);
9152 IRTemp op2 = newTemp(Ity_F32);
9153 IRTemp result = newTemp(Ity_F32);
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_w0(r1));
9157 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009158 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009159 mkexpr(op2)));
9160 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9161 put_fpr_w0(r1, mkexpr(result));
9162
9163 return "sebr";
9164}
9165
florian55085f82012-11-21 00:36:55 +00009166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009167s390_irgen_SDBR(UChar r1, UChar r2)
9168{
9169 IRTemp op1 = newTemp(Ity_F64);
9170 IRTemp op2 = newTemp(Ity_F64);
9171 IRTemp result = newTemp(Ity_F64);
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_dw0(r1));
9175 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009176 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009177 mkexpr(op2)));
9178 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9179 put_fpr_dw0(r1, mkexpr(result));
9180
9181 return "sdbr";
9182}
9183
florian55085f82012-11-21 00:36:55 +00009184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009185s390_irgen_SEB(UChar r1, IRTemp op2addr)
9186{
9187 IRTemp op1 = newTemp(Ity_F32);
9188 IRTemp op2 = newTemp(Ity_F32);
9189 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009190 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009191
9192 assign(op1, get_fpr_w0(r1));
9193 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009194 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009195 mkexpr(op2)));
9196 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9197 put_fpr_w0(r1, mkexpr(result));
9198
9199 return "seb";
9200}
9201
florian55085f82012-11-21 00:36:55 +00009202static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009203s390_irgen_SDB(UChar r1, IRTemp op2addr)
9204{
9205 IRTemp op1 = newTemp(Ity_F64);
9206 IRTemp op2 = newTemp(Ity_F64);
9207 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009208 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009209
9210 assign(op1, get_fpr_dw0(r1));
9211 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009212 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009213 mkexpr(op2)));
9214 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9215 put_fpr_dw0(r1, mkexpr(result));
9216
9217 return "sdb";
9218}
9219
florian55085f82012-11-21 00:36:55 +00009220static const HChar *
florian12390202012-11-10 22:34:14 +00009221s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9222{
9223 IRTemp op1 = newTemp(Ity_D64);
9224 IRTemp op2 = newTemp(Ity_D64);
9225 IRTemp result = newTemp(Ity_D64);
9226 IRTemp rounding_mode;
9227
9228 vassert(s390_host_has_dfp);
9229 vassert(m4 == 0 || s390_host_has_fpext);
9230 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9231 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9232 rounding_mode = encode_dfp_rounding_mode(m4);
9233 assign(op1, get_dpr_dw0(r2));
9234 assign(op2, get_dpr_dw0(r3));
9235 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9236 mkexpr(op2)));
9237 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9238 put_dpr_dw0(r1, mkexpr(result));
9239
9240 return (m4 == 0) ? "adtr" : "adtra";
9241}
9242
florian55085f82012-11-21 00:36:55 +00009243static const HChar *
floriane38f6412012-12-21 17:32:12 +00009244s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9245{
9246 IRTemp op1 = newTemp(Ity_D128);
9247 IRTemp op2 = newTemp(Ity_D128);
9248 IRTemp result = newTemp(Ity_D128);
9249 IRTemp rounding_mode;
9250
9251 vassert(s390_host_has_dfp);
9252 vassert(m4 == 0 || s390_host_has_fpext);
9253 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9254 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9255 rounding_mode = encode_dfp_rounding_mode(m4);
9256 assign(op1, get_dpr_pair(r2));
9257 assign(op2, get_dpr_pair(r3));
9258 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9259 mkexpr(op2)));
9260 put_dpr_pair(r1, mkexpr(result));
9261
9262 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9263
9264 return (m4 == 0) ? "axtr" : "axtra";
9265}
9266
9267static const HChar *
9268s390_irgen_CDTR(UChar r1, UChar r2)
9269{
9270 IRTemp op1 = newTemp(Ity_D64);
9271 IRTemp op2 = newTemp(Ity_D64);
9272 IRTemp cc_vex = newTemp(Ity_I32);
9273 IRTemp cc_s390 = newTemp(Ity_I32);
9274
9275 assign(op1, get_dpr_dw0(r1));
9276 assign(op2, get_dpr_dw0(r2));
9277 assign(cc_vex, binop(Iop_CmpD64, 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 "cdtr";
9283}
9284
9285static const HChar *
9286s390_irgen_CXTR(UChar r1, UChar r2)
9287{
9288 IRTemp op1 = newTemp(Ity_D128);
9289 IRTemp op2 = newTemp(Ity_D128);
9290 IRTemp cc_vex = newTemp(Ity_I32);
9291 IRTemp cc_s390 = newTemp(Ity_I32);
9292
9293 assign(op1, get_dpr_pair(r1));
9294 assign(op2, get_dpr_pair(r2));
9295 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9296
florian2d3d87f2012-12-21 21:05:17 +00009297 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009298 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9299
9300 return "cxtr";
9301}
9302
9303static const HChar *
florian5f034622013-01-13 02:29:05 +00009304s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9305 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9306{
9307 vassert(s390_host_has_dfp);
9308
9309 if (! s390_host_has_fpext) {
9310 emulation_failure(EmFail_S390X_fpext);
9311 } else {
9312 IRTemp op2 = newTemp(Ity_I32);
9313
9314 assign(op2, get_gpr_w1(r2));
9315 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9316 }
9317 return "cdftr";
9318}
9319
9320static const HChar *
9321s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9322 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9323{
9324 vassert(s390_host_has_dfp);
9325
9326 if (! s390_host_has_fpext) {
9327 emulation_failure(EmFail_S390X_fpext);
9328 } else {
9329 IRTemp op2 = newTemp(Ity_I32);
9330
9331 assign(op2, get_gpr_w1(r2));
9332 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9333 }
9334 return "cxftr";
9335}
9336
9337static const HChar *
floriana887acd2013-02-08 23:32:54 +00009338s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9339 UChar r1, UChar r2)
9340{
9341 IRTemp op2 = newTemp(Ity_I64);
9342
9343 vassert(s390_host_has_dfp);
9344 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9345 emulation_warning(EmWarn_S390X_fpext_rounding);
9346 m3 = S390_DFP_ROUND_PER_FPC_0;
9347 }
9348
9349 assign(op2, get_gpr_dw0(r2));
9350 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9351 mkexpr(op2)));
9352
9353 return (m3 == 0) ? "cdgtr" : "cdgtra";
9354}
9355
9356static const HChar *
9357s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9358 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9359{
9360 IRTemp op2 = newTemp(Ity_I64);
9361
9362 vassert(s390_host_has_dfp);
9363
9364 assign(op2, get_gpr_dw0(r2));
9365 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9366
9367 return "cxgtr";
9368}
9369
9370static const HChar *
florian5f034622013-01-13 02:29:05 +00009371s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9372 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9373{
9374 vassert(s390_host_has_dfp);
9375
9376 if (! s390_host_has_fpext) {
9377 emulation_failure(EmFail_S390X_fpext);
9378 } else {
9379 IRTemp op2 = newTemp(Ity_I32);
9380
9381 assign(op2, get_gpr_w1(r2));
9382 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9383 }
9384 return "cdlftr";
9385}
9386
9387static const HChar *
9388s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9389 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9390{
9391 vassert(s390_host_has_dfp);
9392
9393 if (! s390_host_has_fpext) {
9394 emulation_failure(EmFail_S390X_fpext);
9395 } else {
9396 IRTemp op2 = newTemp(Ity_I32);
9397
9398 assign(op2, get_gpr_w1(r2));
9399 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9400 }
9401 return "cxlftr";
9402}
9403
9404static const HChar *
9405s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9406 UChar r1, UChar r2)
9407{
9408 vassert(s390_host_has_dfp);
9409
9410 if (! s390_host_has_fpext) {
9411 emulation_failure(EmFail_S390X_fpext);
9412 } else {
9413 IRTemp op2 = newTemp(Ity_I64);
9414
9415 assign(op2, get_gpr_dw0(r2));
9416 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9417 mkexpr(encode_dfp_rounding_mode(m3)),
9418 mkexpr(op2)));
9419 }
9420 return "cdlgtr";
9421}
9422
9423static const HChar *
9424s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9425 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9426{
9427 vassert(s390_host_has_dfp);
9428
9429 if (! s390_host_has_fpext) {
9430 emulation_failure(EmFail_S390X_fpext);
9431 } else {
9432 IRTemp op2 = newTemp(Ity_I64);
9433
9434 assign(op2, get_gpr_dw0(r2));
9435 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9436 }
9437 return "cxlgtr";
9438}
9439
9440static const HChar *
9441s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9442 UChar r1, UChar r2)
9443{
9444 vassert(s390_host_has_dfp);
9445
9446 if (! s390_host_has_fpext) {
9447 emulation_failure(EmFail_S390X_fpext);
9448 } else {
9449 IRTemp op = newTemp(Ity_D64);
9450 IRTemp result = newTemp(Ity_I32);
9451 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9452
9453 assign(op, get_dpr_dw0(r2));
9454 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9455 mkexpr(op)));
9456 put_gpr_w1(r1, mkexpr(result));
9457 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9458 }
9459 return "cfdtr";
9460}
9461
9462static const HChar *
9463s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9464 UChar r1, UChar r2)
9465{
9466 vassert(s390_host_has_dfp);
9467
9468 if (! s390_host_has_fpext) {
9469 emulation_failure(EmFail_S390X_fpext);
9470 } else {
9471 IRTemp op = newTemp(Ity_D128);
9472 IRTemp result = newTemp(Ity_I32);
9473 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9474
9475 assign(op, get_dpr_pair(r2));
9476 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9477 mkexpr(op)));
9478 put_gpr_w1(r1, mkexpr(result));
9479 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9480 }
9481 return "cfxtr";
9482}
9483
9484static const HChar *
floriana887acd2013-02-08 23:32:54 +00009485s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9486 UChar r1, UChar r2)
9487{
9488 IRTemp op = newTemp(Ity_D64);
9489 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9490
9491 vassert(s390_host_has_dfp);
9492
9493 /* If fpext is not installed and m3 is in 1:7,
9494 rounding mode performed is unpredictable */
9495 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9496 emulation_warning(EmWarn_S390X_fpext_rounding);
9497 m3 = S390_DFP_ROUND_PER_FPC_0;
9498 }
9499
9500 assign(op, get_dpr_dw0(r2));
9501 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9502 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9503
9504 return "cgdtr";
9505}
9506
9507static const HChar *
9508s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9509 UChar r1, UChar r2)
9510{
9511 IRTemp op = newTemp(Ity_D128);
9512 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9513
9514 vassert(s390_host_has_dfp);
9515
9516 /* If fpext is not installed and m3 is in 1:7,
9517 rounding mode performed is unpredictable */
9518 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9519 emulation_warning(EmWarn_S390X_fpext_rounding);
9520 m3 = S390_DFP_ROUND_PER_FPC_0;
9521 }
9522 assign(op, get_dpr_pair(r2));
9523 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9524 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9525
9526 return "cgxtr";
9527}
9528
9529static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009530s390_irgen_CEDTR(UChar r1, UChar r2)
9531{
9532 IRTemp op1 = newTemp(Ity_D64);
9533 IRTemp op2 = newTemp(Ity_D64);
9534 IRTemp cc_vex = newTemp(Ity_I32);
9535 IRTemp cc_s390 = newTemp(Ity_I32);
9536
9537 vassert(s390_host_has_dfp);
9538 assign(op1, get_dpr_dw0(r1));
9539 assign(op2, get_dpr_dw0(r2));
9540 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9541
9542 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9543 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9544
9545 return "cedtr";
9546}
9547
9548static const HChar *
9549s390_irgen_CEXTR(UChar r1, UChar r2)
9550{
9551 IRTemp op1 = newTemp(Ity_D128);
9552 IRTemp op2 = newTemp(Ity_D128);
9553 IRTemp cc_vex = newTemp(Ity_I32);
9554 IRTemp cc_s390 = newTemp(Ity_I32);
9555
9556 vassert(s390_host_has_dfp);
9557 assign(op1, get_dpr_pair(r1));
9558 assign(op2, get_dpr_pair(r2));
9559 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9560
9561 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9562 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9563
9564 return "cextr";
9565}
9566
9567static const HChar *
florian5f034622013-01-13 02:29:05 +00009568s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9569 UChar r1, UChar r2)
9570{
9571 vassert(s390_host_has_dfp);
9572
9573 if (! s390_host_has_fpext) {
9574 emulation_failure(EmFail_S390X_fpext);
9575 } else {
9576 IRTemp op = newTemp(Ity_D64);
9577 IRTemp result = newTemp(Ity_I32);
9578 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9579
9580 assign(op, get_dpr_dw0(r2));
9581 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9582 mkexpr(op)));
9583 put_gpr_w1(r1, mkexpr(result));
9584 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9585 }
9586 return "clfdtr";
9587}
9588
9589static const HChar *
9590s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9591 UChar r1, UChar r2)
9592{
9593 vassert(s390_host_has_dfp);
9594
9595 if (! s390_host_has_fpext) {
9596 emulation_failure(EmFail_S390X_fpext);
9597 } else {
9598 IRTemp op = newTemp(Ity_D128);
9599 IRTemp result = newTemp(Ity_I32);
9600 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9601
9602 assign(op, get_dpr_pair(r2));
9603 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9604 mkexpr(op)));
9605 put_gpr_w1(r1, mkexpr(result));
9606 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9607 }
9608 return "clfxtr";
9609}
9610
9611static const HChar *
9612s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9613 UChar r1, UChar r2)
9614{
9615 vassert(s390_host_has_dfp);
9616
9617 if (! s390_host_has_fpext) {
9618 emulation_failure(EmFail_S390X_fpext);
9619 } else {
9620 IRTemp op = newTemp(Ity_D64);
9621 IRTemp result = newTemp(Ity_I64);
9622 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9623
9624 assign(op, get_dpr_dw0(r2));
9625 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
9626 mkexpr(op)));
9627 put_gpr_dw0(r1, mkexpr(result));
9628 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
9629 }
9630 return "clgdtr";
9631}
9632
9633static const HChar *
9634s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
9635 UChar r1, UChar r2)
9636{
9637 vassert(s390_host_has_dfp);
9638
9639 if (! s390_host_has_fpext) {
9640 emulation_failure(EmFail_S390X_fpext);
9641 } else {
9642 IRTemp op = newTemp(Ity_D128);
9643 IRTemp result = newTemp(Ity_I64);
9644 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9645
9646 assign(op, get_dpr_pair(r2));
9647 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
9648 mkexpr(op)));
9649 put_gpr_dw0(r1, mkexpr(result));
9650 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
9651 rounding_mode);
9652 }
9653 return "clgxtr";
9654}
9655
9656static const HChar *
florian12390202012-11-10 22:34:14 +00009657s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9658{
9659 IRTemp op1 = newTemp(Ity_D64);
9660 IRTemp op2 = newTemp(Ity_D64);
9661 IRTemp result = newTemp(Ity_D64);
9662 IRTemp rounding_mode;
9663
9664 vassert(s390_host_has_dfp);
9665 vassert(m4 == 0 || s390_host_has_fpext);
9666 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9667 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9668 rounding_mode = encode_dfp_rounding_mode(m4);
9669 assign(op1, get_dpr_dw0(r2));
9670 assign(op2, get_dpr_dw0(r3));
9671 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9672 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009673 put_dpr_dw0(r1, mkexpr(result));
9674
9675 return (m4 == 0) ? "ddtr" : "ddtra";
9676}
9677
florian55085f82012-11-21 00:36:55 +00009678static const HChar *
floriane38f6412012-12-21 17:32:12 +00009679s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9680{
9681 IRTemp op1 = newTemp(Ity_D128);
9682 IRTemp op2 = newTemp(Ity_D128);
9683 IRTemp result = newTemp(Ity_D128);
9684 IRTemp rounding_mode;
9685
9686 vassert(s390_host_has_dfp);
9687 vassert(m4 == 0 || s390_host_has_fpext);
9688 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9689 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9690 rounding_mode = encode_dfp_rounding_mode(m4);
9691 assign(op1, get_dpr_pair(r2));
9692 assign(op2, get_dpr_pair(r3));
9693 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9694 mkexpr(op2)));
9695 put_dpr_pair(r1, mkexpr(result));
9696
9697 return (m4 == 0) ? "dxtr" : "dxtra";
9698}
9699
9700static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009701s390_irgen_ESDTR(UChar r1, UChar r2)
9702{
9703 vassert(s390_host_has_dfp);
9704 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
9705 return "esdtr";
9706}
9707
9708static const HChar *
9709s390_irgen_ESXTR(UChar r1, UChar r2)
9710{
9711 vassert(s390_host_has_dfp);
9712 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
9713 return "esxtr";
9714}
9715
9716static const HChar *
floriane38f6412012-12-21 17:32:12 +00009717s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9718{
9719 IRTemp op = newTemp(Ity_D32);
9720
9721 vassert(s390_host_has_dfp);
9722
9723 assign(op, get_dpr_w0(r2));
9724 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
9725
9726 return "ldetr";
9727}
9728
9729static const HChar *
9730s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9731{
9732 IRTemp op = newTemp(Ity_D64);
9733
9734 assign(op, get_dpr_dw0(r2));
9735 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
9736
9737 return "lxdtr";
9738}
9739
9740static const HChar *
9741s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
9742 UChar r1, UChar r2)
9743{
9744 vassert(s390_host_has_dfp);
9745 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9746 emulation_warning(EmWarn_S390X_fpext_rounding);
9747 m3 = S390_DFP_ROUND_PER_FPC_0;
9748 }
9749 IRTemp result = newTemp(Ity_D64);
9750
9751 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
9752 get_dpr_pair(r2)));
9753 put_dpr_dw0(r1, mkexpr(result));
9754
9755 return "ldxtr";
9756}
9757
9758static const HChar *
9759s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
9760 UChar r1, UChar r2)
9761{
9762 vassert(s390_host_has_dfp);
9763 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9764 emulation_warning(EmWarn_S390X_fpext_rounding);
9765 m3 = S390_DFP_ROUND_PER_FPC_0;
9766 }
9767 IRTemp op = newTemp(Ity_D64);
9768
9769 assign(op, get_dpr_dw0(r2));
9770 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
9771 mkexpr(op)));
9772
9773 return "ledtr";
9774}
9775
9776static const HChar *
9777s390_irgen_LTDTR(UChar r1, UChar r2)
9778{
9779 IRTemp result = newTemp(Ity_D64);
9780
9781 assign(result, get_dpr_dw0(r2));
9782 put_dpr_dw0(r1, mkexpr(result));
9783 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9784
9785 return "ltdtr";
9786}
9787
9788static const HChar *
9789s390_irgen_LTXTR(UChar r1, UChar r2)
9790{
9791 IRTemp result = newTemp(Ity_D128);
9792
9793 assign(result, get_dpr_pair(r2));
9794 put_dpr_pair(r1, mkexpr(result));
9795 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9796
9797 return "ltxtr";
9798}
9799
9800static const HChar *
florian12390202012-11-10 22:34:14 +00009801s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9802{
9803 IRTemp op1 = newTemp(Ity_D64);
9804 IRTemp op2 = newTemp(Ity_D64);
9805 IRTemp result = newTemp(Ity_D64);
9806 IRTemp rounding_mode;
9807
9808 vassert(s390_host_has_dfp);
9809 vassert(m4 == 0 || s390_host_has_fpext);
9810 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9811 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9812 rounding_mode = encode_dfp_rounding_mode(m4);
9813 assign(op1, get_dpr_dw0(r2));
9814 assign(op2, get_dpr_dw0(r3));
9815 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9816 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009817 put_dpr_dw0(r1, mkexpr(result));
9818
9819 return (m4 == 0) ? "mdtr" : "mdtra";
9820}
9821
florian55085f82012-11-21 00:36:55 +00009822static const HChar *
floriane38f6412012-12-21 17:32:12 +00009823s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9824{
9825 IRTemp op1 = newTemp(Ity_D128);
9826 IRTemp op2 = newTemp(Ity_D128);
9827 IRTemp result = newTemp(Ity_D128);
9828 IRTemp rounding_mode;
9829
9830 vassert(s390_host_has_dfp);
9831 vassert(m4 == 0 || s390_host_has_fpext);
9832 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9833 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9834 rounding_mode = encode_dfp_rounding_mode(m4);
9835 assign(op1, get_dpr_pair(r2));
9836 assign(op2, get_dpr_pair(r3));
9837 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
9838 mkexpr(op2)));
9839 put_dpr_pair(r1, mkexpr(result));
9840
9841 return (m4 == 0) ? "mxtr" : "mxtra";
9842}
9843
9844static const HChar *
florian12390202012-11-10 22:34:14 +00009845s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9846{
9847 IRTemp op1 = newTemp(Ity_D64);
9848 IRTemp op2 = newTemp(Ity_D64);
9849 IRTemp result = newTemp(Ity_D64);
9850 IRTemp rounding_mode;
9851
9852 vassert(s390_host_has_dfp);
9853 vassert(m4 == 0 || s390_host_has_fpext);
9854 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9855 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9856 rounding_mode = encode_dfp_rounding_mode(m4);
9857 assign(op1, get_dpr_dw0(r2));
9858 assign(op2, get_dpr_dw0(r3));
9859 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9860 mkexpr(op2)));
9861 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9862 put_dpr_dw0(r1, mkexpr(result));
9863
9864 return (m4 == 0) ? "sdtr" : "sdtra";
9865}
9866
floriane38f6412012-12-21 17:32:12 +00009867static const HChar *
9868s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9869{
9870 IRTemp op1 = newTemp(Ity_D128);
9871 IRTemp op2 = newTemp(Ity_D128);
9872 IRTemp result = newTemp(Ity_D128);
9873 IRTemp rounding_mode;
9874
9875 vassert(s390_host_has_dfp);
9876 vassert(m4 == 0 || s390_host_has_fpext);
9877 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9878 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9879 rounding_mode = encode_dfp_rounding_mode(m4);
9880 assign(op1, get_dpr_pair(r2));
9881 assign(op2, get_dpr_pair(r3));
9882 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
9883 mkexpr(op2)));
9884 put_dpr_pair(r1, mkexpr(result));
9885
9886 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9887
9888 return (m4 == 0) ? "sxtr" : "sxtra";
9889}
sewardj2019a972011-03-07 16:04:07 +00009890
florian55085f82012-11-21 00:36:55 +00009891static const HChar *
florian1b901d42013-01-01 22:19:24 +00009892s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
9893{
9894 IRTemp op = newTemp(Ity_D64);
9895
9896 vassert(s390_host_has_dfp);
9897
9898 assign(op, get_dpr_dw0(r3));
9899 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
9900 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9901
9902 return "sldt";
9903}
9904
9905static const HChar *
9906s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
9907{
9908 IRTemp op = newTemp(Ity_D128);
9909
9910 vassert(s390_host_has_dfp);
9911
9912 assign(op, get_dpr_pair(r3));
9913 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
9914 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9915
9916 return "slxt";
9917}
9918
9919static const HChar *
9920s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
9921{
9922 IRTemp op = newTemp(Ity_D64);
9923
9924 vassert(s390_host_has_dfp);
9925
9926 assign(op, get_dpr_dw0(r3));
9927 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
9928 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9929
9930 return "srdt";
9931}
9932
9933static const HChar *
9934s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
9935{
9936 IRTemp op = newTemp(Ity_D128);
9937
9938 vassert(s390_host_has_dfp);
9939
9940 assign(op, get_dpr_pair(r3));
9941 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
9942 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9943
9944 return "srxt";
9945}
9946
9947static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009948s390_irgen_TDCET(UChar r1, IRTemp op2addr)
9949{
9950 IRTemp value = newTemp(Ity_D32);
9951
9952 vassert(s390_host_has_dfp);
9953 assign(value, get_dpr_w0(r1));
9954
9955 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
9956
9957 return "tdcet";
9958}
9959
9960static const HChar *
9961s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
9962{
9963 IRTemp value = newTemp(Ity_D64);
9964
9965 vassert(s390_host_has_dfp);
9966 assign(value, get_dpr_dw0(r1));
9967
9968 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
9969
9970 return "tdcdt";
9971}
9972
9973static const HChar *
9974s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
9975{
9976 IRTemp value = newTemp(Ity_D128);
9977
9978 vassert(s390_host_has_dfp);
9979 assign(value, get_dpr_pair(r1));
9980
9981 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
9982
9983 return "tdcxt";
9984}
9985
9986static const HChar *
9987s390_irgen_TDGET(UChar r1, IRTemp op2addr)
9988{
9989 IRTemp value = newTemp(Ity_D32);
9990
9991 vassert(s390_host_has_dfp);
9992 assign(value, get_dpr_w0(r1));
9993
9994 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
9995
9996 return "tdget";
9997}
9998
9999static const HChar *
10000s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10001{
10002 IRTemp value = newTemp(Ity_D64);
10003
10004 vassert(s390_host_has_dfp);
10005 assign(value, get_dpr_dw0(r1));
10006
10007 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10008
10009 return "tdgdt";
10010}
10011
10012static const HChar *
10013s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10014{
10015 IRTemp value = newTemp(Ity_D128);
10016
10017 vassert(s390_host_has_dfp);
10018 assign(value, get_dpr_pair(r1));
10019
10020 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10021
10022 return "tdgxt";
10023}
10024
10025static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010026s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10027{
florian79e839e2012-05-05 02:20:30 +000010028 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010029
florian79e839e2012-05-05 02:20:30 +000010030 assign(len, mkU64(length));
10031 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010032
10033 return "clc";
10034}
10035
florian55085f82012-11-21 00:36:55 +000010036static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010037s390_irgen_CLCL(UChar r1, UChar r2)
10038{
10039 IRTemp addr1 = newTemp(Ity_I64);
10040 IRTemp addr2 = newTemp(Ity_I64);
10041 IRTemp addr1_load = newTemp(Ity_I64);
10042 IRTemp addr2_load = newTemp(Ity_I64);
10043 IRTemp len1 = newTemp(Ity_I32);
10044 IRTemp len2 = newTemp(Ity_I32);
10045 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10046 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10047 IRTemp single1 = newTemp(Ity_I8);
10048 IRTemp single2 = newTemp(Ity_I8);
10049 IRTemp pad = newTemp(Ity_I8);
10050
10051 assign(addr1, get_gpr_dw0(r1));
10052 assign(r1p1, get_gpr_w1(r1 + 1));
10053 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10054 assign(addr2, get_gpr_dw0(r2));
10055 assign(r2p1, get_gpr_w1(r2 + 1));
10056 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10057 assign(pad, get_gpr_b4(r2 + 1));
10058
10059 /* len1 == 0 and len2 == 0? Exit */
10060 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010061 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10062 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010063
10064 /* Because mkite evaluates both the then-clause and the else-clause
10065 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10066 may be NULL and loading from there would segfault. So we provide a
10067 valid dummy address in that case. Loading from there does no harm and
10068 the value will be discarded at runtime. */
10069 assign(addr1_load,
10070 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10071 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10072 assign(single1,
10073 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10074 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10075
10076 assign(addr2_load,
10077 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10078 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10079 assign(single2,
10080 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10081 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10082
10083 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10084 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010085 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010086
10087 /* Update len1 and addr1, unless len1 == 0. */
10088 put_gpr_dw0(r1,
10089 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10090 mkexpr(addr1),
10091 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10092
10093 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10094 put_gpr_w1(r1 + 1,
10095 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10096 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10097 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10098
10099 /* Update len2 and addr2, unless len2 == 0. */
10100 put_gpr_dw0(r2,
10101 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10102 mkexpr(addr2),
10103 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10104
10105 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10106 put_gpr_w1(r2 + 1,
10107 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10108 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10109 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10110
florian6820ba52012-07-26 02:01:50 +000010111 iterate();
florianb0c9a132011-09-08 15:37:39 +000010112
10113 return "clcl";
10114}
10115
florian55085f82012-11-21 00:36:55 +000010116static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010117s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10118{
10119 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10120
10121 addr1 = newTemp(Ity_I64);
10122 addr3 = newTemp(Ity_I64);
10123 addr1_load = newTemp(Ity_I64);
10124 addr3_load = newTemp(Ity_I64);
10125 len1 = newTemp(Ity_I64);
10126 len3 = newTemp(Ity_I64);
10127 single1 = newTemp(Ity_I8);
10128 single3 = newTemp(Ity_I8);
10129
10130 assign(addr1, get_gpr_dw0(r1));
10131 assign(len1, get_gpr_dw0(r1 + 1));
10132 assign(addr3, get_gpr_dw0(r3));
10133 assign(len3, get_gpr_dw0(r3 + 1));
10134
10135 /* len1 == 0 and len3 == 0? Exit */
10136 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010137 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10138 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010139
10140 /* A mux requires both ways to be possible. This is a way to prevent clcle
10141 from reading from addr1 if it should read from the pad. Since the pad
10142 has no address, just read from the instruction, we discard that anyway */
10143 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010144 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10145 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010146
10147 /* same for addr3 */
10148 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010149 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10150 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010151
10152 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010153 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10154 unop(Iop_64to8, mkexpr(pad2)),
10155 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010156
10157 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010158 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10159 unop(Iop_64to8, mkexpr(pad2)),
10160 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010161
10162 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10163 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010164 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010165
10166 /* If a length in 0 we must not change this length and the address */
10167 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010168 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10169 mkexpr(addr1),
10170 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010171
10172 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010173 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10174 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010175
10176 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010177 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10178 mkexpr(addr3),
10179 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010180
10181 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010182 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10183 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010184
florian6820ba52012-07-26 02:01:50 +000010185 iterate();
sewardj2019a972011-03-07 16:04:07 +000010186
10187 return "clcle";
10188}
floriana64c2432011-07-16 02:11:50 +000010189
florianb0bf6602012-05-05 00:01:16 +000010190
sewardj2019a972011-03-07 16:04:07 +000010191static void
10192s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10193{
florianb0bf6602012-05-05 00:01:16 +000010194 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10195}
sewardj2019a972011-03-07 16:04:07 +000010196
sewardj2019a972011-03-07 16:04:07 +000010197
florianb0bf6602012-05-05 00:01:16 +000010198static void
10199s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10200{
10201 s390_irgen_xonc(Iop_And8, length, start1, start2);
10202}
sewardj2019a972011-03-07 16:04:07 +000010203
sewardj2019a972011-03-07 16:04:07 +000010204
florianb0bf6602012-05-05 00:01:16 +000010205static void
10206s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10207{
10208 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010209}
10210
10211
10212static void
10213s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10214{
10215 IRTemp current1 = newTemp(Ity_I8);
10216 IRTemp current2 = newTemp(Ity_I8);
10217 IRTemp counter = newTemp(Ity_I64);
10218
10219 assign(counter, get_counter_dw0());
10220 put_counter_dw0(mkU64(0));
10221
10222 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10223 mkexpr(counter))));
10224 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10225 mkexpr(counter))));
10226 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10227 False);
10228
10229 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010230 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010231
10232 /* Check for end of field */
10233 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010234 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010235 put_counter_dw0(mkU64(0));
10236}
10237
10238static void
10239s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10240{
10241 IRTemp counter = newTemp(Ity_I64);
10242
10243 assign(counter, get_counter_dw0());
10244
10245 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10246 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10247
10248 /* Check for end of field */
10249 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010250 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010251 put_counter_dw0(mkU64(0));
10252}
10253
florianf87d4fb2012-05-05 02:55:24 +000010254static void
10255s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10256{
10257 IRTemp op = newTemp(Ity_I8);
10258 IRTemp op1 = newTemp(Ity_I8);
10259 IRTemp result = newTemp(Ity_I64);
10260 IRTemp counter = newTemp(Ity_I64);
10261
10262 assign(counter, get_counter_dw0());
10263
10264 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10265
10266 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10267
10268 assign(op1, load(Ity_I8, mkexpr(result)));
10269 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10270
10271 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010272 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010273 put_counter_dw0(mkU64(0));
10274}
sewardj2019a972011-03-07 16:04:07 +000010275
10276
10277static void
10278s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010279 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010280 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010281{
10282 struct SS {
10283 unsigned int op : 8;
10284 unsigned int l : 8;
10285 unsigned int b1 : 4;
10286 unsigned int d1 : 12;
10287 unsigned int b2 : 4;
10288 unsigned int d2 : 12;
10289 };
10290 union {
10291 struct SS dec;
10292 unsigned long bytes;
10293 } ss;
10294 IRTemp cond;
10295 IRDirty *d;
10296 IRTemp torun;
10297
10298 IRTemp start1 = newTemp(Ity_I64);
10299 IRTemp start2 = newTemp(Ity_I64);
10300 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10301 cond = newTemp(Ity_I1);
10302 torun = newTemp(Ity_I64);
10303
10304 assign(torun, load(Ity_I64, mkexpr(addr2)));
10305 /* Start with a check that the saved code is still correct */
10306 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10307 /* If not, save the new value */
10308 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10309 mkIRExprVec_1(mkexpr(torun)));
10310 d->guard = mkexpr(cond);
10311 stmt(IRStmt_Dirty(d));
10312
10313 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010314 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10315 mkU64(guest_IA_curr_instr)));
10316 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010317 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010318
10319 ss.bytes = last_execute_target;
10320 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10321 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10322 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10323 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10324 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10325 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10326 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010327
sewardj2019a972011-03-07 16:04:07 +000010328 last_execute_target = 0;
10329}
10330
florian55085f82012-11-21 00:36:55 +000010331static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010332s390_irgen_EX(UChar r1, IRTemp addr2)
10333{
10334 switch(last_execute_target & 0xff00000000000000ULL) {
10335 case 0:
10336 {
10337 /* no code information yet */
10338 IRDirty *d;
10339
10340 /* so safe the code... */
10341 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10342 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10343 stmt(IRStmt_Dirty(d));
10344 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010345 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10346 mkU64(guest_IA_curr_instr)));
10347 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010348 restart_if(IRExpr_Const(IRConst_U1(True)));
10349
sewardj2019a972011-03-07 16:04:07 +000010350 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010351 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010352 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000010353 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000010354 break;
10355 }
10356
10357 case 0xd200000000000000ULL:
10358 /* special case MVC */
10359 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010360 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010361
10362 case 0xd500000000000000ULL:
10363 /* special case CLC */
10364 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010365 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010366
10367 case 0xd700000000000000ULL:
10368 /* special case XC */
10369 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010370 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010371
florianb0bf6602012-05-05 00:01:16 +000010372 case 0xd600000000000000ULL:
10373 /* special case OC */
10374 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010375 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010376
10377 case 0xd400000000000000ULL:
10378 /* special case NC */
10379 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010380 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010381
florianf87d4fb2012-05-05 02:55:24 +000010382 case 0xdc00000000000000ULL:
10383 /* special case TR */
10384 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010385 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010386
sewardj2019a972011-03-07 16:04:07 +000010387 default:
10388 {
10389 /* everything else will get a self checking prefix that also checks the
10390 register content */
10391 IRDirty *d;
10392 UChar *bytes;
10393 IRTemp cond;
10394 IRTemp orperand;
10395 IRTemp torun;
10396
10397 cond = newTemp(Ity_I1);
10398 orperand = newTemp(Ity_I64);
10399 torun = newTemp(Ity_I64);
10400
10401 if (r1 == 0)
10402 assign(orperand, mkU64(0));
10403 else
10404 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10405 /* This code is going to be translated */
10406 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10407 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10408
10409 /* Start with a check that saved code is still correct */
10410 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10411 mkU64(last_execute_target)));
10412 /* If not, save the new value */
10413 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10414 mkIRExprVec_1(mkexpr(torun)));
10415 d->guard = mkexpr(cond);
10416 stmt(IRStmt_Dirty(d));
10417
10418 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010419 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10420 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010421 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010422
10423 /* Now comes the actual translation */
10424 bytes = (UChar *) &last_execute_target;
10425 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10426 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010427 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010428 vex_printf(" which was executed by\n");
10429 /* dont make useless translations in the next execute */
10430 last_execute_target = 0;
10431 }
10432 }
10433 return "ex";
10434}
10435
florian55085f82012-11-21 00:36:55 +000010436static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010437s390_irgen_EXRL(UChar r1, UInt offset)
10438{
10439 IRTemp addr = newTemp(Ity_I64);
10440 /* we might save one round trip because we know the target */
10441 if (!last_execute_target)
10442 last_execute_target = *(ULong *)(HWord)
10443 (guest_IA_curr_instr + offset * 2UL);
10444 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10445 s390_irgen_EX(r1, addr);
10446 return "exrl";
10447}
10448
florian55085f82012-11-21 00:36:55 +000010449static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010450s390_irgen_IPM(UChar r1)
10451{
10452 // As long as we dont support SPM, lets just assume 0 as program mask
10453 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
10454 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
10455
10456 return "ipm";
10457}
10458
10459
florian55085f82012-11-21 00:36:55 +000010460static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010461s390_irgen_SRST(UChar r1, UChar r2)
10462{
10463 IRTemp address = newTemp(Ity_I64);
10464 IRTemp next = newTemp(Ity_I64);
10465 IRTemp delim = newTemp(Ity_I8);
10466 IRTemp counter = newTemp(Ity_I64);
10467 IRTemp byte = newTemp(Ity_I8);
10468
10469 assign(address, get_gpr_dw0(r2));
10470 assign(next, get_gpr_dw0(r1));
10471
10472 assign(counter, get_counter_dw0());
10473 put_counter_dw0(mkU64(0));
10474
10475 // start = next? CC=2 and out r1 and r2 unchanged
10476 s390_cc_set(2);
10477 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010478 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000010479
10480 assign(byte, load(Ity_I8, mkexpr(address)));
10481 assign(delim, get_gpr_b7(0));
10482
10483 // byte = delim? CC=1, R1=address
10484 s390_cc_set(1);
10485 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000010486 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010487
10488 // else: all equal, no end yet, loop
10489 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10490 put_gpr_dw0(r1, mkexpr(next));
10491 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010492
florian6820ba52012-07-26 02:01:50 +000010493 iterate();
sewardj2019a972011-03-07 16:04:07 +000010494
10495 return "srst";
10496}
10497
florian55085f82012-11-21 00:36:55 +000010498static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010499s390_irgen_CLST(UChar r1, UChar r2)
10500{
10501 IRTemp address1 = newTemp(Ity_I64);
10502 IRTemp address2 = newTemp(Ity_I64);
10503 IRTemp end = newTemp(Ity_I8);
10504 IRTemp counter = newTemp(Ity_I64);
10505 IRTemp byte1 = newTemp(Ity_I8);
10506 IRTemp byte2 = newTemp(Ity_I8);
10507
10508 assign(address1, get_gpr_dw0(r1));
10509 assign(address2, get_gpr_dw0(r2));
10510 assign(end, get_gpr_b7(0));
10511 assign(counter, get_counter_dw0());
10512 put_counter_dw0(mkU64(0));
10513 assign(byte1, load(Ity_I8, mkexpr(address1)));
10514 assign(byte2, load(Ity_I8, mkexpr(address2)));
10515
10516 // end in both? all equal, reset r1 and r2 to start values
10517 s390_cc_set(0);
10518 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
10519 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010520 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10521 binop(Iop_Or8,
10522 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10523 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010524
10525 put_gpr_dw0(r1, mkexpr(address1));
10526 put_gpr_dw0(r2, mkexpr(address2));
10527
10528 // End found in string1
10529 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010530 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010531
10532 // End found in string2
10533 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010534 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010535
10536 // string1 < string2
10537 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010538 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10539 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010540
10541 // string2 < string1
10542 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010543 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10544 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010545
10546 // else: all equal, no end yet, loop
10547 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10548 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10549 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010550
florian6820ba52012-07-26 02:01:50 +000010551 iterate();
sewardj2019a972011-03-07 16:04:07 +000010552
10553 return "clst";
10554}
10555
10556static void
10557s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10558{
10559 UChar reg;
10560 IRTemp addr = newTemp(Ity_I64);
10561
10562 assign(addr, mkexpr(op2addr));
10563 reg = r1;
10564 do {
10565 IRTemp old = addr;
10566
10567 reg %= 16;
10568 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10569 addr = newTemp(Ity_I64);
10570 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10571 reg++;
10572 } while (reg != (r3 + 1));
10573}
10574
florian55085f82012-11-21 00:36:55 +000010575static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010576s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10577{
10578 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10579
10580 return "lm";
10581}
10582
florian55085f82012-11-21 00:36:55 +000010583static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010584s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
10585{
10586 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10587
10588 return "lmy";
10589}
10590
florian55085f82012-11-21 00:36:55 +000010591static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010592s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
10593{
10594 UChar reg;
10595 IRTemp addr = newTemp(Ity_I64);
10596
10597 assign(addr, mkexpr(op2addr));
10598 reg = r1;
10599 do {
10600 IRTemp old = addr;
10601
10602 reg %= 16;
10603 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
10604 addr = newTemp(Ity_I64);
10605 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10606 reg++;
10607 } while (reg != (r3 + 1));
10608
10609 return "lmh";
10610}
10611
florian55085f82012-11-21 00:36:55 +000010612static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010613s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
10614{
10615 UChar reg;
10616 IRTemp addr = newTemp(Ity_I64);
10617
10618 assign(addr, mkexpr(op2addr));
10619 reg = r1;
10620 do {
10621 IRTemp old = addr;
10622
10623 reg %= 16;
10624 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
10625 addr = newTemp(Ity_I64);
10626 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10627 reg++;
10628 } while (reg != (r3 + 1));
10629
10630 return "lmg";
10631}
10632
10633static void
10634s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10635{
10636 UChar reg;
10637 IRTemp addr = newTemp(Ity_I64);
10638
10639 assign(addr, mkexpr(op2addr));
10640 reg = r1;
10641 do {
10642 IRTemp old = addr;
10643
10644 reg %= 16;
10645 store(mkexpr(addr), get_gpr_w1(reg));
10646 addr = newTemp(Ity_I64);
10647 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10648 reg++;
10649 } while( reg != (r3 + 1));
10650}
10651
florian55085f82012-11-21 00:36:55 +000010652static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010653s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
10654{
10655 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10656
10657 return "stm";
10658}
10659
florian55085f82012-11-21 00:36:55 +000010660static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010661s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
10662{
10663 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10664
10665 return "stmy";
10666}
10667
florian55085f82012-11-21 00:36:55 +000010668static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010669s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
10670{
10671 UChar reg;
10672 IRTemp addr = newTemp(Ity_I64);
10673
10674 assign(addr, mkexpr(op2addr));
10675 reg = r1;
10676 do {
10677 IRTemp old = addr;
10678
10679 reg %= 16;
10680 store(mkexpr(addr), get_gpr_w0(reg));
10681 addr = newTemp(Ity_I64);
10682 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10683 reg++;
10684 } while( reg != (r3 + 1));
10685
10686 return "stmh";
10687}
10688
florian55085f82012-11-21 00:36:55 +000010689static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010690s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
10691{
10692 UChar reg;
10693 IRTemp addr = newTemp(Ity_I64);
10694
10695 assign(addr, mkexpr(op2addr));
10696 reg = r1;
10697 do {
10698 IRTemp old = addr;
10699
10700 reg %= 16;
10701 store(mkexpr(addr), get_gpr_dw0(reg));
10702 addr = newTemp(Ity_I64);
10703 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10704 reg++;
10705 } while( reg != (r3 + 1));
10706
10707 return "stmg";
10708}
10709
10710static void
florianb0bf6602012-05-05 00:01:16 +000010711s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000010712{
10713 IRTemp old1 = newTemp(Ity_I8);
10714 IRTemp old2 = newTemp(Ity_I8);
10715 IRTemp new1 = newTemp(Ity_I8);
10716 IRTemp counter = newTemp(Ity_I32);
10717 IRTemp addr1 = newTemp(Ity_I64);
10718
10719 assign(counter, get_counter_w0());
10720
10721 assign(addr1, binop(Iop_Add64, mkexpr(start1),
10722 unop(Iop_32Uto64, mkexpr(counter))));
10723
10724 assign(old1, load(Ity_I8, mkexpr(addr1)));
10725 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10726 unop(Iop_32Uto64,mkexpr(counter)))));
10727 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
10728
10729 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000010730 if (op == Iop_Xor8) {
10731 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000010732 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
10733 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000010734 } else
10735 store(mkexpr(addr1), mkexpr(new1));
10736 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
10737 get_counter_w1()));
10738
10739 /* Check for end of field */
10740 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010741 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010742 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
10743 False);
10744 put_counter_dw0(mkU64(0));
10745}
10746
florian55085f82012-11-21 00:36:55 +000010747static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010748s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
10749{
florianb0bf6602012-05-05 00:01:16 +000010750 IRTemp len = newTemp(Ity_I32);
10751
10752 assign(len, mkU32(length));
10753 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010754
10755 return "xc";
10756}
10757
sewardjb63967e2011-03-24 08:50:04 +000010758static void
10759s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
10760{
10761 IRTemp counter = newTemp(Ity_I32);
10762 IRTemp start = newTemp(Ity_I64);
10763 IRTemp addr = newTemp(Ity_I64);
10764
10765 assign(start,
10766 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
10767
10768 if (length < 8) {
10769 UInt i;
10770
10771 for (i = 0; i <= length; ++i) {
10772 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
10773 }
10774 } else {
10775 assign(counter, get_counter_w0());
10776
10777 assign(addr, binop(Iop_Add64, mkexpr(start),
10778 unop(Iop_32Uto64, mkexpr(counter))));
10779
10780 store(mkexpr(addr), mkU8(0));
10781
10782 /* Check for end of field */
10783 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010784 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000010785
10786 /* Reset counter */
10787 put_counter_dw0(mkU64(0));
10788 }
10789
10790 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
10791
sewardj7ee97522011-05-09 21:45:04 +000010792 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000010793 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
10794}
10795
florian55085f82012-11-21 00:36:55 +000010796static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010797s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
10798{
florianb0bf6602012-05-05 00:01:16 +000010799 IRTemp len = newTemp(Ity_I32);
10800
10801 assign(len, mkU32(length));
10802 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010803
10804 return "nc";
10805}
10806
florian55085f82012-11-21 00:36:55 +000010807static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010808s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
10809{
florianb0bf6602012-05-05 00:01:16 +000010810 IRTemp len = newTemp(Ity_I32);
10811
10812 assign(len, mkU32(length));
10813 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010814
10815 return "oc";
10816}
10817
10818
florian55085f82012-11-21 00:36:55 +000010819static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010820s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
10821{
florian79e839e2012-05-05 02:20:30 +000010822 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010823
florian79e839e2012-05-05 02:20:30 +000010824 assign(len, mkU64(length));
10825 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010826
10827 return "mvc";
10828}
10829
florian55085f82012-11-21 00:36:55 +000010830static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010831s390_irgen_MVCL(UChar r1, UChar r2)
10832{
10833 IRTemp addr1 = newTemp(Ity_I64);
10834 IRTemp addr2 = newTemp(Ity_I64);
10835 IRTemp addr2_load = newTemp(Ity_I64);
10836 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10837 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10838 IRTemp len1 = newTemp(Ity_I32);
10839 IRTemp len2 = newTemp(Ity_I32);
10840 IRTemp pad = newTemp(Ity_I8);
10841 IRTemp single = newTemp(Ity_I8);
10842
10843 assign(addr1, get_gpr_dw0(r1));
10844 assign(r1p1, get_gpr_w1(r1 + 1));
10845 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10846 assign(addr2, get_gpr_dw0(r2));
10847 assign(r2p1, get_gpr_w1(r2 + 1));
10848 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10849 assign(pad, get_gpr_b4(r2 + 1));
10850
10851 /* len1 == 0 ? */
10852 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010853 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010854
10855 /* Check for destructive overlap:
10856 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
10857 s390_cc_set(3);
10858 IRTemp cond1 = newTemp(Ity_I32);
10859 assign(cond1, unop(Iop_1Uto32,
10860 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
10861 IRTemp cond2 = newTemp(Ity_I32);
10862 assign(cond2, unop(Iop_1Uto32,
10863 binop(Iop_CmpLT64U, mkexpr(addr1),
10864 binop(Iop_Add64, mkexpr(addr2),
10865 unop(Iop_32Uto64, mkexpr(len1))))));
10866 IRTemp cond3 = newTemp(Ity_I32);
10867 assign(cond3, unop(Iop_1Uto32,
10868 binop(Iop_CmpLT64U,
10869 mkexpr(addr1),
10870 binop(Iop_Add64, mkexpr(addr2),
10871 unop(Iop_32Uto64, mkexpr(len2))))));
10872
florian6820ba52012-07-26 02:01:50 +000010873 next_insn_if(binop(Iop_CmpEQ32,
10874 binop(Iop_And32,
10875 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10876 mkexpr(cond3)),
10877 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010878
10879 /* See s390_irgen_CLCL for explanation why we cannot load directly
10880 and need two steps. */
10881 assign(addr2_load,
10882 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10883 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10884 assign(single,
10885 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10886 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10887
10888 store(mkexpr(addr1), mkexpr(single));
10889
10890 /* Update addr1 and len1 */
10891 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10892 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10893
10894 /* Update addr2 and len2 */
10895 put_gpr_dw0(r2,
10896 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10897 mkexpr(addr2),
10898 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10899
10900 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10901 put_gpr_w1(r2 + 1,
10902 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10903 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10904 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10905
10906 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010907 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010908
10909 return "mvcl";
10910}
10911
10912
florian55085f82012-11-21 00:36:55 +000010913static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010914s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10915{
10916 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10917
10918 addr1 = newTemp(Ity_I64);
10919 addr3 = newTemp(Ity_I64);
10920 addr3_load = newTemp(Ity_I64);
10921 len1 = newTemp(Ity_I64);
10922 len3 = newTemp(Ity_I64);
10923 single = newTemp(Ity_I8);
10924
10925 assign(addr1, get_gpr_dw0(r1));
10926 assign(len1, get_gpr_dw0(r1 + 1));
10927 assign(addr3, get_gpr_dw0(r3));
10928 assign(len3, get_gpr_dw0(r3 + 1));
10929
10930 // len1 == 0 ?
10931 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010932 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010933
10934 /* This is a hack to prevent mvcle from reading from addr3 if it
10935 should read from the pad. Since the pad has no address, just
10936 read from the instruction, we discard that anyway */
10937 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010938 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10939 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010940
10941 assign(single,
florian6ad49522011-09-09 02:38:55 +000010942 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10943 unop(Iop_64to8, mkexpr(pad2)),
10944 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010945 store(mkexpr(addr1), mkexpr(single));
10946
10947 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10948
10949 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10950
10951 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010952 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10953 mkexpr(addr3),
10954 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010955
10956 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010957 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10958 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010959
sewardj2019a972011-03-07 16:04:07 +000010960 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010961 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010962
10963 return "mvcle";
10964}
10965
florian55085f82012-11-21 00:36:55 +000010966static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010967s390_irgen_MVST(UChar r1, UChar r2)
10968{
10969 IRTemp addr1 = newTemp(Ity_I64);
10970 IRTemp addr2 = newTemp(Ity_I64);
10971 IRTemp end = newTemp(Ity_I8);
10972 IRTemp byte = newTemp(Ity_I8);
10973 IRTemp counter = newTemp(Ity_I64);
10974
10975 assign(addr1, get_gpr_dw0(r1));
10976 assign(addr2, get_gpr_dw0(r2));
10977 assign(counter, get_counter_dw0());
10978 assign(end, get_gpr_b7(0));
10979 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10980 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10981
10982 // We use unlimited as cpu-determined number
10983 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010984 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010985
10986 // and always set cc=1 at the end + update r1
10987 s390_cc_set(1);
10988 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10989 put_counter_dw0(mkU64(0));
10990
10991 return "mvst";
10992}
10993
10994static void
10995s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10996{
10997 IRTemp op1 = newTemp(Ity_I64);
10998 IRTemp result = newTemp(Ity_I64);
10999
11000 assign(op1, binop(Iop_32HLto64,
11001 get_gpr_w1(r1), // high 32 bits
11002 get_gpr_w1(r1 + 1))); // low 32 bits
11003 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11004 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11005 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11006}
11007
11008static void
11009s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11010{
11011 IRTemp op1 = newTemp(Ity_I128);
11012 IRTemp result = newTemp(Ity_I128);
11013
11014 assign(op1, binop(Iop_64HLto128,
11015 get_gpr_dw0(r1), // high 64 bits
11016 get_gpr_dw0(r1 + 1))); // low 64 bits
11017 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11018 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11019 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11020}
11021
11022static void
11023s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11024{
11025 IRTemp op1 = newTemp(Ity_I64);
11026 IRTemp result = newTemp(Ity_I128);
11027
11028 assign(op1, get_gpr_dw0(r1 + 1));
11029 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11030 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11031 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11032}
11033
florian55085f82012-11-21 00:36:55 +000011034static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011035s390_irgen_DR(UChar r1, UChar r2)
11036{
11037 IRTemp op2 = newTemp(Ity_I32);
11038
11039 assign(op2, get_gpr_w1(r2));
11040
11041 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11042
11043 return "dr";
11044}
11045
florian55085f82012-11-21 00:36:55 +000011046static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011047s390_irgen_D(UChar r1, IRTemp op2addr)
11048{
11049 IRTemp op2 = newTemp(Ity_I32);
11050
11051 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11052
11053 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11054
11055 return "d";
11056}
11057
florian55085f82012-11-21 00:36:55 +000011058static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011059s390_irgen_DLR(UChar r1, UChar r2)
11060{
11061 IRTemp op2 = newTemp(Ity_I32);
11062
11063 assign(op2, get_gpr_w1(r2));
11064
11065 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11066
florian7cd1cde2012-08-16 23:57:43 +000011067 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011068}
11069
florian55085f82012-11-21 00:36:55 +000011070static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011071s390_irgen_DL(UChar r1, IRTemp op2addr)
11072{
11073 IRTemp op2 = newTemp(Ity_I32);
11074
11075 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11076
11077 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11078
11079 return "dl";
11080}
11081
florian55085f82012-11-21 00:36:55 +000011082static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011083s390_irgen_DLG(UChar r1, IRTemp op2addr)
11084{
11085 IRTemp op2 = newTemp(Ity_I64);
11086
11087 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11088
11089 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11090
11091 return "dlg";
11092}
11093
florian55085f82012-11-21 00:36:55 +000011094static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011095s390_irgen_DLGR(UChar r1, UChar r2)
11096{
11097 IRTemp op2 = newTemp(Ity_I64);
11098
11099 assign(op2, get_gpr_dw0(r2));
11100
11101 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11102
11103 return "dlgr";
11104}
11105
florian55085f82012-11-21 00:36:55 +000011106static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011107s390_irgen_DSGR(UChar r1, UChar r2)
11108{
11109 IRTemp op2 = newTemp(Ity_I64);
11110
11111 assign(op2, get_gpr_dw0(r2));
11112
11113 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11114
11115 return "dsgr";
11116}
11117
florian55085f82012-11-21 00:36:55 +000011118static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011119s390_irgen_DSG(UChar r1, IRTemp op2addr)
11120{
11121 IRTemp op2 = newTemp(Ity_I64);
11122
11123 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11124
11125 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11126
11127 return "dsg";
11128}
11129
florian55085f82012-11-21 00:36:55 +000011130static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011131s390_irgen_DSGFR(UChar r1, UChar r2)
11132{
11133 IRTemp op2 = newTemp(Ity_I64);
11134
11135 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11136
11137 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11138
11139 return "dsgfr";
11140}
11141
florian55085f82012-11-21 00:36:55 +000011142static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011143s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11144{
11145 IRTemp op2 = newTemp(Ity_I64);
11146
11147 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11148
11149 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11150
11151 return "dsgf";
11152}
11153
11154static void
11155s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11156{
11157 UChar reg;
11158 IRTemp addr = newTemp(Ity_I64);
11159
11160 assign(addr, mkexpr(op2addr));
11161 reg = r1;
11162 do {
11163 IRTemp old = addr;
11164
11165 reg %= 16;
11166 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11167 addr = newTemp(Ity_I64);
11168 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11169 reg++;
11170 } while (reg != (r3 + 1));
11171}
11172
florian55085f82012-11-21 00:36:55 +000011173static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011174s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11175{
11176 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11177
11178 return "lam";
11179}
11180
florian55085f82012-11-21 00:36:55 +000011181static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011182s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11183{
11184 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11185
11186 return "lamy";
11187}
11188
11189static void
11190s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11191{
11192 UChar reg;
11193 IRTemp addr = newTemp(Ity_I64);
11194
11195 assign(addr, mkexpr(op2addr));
11196 reg = r1;
11197 do {
11198 IRTemp old = addr;
11199
11200 reg %= 16;
11201 store(mkexpr(addr), get_ar_w0(reg));
11202 addr = newTemp(Ity_I64);
11203 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11204 reg++;
11205 } while (reg != (r3 + 1));
11206}
11207
florian55085f82012-11-21 00:36:55 +000011208static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011209s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11210{
11211 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11212
11213 return "stam";
11214}
11215
florian55085f82012-11-21 00:36:55 +000011216static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011217s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11218{
11219 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11220
11221 return "stamy";
11222}
11223
11224
11225/* Implementation for 32-bit compare-and-swap */
11226static void
11227s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11228{
11229 IRCAS *cas;
11230 IRTemp op1 = newTemp(Ity_I32);
11231 IRTemp old_mem = newTemp(Ity_I32);
11232 IRTemp op3 = newTemp(Ity_I32);
11233 IRTemp result = newTemp(Ity_I32);
11234 IRTemp nequal = newTemp(Ity_I1);
11235
11236 assign(op1, get_gpr_w1(r1));
11237 assign(op3, get_gpr_w1(r3));
11238
11239 /* The first and second operands are compared. If they are equal,
11240 the third operand is stored at the second- operand location. */
11241 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11242 Iend_BE, mkexpr(op2addr),
11243 NULL, mkexpr(op1), /* expected value */
11244 NULL, mkexpr(op3) /* new value */);
11245 stmt(IRStmt_CAS(cas));
11246
11247 /* Set CC. Operands compared equal -> 0, else 1. */
11248 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11249 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11250
11251 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11252 Otherwise, store the old_value from memory in r1 and yield. */
11253 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11254 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011255 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011256}
11257
florian55085f82012-11-21 00:36:55 +000011258static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011259s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11260{
11261 s390_irgen_cas_32(r1, r3, op2addr);
11262
11263 return "cs";
11264}
11265
florian55085f82012-11-21 00:36:55 +000011266static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011267s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11268{
11269 s390_irgen_cas_32(r1, r3, op2addr);
11270
11271 return "csy";
11272}
11273
florian55085f82012-11-21 00:36:55 +000011274static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011275s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11276{
11277 IRCAS *cas;
11278 IRTemp op1 = newTemp(Ity_I64);
11279 IRTemp old_mem = newTemp(Ity_I64);
11280 IRTemp op3 = newTemp(Ity_I64);
11281 IRTemp result = newTemp(Ity_I64);
11282 IRTemp nequal = newTemp(Ity_I1);
11283
11284 assign(op1, get_gpr_dw0(r1));
11285 assign(op3, get_gpr_dw0(r3));
11286
11287 /* The first and second operands are compared. If they are equal,
11288 the third operand is stored at the second- operand location. */
11289 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11290 Iend_BE, mkexpr(op2addr),
11291 NULL, mkexpr(op1), /* expected value */
11292 NULL, mkexpr(op3) /* new value */);
11293 stmt(IRStmt_CAS(cas));
11294
11295 /* Set CC. Operands compared equal -> 0, else 1. */
11296 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11297 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11298
11299 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11300 Otherwise, store the old_value from memory in r1 and yield. */
11301 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11302 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011303 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011304
11305 return "csg";
11306}
11307
florian448cbba2012-06-06 02:26:01 +000011308/* Implementation for 32-bit compare-double-and-swap */
11309static void
11310s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11311{
11312 IRCAS *cas;
11313 IRTemp op1_high = newTemp(Ity_I32);
11314 IRTemp op1_low = newTemp(Ity_I32);
11315 IRTemp old_mem_high = newTemp(Ity_I32);
11316 IRTemp old_mem_low = newTemp(Ity_I32);
11317 IRTemp op3_high = newTemp(Ity_I32);
11318 IRTemp op3_low = newTemp(Ity_I32);
11319 IRTemp result = newTemp(Ity_I32);
11320 IRTemp nequal = newTemp(Ity_I1);
11321
11322 assign(op1_high, get_gpr_w1(r1));
11323 assign(op1_low, get_gpr_w1(r1+1));
11324 assign(op3_high, get_gpr_w1(r3));
11325 assign(op3_low, get_gpr_w1(r3+1));
11326
11327 /* The first and second operands are compared. If they are equal,
11328 the third operand is stored at the second-operand location. */
11329 cas = mkIRCAS(old_mem_high, old_mem_low,
11330 Iend_BE, mkexpr(op2addr),
11331 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11332 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11333 stmt(IRStmt_CAS(cas));
11334
11335 /* Set CC. Operands compared equal -> 0, else 1. */
11336 assign(result, unop(Iop_1Uto32,
11337 binop(Iop_CmpNE32,
11338 binop(Iop_Or32,
11339 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11340 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11341 mkU32(0))));
11342
11343 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11344
11345 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11346 Otherwise, store the old_value from memory in r1 and yield. */
11347 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11348 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11349 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011350 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011351}
11352
florian55085f82012-11-21 00:36:55 +000011353static const HChar *
florian448cbba2012-06-06 02:26:01 +000011354s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11355{
11356 s390_irgen_cdas_32(r1, r3, op2addr);
11357
11358 return "cds";
11359}
11360
florian55085f82012-11-21 00:36:55 +000011361static const HChar *
florian448cbba2012-06-06 02:26:01 +000011362s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11363{
11364 s390_irgen_cdas_32(r1, r3, op2addr);
11365
11366 return "cdsy";
11367}
11368
florian55085f82012-11-21 00:36:55 +000011369static const HChar *
florian448cbba2012-06-06 02:26:01 +000011370s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11371{
11372 IRCAS *cas;
11373 IRTemp op1_high = newTemp(Ity_I64);
11374 IRTemp op1_low = newTemp(Ity_I64);
11375 IRTemp old_mem_high = newTemp(Ity_I64);
11376 IRTemp old_mem_low = newTemp(Ity_I64);
11377 IRTemp op3_high = newTemp(Ity_I64);
11378 IRTemp op3_low = newTemp(Ity_I64);
11379 IRTemp result = newTemp(Ity_I64);
11380 IRTemp nequal = newTemp(Ity_I1);
11381
11382 assign(op1_high, get_gpr_dw0(r1));
11383 assign(op1_low, get_gpr_dw0(r1+1));
11384 assign(op3_high, get_gpr_dw0(r3));
11385 assign(op3_low, get_gpr_dw0(r3+1));
11386
11387 /* The first and second operands are compared. If they are equal,
11388 the third operand is stored at the second-operand location. */
11389 cas = mkIRCAS(old_mem_high, old_mem_low,
11390 Iend_BE, mkexpr(op2addr),
11391 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11392 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11393 stmt(IRStmt_CAS(cas));
11394
11395 /* Set CC. Operands compared equal -> 0, else 1. */
11396 assign(result, unop(Iop_1Uto64,
11397 binop(Iop_CmpNE64,
11398 binop(Iop_Or64,
11399 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11400 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11401 mkU64(0))));
11402
11403 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11404
11405 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11406 Otherwise, store the old_value from memory in r1 and yield. */
11407 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11408 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11409 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011410 yield_if(mkexpr(nequal));
11411
florian448cbba2012-06-06 02:26:01 +000011412 return "cdsg";
11413}
11414
sewardj2019a972011-03-07 16:04:07 +000011415
11416/* Binary floating point */
11417
florian55085f82012-11-21 00:36:55 +000011418static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011419s390_irgen_AXBR(UChar r1, UChar r2)
11420{
11421 IRTemp op1 = newTemp(Ity_F128);
11422 IRTemp op2 = newTemp(Ity_F128);
11423 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011424 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011425
11426 assign(op1, get_fpr_pair(r1));
11427 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011428 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011429 mkexpr(op2)));
11430 put_fpr_pair(r1, mkexpr(result));
11431
11432 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11433
11434 return "axbr";
11435}
11436
florian55085f82012-11-21 00:36:55 +000011437static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011438s390_irgen_CEBR(UChar r1, UChar r2)
11439{
11440 IRTemp op1 = newTemp(Ity_F32);
11441 IRTemp op2 = newTemp(Ity_F32);
11442 IRTemp cc_vex = newTemp(Ity_I32);
11443 IRTemp cc_s390 = newTemp(Ity_I32);
11444
11445 assign(op1, get_fpr_w0(r1));
11446 assign(op2, get_fpr_w0(r2));
11447 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11448
florian2d3d87f2012-12-21 21:05:17 +000011449 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011450 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11451
11452 return "cebr";
11453}
11454
florian55085f82012-11-21 00:36:55 +000011455static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011456s390_irgen_CDBR(UChar r1, UChar r2)
11457{
11458 IRTemp op1 = newTemp(Ity_F64);
11459 IRTemp op2 = newTemp(Ity_F64);
11460 IRTemp cc_vex = newTemp(Ity_I32);
11461 IRTemp cc_s390 = newTemp(Ity_I32);
11462
11463 assign(op1, get_fpr_dw0(r1));
11464 assign(op2, get_fpr_dw0(r2));
11465 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11466
florian2d3d87f2012-12-21 21:05:17 +000011467 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011468 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11469
11470 return "cdbr";
11471}
11472
florian55085f82012-11-21 00:36:55 +000011473static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011474s390_irgen_CXBR(UChar r1, UChar r2)
11475{
11476 IRTemp op1 = newTemp(Ity_F128);
11477 IRTemp op2 = newTemp(Ity_F128);
11478 IRTemp cc_vex = newTemp(Ity_I32);
11479 IRTemp cc_s390 = newTemp(Ity_I32);
11480
11481 assign(op1, get_fpr_pair(r1));
11482 assign(op2, get_fpr_pair(r2));
11483 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
11484
florian2d3d87f2012-12-21 21:05:17 +000011485 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011486 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11487
11488 return "cxbr";
11489}
11490
florian55085f82012-11-21 00:36:55 +000011491static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011492s390_irgen_CEB(UChar r1, IRTemp op2addr)
11493{
11494 IRTemp op1 = newTemp(Ity_F32);
11495 IRTemp op2 = newTemp(Ity_F32);
11496 IRTemp cc_vex = newTemp(Ity_I32);
11497 IRTemp cc_s390 = newTemp(Ity_I32);
11498
11499 assign(op1, get_fpr_w0(r1));
11500 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11501 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11502
florian2d3d87f2012-12-21 21:05:17 +000011503 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011504 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11505
11506 return "ceb";
11507}
11508
florian55085f82012-11-21 00:36:55 +000011509static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011510s390_irgen_CDB(UChar r1, IRTemp op2addr)
11511{
11512 IRTemp op1 = newTemp(Ity_F64);
11513 IRTemp op2 = newTemp(Ity_F64);
11514 IRTemp cc_vex = newTemp(Ity_I32);
11515 IRTemp cc_s390 = newTemp(Ity_I32);
11516
11517 assign(op1, get_fpr_dw0(r1));
11518 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11519 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11520
florian2d3d87f2012-12-21 21:05:17 +000011521 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011522 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11523
11524 return "cdb";
11525}
11526
florian55085f82012-11-21 00:36:55 +000011527static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011528s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11529 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011530{
11531 IRTemp op2 = newTemp(Ity_I32);
11532
11533 assign(op2, get_gpr_w1(r2));
11534 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11535
11536 return "cxfbr";
11537}
11538
florian55085f82012-11-21 00:36:55 +000011539static const HChar *
floriand2129202012-09-01 20:01:39 +000011540s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11541 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011542{
floriane75dafa2012-09-01 17:54:09 +000011543 if (! s390_host_has_fpext) {
11544 emulation_failure(EmFail_S390X_fpext);
11545 } else {
11546 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011547
floriane75dafa2012-09-01 17:54:09 +000011548 assign(op2, get_gpr_w1(r2));
11549 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11550 }
florian1c8f7ff2012-09-01 00:12:11 +000011551 return "cxlfbr";
11552}
11553
11554
florian55085f82012-11-21 00:36:55 +000011555static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011556s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11557 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011558{
11559 IRTemp op2 = newTemp(Ity_I64);
11560
11561 assign(op2, get_gpr_dw0(r2));
11562 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11563
11564 return "cxgbr";
11565}
11566
florian55085f82012-11-21 00:36:55 +000011567static const HChar *
floriand2129202012-09-01 20:01:39 +000011568s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11569 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011570{
floriane75dafa2012-09-01 17:54:09 +000011571 if (! s390_host_has_fpext) {
11572 emulation_failure(EmFail_S390X_fpext);
11573 } else {
11574 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011575
floriane75dafa2012-09-01 17:54:09 +000011576 assign(op2, get_gpr_dw0(r2));
11577 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11578 }
florian1c8f7ff2012-09-01 00:12:11 +000011579 return "cxlgbr";
11580}
11581
florian55085f82012-11-21 00:36:55 +000011582static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011583s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11584 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011585{
11586 IRTemp op = newTemp(Ity_F128);
11587 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011588 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011589
11590 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011591 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011592 mkexpr(op)));
11593 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011594 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011595
11596 return "cfxbr";
11597}
11598
florian55085f82012-11-21 00:36:55 +000011599static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011600s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
11601 UChar r1, UChar r2)
11602{
floriane75dafa2012-09-01 17:54:09 +000011603 if (! s390_host_has_fpext) {
11604 emulation_failure(EmFail_S390X_fpext);
11605 } else {
11606 IRTemp op = newTemp(Ity_F128);
11607 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011608 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011609
floriane75dafa2012-09-01 17:54:09 +000011610 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011611 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011612 mkexpr(op)));
11613 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011614 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011615 }
florian1c8f7ff2012-09-01 00:12:11 +000011616 return "clfxbr";
11617}
11618
11619
florian55085f82012-11-21 00:36:55 +000011620static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011621s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
11622 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011623{
11624 IRTemp op = newTemp(Ity_F128);
11625 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011626 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011627
11628 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011629 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011630 mkexpr(op)));
11631 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011632 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011633
11634 return "cgxbr";
11635}
11636
florian55085f82012-11-21 00:36:55 +000011637static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011638s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
11639 UChar r1, UChar r2)
11640{
floriane75dafa2012-09-01 17:54:09 +000011641 if (! s390_host_has_fpext) {
11642 emulation_failure(EmFail_S390X_fpext);
11643 } else {
11644 IRTemp op = newTemp(Ity_F128);
11645 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011646 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011647
floriane75dafa2012-09-01 17:54:09 +000011648 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011649 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011650 mkexpr(op)));
11651 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011652 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
11653 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011654 }
florian1c8f7ff2012-09-01 00:12:11 +000011655 return "clgxbr";
11656}
11657
florian55085f82012-11-21 00:36:55 +000011658static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011659s390_irgen_DXBR(UChar r1, UChar r2)
11660{
11661 IRTemp op1 = newTemp(Ity_F128);
11662 IRTemp op2 = newTemp(Ity_F128);
11663 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011664 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011665
11666 assign(op1, get_fpr_pair(r1));
11667 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011668 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011669 mkexpr(op2)));
11670 put_fpr_pair(r1, mkexpr(result));
11671
11672 return "dxbr";
11673}
11674
florian55085f82012-11-21 00:36:55 +000011675static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011676s390_irgen_LTXBR(UChar r1, UChar r2)
11677{
11678 IRTemp result = newTemp(Ity_F128);
11679
11680 assign(result, get_fpr_pair(r2));
11681 put_fpr_pair(r1, mkexpr(result));
11682 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11683
11684 return "ltxbr";
11685}
11686
florian55085f82012-11-21 00:36:55 +000011687static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011688s390_irgen_LCXBR(UChar r1, UChar r2)
11689{
11690 IRTemp result = newTemp(Ity_F128);
11691
11692 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
11693 put_fpr_pair(r1, mkexpr(result));
11694 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11695
11696 return "lcxbr";
11697}
11698
florian55085f82012-11-21 00:36:55 +000011699static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011700s390_irgen_LXDBR(UChar r1, UChar r2)
11701{
11702 IRTemp op = newTemp(Ity_F64);
11703
11704 assign(op, get_fpr_dw0(r2));
11705 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11706
11707 return "lxdbr";
11708}
11709
florian55085f82012-11-21 00:36:55 +000011710static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011711s390_irgen_LXEBR(UChar r1, UChar r2)
11712{
11713 IRTemp op = newTemp(Ity_F32);
11714
11715 assign(op, get_fpr_w0(r2));
11716 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11717
11718 return "lxebr";
11719}
11720
florian55085f82012-11-21 00:36:55 +000011721static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011722s390_irgen_LXDB(UChar r1, IRTemp op2addr)
11723{
11724 IRTemp op = newTemp(Ity_F64);
11725
11726 assign(op, load(Ity_F64, mkexpr(op2addr)));
11727 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11728
11729 return "lxdb";
11730}
11731
florian55085f82012-11-21 00:36:55 +000011732static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011733s390_irgen_LXEB(UChar r1, IRTemp op2addr)
11734{
11735 IRTemp op = newTemp(Ity_F32);
11736
11737 assign(op, load(Ity_F32, mkexpr(op2addr)));
11738 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11739
11740 return "lxeb";
11741}
11742
florian55085f82012-11-21 00:36:55 +000011743static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011744s390_irgen_LNEBR(UChar r1, UChar r2)
11745{
11746 IRTemp result = newTemp(Ity_F32);
11747
11748 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
11749 put_fpr_w0(r1, mkexpr(result));
11750 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11751
11752 return "lnebr";
11753}
11754
florian55085f82012-11-21 00:36:55 +000011755static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011756s390_irgen_LNDBR(UChar r1, UChar r2)
11757{
11758 IRTemp result = newTemp(Ity_F64);
11759
11760 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11761 put_fpr_dw0(r1, mkexpr(result));
11762 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11763
11764 return "lndbr";
11765}
11766
florian55085f82012-11-21 00:36:55 +000011767static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011768s390_irgen_LNXBR(UChar r1, UChar r2)
11769{
11770 IRTemp result = newTemp(Ity_F128);
11771
11772 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
11773 put_fpr_pair(r1, mkexpr(result));
11774 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11775
11776 return "lnxbr";
11777}
11778
florian55085f82012-11-21 00:36:55 +000011779static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011780s390_irgen_LPEBR(UChar r1, UChar r2)
11781{
11782 IRTemp result = newTemp(Ity_F32);
11783
11784 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
11785 put_fpr_w0(r1, mkexpr(result));
11786 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11787
11788 return "lpebr";
11789}
11790
florian55085f82012-11-21 00:36:55 +000011791static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011792s390_irgen_LPDBR(UChar r1, UChar r2)
11793{
11794 IRTemp result = newTemp(Ity_F64);
11795
11796 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11797 put_fpr_dw0(r1, mkexpr(result));
11798 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11799
11800 return "lpdbr";
11801}
11802
florian55085f82012-11-21 00:36:55 +000011803static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011804s390_irgen_LPXBR(UChar r1, UChar r2)
11805{
11806 IRTemp result = newTemp(Ity_F128);
11807
11808 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
11809 put_fpr_pair(r1, mkexpr(result));
11810 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11811
11812 return "lpxbr";
11813}
11814
florian55085f82012-11-21 00:36:55 +000011815static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011816s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
11817 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011818{
florian125e20d2012-10-07 15:42:37 +000011819 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011820 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011821 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011822 }
sewardj2019a972011-03-07 16:04:07 +000011823 IRTemp result = newTemp(Ity_F64);
11824
floriandb4fcaa2012-09-05 19:54:08 +000011825 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011826 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011827 put_fpr_dw0(r1, mkexpr(result));
11828
11829 return "ldxbr";
11830}
11831
florian55085f82012-11-21 00:36:55 +000011832static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011833s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11834 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011835{
florian125e20d2012-10-07 15:42:37 +000011836 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011837 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011838 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011839 }
sewardj2019a972011-03-07 16:04:07 +000011840 IRTemp result = newTemp(Ity_F32);
11841
floriandb4fcaa2012-09-05 19:54:08 +000011842 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011843 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011844 put_fpr_w0(r1, mkexpr(result));
11845
11846 return "lexbr";
11847}
11848
florian55085f82012-11-21 00:36:55 +000011849static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011850s390_irgen_MXBR(UChar r1, UChar r2)
11851{
11852 IRTemp op1 = newTemp(Ity_F128);
11853 IRTemp op2 = newTemp(Ity_F128);
11854 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011855 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011856
11857 assign(op1, get_fpr_pair(r1));
11858 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011859 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011860 mkexpr(op2)));
11861 put_fpr_pair(r1, mkexpr(result));
11862
11863 return "mxbr";
11864}
11865
florian55085f82012-11-21 00:36:55 +000011866static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011867s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11868{
florian125e20d2012-10-07 15:42:37 +000011869 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011870
floriandb4fcaa2012-09-05 19:54:08 +000011871 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011872 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011873
11874 return "maebr";
11875}
11876
florian55085f82012-11-21 00:36:55 +000011877static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011878s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11879{
florian125e20d2012-10-07 15:42:37 +000011880 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011881
floriandb4fcaa2012-09-05 19:54:08 +000011882 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011883 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011884
11885 return "madbr";
11886}
11887
florian55085f82012-11-21 00:36:55 +000011888static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011889s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11890{
11891 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011892 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011893
floriandb4fcaa2012-09-05 19:54:08 +000011894 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011895 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011896
11897 return "maeb";
11898}
11899
florian55085f82012-11-21 00:36:55 +000011900static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011901s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11902{
11903 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011904 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011905
floriandb4fcaa2012-09-05 19:54:08 +000011906 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011907 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011908
11909 return "madb";
11910}
11911
florian55085f82012-11-21 00:36:55 +000011912static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011913s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11914{
florian125e20d2012-10-07 15:42:37 +000011915 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011916
floriandb4fcaa2012-09-05 19:54:08 +000011917 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011918 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011919
11920 return "msebr";
11921}
11922
florian55085f82012-11-21 00:36:55 +000011923static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011924s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11925{
florian125e20d2012-10-07 15:42:37 +000011926 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011927
floriandb4fcaa2012-09-05 19:54:08 +000011928 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011929 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011930
11931 return "msdbr";
11932}
11933
florian55085f82012-11-21 00:36:55 +000011934static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011935s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11936{
11937 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011938 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011939
floriandb4fcaa2012-09-05 19:54:08 +000011940 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011941 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011942
11943 return "mseb";
11944}
11945
florian55085f82012-11-21 00:36:55 +000011946static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011947s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11948{
11949 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011950 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011951
floriandb4fcaa2012-09-05 19:54:08 +000011952 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011953 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011954
11955 return "msdb";
11956}
11957
florian55085f82012-11-21 00:36:55 +000011958static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011959s390_irgen_SQEBR(UChar r1, UChar r2)
11960{
11961 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011962 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011963
floriandb4fcaa2012-09-05 19:54:08 +000011964 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011965 put_fpr_w0(r1, mkexpr(result));
11966
11967 return "sqebr";
11968}
11969
florian55085f82012-11-21 00:36:55 +000011970static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011971s390_irgen_SQDBR(UChar r1, UChar r2)
11972{
11973 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011974 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011975
floriandb4fcaa2012-09-05 19:54:08 +000011976 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011977 put_fpr_dw0(r1, mkexpr(result));
11978
11979 return "sqdbr";
11980}
11981
florian55085f82012-11-21 00:36:55 +000011982static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011983s390_irgen_SQXBR(UChar r1, UChar r2)
11984{
11985 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011986 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011987
floriandb4fcaa2012-09-05 19:54:08 +000011988 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11989 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011990 put_fpr_pair(r1, mkexpr(result));
11991
11992 return "sqxbr";
11993}
11994
florian55085f82012-11-21 00:36:55 +000011995static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011996s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11997{
11998 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011999 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012000
12001 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012002 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012003
12004 return "sqeb";
12005}
12006
florian55085f82012-11-21 00:36:55 +000012007static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012008s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12009{
12010 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012011 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012012
12013 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012014 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012015
12016 return "sqdb";
12017}
12018
florian55085f82012-11-21 00:36:55 +000012019static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012020s390_irgen_SXBR(UChar r1, UChar r2)
12021{
12022 IRTemp op1 = newTemp(Ity_F128);
12023 IRTemp op2 = newTemp(Ity_F128);
12024 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012025 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012026
12027 assign(op1, get_fpr_pair(r1));
12028 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012029 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012030 mkexpr(op2)));
12031 put_fpr_pair(r1, mkexpr(result));
12032 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12033
12034 return "sxbr";
12035}
12036
florian55085f82012-11-21 00:36:55 +000012037static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012038s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12039{
12040 IRTemp value = newTemp(Ity_F32);
12041
12042 assign(value, get_fpr_w0(r1));
12043
12044 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12045
12046 return "tceb";
12047}
12048
florian55085f82012-11-21 00:36:55 +000012049static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012050s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12051{
12052 IRTemp value = newTemp(Ity_F64);
12053
12054 assign(value, get_fpr_dw0(r1));
12055
12056 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12057
12058 return "tcdb";
12059}
12060
florian55085f82012-11-21 00:36:55 +000012061static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012062s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12063{
12064 IRTemp value = newTemp(Ity_F128);
12065
12066 assign(value, get_fpr_pair(r1));
12067
12068 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12069
12070 return "tcxb";
12071}
12072
florian55085f82012-11-21 00:36:55 +000012073static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012074s390_irgen_LCDFR(UChar r1, UChar r2)
12075{
12076 IRTemp result = newTemp(Ity_F64);
12077
12078 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12079 put_fpr_dw0(r1, mkexpr(result));
12080
12081 return "lcdfr";
12082}
12083
florian55085f82012-11-21 00:36:55 +000012084static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012085s390_irgen_LNDFR(UChar r1, UChar r2)
12086{
12087 IRTemp result = newTemp(Ity_F64);
12088
12089 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12090 put_fpr_dw0(r1, mkexpr(result));
12091
12092 return "lndfr";
12093}
12094
florian55085f82012-11-21 00:36:55 +000012095static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012096s390_irgen_LPDFR(UChar r1, UChar r2)
12097{
12098 IRTemp result = newTemp(Ity_F64);
12099
12100 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12101 put_fpr_dw0(r1, mkexpr(result));
12102
12103 return "lpdfr";
12104}
12105
florian55085f82012-11-21 00:36:55 +000012106static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012107s390_irgen_LDGR(UChar r1, UChar r2)
12108{
12109 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12110
12111 return "ldgr";
12112}
12113
florian55085f82012-11-21 00:36:55 +000012114static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012115s390_irgen_LGDR(UChar r1, UChar r2)
12116{
12117 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12118
12119 return "lgdr";
12120}
12121
12122
florian55085f82012-11-21 00:36:55 +000012123static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012124s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12125{
12126 IRTemp sign = newTemp(Ity_I64);
12127 IRTemp value = newTemp(Ity_I64);
12128
12129 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12130 mkU64(1ULL << 63)));
12131 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12132 mkU64((1ULL << 63) - 1)));
12133 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12134 mkexpr(sign))));
12135
12136 return "cpsdr";
12137}
12138
12139
sewardj2019a972011-03-07 16:04:07 +000012140static IRExpr *
12141s390_call_cvb(IRExpr *in)
12142{
12143 IRExpr **args, *call;
12144
12145 args = mkIRExprVec_1(in);
12146 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12147 "s390_do_cvb", &s390_do_cvb, args);
12148
12149 /* Nothing is excluded from definedness checking. */
12150 call->Iex.CCall.cee->mcx_mask = 0;
12151
12152 return call;
12153}
12154
florian55085f82012-11-21 00:36:55 +000012155static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012156s390_irgen_CVB(UChar r1, IRTemp op2addr)
12157{
12158 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12159
12160 return "cvb";
12161}
12162
florian55085f82012-11-21 00:36:55 +000012163static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012164s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12165{
12166 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12167
12168 return "cvby";
12169}
12170
12171
sewardj2019a972011-03-07 16:04:07 +000012172static IRExpr *
12173s390_call_cvd(IRExpr *in)
12174{
12175 IRExpr **args, *call;
12176
12177 args = mkIRExprVec_1(in);
12178 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12179 "s390_do_cvd", &s390_do_cvd, args);
12180
12181 /* Nothing is excluded from definedness checking. */
12182 call->Iex.CCall.cee->mcx_mask = 0;
12183
12184 return call;
12185}
12186
florian55085f82012-11-21 00:36:55 +000012187static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012188s390_irgen_CVD(UChar r1, IRTemp op2addr)
12189{
florian11b8ee82012-08-06 13:35:33 +000012190 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012191
12192 return "cvd";
12193}
12194
florian55085f82012-11-21 00:36:55 +000012195static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012196s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12197{
12198 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12199
12200 return "cvdy";
12201}
12202
florian55085f82012-11-21 00:36:55 +000012203static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012204s390_irgen_FLOGR(UChar r1, UChar r2)
12205{
12206 IRTemp input = newTemp(Ity_I64);
12207 IRTemp not_zero = newTemp(Ity_I64);
12208 IRTemp tmpnum = newTemp(Ity_I64);
12209 IRTemp num = newTemp(Ity_I64);
12210 IRTemp shift_amount = newTemp(Ity_I8);
12211
12212 /* We use the "count leading zeroes" operator because the number of
12213 leading zeroes is identical with the bit position of the first '1' bit.
12214 However, that operator does not work when the input value is zero.
12215 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12216 the modified value. If input == 0, then the result is 64. Otherwise,
12217 the result of Clz64 is what we want. */
12218
12219 assign(input, get_gpr_dw0(r2));
12220 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12221 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12222
12223 /* num = (input == 0) ? 64 : tmpnum */
12224 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12225 /* == 0 */ mkU64(64),
12226 /* != 0 */ mkexpr(tmpnum)));
12227
12228 put_gpr_dw0(r1, mkexpr(num));
12229
12230 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12231 is to first shift the input value by NUM + 1 bits to the left which
12232 causes the leftmost '1' bit to disappear. Then we shift logically to
12233 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12234 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12235 the width of the value-to-be-shifted, we need to special case
12236 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12237 For both such INPUT values the result will be 0. */
12238
12239 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12240 mkU64(1))));
12241
12242 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012243 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12244 /* == 0 || == 1*/ mkU64(0),
12245 /* otherwise */
12246 binop(Iop_Shr64,
12247 binop(Iop_Shl64, mkexpr(input),
12248 mkexpr(shift_amount)),
12249 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012250
12251 /* Compare the original value as an unsigned integer with 0. */
12252 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12253 mktemp(Ity_I64, mkU64(0)), False);
12254
12255 return "flogr";
12256}
12257
florian55085f82012-11-21 00:36:55 +000012258static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012259s390_irgen_STCK(IRTemp op2addr)
12260{
12261 IRDirty *d;
12262 IRTemp cc = newTemp(Ity_I64);
12263
12264 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12265 &s390x_dirtyhelper_STCK,
12266 mkIRExprVec_1(mkexpr(op2addr)));
12267 d->mFx = Ifx_Write;
12268 d->mAddr = mkexpr(op2addr);
12269 d->mSize = 8;
12270 stmt(IRStmt_Dirty(d));
12271 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12272 mkexpr(cc), mkU64(0), mkU64(0));
12273 return "stck";
12274}
12275
florian55085f82012-11-21 00:36:55 +000012276static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012277s390_irgen_STCKF(IRTemp op2addr)
12278{
florianc5c669b2012-08-26 14:32:28 +000012279 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012280 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012281 } else {
12282 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012283
florianc5c669b2012-08-26 14:32:28 +000012284 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12285 &s390x_dirtyhelper_STCKF,
12286 mkIRExprVec_1(mkexpr(op2addr)));
12287 d->mFx = Ifx_Write;
12288 d->mAddr = mkexpr(op2addr);
12289 d->mSize = 8;
12290 stmt(IRStmt_Dirty(d));
12291 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12292 mkexpr(cc), mkU64(0), mkU64(0));
12293 }
sewardj1e5fea62011-05-17 16:18:36 +000012294 return "stckf";
12295}
12296
florian55085f82012-11-21 00:36:55 +000012297static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012298s390_irgen_STCKE(IRTemp op2addr)
12299{
12300 IRDirty *d;
12301 IRTemp cc = newTemp(Ity_I64);
12302
12303 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12304 &s390x_dirtyhelper_STCKE,
12305 mkIRExprVec_1(mkexpr(op2addr)));
12306 d->mFx = Ifx_Write;
12307 d->mAddr = mkexpr(op2addr);
12308 d->mSize = 16;
12309 stmt(IRStmt_Dirty(d));
12310 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12311 mkexpr(cc), mkU64(0), mkU64(0));
12312 return "stcke";
12313}
12314
florian55085f82012-11-21 00:36:55 +000012315static const HChar *
florian933065d2011-07-11 01:48:02 +000012316s390_irgen_STFLE(IRTemp op2addr)
12317{
florian4e0083e2012-08-26 03:41:56 +000012318 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012319 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012320 return "stfle";
12321 }
12322
florian933065d2011-07-11 01:48:02 +000012323 IRDirty *d;
12324 IRTemp cc = newTemp(Ity_I64);
12325
12326 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12327 &s390x_dirtyhelper_STFLE,
12328 mkIRExprVec_1(mkexpr(op2addr)));
12329
12330 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
12331
sewardjc9069f22012-06-01 16:09:50 +000012332 d->nFxState = 1;
12333 vex_bzero(&d->fxState, sizeof(d->fxState));
12334
florian933065d2011-07-11 01:48:02 +000012335 d->fxState[0].fx = Ifx_Modify; /* read then write */
12336 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12337 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012338
12339 d->mAddr = mkexpr(op2addr);
12340 /* Pretend all double words are written */
12341 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12342 d->mFx = Ifx_Write;
12343
12344 stmt(IRStmt_Dirty(d));
12345
12346 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12347
12348 return "stfle";
12349}
12350
florian55085f82012-11-21 00:36:55 +000012351static const HChar *
floriana4384a32011-08-11 16:58:45 +000012352s390_irgen_CKSM(UChar r1,UChar r2)
12353{
12354 IRTemp addr = newTemp(Ity_I64);
12355 IRTemp op = newTemp(Ity_I32);
12356 IRTemp len = newTemp(Ity_I64);
12357 IRTemp oldval = newTemp(Ity_I32);
12358 IRTemp mask = newTemp(Ity_I32);
12359 IRTemp newop = newTemp(Ity_I32);
12360 IRTemp result = newTemp(Ity_I32);
12361 IRTemp result1 = newTemp(Ity_I32);
12362 IRTemp inc = newTemp(Ity_I64);
12363
12364 assign(oldval, get_gpr_w1(r1));
12365 assign(addr, get_gpr_dw0(r2));
12366 assign(len, get_gpr_dw0(r2+1));
12367
12368 /* Condition code is always zero. */
12369 s390_cc_set(0);
12370
12371 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012372 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012373
12374 /* Assiging the increment variable to adjust address and length
12375 later on. */
12376 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12377 mkexpr(len), mkU64(4)));
12378
12379 /* If length < 4 the final 4-byte 2nd operand value is computed by
12380 appending the remaining bytes to the right with 0. This is done
12381 by AND'ing the 4 bytes loaded from memory with an appropriate
12382 mask. If length >= 4, that mask is simply 0xffffffff. */
12383
12384 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12385 /* Mask computation when len < 4:
12386 0xffffffff << (32 - (len % 4)*8) */
12387 binop(Iop_Shl32, mkU32(0xffffffff),
12388 unop(Iop_32to8,
12389 binop(Iop_Sub32, mkU32(32),
12390 binop(Iop_Shl32,
12391 unop(Iop_64to32,
12392 binop(Iop_And64,
12393 mkexpr(len), mkU64(3))),
12394 mkU8(3))))),
12395 mkU32(0xffffffff)));
12396
12397 assign(op, load(Ity_I32, mkexpr(addr)));
12398 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12399 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12400
12401 /* Checking for carry */
12402 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12403 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12404 mkexpr(result)));
12405
12406 put_gpr_w1(r1, mkexpr(result1));
12407 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12408 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12409
florian6820ba52012-07-26 02:01:50 +000012410 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012411
12412 return "cksm";
12413}
12414
florian55085f82012-11-21 00:36:55 +000012415static const HChar *
florian9af37692012-01-15 21:01:16 +000012416s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12417{
12418 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12419 src_addr = newTemp(Ity_I64);
12420 des_addr = newTemp(Ity_I64);
12421 tab_addr = newTemp(Ity_I64);
12422 test_byte = newTemp(Ity_I8);
12423 src_len = newTemp(Ity_I64);
12424
12425 assign(src_addr, get_gpr_dw0(r2));
12426 assign(des_addr, get_gpr_dw0(r1));
12427 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012428 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012429 assign(test_byte, get_gpr_b7(0));
12430
12431 IRTemp op = newTemp(Ity_I8);
12432 IRTemp op1 = newTemp(Ity_I8);
12433 IRTemp result = newTemp(Ity_I64);
12434
12435 /* End of source string? We're done; proceed to next insn */
12436 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012437 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012438
12439 /* Load character from source string, index translation table and
12440 store translated character in op1. */
12441 assign(op, load(Ity_I8, mkexpr(src_addr)));
12442
12443 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12444 mkexpr(tab_addr)));
12445 assign(op1, load(Ity_I8, mkexpr(result)));
12446
12447 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12448 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012449 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000012450 }
12451 store(get_gpr_dw0(r1), mkexpr(op1));
12452
12453 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12454 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12455 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12456
florian6820ba52012-07-26 02:01:50 +000012457 iterate();
florian9af37692012-01-15 21:01:16 +000012458
12459 return "troo";
12460}
12461
florian55085f82012-11-21 00:36:55 +000012462static const HChar *
florian730448f2012-02-04 17:07:07 +000012463s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
12464{
12465 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12466 src_addr = newTemp(Ity_I64);
12467 des_addr = newTemp(Ity_I64);
12468 tab_addr = newTemp(Ity_I64);
12469 test_byte = newTemp(Ity_I8);
12470 src_len = newTemp(Ity_I64);
12471
12472 assign(src_addr, get_gpr_dw0(r2));
12473 assign(des_addr, get_gpr_dw0(r1));
12474 assign(tab_addr, get_gpr_dw0(1));
12475 assign(src_len, get_gpr_dw0(r1+1));
12476 assign(test_byte, get_gpr_b7(0));
12477
12478 IRTemp op = newTemp(Ity_I16);
12479 IRTemp op1 = newTemp(Ity_I8);
12480 IRTemp result = newTemp(Ity_I64);
12481
12482 /* End of source string? We're done; proceed to next insn */
12483 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012484 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012485
12486 /* Load character from source string, index translation table and
12487 store translated character in op1. */
12488 assign(op, load(Ity_I16, mkexpr(src_addr)));
12489
12490 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12491 mkexpr(tab_addr)));
12492
12493 assign(op1, load(Ity_I8, mkexpr(result)));
12494
12495 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12496 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012497 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012498 }
12499 store(get_gpr_dw0(r1), mkexpr(op1));
12500
12501 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12502 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12503 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12504
florian6820ba52012-07-26 02:01:50 +000012505 iterate();
florian730448f2012-02-04 17:07:07 +000012506
12507 return "trto";
12508}
12509
florian55085f82012-11-21 00:36:55 +000012510static const HChar *
florian730448f2012-02-04 17:07:07 +000012511s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
12512{
12513 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12514 src_addr = newTemp(Ity_I64);
12515 des_addr = newTemp(Ity_I64);
12516 tab_addr = newTemp(Ity_I64);
12517 test_byte = newTemp(Ity_I16);
12518 src_len = newTemp(Ity_I64);
12519
12520 assign(src_addr, get_gpr_dw0(r2));
12521 assign(des_addr, get_gpr_dw0(r1));
12522 assign(tab_addr, get_gpr_dw0(1));
12523 assign(src_len, get_gpr_dw0(r1+1));
12524 assign(test_byte, get_gpr_hw3(0));
12525
12526 IRTemp op = newTemp(Ity_I8);
12527 IRTemp op1 = newTemp(Ity_I16);
12528 IRTemp result = newTemp(Ity_I64);
12529
12530 /* End of source string? We're done; proceed to next insn */
12531 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012532 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012533
12534 /* Load character from source string, index translation table and
12535 store translated character in op1. */
12536 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12537
12538 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12539 mkexpr(tab_addr)));
12540 assign(op1, load(Ity_I16, mkexpr(result)));
12541
12542 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12543 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012544 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012545 }
12546 store(get_gpr_dw0(r1), mkexpr(op1));
12547
12548 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12549 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12550 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12551
florian6820ba52012-07-26 02:01:50 +000012552 iterate();
florian730448f2012-02-04 17:07:07 +000012553
12554 return "trot";
12555}
12556
florian55085f82012-11-21 00:36:55 +000012557static const HChar *
florian730448f2012-02-04 17:07:07 +000012558s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12559{
12560 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12561 src_addr = newTemp(Ity_I64);
12562 des_addr = newTemp(Ity_I64);
12563 tab_addr = newTemp(Ity_I64);
12564 test_byte = newTemp(Ity_I16);
12565 src_len = newTemp(Ity_I64);
12566
12567 assign(src_addr, get_gpr_dw0(r2));
12568 assign(des_addr, get_gpr_dw0(r1));
12569 assign(tab_addr, get_gpr_dw0(1));
12570 assign(src_len, get_gpr_dw0(r1+1));
12571 assign(test_byte, get_gpr_hw3(0));
12572
12573 IRTemp op = newTemp(Ity_I16);
12574 IRTemp op1 = newTemp(Ity_I16);
12575 IRTemp result = newTemp(Ity_I64);
12576
12577 /* End of source string? We're done; proceed to next insn */
12578 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012579 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012580
12581 /* Load character from source string, index translation table and
12582 store translated character in op1. */
12583 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12584
12585 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12586 mkexpr(tab_addr)));
12587 assign(op1, load(Ity_I16, mkexpr(result)));
12588
12589 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12590 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012591 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012592 }
12593
12594 store(get_gpr_dw0(r1), mkexpr(op1));
12595
12596 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12597 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12598 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12599
florian6820ba52012-07-26 02:01:50 +000012600 iterate();
florian730448f2012-02-04 17:07:07 +000012601
12602 return "trtt";
12603}
12604
florian55085f82012-11-21 00:36:55 +000012605static const HChar *
florian730448f2012-02-04 17:07:07 +000012606s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
12607{
florianf87d4fb2012-05-05 02:55:24 +000012608 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000012609
florianf87d4fb2012-05-05 02:55:24 +000012610 assign(len, mkU64(length));
12611 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000012612
12613 return "tr";
12614}
12615
florian55085f82012-11-21 00:36:55 +000012616static const HChar *
florian730448f2012-02-04 17:07:07 +000012617s390_irgen_TRE(UChar r1,UChar r2)
12618{
12619 IRTemp src_addr, tab_addr, src_len, test_byte;
12620 src_addr = newTemp(Ity_I64);
12621 tab_addr = newTemp(Ity_I64);
12622 src_len = newTemp(Ity_I64);
12623 test_byte = newTemp(Ity_I8);
12624
12625 assign(src_addr, get_gpr_dw0(r1));
12626 assign(src_len, get_gpr_dw0(r1+1));
12627 assign(tab_addr, get_gpr_dw0(r2));
12628 assign(test_byte, get_gpr_b7(0));
12629
12630 IRTemp op = newTemp(Ity_I8);
12631 IRTemp op1 = newTemp(Ity_I8);
12632 IRTemp result = newTemp(Ity_I64);
12633
12634 /* End of source string? We're done; proceed to next insn */
12635 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012636 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012637
12638 /* Load character from source string and compare with test byte */
12639 assign(op, load(Ity_I8, mkexpr(src_addr)));
12640
12641 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012642 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012643
12644 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12645 mkexpr(tab_addr)));
12646
12647 assign(op1, load(Ity_I8, mkexpr(result)));
12648
12649 store(get_gpr_dw0(r1), mkexpr(op1));
12650 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12651 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12652
florian6820ba52012-07-26 02:01:50 +000012653 iterate();
florian730448f2012-02-04 17:07:07 +000012654
12655 return "tre";
12656}
12657
floriana0100c92012-07-20 00:06:35 +000012658static IRExpr *
12659s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
12660{
12661 IRExpr **args, *call;
12662 args = mkIRExprVec_2(srcval, low_surrogate);
12663 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12664 "s390_do_cu21", &s390_do_cu21, args);
12665
12666 /* Nothing is excluded from definedness checking. */
12667 call->Iex.CCall.cee->mcx_mask = 0;
12668
12669 return call;
12670}
12671
florian55085f82012-11-21 00:36:55 +000012672static const HChar *
floriana0100c92012-07-20 00:06:35 +000012673s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
12674{
12675 IRTemp addr1 = newTemp(Ity_I64);
12676 IRTemp addr2 = newTemp(Ity_I64);
12677 IRTemp len1 = newTemp(Ity_I64);
12678 IRTemp len2 = newTemp(Ity_I64);
12679
12680 assign(addr1, get_gpr_dw0(r1));
12681 assign(addr2, get_gpr_dw0(r2));
12682 assign(len1, get_gpr_dw0(r1 + 1));
12683 assign(len2, get_gpr_dw0(r2 + 1));
12684
12685 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12686 there are less than 2 bytes left, then the 2nd operand is exhausted
12687 and we're done here. cc = 0 */
12688 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012689 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000012690
12691 /* There are at least two bytes there. Read them. */
12692 IRTemp srcval = newTemp(Ity_I32);
12693 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12694
12695 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12696 inside the interval [0xd800 - 0xdbff] */
12697 IRTemp is_high_surrogate = newTemp(Ity_I32);
12698 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12699 mkU32(1), mkU32(0));
12700 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12701 mkU32(1), mkU32(0));
12702 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12703
12704 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12705 then the 2nd operand is exhausted and we're done here. cc = 0 */
12706 IRExpr *not_enough_bytes =
12707 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12708
florian6820ba52012-07-26 02:01:50 +000012709 next_insn_if(binop(Iop_CmpEQ32,
12710 binop(Iop_And32, mkexpr(is_high_surrogate),
12711 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000012712
12713 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12714 surrogate, read the next two bytes (low surrogate). */
12715 IRTemp low_surrogate = newTemp(Ity_I32);
12716 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12717
12718 assign(low_surrogate,
12719 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12720 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12721 mkU32(0))); // any value is fine; it will not be used
12722
12723 /* Call the helper */
12724 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012725 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
12726 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000012727
12728 /* Before we can test whether the 1st operand is exhausted we need to
12729 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12730 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12731 IRExpr *invalid_low_surrogate =
12732 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12733
12734 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012735 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000012736 }
12737
12738 /* Now test whether the 1st operand is exhausted */
12739 IRTemp num_bytes = newTemp(Ity_I64);
12740 assign(num_bytes, binop(Iop_And64,
12741 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12742 mkU64(0xff)));
12743 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012744 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000012745
12746 /* Extract the bytes to be stored at addr1 */
12747 IRTemp data = newTemp(Ity_I64);
12748 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12749
12750 /* To store the bytes construct 4 dirty helper calls. The helper calls
12751 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12752 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012753 UInt i;
floriana0100c92012-07-20 00:06:35 +000012754 for (i = 1; i <= 4; ++i) {
12755 IRDirty *d;
12756
12757 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12758 &s390x_dirtyhelper_CUxy,
12759 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12760 mkexpr(num_bytes)));
12761 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12762 d->mFx = Ifx_Write;
12763 d->mAddr = mkexpr(addr1);
12764 d->mSize = i;
12765 stmt(IRStmt_Dirty(d));
12766 }
12767
12768 /* Update source address and length */
12769 IRTemp num_src_bytes = newTemp(Ity_I64);
12770 assign(num_src_bytes,
12771 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12772 mkU64(4), mkU64(2)));
12773 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12774 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12775
12776 /* Update destination address and length */
12777 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12778 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12779
florian6820ba52012-07-26 02:01:50 +000012780 iterate();
floriana0100c92012-07-20 00:06:35 +000012781
12782 return "cu21";
12783}
12784
florian2a415a12012-07-21 17:41:36 +000012785static IRExpr *
12786s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
12787{
12788 IRExpr **args, *call;
12789 args = mkIRExprVec_2(srcval, low_surrogate);
12790 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12791 "s390_do_cu24", &s390_do_cu24, args);
12792
12793 /* Nothing is excluded from definedness checking. */
12794 call->Iex.CCall.cee->mcx_mask = 0;
12795
12796 return call;
12797}
12798
florian55085f82012-11-21 00:36:55 +000012799static const HChar *
florian2a415a12012-07-21 17:41:36 +000012800s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
12801{
12802 IRTemp addr1 = newTemp(Ity_I64);
12803 IRTemp addr2 = newTemp(Ity_I64);
12804 IRTemp len1 = newTemp(Ity_I64);
12805 IRTemp len2 = newTemp(Ity_I64);
12806
12807 assign(addr1, get_gpr_dw0(r1));
12808 assign(addr2, get_gpr_dw0(r2));
12809 assign(len1, get_gpr_dw0(r1 + 1));
12810 assign(len2, get_gpr_dw0(r2 + 1));
12811
12812 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12813 there are less than 2 bytes left, then the 2nd operand is exhausted
12814 and we're done here. cc = 0 */
12815 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012816 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000012817
12818 /* There are at least two bytes there. Read them. */
12819 IRTemp srcval = newTemp(Ity_I32);
12820 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12821
12822 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12823 inside the interval [0xd800 - 0xdbff] */
12824 IRTemp is_high_surrogate = newTemp(Ity_I32);
12825 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12826 mkU32(1), mkU32(0));
12827 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12828 mkU32(1), mkU32(0));
12829 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12830
12831 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12832 then the 2nd operand is exhausted and we're done here. cc = 0 */
12833 IRExpr *not_enough_bytes =
12834 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12835
florian6820ba52012-07-26 02:01:50 +000012836 next_insn_if(binop(Iop_CmpEQ32,
12837 binop(Iop_And32, mkexpr(is_high_surrogate),
12838 not_enough_bytes),
12839 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012840
12841 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12842 surrogate, read the next two bytes (low surrogate). */
12843 IRTemp low_surrogate = newTemp(Ity_I32);
12844 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12845
12846 assign(low_surrogate,
12847 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12848 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12849 mkU32(0))); // any value is fine; it will not be used
12850
12851 /* Call the helper */
12852 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012853 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12854 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012855
12856 /* Before we can test whether the 1st operand is exhausted we need to
12857 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12858 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12859 IRExpr *invalid_low_surrogate =
12860 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12861
12862 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012863 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012864 }
12865
12866 /* Now test whether the 1st operand is exhausted */
12867 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012868 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012869
12870 /* Extract the bytes to be stored at addr1 */
12871 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12872
12873 store(mkexpr(addr1), data);
12874
12875 /* Update source address and length */
12876 IRTemp num_src_bytes = newTemp(Ity_I64);
12877 assign(num_src_bytes,
12878 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12879 mkU64(4), mkU64(2)));
12880 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12881 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12882
12883 /* Update destination address and length */
12884 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12885 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12886
florian6820ba52012-07-26 02:01:50 +000012887 iterate();
florian2a415a12012-07-21 17:41:36 +000012888
12889 return "cu24";
12890}
floriana4384a32011-08-11 16:58:45 +000012891
florian956194b2012-07-28 22:18:32 +000012892static IRExpr *
12893s390_call_cu42(IRExpr *srcval)
12894{
12895 IRExpr **args, *call;
12896 args = mkIRExprVec_1(srcval);
12897 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12898 "s390_do_cu42", &s390_do_cu42, args);
12899
12900 /* Nothing is excluded from definedness checking. */
12901 call->Iex.CCall.cee->mcx_mask = 0;
12902
12903 return call;
12904}
12905
florian55085f82012-11-21 00:36:55 +000012906static const HChar *
florian956194b2012-07-28 22:18:32 +000012907s390_irgen_CU42(UChar r1, UChar r2)
12908{
12909 IRTemp addr1 = newTemp(Ity_I64);
12910 IRTemp addr2 = newTemp(Ity_I64);
12911 IRTemp len1 = newTemp(Ity_I64);
12912 IRTemp len2 = newTemp(Ity_I64);
12913
12914 assign(addr1, get_gpr_dw0(r1));
12915 assign(addr2, get_gpr_dw0(r2));
12916 assign(len1, get_gpr_dw0(r1 + 1));
12917 assign(len2, get_gpr_dw0(r2 + 1));
12918
12919 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12920 there are less than 4 bytes left, then the 2nd operand is exhausted
12921 and we're done here. cc = 0 */
12922 s390_cc_set(0);
12923 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12924
12925 /* Read the 2nd operand. */
12926 IRTemp srcval = newTemp(Ity_I32);
12927 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12928
12929 /* Call the helper */
12930 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012931 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012932
12933 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12934 cc=2 outranks cc=1 (1st operand exhausted) */
12935 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12936
12937 s390_cc_set(2);
12938 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12939
12940 /* Now test whether the 1st operand is exhausted */
12941 IRTemp num_bytes = newTemp(Ity_I64);
12942 assign(num_bytes, binop(Iop_And64,
12943 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12944 mkU64(0xff)));
12945 s390_cc_set(1);
12946 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12947
12948 /* Extract the bytes to be stored at addr1 */
12949 IRTemp data = newTemp(Ity_I64);
12950 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12951
12952 /* To store the bytes construct 2 dirty helper calls. The helper calls
12953 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12954 that only one of them will be called at runtime. */
12955
12956 Int i;
12957 for (i = 2; i <= 4; ++i) {
12958 IRDirty *d;
12959
12960 if (i == 3) continue; // skip this one
12961
12962 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12963 &s390x_dirtyhelper_CUxy,
12964 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12965 mkexpr(num_bytes)));
12966 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12967 d->mFx = Ifx_Write;
12968 d->mAddr = mkexpr(addr1);
12969 d->mSize = i;
12970 stmt(IRStmt_Dirty(d));
12971 }
12972
12973 /* Update source address and length */
12974 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12975 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12976
12977 /* Update destination address and length */
12978 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12979 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12980
12981 iterate();
12982
12983 return "cu42";
12984}
12985
florian6d9b9b22012-08-03 18:35:39 +000012986static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012987s390_call_cu41(IRExpr *srcval)
12988{
12989 IRExpr **args, *call;
12990 args = mkIRExprVec_1(srcval);
12991 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12992 "s390_do_cu41", &s390_do_cu41, args);
12993
12994 /* Nothing is excluded from definedness checking. */
12995 call->Iex.CCall.cee->mcx_mask = 0;
12996
12997 return call;
12998}
12999
florian55085f82012-11-21 00:36:55 +000013000static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013001s390_irgen_CU41(UChar r1, UChar r2)
13002{
13003 IRTemp addr1 = newTemp(Ity_I64);
13004 IRTemp addr2 = newTemp(Ity_I64);
13005 IRTemp len1 = newTemp(Ity_I64);
13006 IRTemp len2 = newTemp(Ity_I64);
13007
13008 assign(addr1, get_gpr_dw0(r1));
13009 assign(addr2, get_gpr_dw0(r2));
13010 assign(len1, get_gpr_dw0(r1 + 1));
13011 assign(len2, get_gpr_dw0(r2 + 1));
13012
13013 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13014 there are less than 4 bytes left, then the 2nd operand is exhausted
13015 and we're done here. cc = 0 */
13016 s390_cc_set(0);
13017 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13018
13019 /* Read the 2nd operand. */
13020 IRTemp srcval = newTemp(Ity_I32);
13021 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13022
13023 /* Call the helper */
13024 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013025 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013026
13027 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13028 cc=2 outranks cc=1 (1st operand exhausted) */
13029 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13030
13031 s390_cc_set(2);
13032 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13033
13034 /* Now test whether the 1st operand is exhausted */
13035 IRTemp num_bytes = newTemp(Ity_I64);
13036 assign(num_bytes, binop(Iop_And64,
13037 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13038 mkU64(0xff)));
13039 s390_cc_set(1);
13040 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13041
13042 /* Extract the bytes to be stored at addr1 */
13043 IRTemp data = newTemp(Ity_I64);
13044 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13045
13046 /* To store the bytes construct 4 dirty helper calls. The helper calls
13047 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13048 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013049 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013050 for (i = 1; i <= 4; ++i) {
13051 IRDirty *d;
13052
13053 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13054 &s390x_dirtyhelper_CUxy,
13055 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13056 mkexpr(num_bytes)));
13057 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13058 d->mFx = Ifx_Write;
13059 d->mAddr = mkexpr(addr1);
13060 d->mSize = i;
13061 stmt(IRStmt_Dirty(d));
13062 }
13063
13064 /* Update source address and length */
13065 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13066 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13067
13068 /* Update destination address and length */
13069 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13070 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13071
13072 iterate();
13073
13074 return "cu41";
13075}
13076
13077static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013078s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013079{
13080 IRExpr **args, *call;
13081 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013082 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13083 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013084
13085 /* Nothing is excluded from definedness checking. */
13086 call->Iex.CCall.cee->mcx_mask = 0;
13087
13088 return call;
13089}
13090
13091static IRExpr *
13092s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13093 IRExpr *byte4, IRExpr *stuff)
13094{
13095 IRExpr **args, *call;
13096 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13097 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13098 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13099
13100 /* Nothing is excluded from definedness checking. */
13101 call->Iex.CCall.cee->mcx_mask = 0;
13102
13103 return call;
13104}
13105
florian3f8a96a2012-08-05 02:59:55 +000013106static IRExpr *
13107s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13108 IRExpr *byte4, IRExpr *stuff)
13109{
13110 IRExpr **args, *call;
13111 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13112 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13113 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13114
13115 /* Nothing is excluded from definedness checking. */
13116 call->Iex.CCall.cee->mcx_mask = 0;
13117
13118 return call;
13119}
13120
13121static void
13122s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013123{
13124 IRTemp addr1 = newTemp(Ity_I64);
13125 IRTemp addr2 = newTemp(Ity_I64);
13126 IRTemp len1 = newTemp(Ity_I64);
13127 IRTemp len2 = newTemp(Ity_I64);
13128
13129 assign(addr1, get_gpr_dw0(r1));
13130 assign(addr2, get_gpr_dw0(r2));
13131 assign(len1, get_gpr_dw0(r1 + 1));
13132 assign(len2, get_gpr_dw0(r2 + 1));
13133
13134 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13135
13136 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13137 there is less than 1 byte left, then the 2nd operand is exhausted
13138 and we're done here. cc = 0 */
13139 s390_cc_set(0);
13140 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13141
13142 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013143 IRTemp byte1 = newTemp(Ity_I64);
13144 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013145
13146 /* Call the helper to get number of bytes and invalid byte indicator */
13147 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013148 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013149 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013150
13151 /* Check for invalid 1st byte */
13152 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13153 s390_cc_set(2);
13154 next_insn_if(is_invalid);
13155
13156 /* How many bytes do we have to read? */
13157 IRTemp num_src_bytes = newTemp(Ity_I64);
13158 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13159
13160 /* Now test whether the 2nd operand is exhausted */
13161 s390_cc_set(0);
13162 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13163
13164 /* Read the remaining bytes */
13165 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13166
13167 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13168 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013169 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013170 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13171 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013172 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013173 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13174 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013175 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013176
13177 /* Call the helper to get the converted value and invalid byte indicator.
13178 We can pass at most 5 arguments; therefore some encoding is needed
13179 here */
13180 IRExpr *stuff = binop(Iop_Or64,
13181 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13182 mkU64(extended_checking));
13183 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013184
13185 if (is_cu12) {
13186 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13187 byte4, stuff));
13188 } else {
13189 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13190 byte4, stuff));
13191 }
florian6d9b9b22012-08-03 18:35:39 +000013192
13193 /* Check for invalid character */
13194 s390_cc_set(2);
13195 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13196 next_insn_if(is_invalid);
13197
13198 /* Now test whether the 1st operand is exhausted */
13199 IRTemp num_bytes = newTemp(Ity_I64);
13200 assign(num_bytes, binop(Iop_And64,
13201 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13202 mkU64(0xff)));
13203 s390_cc_set(1);
13204 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13205
13206 /* Extract the bytes to be stored at addr1 */
13207 IRTemp data = newTemp(Ity_I64);
13208 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13209
florian3f8a96a2012-08-05 02:59:55 +000013210 if (is_cu12) {
13211 /* To store the bytes construct 2 dirty helper calls. The helper calls
13212 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13213 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013214
florian3f8a96a2012-08-05 02:59:55 +000013215 Int i;
13216 for (i = 2; i <= 4; ++i) {
13217 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013218
florian3f8a96a2012-08-05 02:59:55 +000013219 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013220
florian3f8a96a2012-08-05 02:59:55 +000013221 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13222 &s390x_dirtyhelper_CUxy,
13223 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13224 mkexpr(num_bytes)));
13225 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13226 d->mFx = Ifx_Write;
13227 d->mAddr = mkexpr(addr1);
13228 d->mSize = i;
13229 stmt(IRStmt_Dirty(d));
13230 }
13231 } else {
13232 // cu14
13233 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013234 }
13235
13236 /* Update source address and length */
13237 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13238 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13239
13240 /* Update destination address and length */
13241 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13242 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13243
13244 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013245}
13246
florian55085f82012-11-21 00:36:55 +000013247static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013248s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13249{
13250 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013251
13252 return "cu12";
13253}
13254
florian55085f82012-11-21 00:36:55 +000013255static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013256s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13257{
13258 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13259
13260 return "cu14";
13261}
13262
florian8c88cb62012-08-26 18:58:13 +000013263static IRExpr *
13264s390_call_ecag(IRExpr *op2addr)
13265{
13266 IRExpr **args, *call;
13267
13268 args = mkIRExprVec_1(op2addr);
13269 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13270 "s390_do_ecag", &s390_do_ecag, args);
13271
13272 /* Nothing is excluded from definedness checking. */
13273 call->Iex.CCall.cee->mcx_mask = 0;
13274
13275 return call;
13276}
13277
florian55085f82012-11-21 00:36:55 +000013278static const HChar *
floriand2129202012-09-01 20:01:39 +000013279s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013280{
13281 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013282 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013283 } else {
13284 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13285 }
13286
13287 return "ecag";
13288}
13289
13290
florianb7def222012-12-04 04:45:32 +000013291/* New insns are added here.
13292 If an insn is contingent on a facility being installed also
13293 check whether the list of supported facilities in function
13294 s390x_dirtyhelper_STFLE needs updating */
13295
sewardj2019a972011-03-07 16:04:07 +000013296/*------------------------------------------------------------*/
13297/*--- Build IR for special instructions ---*/
13298/*------------------------------------------------------------*/
13299
florianb4df7682011-07-05 02:09:01 +000013300static void
sewardj2019a972011-03-07 16:04:07 +000013301s390_irgen_client_request(void)
13302{
13303 if (0)
13304 vex_printf("%%R3 = client_request ( %%R2 )\n");
13305
florianf9e1ed72012-04-17 02:41:56 +000013306 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13307 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013308
florianf9e1ed72012-04-17 02:41:56 +000013309 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013310 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013311
13312 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013313}
13314
florianb4df7682011-07-05 02:09:01 +000013315static void
sewardj2019a972011-03-07 16:04:07 +000013316s390_irgen_guest_NRADDR(void)
13317{
13318 if (0)
13319 vex_printf("%%R3 = guest_NRADDR\n");
13320
floriane88b3c92011-07-05 02:48:39 +000013321 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013322}
13323
florianb4df7682011-07-05 02:09:01 +000013324static void
sewardj2019a972011-03-07 16:04:07 +000013325s390_irgen_call_noredir(void)
13326{
florianf9e1ed72012-04-17 02:41:56 +000013327 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13328 + S390_SPECIAL_OP_SIZE;
13329
sewardj2019a972011-03-07 16:04:07 +000013330 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013331 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013332
13333 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013334 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013335
13336 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013337 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013338}
13339
13340/* Force proper alignment for the structures below. */
13341#pragma pack(1)
13342
13343
13344static s390_decode_t
13345s390_decode_2byte_and_irgen(UChar *bytes)
13346{
13347 typedef union {
13348 struct {
13349 unsigned int op : 16;
13350 } E;
13351 struct {
13352 unsigned int op : 8;
13353 unsigned int i : 8;
13354 } I;
13355 struct {
13356 unsigned int op : 8;
13357 unsigned int r1 : 4;
13358 unsigned int r2 : 4;
13359 } RR;
13360 } formats;
13361 union {
13362 formats fmt;
13363 UShort value;
13364 } ovl;
13365
13366 vassert(sizeof(formats) == 2);
13367
florianffbd84d2012-12-09 02:06:29 +000013368 ((UChar *)(&ovl.value))[0] = bytes[0];
13369 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013370
13371 switch (ovl.value & 0xffff) {
13372 case 0x0101: /* PR */ goto unimplemented;
13373 case 0x0102: /* UPT */ goto unimplemented;
13374 case 0x0104: /* PTFF */ goto unimplemented;
13375 case 0x0107: /* SCKPF */ goto unimplemented;
13376 case 0x010a: /* PFPO */ goto unimplemented;
13377 case 0x010b: /* TAM */ goto unimplemented;
13378 case 0x010c: /* SAM24 */ goto unimplemented;
13379 case 0x010d: /* SAM31 */ goto unimplemented;
13380 case 0x010e: /* SAM64 */ goto unimplemented;
13381 case 0x01ff: /* TRAP2 */ goto unimplemented;
13382 }
13383
13384 switch ((ovl.value & 0xff00) >> 8) {
13385 case 0x04: /* SPM */ goto unimplemented;
13386 case 0x05: /* BALR */ goto unimplemented;
13387 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13388 goto ok;
13389 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13390 goto ok;
13391 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13392 case 0x0b: /* BSM */ goto unimplemented;
13393 case 0x0c: /* BASSM */ goto unimplemented;
13394 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13395 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013396 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13397 goto ok;
13398 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13399 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013400 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13401 goto ok;
13402 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13403 goto ok;
13404 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13405 goto ok;
13406 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13407 goto ok;
13408 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13409 goto ok;
13410 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13411 goto ok;
13412 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13413 goto ok;
13414 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13415 goto ok;
13416 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13417 goto ok;
13418 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13419 goto ok;
13420 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13421 goto ok;
13422 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13423 goto ok;
13424 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13425 goto ok;
13426 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13427 goto ok;
13428 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13429 goto ok;
13430 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13431 goto ok;
13432 case 0x20: /* LPDR */ goto unimplemented;
13433 case 0x21: /* LNDR */ goto unimplemented;
13434 case 0x22: /* LTDR */ goto unimplemented;
13435 case 0x23: /* LCDR */ goto unimplemented;
13436 case 0x24: /* HDR */ goto unimplemented;
13437 case 0x25: /* LDXR */ goto unimplemented;
13438 case 0x26: /* MXR */ goto unimplemented;
13439 case 0x27: /* MXDR */ goto unimplemented;
13440 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13441 goto ok;
13442 case 0x29: /* CDR */ goto unimplemented;
13443 case 0x2a: /* ADR */ goto unimplemented;
13444 case 0x2b: /* SDR */ goto unimplemented;
13445 case 0x2c: /* MDR */ goto unimplemented;
13446 case 0x2d: /* DDR */ goto unimplemented;
13447 case 0x2e: /* AWR */ goto unimplemented;
13448 case 0x2f: /* SWR */ goto unimplemented;
13449 case 0x30: /* LPER */ goto unimplemented;
13450 case 0x31: /* LNER */ goto unimplemented;
13451 case 0x32: /* LTER */ goto unimplemented;
13452 case 0x33: /* LCER */ goto unimplemented;
13453 case 0x34: /* HER */ goto unimplemented;
13454 case 0x35: /* LEDR */ goto unimplemented;
13455 case 0x36: /* AXR */ goto unimplemented;
13456 case 0x37: /* SXR */ goto unimplemented;
13457 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13458 goto ok;
13459 case 0x39: /* CER */ goto unimplemented;
13460 case 0x3a: /* AER */ goto unimplemented;
13461 case 0x3b: /* SER */ goto unimplemented;
13462 case 0x3c: /* MDER */ goto unimplemented;
13463 case 0x3d: /* DER */ goto unimplemented;
13464 case 0x3e: /* AUR */ goto unimplemented;
13465 case 0x3f: /* SUR */ goto unimplemented;
13466 }
13467
13468 return S390_DECODE_UNKNOWN_INSN;
13469
13470ok:
13471 return S390_DECODE_OK;
13472
13473unimplemented:
13474 return S390_DECODE_UNIMPLEMENTED_INSN;
13475}
13476
13477static s390_decode_t
13478s390_decode_4byte_and_irgen(UChar *bytes)
13479{
13480 typedef union {
13481 struct {
13482 unsigned int op1 : 8;
13483 unsigned int r1 : 4;
13484 unsigned int op2 : 4;
13485 unsigned int i2 : 16;
13486 } RI;
13487 struct {
13488 unsigned int op : 16;
13489 unsigned int : 8;
13490 unsigned int r1 : 4;
13491 unsigned int r2 : 4;
13492 } RRE;
13493 struct {
13494 unsigned int op : 16;
13495 unsigned int r1 : 4;
13496 unsigned int : 4;
13497 unsigned int r3 : 4;
13498 unsigned int r2 : 4;
13499 } RRF;
13500 struct {
13501 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000013502 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000013503 unsigned int m4 : 4;
13504 unsigned int r1 : 4;
13505 unsigned int r2 : 4;
13506 } RRF2;
13507 struct {
13508 unsigned int op : 16;
13509 unsigned int r3 : 4;
13510 unsigned int : 4;
13511 unsigned int r1 : 4;
13512 unsigned int r2 : 4;
13513 } RRF3;
13514 struct {
13515 unsigned int op : 16;
13516 unsigned int r3 : 4;
13517 unsigned int : 4;
13518 unsigned int r1 : 4;
13519 unsigned int r2 : 4;
13520 } RRR;
13521 struct {
13522 unsigned int op : 16;
13523 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013524 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013525 unsigned int r1 : 4;
13526 unsigned int r2 : 4;
13527 } RRF4;
13528 struct {
floriane38f6412012-12-21 17:32:12 +000013529 unsigned int op : 16;
13530 unsigned int : 4;
13531 unsigned int m4 : 4;
13532 unsigned int r1 : 4;
13533 unsigned int r2 : 4;
13534 } RRF5;
13535 struct {
sewardj2019a972011-03-07 16:04:07 +000013536 unsigned int op : 8;
13537 unsigned int r1 : 4;
13538 unsigned int r3 : 4;
13539 unsigned int b2 : 4;
13540 unsigned int d2 : 12;
13541 } RS;
13542 struct {
13543 unsigned int op : 8;
13544 unsigned int r1 : 4;
13545 unsigned int r3 : 4;
13546 unsigned int i2 : 16;
13547 } RSI;
13548 struct {
13549 unsigned int op : 8;
13550 unsigned int r1 : 4;
13551 unsigned int x2 : 4;
13552 unsigned int b2 : 4;
13553 unsigned int d2 : 12;
13554 } RX;
13555 struct {
13556 unsigned int op : 16;
13557 unsigned int b2 : 4;
13558 unsigned int d2 : 12;
13559 } S;
13560 struct {
13561 unsigned int op : 8;
13562 unsigned int i2 : 8;
13563 unsigned int b1 : 4;
13564 unsigned int d1 : 12;
13565 } SI;
13566 } formats;
13567 union {
13568 formats fmt;
13569 UInt value;
13570 } ovl;
13571
13572 vassert(sizeof(formats) == 4);
13573
florianffbd84d2012-12-09 02:06:29 +000013574 ((UChar *)(&ovl.value))[0] = bytes[0];
13575 ((UChar *)(&ovl.value))[1] = bytes[1];
13576 ((UChar *)(&ovl.value))[2] = bytes[2];
13577 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013578
13579 switch ((ovl.value & 0xff0f0000) >> 16) {
13580 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13581 ovl.fmt.RI.i2); goto ok;
13582 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13583 ovl.fmt.RI.i2); goto ok;
13584 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
13585 ovl.fmt.RI.i2); goto ok;
13586 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
13587 ovl.fmt.RI.i2); goto ok;
13588 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
13589 ovl.fmt.RI.i2); goto ok;
13590 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
13591 ovl.fmt.RI.i2); goto ok;
13592 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
13593 ovl.fmt.RI.i2); goto ok;
13594 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
13595 ovl.fmt.RI.i2); goto ok;
13596 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
13597 ovl.fmt.RI.i2); goto ok;
13598 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
13599 ovl.fmt.RI.i2); goto ok;
13600 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
13601 ovl.fmt.RI.i2); goto ok;
13602 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
13603 ovl.fmt.RI.i2); goto ok;
13604 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
13605 ovl.fmt.RI.i2); goto ok;
13606 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
13607 ovl.fmt.RI.i2); goto ok;
13608 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
13609 ovl.fmt.RI.i2); goto ok;
13610 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
13611 ovl.fmt.RI.i2); goto ok;
13612 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
13613 ovl.fmt.RI.i2); goto ok;
13614 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
13615 ovl.fmt.RI.i2); goto ok;
13616 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
13617 ovl.fmt.RI.i2); goto ok;
13618 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
13619 ovl.fmt.RI.i2); goto ok;
13620 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13621 goto ok;
13622 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
13623 ovl.fmt.RI.i2); goto ok;
13624 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
13625 ovl.fmt.RI.i2); goto ok;
13626 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
13627 ovl.fmt.RI.i2); goto ok;
13628 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13629 goto ok;
13630 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
13631 ovl.fmt.RI.i2); goto ok;
13632 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13633 goto ok;
13634 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
13635 ovl.fmt.RI.i2); goto ok;
13636 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13637 goto ok;
13638 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
13639 ovl.fmt.RI.i2); goto ok;
13640 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13641 goto ok;
13642 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
13643 ovl.fmt.RI.i2); goto ok;
13644 }
13645
13646 switch ((ovl.value & 0xffff0000) >> 16) {
13647 case 0x8000: /* SSM */ goto unimplemented;
13648 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013649 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013650 case 0xb202: /* STIDP */ goto unimplemented;
13651 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013652 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
13653 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013654 case 0xb206: /* SCKC */ goto unimplemented;
13655 case 0xb207: /* STCKC */ goto unimplemented;
13656 case 0xb208: /* SPT */ goto unimplemented;
13657 case 0xb209: /* STPT */ goto unimplemented;
13658 case 0xb20a: /* SPKA */ goto unimplemented;
13659 case 0xb20b: /* IPK */ goto unimplemented;
13660 case 0xb20d: /* PTLB */ goto unimplemented;
13661 case 0xb210: /* SPX */ goto unimplemented;
13662 case 0xb211: /* STPX */ goto unimplemented;
13663 case 0xb212: /* STAP */ goto unimplemented;
13664 case 0xb214: /* SIE */ goto unimplemented;
13665 case 0xb218: /* PC */ goto unimplemented;
13666 case 0xb219: /* SAC */ goto unimplemented;
13667 case 0xb21a: /* CFC */ goto unimplemented;
13668 case 0xb221: /* IPTE */ goto unimplemented;
13669 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
13670 case 0xb223: /* IVSK */ goto unimplemented;
13671 case 0xb224: /* IAC */ goto unimplemented;
13672 case 0xb225: /* SSAR */ goto unimplemented;
13673 case 0xb226: /* EPAR */ goto unimplemented;
13674 case 0xb227: /* ESAR */ goto unimplemented;
13675 case 0xb228: /* PT */ goto unimplemented;
13676 case 0xb229: /* ISKE */ goto unimplemented;
13677 case 0xb22a: /* RRBE */ goto unimplemented;
13678 case 0xb22b: /* SSKE */ goto unimplemented;
13679 case 0xb22c: /* TB */ goto unimplemented;
13680 case 0xb22d: /* DXR */ goto unimplemented;
13681 case 0xb22e: /* PGIN */ goto unimplemented;
13682 case 0xb22f: /* PGOUT */ goto unimplemented;
13683 case 0xb230: /* CSCH */ goto unimplemented;
13684 case 0xb231: /* HSCH */ goto unimplemented;
13685 case 0xb232: /* MSCH */ goto unimplemented;
13686 case 0xb233: /* SSCH */ goto unimplemented;
13687 case 0xb234: /* STSCH */ goto unimplemented;
13688 case 0xb235: /* TSCH */ goto unimplemented;
13689 case 0xb236: /* TPI */ goto unimplemented;
13690 case 0xb237: /* SAL */ goto unimplemented;
13691 case 0xb238: /* RSCH */ goto unimplemented;
13692 case 0xb239: /* STCRW */ goto unimplemented;
13693 case 0xb23a: /* STCPS */ goto unimplemented;
13694 case 0xb23b: /* RCHP */ goto unimplemented;
13695 case 0xb23c: /* SCHM */ goto unimplemented;
13696 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000013697 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
13698 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013699 case 0xb244: /* SQDR */ goto unimplemented;
13700 case 0xb245: /* SQER */ goto unimplemented;
13701 case 0xb246: /* STURA */ goto unimplemented;
13702 case 0xb247: /* MSTA */ goto unimplemented;
13703 case 0xb248: /* PALB */ goto unimplemented;
13704 case 0xb249: /* EREG */ goto unimplemented;
13705 case 0xb24a: /* ESTA */ goto unimplemented;
13706 case 0xb24b: /* LURA */ goto unimplemented;
13707 case 0xb24c: /* TAR */ goto unimplemented;
13708 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
13709 ovl.fmt.RRE.r2); goto ok;
13710 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13711 goto ok;
13712 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13713 goto ok;
13714 case 0xb250: /* CSP */ goto unimplemented;
13715 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
13716 ovl.fmt.RRE.r2); goto ok;
13717 case 0xb254: /* MVPG */ goto unimplemented;
13718 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
13719 ovl.fmt.RRE.r2); goto ok;
13720 case 0xb257: /* CUSE */ goto unimplemented;
13721 case 0xb258: /* BSG */ goto unimplemented;
13722 case 0xb25a: /* BSA */ goto unimplemented;
13723 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
13724 ovl.fmt.RRE.r2); goto ok;
13725 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
13726 ovl.fmt.RRE.r2); goto ok;
13727 case 0xb263: /* CMPSC */ goto unimplemented;
13728 case 0xb274: /* SIGA */ goto unimplemented;
13729 case 0xb276: /* XSCH */ goto unimplemented;
13730 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013731 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 +000013732 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013733 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 +000013734 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013735 case 0xb280: /* LPP */ goto unimplemented;
13736 case 0xb284: /* LCCTL */ goto unimplemented;
13737 case 0xb285: /* LPCTL */ goto unimplemented;
13738 case 0xb286: /* QSI */ goto unimplemented;
13739 case 0xb287: /* LSCTL */ goto unimplemented;
13740 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013741 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
13742 goto ok;
13743 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13744 goto ok;
13745 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13746 goto ok;
florian730448f2012-02-04 17:07:07 +000013747 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 +000013748 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
13749 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13750 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000013751 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
13752 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13753 goto ok;
florian933065d2011-07-11 01:48:02 +000013754 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
13755 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013756 case 0xb2b1: /* STFL */ goto unimplemented;
13757 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000013758 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
13759 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013760 case 0xb2b9: /* SRNMT */ goto unimplemented;
13761 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013762 case 0xb2e0: /* SCCTR */ goto unimplemented;
13763 case 0xb2e1: /* SPCTR */ goto unimplemented;
13764 case 0xb2e4: /* ECCTR */ goto unimplemented;
13765 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013766 case 0xb2e8: /* PPA */ goto unimplemented;
13767 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013768 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013769 case 0xb2f8: /* TEND */ goto unimplemented;
13770 case 0xb2fa: /* NIAI */ goto unimplemented;
13771 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013772 case 0xb2ff: /* TRAP4 */ goto unimplemented;
13773 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
13774 ovl.fmt.RRE.r2); goto ok;
13775 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
13776 ovl.fmt.RRE.r2); goto ok;
13777 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
13778 ovl.fmt.RRE.r2); goto ok;
13779 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
13780 ovl.fmt.RRE.r2); goto ok;
13781 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
13782 ovl.fmt.RRE.r2); goto ok;
13783 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
13784 ovl.fmt.RRE.r2); goto ok;
13785 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
13786 ovl.fmt.RRE.r2); goto ok;
13787 case 0xb307: /* MXDBR */ goto unimplemented;
13788 case 0xb308: /* KEBR */ goto unimplemented;
13789 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
13790 ovl.fmt.RRE.r2); goto ok;
13791 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
13792 ovl.fmt.RRE.r2); goto ok;
13793 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
13794 ovl.fmt.RRE.r2); goto ok;
13795 case 0xb30c: /* MDEBR */ goto unimplemented;
13796 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
13797 ovl.fmt.RRE.r2); goto ok;
13798 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
13799 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13800 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
13801 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13802 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
13803 ovl.fmt.RRE.r2); goto ok;
13804 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
13805 ovl.fmt.RRE.r2); goto ok;
13806 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
13807 ovl.fmt.RRE.r2); goto ok;
13808 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
13809 ovl.fmt.RRE.r2); goto ok;
13810 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
13811 ovl.fmt.RRE.r2); goto ok;
13812 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
13813 ovl.fmt.RRE.r2); goto ok;
13814 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
13815 ovl.fmt.RRE.r2); goto ok;
13816 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
13817 ovl.fmt.RRE.r2); goto ok;
13818 case 0xb318: /* KDBR */ goto unimplemented;
13819 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
13820 ovl.fmt.RRE.r2); goto ok;
13821 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
13822 ovl.fmt.RRE.r2); goto ok;
13823 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
13824 ovl.fmt.RRE.r2); goto ok;
13825 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
13826 ovl.fmt.RRE.r2); goto ok;
13827 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
13828 ovl.fmt.RRE.r2); goto ok;
13829 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
13830 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13831 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
13832 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13833 case 0xb324: /* LDER */ goto unimplemented;
13834 case 0xb325: /* LXDR */ goto unimplemented;
13835 case 0xb326: /* LXER */ goto unimplemented;
13836 case 0xb32e: /* MAER */ goto unimplemented;
13837 case 0xb32f: /* MSER */ goto unimplemented;
13838 case 0xb336: /* SQXR */ goto unimplemented;
13839 case 0xb337: /* MEER */ goto unimplemented;
13840 case 0xb338: /* MAYLR */ goto unimplemented;
13841 case 0xb339: /* MYLR */ goto unimplemented;
13842 case 0xb33a: /* MAYR */ goto unimplemented;
13843 case 0xb33b: /* MYR */ goto unimplemented;
13844 case 0xb33c: /* MAYHR */ goto unimplemented;
13845 case 0xb33d: /* MYHR */ goto unimplemented;
13846 case 0xb33e: /* MADR */ goto unimplemented;
13847 case 0xb33f: /* MSDR */ goto unimplemented;
13848 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
13849 ovl.fmt.RRE.r2); goto ok;
13850 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
13851 ovl.fmt.RRE.r2); goto ok;
13852 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
13853 ovl.fmt.RRE.r2); goto ok;
13854 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
13855 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013856 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13857 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13858 ovl.fmt.RRF2.r2); goto ok;
13859 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13860 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13861 ovl.fmt.RRF2.r2); goto ok;
13862 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13863 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13864 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013865 case 0xb347: /* FIXBR */ goto unimplemented;
13866 case 0xb348: /* KXBR */ goto unimplemented;
13867 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13868 ovl.fmt.RRE.r2); goto ok;
13869 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13870 ovl.fmt.RRE.r2); goto ok;
13871 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13872 ovl.fmt.RRE.r2); goto ok;
13873 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13874 ovl.fmt.RRE.r2); goto ok;
13875 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13876 ovl.fmt.RRE.r2); goto ok;
13877 case 0xb350: /* TBEDR */ goto unimplemented;
13878 case 0xb351: /* TBDR */ goto unimplemented;
13879 case 0xb353: /* DIEBR */ goto unimplemented;
13880 case 0xb357: /* FIEBR */ goto unimplemented;
13881 case 0xb358: /* THDER */ goto unimplemented;
13882 case 0xb359: /* THDR */ goto unimplemented;
13883 case 0xb35b: /* DIDBR */ goto unimplemented;
13884 case 0xb35f: /* FIDBR */ goto unimplemented;
13885 case 0xb360: /* LPXR */ goto unimplemented;
13886 case 0xb361: /* LNXR */ goto unimplemented;
13887 case 0xb362: /* LTXR */ goto unimplemented;
13888 case 0xb363: /* LCXR */ goto unimplemented;
13889 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13890 ovl.fmt.RRE.r2); goto ok;
13891 case 0xb366: /* LEXR */ goto unimplemented;
13892 case 0xb367: /* FIXR */ goto unimplemented;
13893 case 0xb369: /* CXR */ goto unimplemented;
13894 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13895 ovl.fmt.RRE.r2); goto ok;
13896 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13897 ovl.fmt.RRE.r2); goto ok;
13898 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13899 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13900 goto ok;
13901 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13902 ovl.fmt.RRE.r2); goto ok;
13903 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13904 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13905 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13906 case 0xb377: /* FIER */ goto unimplemented;
13907 case 0xb37f: /* FIDR */ goto unimplemented;
13908 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13909 case 0xb385: /* SFASR */ goto unimplemented;
13910 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013911 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13912 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13913 ovl.fmt.RRF2.r2); goto ok;
13914 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13915 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13916 ovl.fmt.RRF2.r2); goto ok;
13917 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13918 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13919 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013920 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13921 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13922 ovl.fmt.RRF2.r2); goto ok;
13923 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13924 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13925 ovl.fmt.RRF2.r2); goto ok;
13926 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13927 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13928 ovl.fmt.RRF2.r2); goto ok;
13929 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13930 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13931 ovl.fmt.RRF2.r2); goto ok;
13932 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13933 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13934 ovl.fmt.RRF2.r2); goto ok;
13935 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13936 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13937 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013938 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13939 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13940 ovl.fmt.RRF2.r2); goto ok;
13941 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13942 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13943 ovl.fmt.RRF2.r2); goto ok;
13944 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13945 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13946 ovl.fmt.RRF2.r2); goto ok;
13947 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13948 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13949 ovl.fmt.RRF2.r2); goto ok;
13950 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13951 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13952 ovl.fmt.RRF2.r2); goto ok;
13953 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13954 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13955 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013956 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13957 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13958 ovl.fmt.RRF2.r2); goto ok;
13959 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13960 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13961 ovl.fmt.RRF2.r2); goto ok;
13962 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13963 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13964 ovl.fmt.RRF2.r2); goto ok;
13965 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13966 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13967 ovl.fmt.RRF2.r2); goto ok;
13968 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13969 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13970 ovl.fmt.RRF2.r2); goto ok;
13971 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13972 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13973 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013974 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13975 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13976 ovl.fmt.RRF2.r2); goto ok;
13977 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13978 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13979 ovl.fmt.RRF2.r2); goto ok;
13980 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13981 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13982 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013983 case 0xb3b4: /* CEFR */ goto unimplemented;
13984 case 0xb3b5: /* CDFR */ goto unimplemented;
13985 case 0xb3b6: /* CXFR */ goto unimplemented;
13986 case 0xb3b8: /* CFER */ goto unimplemented;
13987 case 0xb3b9: /* CFDR */ goto unimplemented;
13988 case 0xb3ba: /* CFXR */ goto unimplemented;
13989 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13990 ovl.fmt.RRE.r2); goto ok;
13991 case 0xb3c4: /* CEGR */ goto unimplemented;
13992 case 0xb3c5: /* CDGR */ goto unimplemented;
13993 case 0xb3c6: /* CXGR */ goto unimplemented;
13994 case 0xb3c8: /* CGER */ goto unimplemented;
13995 case 0xb3c9: /* CGDR */ goto unimplemented;
13996 case 0xb3ca: /* CGXR */ goto unimplemented;
13997 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13998 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013999 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14000 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14001 ovl.fmt.RRF4.r2); goto ok;
14002 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14003 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14004 ovl.fmt.RRF4.r2); goto ok;
14005 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14006 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14007 ovl.fmt.RRF4.r2); goto ok;
14008 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14009 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14010 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014011 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14012 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14013 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14014 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14015 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014016 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14017 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014018 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014019 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14020 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14021 ovl.fmt.RRF4.r2); goto ok;
14022 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14023 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14024 ovl.fmt.RRF4.r2); goto ok;
14025 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14026 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14027 ovl.fmt.RRF4.r2); goto ok;
14028 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14029 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14030 ovl.fmt.RRF4.r2); goto ok;
14031 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14032 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14033 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14034 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14035 ovl.fmt.RRF2.r2); goto ok;
14036 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14037 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014038 case 0xb3df: /* FIXTR */ goto unimplemented;
14039 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014040 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14041 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14042 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014043 case 0xb3e2: /* CUDTR */ goto unimplemented;
14044 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014045 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14046 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014047 case 0xb3e5: /* EEDTR */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000014048 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14049 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014050 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014051 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14052 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14053 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014054 case 0xb3ea: /* CUXTR */ goto unimplemented;
14055 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014056 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14057 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014058 case 0xb3ed: /* EEXTR */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000014059 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14060 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014061 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14062 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14063 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014064 case 0xb3f2: /* CDUTR */ goto unimplemented;
14065 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014066 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14067 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014068 case 0xb3f5: /* QADTR */ goto unimplemented;
14069 case 0xb3f6: /* IEDTR */ goto unimplemented;
14070 case 0xb3f7: /* RRDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014071 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14072 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14073 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014074 case 0xb3fa: /* CXUTR */ goto unimplemented;
14075 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014076 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14077 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014078 case 0xb3fd: /* QAXTR */ goto unimplemented;
14079 case 0xb3fe: /* IEXTR */ goto unimplemented;
14080 case 0xb3ff: /* RRXTR */ goto unimplemented;
14081 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14082 ovl.fmt.RRE.r2); goto ok;
14083 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14084 ovl.fmt.RRE.r2); goto ok;
14085 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14086 ovl.fmt.RRE.r2); goto ok;
14087 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14088 ovl.fmt.RRE.r2); goto ok;
14089 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14090 ovl.fmt.RRE.r2); goto ok;
14091 case 0xb905: /* LURAG */ goto unimplemented;
14092 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14093 ovl.fmt.RRE.r2); goto ok;
14094 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14095 ovl.fmt.RRE.r2); goto ok;
14096 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14097 ovl.fmt.RRE.r2); goto ok;
14098 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14099 ovl.fmt.RRE.r2); goto ok;
14100 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14101 ovl.fmt.RRE.r2); goto ok;
14102 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14103 ovl.fmt.RRE.r2); goto ok;
14104 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14105 ovl.fmt.RRE.r2); goto ok;
14106 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14107 ovl.fmt.RRE.r2); goto ok;
14108 case 0xb90e: /* EREGG */ goto unimplemented;
14109 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14110 ovl.fmt.RRE.r2); goto ok;
14111 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14112 ovl.fmt.RRE.r2); goto ok;
14113 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14114 ovl.fmt.RRE.r2); goto ok;
14115 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14116 ovl.fmt.RRE.r2); goto ok;
14117 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14118 ovl.fmt.RRE.r2); goto ok;
14119 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14120 ovl.fmt.RRE.r2); goto ok;
14121 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14122 ovl.fmt.RRE.r2); goto ok;
14123 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14124 ovl.fmt.RRE.r2); goto ok;
14125 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14126 ovl.fmt.RRE.r2); goto ok;
14127 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14128 ovl.fmt.RRE.r2); goto ok;
14129 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14130 ovl.fmt.RRE.r2); goto ok;
14131 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14132 ovl.fmt.RRE.r2); goto ok;
14133 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14134 ovl.fmt.RRE.r2); goto ok;
14135 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14136 ovl.fmt.RRE.r2); goto ok;
14137 case 0xb91e: /* KMAC */ goto unimplemented;
14138 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14139 ovl.fmt.RRE.r2); goto ok;
14140 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14141 ovl.fmt.RRE.r2); goto ok;
14142 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14143 ovl.fmt.RRE.r2); goto ok;
14144 case 0xb925: /* STURG */ goto unimplemented;
14145 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14146 ovl.fmt.RRE.r2); goto ok;
14147 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14148 ovl.fmt.RRE.r2); goto ok;
14149 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014150 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014151 case 0xb92b: /* KMO */ goto unimplemented;
14152 case 0xb92c: /* PCC */ goto unimplemented;
14153 case 0xb92d: /* KMCTR */ goto unimplemented;
14154 case 0xb92e: /* KM */ goto unimplemented;
14155 case 0xb92f: /* KMC */ goto unimplemented;
14156 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14157 ovl.fmt.RRE.r2); goto ok;
14158 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14159 ovl.fmt.RRE.r2); goto ok;
14160 case 0xb93e: /* KIMD */ goto unimplemented;
14161 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014162 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14163 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14164 ovl.fmt.RRF2.r2); goto ok;
14165 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14166 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14167 ovl.fmt.RRF2.r2); goto ok;
14168 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14169 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14170 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014171 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14172 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014173 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14174 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14175 ovl.fmt.RRF2.r2); goto ok;
14176 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14177 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14178 ovl.fmt.RRF2.r2); goto ok;
14179 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14180 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14181 ovl.fmt.RRF2.r2); goto ok;
14182 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14183 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14184 ovl.fmt.RRF2.r2); goto ok;
14185 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14186 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14187 ovl.fmt.RRF2.r2); goto ok;
14188 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14189 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14190 ovl.fmt.RRF2.r2); goto ok;
14191 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14192 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14193 ovl.fmt.RRF2.r2); goto ok;
14194 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14195 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14196 ovl.fmt.RRF2.r2); goto ok;
14197 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14198 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14199 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014200 case 0xb960: /* CGRT */ goto unimplemented;
14201 case 0xb961: /* CLGRT */ goto unimplemented;
14202 case 0xb972: /* CRT */ goto unimplemented;
14203 case 0xb973: /* CLRT */ goto unimplemented;
14204 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14205 ovl.fmt.RRE.r2); goto ok;
14206 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14207 ovl.fmt.RRE.r2); goto ok;
14208 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14209 ovl.fmt.RRE.r2); goto ok;
14210 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14211 ovl.fmt.RRE.r2); goto ok;
14212 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14213 ovl.fmt.RRE.r2); goto ok;
14214 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14215 ovl.fmt.RRE.r2); goto ok;
14216 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14217 ovl.fmt.RRE.r2); goto ok;
14218 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14219 ovl.fmt.RRE.r2); goto ok;
14220 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14221 ovl.fmt.RRE.r2); goto ok;
14222 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14223 ovl.fmt.RRE.r2); goto ok;
14224 case 0xb98a: /* CSPG */ goto unimplemented;
14225 case 0xb98d: /* EPSW */ goto unimplemented;
14226 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014227 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014228 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14229 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14230 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14231 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14232 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14233 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014234 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14235 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014236 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14237 ovl.fmt.RRE.r2); goto ok;
14238 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14239 ovl.fmt.RRE.r2); goto ok;
14240 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14241 ovl.fmt.RRE.r2); goto ok;
14242 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14243 ovl.fmt.RRE.r2); goto ok;
14244 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14245 ovl.fmt.RRE.r2); goto ok;
14246 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14247 ovl.fmt.RRE.r2); goto ok;
14248 case 0xb99a: /* EPAIR */ goto unimplemented;
14249 case 0xb99b: /* ESAIR */ goto unimplemented;
14250 case 0xb99d: /* ESEA */ goto unimplemented;
14251 case 0xb99e: /* PTI */ goto unimplemented;
14252 case 0xb99f: /* SSAIR */ goto unimplemented;
14253 case 0xb9a2: /* PTF */ goto unimplemented;
14254 case 0xb9aa: /* LPTEA */ goto unimplemented;
14255 case 0xb9ae: /* RRBM */ goto unimplemented;
14256 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014257 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14258 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14259 goto ok;
florian2a415a12012-07-21 17:41:36 +000014260 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14261 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14262 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014263 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14264 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014265 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14266 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014267 case 0xb9bd: /* TRTRE */ goto unimplemented;
14268 case 0xb9be: /* SRSTU */ goto unimplemented;
14269 case 0xb9bf: /* TRTE */ goto unimplemented;
14270 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14271 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14272 goto ok;
14273 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14274 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14275 goto ok;
14276 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14277 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14278 goto ok;
14279 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14280 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14281 goto ok;
14282 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14283 ovl.fmt.RRE.r2); goto ok;
14284 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14285 ovl.fmt.RRE.r2); goto ok;
14286 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14287 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14288 goto ok;
14289 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14290 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14291 goto ok;
14292 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14293 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14294 goto ok;
14295 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14296 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14297 goto ok;
14298 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14299 ovl.fmt.RRE.r2); goto ok;
14300 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14301 ovl.fmt.RRE.r2); goto ok;
14302 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014303 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14304 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14305 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014306 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14307 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14308 goto ok;
14309 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14310 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14311 goto ok;
14312 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14313 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14314 goto ok;
14315 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14316 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14317 goto ok;
14318 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14319 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14320 goto ok;
14321 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14322 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14323 goto ok;
14324 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14325 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14326 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014327 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14328 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14329 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014330 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14331 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14332 goto ok;
14333 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14334 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14335 goto ok;
14336 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14337 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14338 goto ok;
14339 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14340 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14341 goto ok;
14342 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14343 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14344 goto ok;
14345 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14346 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14347 goto ok;
14348 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14349 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14350 goto ok;
14351 }
14352
14353 switch ((ovl.value & 0xff000000) >> 24) {
14354 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14355 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14356 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14357 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14358 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14359 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14360 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14361 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14362 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14363 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14364 case 0x45: /* BAL */ goto unimplemented;
14365 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14366 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14367 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14368 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14369 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14370 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14371 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14372 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14373 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14374 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14375 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14376 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14377 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14378 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14379 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14380 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14381 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14382 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14383 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14384 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14385 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14386 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14387 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14388 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14389 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14390 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14391 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14392 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14393 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14394 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14395 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14396 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14397 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14398 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14399 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14400 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14401 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14402 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14403 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14404 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14405 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14406 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14407 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14408 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14409 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14410 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14411 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14412 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14413 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14414 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14415 case 0x67: /* MXD */ goto unimplemented;
14416 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14417 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14418 case 0x69: /* CD */ goto unimplemented;
14419 case 0x6a: /* AD */ goto unimplemented;
14420 case 0x6b: /* SD */ goto unimplemented;
14421 case 0x6c: /* MD */ goto unimplemented;
14422 case 0x6d: /* DD */ goto unimplemented;
14423 case 0x6e: /* AW */ goto unimplemented;
14424 case 0x6f: /* SW */ goto unimplemented;
14425 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14426 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14427 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14428 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14429 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14430 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14431 case 0x79: /* CE */ goto unimplemented;
14432 case 0x7a: /* AE */ goto unimplemented;
14433 case 0x7b: /* SE */ goto unimplemented;
14434 case 0x7c: /* MDE */ goto unimplemented;
14435 case 0x7d: /* DE */ goto unimplemented;
14436 case 0x7e: /* AU */ goto unimplemented;
14437 case 0x7f: /* SU */ goto unimplemented;
14438 case 0x83: /* DIAG */ goto unimplemented;
14439 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
14440 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14441 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
14442 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14443 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14444 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14445 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14446 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14447 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14448 ovl.fmt.RS.d2); goto ok;
14449 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14450 ovl.fmt.RS.d2); goto ok;
14451 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14452 ovl.fmt.RS.d2); goto ok;
14453 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14454 ovl.fmt.RS.d2); goto ok;
14455 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14456 ovl.fmt.RS.d2); goto ok;
14457 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14458 ovl.fmt.RS.d2); goto ok;
14459 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14460 ovl.fmt.RS.d2); goto ok;
14461 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14462 ovl.fmt.RS.d2); goto ok;
14463 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14464 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14465 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14466 ovl.fmt.SI.d1); goto ok;
14467 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14468 ovl.fmt.SI.d1); goto ok;
14469 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14470 ovl.fmt.SI.d1); goto ok;
14471 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14472 ovl.fmt.SI.d1); goto ok;
14473 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14474 ovl.fmt.SI.d1); goto ok;
14475 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14476 ovl.fmt.SI.d1); goto ok;
14477 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14478 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14479 case 0x99: /* TRACE */ goto unimplemented;
14480 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14481 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14482 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14483 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14484 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
14485 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14486 goto ok;
14487 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
14488 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14489 goto ok;
14490 case 0xac: /* STNSM */ goto unimplemented;
14491 case 0xad: /* STOSM */ goto unimplemented;
14492 case 0xae: /* SIGP */ goto unimplemented;
14493 case 0xaf: /* MC */ goto unimplemented;
14494 case 0xb1: /* LRA */ goto unimplemented;
14495 case 0xb6: /* STCTL */ goto unimplemented;
14496 case 0xb7: /* LCTL */ goto unimplemented;
14497 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14498 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014499 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14500 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014501 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14502 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14503 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14504 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14505 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14506 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14507 }
14508
14509 return S390_DECODE_UNKNOWN_INSN;
14510
14511ok:
14512 return S390_DECODE_OK;
14513
14514unimplemented:
14515 return S390_DECODE_UNIMPLEMENTED_INSN;
14516}
14517
14518static s390_decode_t
14519s390_decode_6byte_and_irgen(UChar *bytes)
14520{
14521 typedef union {
14522 struct {
14523 unsigned int op1 : 8;
14524 unsigned int r1 : 4;
14525 unsigned int r3 : 4;
14526 unsigned int i2 : 16;
14527 unsigned int : 8;
14528 unsigned int op2 : 8;
14529 } RIE;
14530 struct {
14531 unsigned int op1 : 8;
14532 unsigned int r1 : 4;
14533 unsigned int r2 : 4;
14534 unsigned int i3 : 8;
14535 unsigned int i4 : 8;
14536 unsigned int i5 : 8;
14537 unsigned int op2 : 8;
14538 } RIE_RRUUU;
14539 struct {
14540 unsigned int op1 : 8;
14541 unsigned int r1 : 4;
14542 unsigned int : 4;
14543 unsigned int i2 : 16;
14544 unsigned int m3 : 4;
14545 unsigned int : 4;
14546 unsigned int op2 : 8;
14547 } RIEv1;
14548 struct {
14549 unsigned int op1 : 8;
14550 unsigned int r1 : 4;
14551 unsigned int r2 : 4;
14552 unsigned int i4 : 16;
14553 unsigned int m3 : 4;
14554 unsigned int : 4;
14555 unsigned int op2 : 8;
14556 } RIE_RRPU;
14557 struct {
14558 unsigned int op1 : 8;
14559 unsigned int r1 : 4;
14560 unsigned int m3 : 4;
14561 unsigned int i4 : 16;
14562 unsigned int i2 : 8;
14563 unsigned int op2 : 8;
14564 } RIEv3;
14565 struct {
14566 unsigned int op1 : 8;
14567 unsigned int r1 : 4;
14568 unsigned int op2 : 4;
14569 unsigned int i2 : 32;
14570 } RIL;
14571 struct {
14572 unsigned int op1 : 8;
14573 unsigned int r1 : 4;
14574 unsigned int m3 : 4;
14575 unsigned int b4 : 4;
14576 unsigned int d4 : 12;
14577 unsigned int i2 : 8;
14578 unsigned int op2 : 8;
14579 } RIS;
14580 struct {
14581 unsigned int op1 : 8;
14582 unsigned int r1 : 4;
14583 unsigned int r2 : 4;
14584 unsigned int b4 : 4;
14585 unsigned int d4 : 12;
14586 unsigned int m3 : 4;
14587 unsigned int : 4;
14588 unsigned int op2 : 8;
14589 } RRS;
14590 struct {
14591 unsigned int op1 : 8;
14592 unsigned int l1 : 4;
14593 unsigned int : 4;
14594 unsigned int b1 : 4;
14595 unsigned int d1 : 12;
14596 unsigned int : 8;
14597 unsigned int op2 : 8;
14598 } RSL;
14599 struct {
14600 unsigned int op1 : 8;
14601 unsigned int r1 : 4;
14602 unsigned int r3 : 4;
14603 unsigned int b2 : 4;
14604 unsigned int dl2 : 12;
14605 unsigned int dh2 : 8;
14606 unsigned int op2 : 8;
14607 } RSY;
14608 struct {
14609 unsigned int op1 : 8;
14610 unsigned int r1 : 4;
14611 unsigned int x2 : 4;
14612 unsigned int b2 : 4;
14613 unsigned int d2 : 12;
14614 unsigned int : 8;
14615 unsigned int op2 : 8;
14616 } RXE;
14617 struct {
14618 unsigned int op1 : 8;
14619 unsigned int r3 : 4;
14620 unsigned int x2 : 4;
14621 unsigned int b2 : 4;
14622 unsigned int d2 : 12;
14623 unsigned int r1 : 4;
14624 unsigned int : 4;
14625 unsigned int op2 : 8;
14626 } RXF;
14627 struct {
14628 unsigned int op1 : 8;
14629 unsigned int r1 : 4;
14630 unsigned int x2 : 4;
14631 unsigned int b2 : 4;
14632 unsigned int dl2 : 12;
14633 unsigned int dh2 : 8;
14634 unsigned int op2 : 8;
14635 } RXY;
14636 struct {
14637 unsigned int op1 : 8;
14638 unsigned int i2 : 8;
14639 unsigned int b1 : 4;
14640 unsigned int dl1 : 12;
14641 unsigned int dh1 : 8;
14642 unsigned int op2 : 8;
14643 } SIY;
14644 struct {
14645 unsigned int op : 8;
14646 unsigned int l : 8;
14647 unsigned int b1 : 4;
14648 unsigned int d1 : 12;
14649 unsigned int b2 : 4;
14650 unsigned int d2 : 12;
14651 } SS;
14652 struct {
14653 unsigned int op : 8;
14654 unsigned int l1 : 4;
14655 unsigned int l2 : 4;
14656 unsigned int b1 : 4;
14657 unsigned int d1 : 12;
14658 unsigned int b2 : 4;
14659 unsigned int d2 : 12;
14660 } SS_LLRDRD;
14661 struct {
14662 unsigned int op : 8;
14663 unsigned int r1 : 4;
14664 unsigned int r3 : 4;
14665 unsigned int b2 : 4;
14666 unsigned int d2 : 12;
14667 unsigned int b4 : 4;
14668 unsigned int d4 : 12;
14669 } SS_RRRDRD2;
14670 struct {
14671 unsigned int op : 16;
14672 unsigned int b1 : 4;
14673 unsigned int d1 : 12;
14674 unsigned int b2 : 4;
14675 unsigned int d2 : 12;
14676 } SSE;
14677 struct {
14678 unsigned int op1 : 8;
14679 unsigned int r3 : 4;
14680 unsigned int op2 : 4;
14681 unsigned int b1 : 4;
14682 unsigned int d1 : 12;
14683 unsigned int b2 : 4;
14684 unsigned int d2 : 12;
14685 } SSF;
14686 struct {
14687 unsigned int op : 16;
14688 unsigned int b1 : 4;
14689 unsigned int d1 : 12;
14690 unsigned int i2 : 16;
14691 } SIL;
14692 } formats;
14693 union {
14694 formats fmt;
14695 ULong value;
14696 } ovl;
14697
14698 vassert(sizeof(formats) == 6);
14699
florianffbd84d2012-12-09 02:06:29 +000014700 ((UChar *)(&ovl.value))[0] = bytes[0];
14701 ((UChar *)(&ovl.value))[1] = bytes[1];
14702 ((UChar *)(&ovl.value))[2] = bytes[2];
14703 ((UChar *)(&ovl.value))[3] = bytes[3];
14704 ((UChar *)(&ovl.value))[4] = bytes[4];
14705 ((UChar *)(&ovl.value))[5] = bytes[5];
14706 ((UChar *)(&ovl.value))[6] = 0x0;
14707 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000014708
14709 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
14710 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
14711 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14712 ovl.fmt.RXY.dl2,
14713 ovl.fmt.RXY.dh2); goto ok;
14714 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
14715 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
14716 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14717 ovl.fmt.RXY.dl2,
14718 ovl.fmt.RXY.dh2); goto ok;
14719 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
14720 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14721 ovl.fmt.RXY.dl2,
14722 ovl.fmt.RXY.dh2); goto ok;
14723 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
14724 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14725 ovl.fmt.RXY.dl2,
14726 ovl.fmt.RXY.dh2); goto ok;
14727 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
14728 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14729 ovl.fmt.RXY.dl2,
14730 ovl.fmt.RXY.dh2); goto ok;
14731 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
14732 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14733 ovl.fmt.RXY.dl2,
14734 ovl.fmt.RXY.dh2); goto ok;
14735 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
14736 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14737 ovl.fmt.RXY.dl2,
14738 ovl.fmt.RXY.dh2); goto ok;
14739 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
14740 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14741 ovl.fmt.RXY.dl2,
14742 ovl.fmt.RXY.dh2); goto ok;
14743 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
14744 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14745 ovl.fmt.RXY.dl2,
14746 ovl.fmt.RXY.dh2); goto ok;
14747 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
14748 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
14749 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14750 ovl.fmt.RXY.dl2,
14751 ovl.fmt.RXY.dh2); goto ok;
14752 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
14753 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14754 ovl.fmt.RXY.dl2,
14755 ovl.fmt.RXY.dh2); goto ok;
14756 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
14757 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
14758 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14759 ovl.fmt.RXY.dl2,
14760 ovl.fmt.RXY.dh2); goto ok;
14761 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
14762 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14763 ovl.fmt.RXY.dl2,
14764 ovl.fmt.RXY.dh2); goto ok;
14765 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
14766 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14767 ovl.fmt.RXY.dl2,
14768 ovl.fmt.RXY.dh2); goto ok;
14769 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
14770 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14771 ovl.fmt.RXY.dl2,
14772 ovl.fmt.RXY.dh2); goto ok;
14773 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
14774 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14775 ovl.fmt.RXY.dl2,
14776 ovl.fmt.RXY.dh2); goto ok;
14777 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
14778 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14779 ovl.fmt.RXY.dl2,
14780 ovl.fmt.RXY.dh2); goto ok;
14781 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
14782 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14783 ovl.fmt.RXY.dl2,
14784 ovl.fmt.RXY.dh2); goto ok;
14785 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
14786 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14787 ovl.fmt.RXY.dl2,
14788 ovl.fmt.RXY.dh2); goto ok;
14789 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
14790 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14791 ovl.fmt.RXY.dl2,
14792 ovl.fmt.RXY.dh2); goto ok;
14793 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
14794 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14795 ovl.fmt.RXY.dl2,
14796 ovl.fmt.RXY.dh2); goto ok;
14797 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
14798 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14799 ovl.fmt.RXY.dl2,
14800 ovl.fmt.RXY.dh2); goto ok;
14801 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
14802 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14803 ovl.fmt.RXY.dl2,
14804 ovl.fmt.RXY.dh2); goto ok;
14805 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
14806 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14807 ovl.fmt.RXY.dl2,
14808 ovl.fmt.RXY.dh2); goto ok;
14809 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
14810 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14811 ovl.fmt.RXY.dl2,
14812 ovl.fmt.RXY.dh2); goto ok;
14813 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
14814 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14815 ovl.fmt.RXY.dl2,
14816 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014817 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014818 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
14819 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14820 ovl.fmt.RXY.dl2,
14821 ovl.fmt.RXY.dh2); goto ok;
14822 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
14823 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
14824 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14825 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14826 ovl.fmt.RXY.dh2); goto ok;
14827 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
14828 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14829 ovl.fmt.RXY.dl2,
14830 ovl.fmt.RXY.dh2); goto ok;
14831 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
14832 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14833 ovl.fmt.RXY.dl2,
14834 ovl.fmt.RXY.dh2); goto ok;
14835 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
14836 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14837 ovl.fmt.RXY.dl2,
14838 ovl.fmt.RXY.dh2); goto ok;
14839 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
14840 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14841 ovl.fmt.RXY.dl2,
14842 ovl.fmt.RXY.dh2); goto ok;
14843 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
14844 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14845 ovl.fmt.RXY.dl2,
14846 ovl.fmt.RXY.dh2); goto ok;
14847 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
14848 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14849 ovl.fmt.RXY.dl2,
14850 ovl.fmt.RXY.dh2); goto ok;
14851 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
14852 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14853 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14854 ovl.fmt.RXY.dh2); goto ok;
14855 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
14856 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14857 ovl.fmt.RXY.dl2,
14858 ovl.fmt.RXY.dh2); goto ok;
14859 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
14860 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14861 ovl.fmt.RXY.dl2,
14862 ovl.fmt.RXY.dh2); goto ok;
14863 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
14864 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14865 ovl.fmt.RXY.dl2,
14866 ovl.fmt.RXY.dh2); goto ok;
14867 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
14868 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14869 ovl.fmt.RXY.dl2,
14870 ovl.fmt.RXY.dh2); goto ok;
14871 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
14872 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14873 ovl.fmt.RXY.dl2,
14874 ovl.fmt.RXY.dh2); goto ok;
14875 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
14876 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14877 ovl.fmt.RXY.dl2,
14878 ovl.fmt.RXY.dh2); goto ok;
14879 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
14880 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14881 ovl.fmt.RXY.dl2,
14882 ovl.fmt.RXY.dh2); goto ok;
14883 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
14884 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14885 ovl.fmt.RXY.dl2,
14886 ovl.fmt.RXY.dh2); goto ok;
14887 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
14888 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14889 ovl.fmt.RXY.dl2,
14890 ovl.fmt.RXY.dh2); goto ok;
14891 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
14892 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14893 ovl.fmt.RXY.dl2,
14894 ovl.fmt.RXY.dh2); goto ok;
14895 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
14896 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14897 ovl.fmt.RXY.dl2,
14898 ovl.fmt.RXY.dh2); goto ok;
14899 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
14900 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14901 ovl.fmt.RXY.dl2,
14902 ovl.fmt.RXY.dh2); goto ok;
14903 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
14904 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14905 ovl.fmt.RXY.dl2,
14906 ovl.fmt.RXY.dh2); goto ok;
14907 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
14908 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14909 ovl.fmt.RXY.dl2,
14910 ovl.fmt.RXY.dh2); goto ok;
14911 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
14912 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14913 ovl.fmt.RXY.dl2,
14914 ovl.fmt.RXY.dh2); goto ok;
14915 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
14916 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14917 ovl.fmt.RXY.dl2,
14918 ovl.fmt.RXY.dh2); goto ok;
14919 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
14920 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14921 ovl.fmt.RXY.dl2,
14922 ovl.fmt.RXY.dh2); goto ok;
14923 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
14924 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14925 ovl.fmt.RXY.dl2,
14926 ovl.fmt.RXY.dh2); goto ok;
14927 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
14928 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14929 ovl.fmt.RXY.dl2,
14930 ovl.fmt.RXY.dh2); goto ok;
14931 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
14932 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14933 ovl.fmt.RXY.dl2,
14934 ovl.fmt.RXY.dh2); goto ok;
14935 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
14936 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14937 ovl.fmt.RXY.dl2,
14938 ovl.fmt.RXY.dh2); goto ok;
14939 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
14940 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14941 ovl.fmt.RXY.dl2,
14942 ovl.fmt.RXY.dh2); goto ok;
14943 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
14944 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14945 ovl.fmt.RXY.dl2,
14946 ovl.fmt.RXY.dh2); goto ok;
14947 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
14948 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14949 ovl.fmt.RXY.dl2,
14950 ovl.fmt.RXY.dh2); goto ok;
14951 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
14952 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14953 ovl.fmt.RXY.dl2,
14954 ovl.fmt.RXY.dh2); goto ok;
14955 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
14956 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14957 ovl.fmt.RXY.dl2,
14958 ovl.fmt.RXY.dh2); goto ok;
14959 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
14960 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14961 ovl.fmt.RXY.dl2,
14962 ovl.fmt.RXY.dh2); goto ok;
14963 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
14964 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14965 ovl.fmt.RXY.dl2,
14966 ovl.fmt.RXY.dh2); goto ok;
14967 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
14968 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14969 ovl.fmt.RXY.dl2,
14970 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014971 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014972 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
14973 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14974 ovl.fmt.RXY.dl2,
14975 ovl.fmt.RXY.dh2); goto ok;
14976 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14977 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14978 ovl.fmt.RXY.dl2,
14979 ovl.fmt.RXY.dh2); goto ok;
14980 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14981 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14982 ovl.fmt.RXY.dl2,
14983 ovl.fmt.RXY.dh2); goto ok;
14984 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14985 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14986 ovl.fmt.RXY.dl2,
14987 ovl.fmt.RXY.dh2); goto ok;
14988 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14989 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14990 ovl.fmt.RXY.dl2,
14991 ovl.fmt.RXY.dh2); goto ok;
14992 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14993 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14994 ovl.fmt.RXY.dl2,
14995 ovl.fmt.RXY.dh2); goto ok;
14996 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14997 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14998 ovl.fmt.RXY.dl2,
14999 ovl.fmt.RXY.dh2); goto ok;
15000 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15001 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15002 ovl.fmt.RXY.dl2,
15003 ovl.fmt.RXY.dh2); goto ok;
15004 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15005 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15006 ovl.fmt.RXY.dl2,
15007 ovl.fmt.RXY.dh2); goto ok;
15008 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15009 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15010 ovl.fmt.RXY.dl2,
15011 ovl.fmt.RXY.dh2); goto ok;
15012 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15013 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15014 ovl.fmt.RXY.dl2,
15015 ovl.fmt.RXY.dh2); goto ok;
15016 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15017 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15018 ovl.fmt.RXY.dl2,
15019 ovl.fmt.RXY.dh2); goto ok;
15020 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15021 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15022 ovl.fmt.RXY.dl2,
15023 ovl.fmt.RXY.dh2); goto ok;
15024 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15025 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15026 ovl.fmt.RXY.dl2,
15027 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015028 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15029 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15030 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015031 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15032 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15033 ovl.fmt.RXY.dl2,
15034 ovl.fmt.RXY.dh2); goto ok;
15035 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15036 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15037 ovl.fmt.RXY.dl2,
15038 ovl.fmt.RXY.dh2); goto ok;
15039 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15040 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15041 ovl.fmt.RXY.dl2,
15042 ovl.fmt.RXY.dh2); goto ok;
15043 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15044 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15045 ovl.fmt.RXY.dl2,
15046 ovl.fmt.RXY.dh2); goto ok;
15047 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15048 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15049 ovl.fmt.RXY.dl2,
15050 ovl.fmt.RXY.dh2); goto ok;
15051 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15052 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15053 ovl.fmt.RXY.dl2,
15054 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015055 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015056 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15057 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15058 ovl.fmt.RXY.dl2,
15059 ovl.fmt.RXY.dh2); goto ok;
15060 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15061 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15062 ovl.fmt.RXY.dl2,
15063 ovl.fmt.RXY.dh2); goto ok;
15064 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15065 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15066 ovl.fmt.RXY.dl2,
15067 ovl.fmt.RXY.dh2); goto ok;
15068 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15069 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15070 ovl.fmt.RXY.dl2,
15071 ovl.fmt.RXY.dh2); goto ok;
15072 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15073 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15074 ovl.fmt.RSY.dl2,
15075 ovl.fmt.RSY.dh2); goto ok;
15076 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15077 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15078 ovl.fmt.RSY.dl2,
15079 ovl.fmt.RSY.dh2); goto ok;
15080 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15081 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15082 ovl.fmt.RSY.dl2,
15083 ovl.fmt.RSY.dh2); goto ok;
15084 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15085 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15086 ovl.fmt.RSY.dl2,
15087 ovl.fmt.RSY.dh2); goto ok;
15088 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15089 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15090 ovl.fmt.RSY.dl2,
15091 ovl.fmt.RSY.dh2); goto ok;
15092 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15093 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15094 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15095 ovl.fmt.RSY.dl2,
15096 ovl.fmt.RSY.dh2); goto ok;
15097 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15098 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15099 ovl.fmt.RSY.dl2,
15100 ovl.fmt.RSY.dh2); goto ok;
15101 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15102 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15103 ovl.fmt.RSY.dl2,
15104 ovl.fmt.RSY.dh2); goto ok;
15105 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15106 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15107 ovl.fmt.RSY.dl2,
15108 ovl.fmt.RSY.dh2); goto ok;
15109 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15110 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15111 ovl.fmt.RSY.dl2,
15112 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015113 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015114 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15115 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15116 ovl.fmt.RSY.dl2,
15117 ovl.fmt.RSY.dh2); goto ok;
15118 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15119 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15120 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15121 ovl.fmt.RSY.dl2,
15122 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015123 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015124 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15125 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15126 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15127 ovl.fmt.RSY.dh2); goto ok;
15128 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15129 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15130 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15131 ovl.fmt.RSY.dh2); goto ok;
15132 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15133 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15134 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15135 ovl.fmt.RSY.dl2,
15136 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015137 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15138 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15139 ovl.fmt.RSY.dl2,
15140 ovl.fmt.RSY.dh2); goto ok;
15141 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15142 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15143 ovl.fmt.RSY.dl2,
15144 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015145 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15146 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15147 ovl.fmt.RSY.dl2,
15148 ovl.fmt.RSY.dh2); goto ok;
15149 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15150 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15151 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15152 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015153 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15154 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15155 ovl.fmt.RSY.dl2,
15156 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015157 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15158 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15159 ovl.fmt.SIY.dh1); goto ok;
15160 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15161 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15162 ovl.fmt.SIY.dh1); goto ok;
15163 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15164 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15165 ovl.fmt.SIY.dh1); goto ok;
15166 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15167 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15168 ovl.fmt.SIY.dh1); goto ok;
15169 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15170 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15171 ovl.fmt.SIY.dh1); goto ok;
15172 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15173 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15174 ovl.fmt.SIY.dh1); goto ok;
15175 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15176 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15177 ovl.fmt.SIY.dh1); goto ok;
15178 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15179 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15180 ovl.fmt.SIY.dh1); goto ok;
15181 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15182 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15183 ovl.fmt.SIY.dh1); goto ok;
15184 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15185 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15186 ovl.fmt.SIY.dh1); goto ok;
15187 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15188 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15189 ovl.fmt.RSY.dl2,
15190 ovl.fmt.RSY.dh2); goto ok;
15191 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15192 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15193 ovl.fmt.RSY.dl2,
15194 ovl.fmt.RSY.dh2); goto ok;
15195 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15196 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15197 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15198 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15199 ovl.fmt.RSY.dl2,
15200 ovl.fmt.RSY.dh2); goto ok;
15201 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15202 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15203 ovl.fmt.RSY.dl2,
15204 ovl.fmt.RSY.dh2); goto ok;
15205 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15206 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15207 ovl.fmt.RSY.dl2,
15208 ovl.fmt.RSY.dh2); goto ok;
15209 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15210 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15211 ovl.fmt.RSY.dl2,
15212 ovl.fmt.RSY.dh2); goto ok;
15213 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15214 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15215 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15216 ovl.fmt.RSY.dh2); goto ok;
15217 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15218 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15219 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15220 ovl.fmt.RSY.dl2,
15221 ovl.fmt.RSY.dh2); goto ok;
15222 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15223 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15224 ovl.fmt.RSY.dl2,
15225 ovl.fmt.RSY.dh2); goto ok;
15226 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15227 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15228 ovl.fmt.RSY.dl2,
15229 ovl.fmt.RSY.dh2); goto ok;
15230 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15231 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15232 ovl.fmt.RSY.dl2,
15233 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015234 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15235 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15236 ovl.fmt.RSY.dl2,
15237 ovl.fmt.RSY.dh2,
15238 S390_XMNM_LOCG); goto ok;
15239 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15240 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15241 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15242 ovl.fmt.RSY.dh2,
15243 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015244 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15245 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15246 ovl.fmt.RSY.dl2,
15247 ovl.fmt.RSY.dh2); goto ok;
15248 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15249 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15250 ovl.fmt.RSY.dl2,
15251 ovl.fmt.RSY.dh2); goto ok;
15252 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15253 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15254 ovl.fmt.RSY.dl2,
15255 ovl.fmt.RSY.dh2); goto ok;
15256 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15257 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15258 ovl.fmt.RSY.dl2,
15259 ovl.fmt.RSY.dh2); goto ok;
15260 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15261 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15262 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15263 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015264 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15265 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15266 ovl.fmt.RSY.dl2,
15267 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15268 goto ok;
15269 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15270 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15271 ovl.fmt.RSY.dl2,
15272 ovl.fmt.RSY.dh2,
15273 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015274 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15275 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15276 ovl.fmt.RSY.dl2,
15277 ovl.fmt.RSY.dh2); goto ok;
15278 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15279 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15280 ovl.fmt.RSY.dl2,
15281 ovl.fmt.RSY.dh2); goto ok;
15282 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15283 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15284 ovl.fmt.RSY.dl2,
15285 ovl.fmt.RSY.dh2); goto ok;
15286 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15287 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15288 ovl.fmt.RSY.dl2,
15289 ovl.fmt.RSY.dh2); goto ok;
15290 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15291 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15292 ovl.fmt.RSY.dl2,
15293 ovl.fmt.RSY.dh2); goto ok;
15294 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15295 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15296 goto ok;
15297 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15298 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15299 goto ok;
15300 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15301 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15302 ovl.fmt.RIE_RRUUU.r1,
15303 ovl.fmt.RIE_RRUUU.r2,
15304 ovl.fmt.RIE_RRUUU.i3,
15305 ovl.fmt.RIE_RRUUU.i4,
15306 ovl.fmt.RIE_RRUUU.i5);
15307 goto ok;
15308 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15309 ovl.fmt.RIE_RRUUU.r1,
15310 ovl.fmt.RIE_RRUUU.r2,
15311 ovl.fmt.RIE_RRUUU.i3,
15312 ovl.fmt.RIE_RRUUU.i4,
15313 ovl.fmt.RIE_RRUUU.i5);
15314 goto ok;
15315 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15316 ovl.fmt.RIE_RRUUU.r1,
15317 ovl.fmt.RIE_RRUUU.r2,
15318 ovl.fmt.RIE_RRUUU.i3,
15319 ovl.fmt.RIE_RRUUU.i4,
15320 ovl.fmt.RIE_RRUUU.i5);
15321 goto ok;
15322 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15323 ovl.fmt.RIE_RRUUU.r1,
15324 ovl.fmt.RIE_RRUUU.r2,
15325 ovl.fmt.RIE_RRUUU.i3,
15326 ovl.fmt.RIE_RRUUU.i4,
15327 ovl.fmt.RIE_RRUUU.i5);
15328 goto ok;
florian2289cd42012-12-05 04:23:42 +000015329 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015330 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15331 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15332 ovl.fmt.RIE_RRPU.r1,
15333 ovl.fmt.RIE_RRPU.r2,
15334 ovl.fmt.RIE_RRPU.i4,
15335 ovl.fmt.RIE_RRPU.m3); goto ok;
15336 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15337 ovl.fmt.RIE_RRPU.r1,
15338 ovl.fmt.RIE_RRPU.r2,
15339 ovl.fmt.RIE_RRPU.i4,
15340 ovl.fmt.RIE_RRPU.m3); goto ok;
15341 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15342 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15343 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15344 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15345 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15346 ovl.fmt.RIE_RRPU.r1,
15347 ovl.fmt.RIE_RRPU.r2,
15348 ovl.fmt.RIE_RRPU.i4,
15349 ovl.fmt.RIE_RRPU.m3); goto ok;
15350 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15351 ovl.fmt.RIE_RRPU.r1,
15352 ovl.fmt.RIE_RRPU.r2,
15353 ovl.fmt.RIE_RRPU.i4,
15354 ovl.fmt.RIE_RRPU.m3); goto ok;
15355 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15356 ovl.fmt.RIEv3.r1,
15357 ovl.fmt.RIEv3.m3,
15358 ovl.fmt.RIEv3.i4,
15359 ovl.fmt.RIEv3.i2); goto ok;
15360 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15361 ovl.fmt.RIEv3.r1,
15362 ovl.fmt.RIEv3.m3,
15363 ovl.fmt.RIEv3.i4,
15364 ovl.fmt.RIEv3.i2); goto ok;
15365 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15366 ovl.fmt.RIEv3.r1,
15367 ovl.fmt.RIEv3.m3,
15368 ovl.fmt.RIEv3.i4,
15369 ovl.fmt.RIEv3.i2); goto ok;
15370 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15371 ovl.fmt.RIEv3.r1,
15372 ovl.fmt.RIEv3.m3,
15373 ovl.fmt.RIEv3.i4,
15374 ovl.fmt.RIEv3.i2); goto ok;
15375 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15376 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15377 goto ok;
15378 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15379 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15380 ovl.fmt.RIE.i2); goto ok;
15381 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15382 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15383 ovl.fmt.RIE.i2); goto ok;
15384 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15385 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15386 ovl.fmt.RIE.i2); goto ok;
15387 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15388 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15389 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15390 goto ok;
15391 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15392 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15393 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15394 goto ok;
15395 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15396 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15397 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15398 goto ok;
15399 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15400 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15401 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15402 goto ok;
15403 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15404 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15405 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15406 ovl.fmt.RIS.i2); goto ok;
15407 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15408 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15409 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15410 ovl.fmt.RIS.i2); goto ok;
15411 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15412 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15413 ovl.fmt.RIS.d4,
15414 ovl.fmt.RIS.i2); goto ok;
15415 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15416 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15417 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15418 ovl.fmt.RIS.i2); goto ok;
15419 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15420 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15421 ovl.fmt.RXE.d2); goto ok;
15422 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15423 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15424 ovl.fmt.RXE.d2); goto ok;
15425 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15426 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15427 ovl.fmt.RXE.d2); goto ok;
15428 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15429 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15430 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15431 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15432 ovl.fmt.RXE.d2); goto ok;
15433 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15434 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15435 ovl.fmt.RXE.d2); goto ok;
15436 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
15437 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15438 ovl.fmt.RXE.d2); goto ok;
15439 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
15440 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
15441 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15442 ovl.fmt.RXE.d2); goto ok;
15443 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
15444 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15445 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15446 ovl.fmt.RXF.r1); goto ok;
15447 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
15448 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15449 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15450 ovl.fmt.RXF.r1); goto ok;
15451 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
15452 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15453 ovl.fmt.RXE.d2); goto ok;
15454 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
15455 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15456 ovl.fmt.RXE.d2); goto ok;
15457 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
15458 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15459 ovl.fmt.RXE.d2); goto ok;
15460 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
15461 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15462 ovl.fmt.RXE.d2); goto ok;
15463 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
15464 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15465 ovl.fmt.RXE.d2); goto ok;
15466 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
15467 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15468 ovl.fmt.RXE.d2); goto ok;
15469 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
15470 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
15471 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15472 ovl.fmt.RXE.d2); goto ok;
15473 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
15474 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15475 ovl.fmt.RXE.d2); goto ok;
15476 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
15477 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15478 ovl.fmt.RXE.d2); goto ok;
15479 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
15480 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15481 ovl.fmt.RXE.d2); goto ok;
15482 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
15483 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15484 ovl.fmt.RXE.d2); goto ok;
15485 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
15486 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15487 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15488 ovl.fmt.RXF.r1); goto ok;
15489 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
15490 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15491 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15492 ovl.fmt.RXF.r1); goto ok;
15493 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
15494 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
15495 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
15496 case 0xed000000002eULL: /* MAE */ goto unimplemented;
15497 case 0xed000000002fULL: /* MSE */ goto unimplemented;
15498 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
15499 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
15500 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
15501 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
15502 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
15503 case 0xed000000003aULL: /* MAY */ goto unimplemented;
15504 case 0xed000000003bULL: /* MY */ goto unimplemented;
15505 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
15506 case 0xed000000003dULL: /* MYH */ goto unimplemented;
15507 case 0xed000000003eULL: /* MAD */ goto unimplemented;
15508 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000015509 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
15510 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15511 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15512 ovl.fmt.RXF.r1); goto ok;
15513 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
15514 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15515 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15516 ovl.fmt.RXF.r1); goto ok;
15517 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
15518 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15519 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15520 ovl.fmt.RXF.r1); goto ok;
15521 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
15522 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15523 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15524 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000015525 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
15526 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15527 ovl.fmt.RXE.d2); goto ok;
15528 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
15529 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15530 ovl.fmt.RXE.d2); goto ok;
15531 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
15532 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15533 ovl.fmt.RXE.d2); goto ok;
15534 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
15535 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15536 ovl.fmt.RXE.d2); goto ok;
15537 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
15538 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15539 ovl.fmt.RXE.d2); goto ok;
15540 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
15541 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15542 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015543 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
15544 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15545 ovl.fmt.RXY.dl2,
15546 ovl.fmt.RXY.dh2); goto ok;
15547 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
15548 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15549 ovl.fmt.RXY.dl2,
15550 ovl.fmt.RXY.dh2); goto ok;
15551 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
15552 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15553 ovl.fmt.RXY.dl2,
15554 ovl.fmt.RXY.dh2); goto ok;
15555 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
15556 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15557 ovl.fmt.RXY.dl2,
15558 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015559 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
15560 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
15561 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
15562 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015563 }
15564
15565 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
15566 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
15567 ovl.fmt.RIL.i2); goto ok;
15568 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
15569 ovl.fmt.RIL.i2); goto ok;
15570 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
15571 ovl.fmt.RIL.i2); goto ok;
15572 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
15573 ovl.fmt.RIL.i2); goto ok;
15574 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
15575 ovl.fmt.RIL.i2); goto ok;
15576 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
15577 ovl.fmt.RIL.i2); goto ok;
15578 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
15579 ovl.fmt.RIL.i2); goto ok;
15580 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
15581 ovl.fmt.RIL.i2); goto ok;
15582 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
15583 ovl.fmt.RIL.i2); goto ok;
15584 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
15585 ovl.fmt.RIL.i2); goto ok;
15586 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
15587 ovl.fmt.RIL.i2); goto ok;
15588 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
15589 ovl.fmt.RIL.i2); goto ok;
15590 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
15591 ovl.fmt.RIL.i2); goto ok;
15592 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
15593 ovl.fmt.RIL.i2); goto ok;
15594 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
15595 ovl.fmt.RIL.i2); goto ok;
15596 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
15597 ovl.fmt.RIL.i2); goto ok;
15598 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
15599 ovl.fmt.RIL.i2); goto ok;
15600 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
15601 ovl.fmt.RIL.i2); goto ok;
15602 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
15603 ovl.fmt.RIL.i2); goto ok;
15604 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
15605 ovl.fmt.RIL.i2); goto ok;
15606 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
15607 ovl.fmt.RIL.i2); goto ok;
15608 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
15609 ovl.fmt.RIL.i2); goto ok;
15610 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
15611 ovl.fmt.RIL.i2); goto ok;
15612 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
15613 ovl.fmt.RIL.i2); goto ok;
15614 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
15615 ovl.fmt.RIL.i2); goto ok;
15616 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
15617 ovl.fmt.RIL.i2); goto ok;
15618 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
15619 ovl.fmt.RIL.i2); goto ok;
15620 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
15621 ovl.fmt.RIL.i2); goto ok;
15622 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
15623 ovl.fmt.RIL.i2); goto ok;
15624 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
15625 ovl.fmt.RIL.i2); goto ok;
15626 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
15627 ovl.fmt.RIL.i2); goto ok;
15628 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
15629 ovl.fmt.RIL.i2); goto ok;
15630 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
15631 ovl.fmt.RIL.i2); goto ok;
15632 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
15633 ovl.fmt.RIL.i2); goto ok;
15634 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
15635 ovl.fmt.RIL.i2); goto ok;
15636 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
15637 ovl.fmt.RIL.i2); goto ok;
15638 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
15639 ovl.fmt.RIL.i2); goto ok;
15640 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
15641 ovl.fmt.RIL.i2); goto ok;
15642 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
15643 ovl.fmt.RIL.i2); goto ok;
15644 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
15645 ovl.fmt.RIL.i2); goto ok;
15646 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
15647 ovl.fmt.RIL.i2); goto ok;
15648 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
15649 ovl.fmt.RIL.i2); goto ok;
15650 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
15651 ovl.fmt.RIL.i2); goto ok;
15652 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
15653 ovl.fmt.RIL.i2); goto ok;
15654 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
15655 ovl.fmt.RIL.i2); goto ok;
15656 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
15657 ovl.fmt.RIL.i2); goto ok;
15658 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
15659 ovl.fmt.RIL.i2); goto ok;
15660 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
15661 ovl.fmt.RIL.i2); goto ok;
15662 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
15663 ovl.fmt.RIL.i2); goto ok;
15664 case 0xc800ULL: /* MVCOS */ goto unimplemented;
15665 case 0xc801ULL: /* ECTG */ goto unimplemented;
15666 case 0xc802ULL: /* CSST */ goto unimplemented;
15667 case 0xc804ULL: /* LPD */ goto unimplemented;
15668 case 0xc805ULL: /* LPDG */ goto unimplemented;
15669 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
15670 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
15671 ovl.fmt.RIL.i2); goto ok;
15672 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
15673 ovl.fmt.RIL.i2); goto ok;
15674 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
15675 ovl.fmt.RIL.i2); goto ok;
15676 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
15677 ovl.fmt.RIL.i2); goto ok;
15678 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
15679 ovl.fmt.RIL.i2); goto ok;
15680 }
15681
15682 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000015683 case 0xc5ULL: /* BPRP */ goto unimplemented;
15684 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015685 case 0xd0ULL: /* TRTR */ goto unimplemented;
15686 case 0xd1ULL: /* MVN */ goto unimplemented;
15687 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
15688 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15689 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15690 case 0xd3ULL: /* MVZ */ goto unimplemented;
15691 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
15692 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15693 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15694 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
15695 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15696 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15697 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
15698 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15699 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000015700 case 0xd7ULL:
15701 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
15702 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
15703 else
15704 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
15705 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15706 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
15707 goto ok;
sewardj2019a972011-03-07 16:04:07 +000015708 case 0xd9ULL: /* MVCK */ goto unimplemented;
15709 case 0xdaULL: /* MVCP */ goto unimplemented;
15710 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015711 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
15712 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15713 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015714 case 0xddULL: /* TRT */ goto unimplemented;
15715 case 0xdeULL: /* ED */ goto unimplemented;
15716 case 0xdfULL: /* EDMK */ goto unimplemented;
15717 case 0xe1ULL: /* PKU */ goto unimplemented;
15718 case 0xe2ULL: /* UNPKU */ goto unimplemented;
15719 case 0xe8ULL: /* MVCIN */ goto unimplemented;
15720 case 0xe9ULL: /* PKA */ goto unimplemented;
15721 case 0xeaULL: /* UNPKA */ goto unimplemented;
15722 case 0xeeULL: /* PLO */ goto unimplemented;
15723 case 0xefULL: /* LMD */ goto unimplemented;
15724 case 0xf0ULL: /* SRP */ goto unimplemented;
15725 case 0xf1ULL: /* MVO */ goto unimplemented;
15726 case 0xf2ULL: /* PACK */ goto unimplemented;
15727 case 0xf3ULL: /* UNPK */ goto unimplemented;
15728 case 0xf8ULL: /* ZAP */ goto unimplemented;
15729 case 0xf9ULL: /* CP */ goto unimplemented;
15730 case 0xfaULL: /* AP */ goto unimplemented;
15731 case 0xfbULL: /* SP */ goto unimplemented;
15732 case 0xfcULL: /* MP */ goto unimplemented;
15733 case 0xfdULL: /* DP */ goto unimplemented;
15734 }
15735
15736 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
15737 case 0xe500ULL: /* LASP */ goto unimplemented;
15738 case 0xe501ULL: /* TPROT */ goto unimplemented;
15739 case 0xe502ULL: /* STRAG */ goto unimplemented;
15740 case 0xe50eULL: /* MVCSK */ goto unimplemented;
15741 case 0xe50fULL: /* MVCDK */ goto unimplemented;
15742 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
15743 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15744 goto ok;
15745 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
15746 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15747 goto ok;
15748 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
15749 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15750 goto ok;
15751 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
15752 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15753 goto ok;
15754 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
15755 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15756 goto ok;
15757 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
15758 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15759 goto ok;
15760 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
15761 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15762 goto ok;
15763 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
15764 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15765 goto ok;
15766 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
15767 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15768 goto ok;
florian2289cd42012-12-05 04:23:42 +000015769 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
15770 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015771 }
15772
15773 return S390_DECODE_UNKNOWN_INSN;
15774
15775ok:
15776 return S390_DECODE_OK;
15777
15778unimplemented:
15779 return S390_DECODE_UNIMPLEMENTED_INSN;
15780}
15781
15782/* Handle "special" instructions. */
15783static s390_decode_t
15784s390_decode_special_and_irgen(UChar *bytes)
15785{
15786 s390_decode_t status = S390_DECODE_OK;
15787
15788 /* Got a "Special" instruction preamble. Which one is it? */
15789 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
15790 s390_irgen_client_request();
15791 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
15792 s390_irgen_guest_NRADDR();
15793 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
15794 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000015795 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
15796 vex_inject_ir(irsb, Iend_BE);
15797
15798 /* Invalidate the current insn. The reason is that the IRop we're
15799 injecting here can change. In which case the translation has to
15800 be redone. For ease of handling, we simply invalidate all the
15801 time. */
15802 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
15803 mkU64(guest_IA_curr_instr)));
15804 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
15805 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
15806 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
15807 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
15808
15809 put_IA(mkaddr_expr(guest_IA_next_instr));
15810 dis_res->whatNext = Dis_StopHere;
15811 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000015812 } else {
15813 /* We don't know what it is. */
15814 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
15815 }
15816
15817 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15818
15819 return status;
15820}
15821
15822
15823/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000015824static UInt
sewardj2019a972011-03-07 16:04:07 +000015825s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
15826{
15827 s390_decode_t status;
15828
15829 dis_res = dres;
15830
15831 /* Spot the 8-byte preamble: 18ff lr r15,r15
15832 1811 lr r1,r1
15833 1822 lr r2,r2
15834 1833 lr r3,r3 */
15835 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
15836 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
15837 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
15838
15839 /* Handle special instruction that follows that preamble. */
15840 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000015841
15842 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15843 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15844
15845 status =
15846 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000015847 } else {
15848 /* Handle normal instructions. */
15849 switch (insn_length) {
15850 case 2:
15851 status = s390_decode_2byte_and_irgen(bytes);
15852 break;
15853
15854 case 4:
15855 status = s390_decode_4byte_and_irgen(bytes);
15856 break;
15857
15858 case 6:
15859 status = s390_decode_6byte_and_irgen(bytes);
15860 break;
15861
15862 default:
15863 status = S390_DECODE_ERROR;
15864 break;
15865 }
15866 }
florian5fcbba22011-07-27 20:40:22 +000015867 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000015868 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
15869 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000015870 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000015871 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000015872 }
15873
15874 if (status == S390_DECODE_OK) return insn_length; /* OK */
15875
15876 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000015877 if (sigill_diag) {
15878 vex_printf("vex s390->IR: ");
15879 switch (status) {
15880 case S390_DECODE_UNKNOWN_INSN:
15881 vex_printf("unknown insn: ");
15882 break;
sewardj2019a972011-03-07 16:04:07 +000015883
sewardj442e51a2012-12-06 18:08:04 +000015884 case S390_DECODE_UNIMPLEMENTED_INSN:
15885 vex_printf("unimplemented insn: ");
15886 break;
sewardj2019a972011-03-07 16:04:07 +000015887
sewardj442e51a2012-12-06 18:08:04 +000015888 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
15889 vex_printf("unimplemented special insn: ");
15890 break;
sewardj2019a972011-03-07 16:04:07 +000015891
sewardj442e51a2012-12-06 18:08:04 +000015892 default:
15893 case S390_DECODE_ERROR:
15894 vex_printf("decoding error: ");
15895 break;
15896 }
15897
15898 vex_printf("%02x%02x", bytes[0], bytes[1]);
15899 if (insn_length > 2) {
15900 vex_printf(" %02x%02x", bytes[2], bytes[3]);
15901 }
15902 if (insn_length > 4) {
15903 vex_printf(" %02x%02x", bytes[4], bytes[5]);
15904 }
15905 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000015906 }
15907
sewardj2019a972011-03-07 16:04:07 +000015908 return 0; /* Failed */
15909}
15910
15911
sewardj2019a972011-03-07 16:04:07 +000015912/* Disassemble a single instruction INSN into IR. */
15913static DisResult
florian420c5012011-07-22 02:12:28 +000015914disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000015915{
15916 UChar byte;
15917 UInt insn_length;
15918 DisResult dres;
15919
15920 /* ---------------------------------------------------- */
15921 /* --- Compute instruction length -- */
15922 /* ---------------------------------------------------- */
15923
15924 /* Get the first byte of the insn. */
15925 byte = insn[0];
15926
15927 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
15928 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
15929 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
15930
15931 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15932
15933 /* ---------------------------------------------------- */
15934 /* --- Initialise the DisResult data -- */
15935 /* ---------------------------------------------------- */
15936 dres.whatNext = Dis_Continue;
15937 dres.len = insn_length;
15938 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000015939 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000015940
floriana99f20e2011-07-17 14:16:41 +000015941 /* fixs390: consider chasing of conditional jumps */
15942
sewardj2019a972011-03-07 16:04:07 +000015943 /* Normal and special instruction handling starts here. */
15944 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
15945 /* All decode failures end up here. The decoder has already issued an
15946 error message.
15947 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000015948 not been executed, and (is currently) the next to be executed.
15949 The insn address in the guest state needs to be set to
15950 guest_IA_curr_instr, otherwise the complaint will report an
15951 incorrect address. */
15952 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000015953
florian8844a632012-04-13 04:04:06 +000015954 dres.whatNext = Dis_StopHere;
15955 dres.jk_StopHere = Ijk_NoDecode;
15956 dres.continueAt = 0;
15957 dres.len = 0;
15958 } else {
15959 /* Decode success */
15960 switch (dres.whatNext) {
15961 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015962 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015963 break;
15964 case Dis_ResteerU:
15965 case Dis_ResteerC:
15966 put_IA(mkaddr_expr(dres.continueAt));
15967 break;
15968 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000015969 if (dres.jk_StopHere == Ijk_EmWarn ||
15970 dres.jk_StopHere == Ijk_EmFail) {
15971 /* We assume here, that emulation warnings are not given for
15972 insns that transfer control. There is no good way to
15973 do that. */
15974 put_IA(mkaddr_expr(guest_IA_next_instr));
15975 }
florian8844a632012-04-13 04:04:06 +000015976 break;
15977 default:
15978 vassert(0);
15979 }
sewardj2019a972011-03-07 16:04:07 +000015980 }
15981
15982 return dres;
15983}
15984
15985
15986/*------------------------------------------------------------*/
15987/*--- Top-level fn ---*/
15988/*------------------------------------------------------------*/
15989
15990/* Disassemble a single instruction into IR. The instruction
15991 is located in host memory at &guest_code[delta]. */
15992
15993DisResult
15994disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015995 Bool (*resteerOkFn)(void *, Addr64),
15996 Bool resteerCisOk,
15997 void *callback_opaque,
15998 UChar *guest_code,
15999 Long delta,
16000 Addr64 guest_IP,
16001 VexArch guest_arch,
16002 VexArchInfo *archinfo,
16003 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000016004 Bool host_bigendian,
16005 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016006{
16007 vassert(guest_arch == VexArchS390X);
16008
16009 /* The instruction decoder requires a big-endian machine. */
16010 vassert(host_bigendian == True);
16011
16012 /* Set globals (see top of this file) */
16013 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016014 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016015 resteer_fn = resteerOkFn;
16016 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016017 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016018
florian420c5012011-07-22 02:12:28 +000016019 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016020}
16021
16022/*---------------------------------------------------------------*/
16023/*--- end guest_s390_toIR.c ---*/
16024/*---------------------------------------------------------------*/