blob: f1fc84909853c8ac738eadfc3a438580f17b8557 [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);
florian1bb7f6f2013-02-11 00:03:27 +00009229
9230 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9231 emulation_warning(EmWarn_S390X_fpext_rounding);
9232 m4 = S390_DFP_ROUND_PER_FPC_0;
9233 }
9234
florian12390202012-11-10 22:34:14 +00009235 rounding_mode = encode_dfp_rounding_mode(m4);
9236 assign(op1, get_dpr_dw0(r2));
9237 assign(op2, get_dpr_dw0(r3));
9238 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9239 mkexpr(op2)));
9240 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9241 put_dpr_dw0(r1, mkexpr(result));
9242
9243 return (m4 == 0) ? "adtr" : "adtra";
9244}
9245
florian55085f82012-11-21 00:36:55 +00009246static const HChar *
floriane38f6412012-12-21 17:32:12 +00009247s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9248{
9249 IRTemp op1 = newTemp(Ity_D128);
9250 IRTemp op2 = newTemp(Ity_D128);
9251 IRTemp result = newTemp(Ity_D128);
9252 IRTemp rounding_mode;
9253
9254 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009255
9256 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9257 emulation_warning(EmWarn_S390X_fpext_rounding);
9258 m4 = S390_DFP_ROUND_PER_FPC_0;
9259 }
9260
floriane38f6412012-12-21 17:32:12 +00009261 rounding_mode = encode_dfp_rounding_mode(m4);
9262 assign(op1, get_dpr_pair(r2));
9263 assign(op2, get_dpr_pair(r3));
9264 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9265 mkexpr(op2)));
9266 put_dpr_pair(r1, mkexpr(result));
9267
9268 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9269
9270 return (m4 == 0) ? "axtr" : "axtra";
9271}
9272
9273static const HChar *
9274s390_irgen_CDTR(UChar r1, UChar r2)
9275{
9276 IRTemp op1 = newTemp(Ity_D64);
9277 IRTemp op2 = newTemp(Ity_D64);
9278 IRTemp cc_vex = newTemp(Ity_I32);
9279 IRTemp cc_s390 = newTemp(Ity_I32);
9280
9281 assign(op1, get_dpr_dw0(r1));
9282 assign(op2, get_dpr_dw0(r2));
9283 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9284
florian2d3d87f2012-12-21 21:05:17 +00009285 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009286 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9287
9288 return "cdtr";
9289}
9290
9291static const HChar *
9292s390_irgen_CXTR(UChar r1, UChar r2)
9293{
9294 IRTemp op1 = newTemp(Ity_D128);
9295 IRTemp op2 = newTemp(Ity_D128);
9296 IRTemp cc_vex = newTemp(Ity_I32);
9297 IRTemp cc_s390 = newTemp(Ity_I32);
9298
9299 assign(op1, get_dpr_pair(r1));
9300 assign(op2, get_dpr_pair(r2));
9301 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9302
florian2d3d87f2012-12-21 21:05:17 +00009303 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009304 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9305
9306 return "cxtr";
9307}
9308
9309static const HChar *
florian5f034622013-01-13 02:29:05 +00009310s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9311 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9312{
9313 vassert(s390_host_has_dfp);
9314
9315 if (! s390_host_has_fpext) {
9316 emulation_failure(EmFail_S390X_fpext);
9317 } else {
9318 IRTemp op2 = newTemp(Ity_I32);
9319
9320 assign(op2, get_gpr_w1(r2));
9321 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9322 }
9323 return "cdftr";
9324}
9325
9326static const HChar *
9327s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9328 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9329{
9330 vassert(s390_host_has_dfp);
9331
9332 if (! s390_host_has_fpext) {
9333 emulation_failure(EmFail_S390X_fpext);
9334 } else {
9335 IRTemp op2 = newTemp(Ity_I32);
9336
9337 assign(op2, get_gpr_w1(r2));
9338 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9339 }
9340 return "cxftr";
9341}
9342
9343static const HChar *
floriana887acd2013-02-08 23:32:54 +00009344s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9345 UChar r1, UChar r2)
9346{
9347 IRTemp op2 = newTemp(Ity_I64);
9348
9349 vassert(s390_host_has_dfp);
9350 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9351 emulation_warning(EmWarn_S390X_fpext_rounding);
9352 m3 = S390_DFP_ROUND_PER_FPC_0;
9353 }
9354
9355 assign(op2, get_gpr_dw0(r2));
9356 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9357 mkexpr(op2)));
9358
9359 return (m3 == 0) ? "cdgtr" : "cdgtra";
9360}
9361
9362static const HChar *
9363s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9364 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9365{
9366 IRTemp op2 = newTemp(Ity_I64);
9367
9368 vassert(s390_host_has_dfp);
9369
florian1bb7f6f2013-02-11 00:03:27 +00009370 /* No emulation warning here about an non-zero m3 on hosts without
9371 floating point extension facility. No rounding is performed */
9372
floriana887acd2013-02-08 23:32:54 +00009373 assign(op2, get_gpr_dw0(r2));
9374 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9375
9376 return "cxgtr";
9377}
9378
9379static const HChar *
florian5f034622013-01-13 02:29:05 +00009380s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9381 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9382{
9383 vassert(s390_host_has_dfp);
9384
9385 if (! s390_host_has_fpext) {
9386 emulation_failure(EmFail_S390X_fpext);
9387 } else {
9388 IRTemp op2 = newTemp(Ity_I32);
9389
9390 assign(op2, get_gpr_w1(r2));
9391 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9392 }
9393 return "cdlftr";
9394}
9395
9396static const HChar *
9397s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9398 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9399{
9400 vassert(s390_host_has_dfp);
9401
9402 if (! s390_host_has_fpext) {
9403 emulation_failure(EmFail_S390X_fpext);
9404 } else {
9405 IRTemp op2 = newTemp(Ity_I32);
9406
9407 assign(op2, get_gpr_w1(r2));
9408 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9409 }
9410 return "cxlftr";
9411}
9412
9413static const HChar *
9414s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9415 UChar r1, UChar r2)
9416{
9417 vassert(s390_host_has_dfp);
9418
9419 if (! s390_host_has_fpext) {
9420 emulation_failure(EmFail_S390X_fpext);
9421 } else {
9422 IRTemp op2 = newTemp(Ity_I64);
9423
9424 assign(op2, get_gpr_dw0(r2));
9425 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9426 mkexpr(encode_dfp_rounding_mode(m3)),
9427 mkexpr(op2)));
9428 }
9429 return "cdlgtr";
9430}
9431
9432static const HChar *
9433s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9434 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9435{
9436 vassert(s390_host_has_dfp);
9437
9438 if (! s390_host_has_fpext) {
9439 emulation_failure(EmFail_S390X_fpext);
9440 } else {
9441 IRTemp op2 = newTemp(Ity_I64);
9442
9443 assign(op2, get_gpr_dw0(r2));
9444 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9445 }
9446 return "cxlgtr";
9447}
9448
9449static const HChar *
9450s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9451 UChar r1, UChar r2)
9452{
9453 vassert(s390_host_has_dfp);
9454
9455 if (! s390_host_has_fpext) {
9456 emulation_failure(EmFail_S390X_fpext);
9457 } else {
9458 IRTemp op = newTemp(Ity_D64);
9459 IRTemp result = newTemp(Ity_I32);
9460 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9461
9462 assign(op, get_dpr_dw0(r2));
9463 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9464 mkexpr(op)));
9465 put_gpr_w1(r1, mkexpr(result));
9466 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9467 }
9468 return "cfdtr";
9469}
9470
9471static const HChar *
9472s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9473 UChar r1, UChar r2)
9474{
9475 vassert(s390_host_has_dfp);
9476
9477 if (! s390_host_has_fpext) {
9478 emulation_failure(EmFail_S390X_fpext);
9479 } else {
9480 IRTemp op = newTemp(Ity_D128);
9481 IRTemp result = newTemp(Ity_I32);
9482 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9483
9484 assign(op, get_dpr_pair(r2));
9485 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9486 mkexpr(op)));
9487 put_gpr_w1(r1, mkexpr(result));
9488 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9489 }
9490 return "cfxtr";
9491}
9492
9493static const HChar *
floriana887acd2013-02-08 23:32:54 +00009494s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9495 UChar r1, UChar r2)
9496{
9497 IRTemp op = newTemp(Ity_D64);
9498 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9499
9500 vassert(s390_host_has_dfp);
9501
9502 /* If fpext is not installed and m3 is in 1:7,
9503 rounding mode performed is unpredictable */
9504 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9505 emulation_warning(EmWarn_S390X_fpext_rounding);
9506 m3 = S390_DFP_ROUND_PER_FPC_0;
9507 }
9508
9509 assign(op, get_dpr_dw0(r2));
9510 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9511 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9512
9513 return "cgdtr";
9514}
9515
9516static const HChar *
9517s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9518 UChar r1, UChar r2)
9519{
9520 IRTemp op = newTemp(Ity_D128);
9521 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9522
9523 vassert(s390_host_has_dfp);
9524
9525 /* If fpext is not installed and m3 is in 1:7,
9526 rounding mode performed is unpredictable */
9527 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9528 emulation_warning(EmWarn_S390X_fpext_rounding);
9529 m3 = S390_DFP_ROUND_PER_FPC_0;
9530 }
9531 assign(op, get_dpr_pair(r2));
9532 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9533 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9534
9535 return "cgxtr";
9536}
9537
9538static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009539s390_irgen_CEDTR(UChar r1, UChar r2)
9540{
9541 IRTemp op1 = newTemp(Ity_D64);
9542 IRTemp op2 = newTemp(Ity_D64);
9543 IRTemp cc_vex = newTemp(Ity_I32);
9544 IRTemp cc_s390 = newTemp(Ity_I32);
9545
9546 vassert(s390_host_has_dfp);
9547 assign(op1, get_dpr_dw0(r1));
9548 assign(op2, get_dpr_dw0(r2));
9549 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9550
9551 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9552 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9553
9554 return "cedtr";
9555}
9556
9557static const HChar *
9558s390_irgen_CEXTR(UChar r1, UChar r2)
9559{
9560 IRTemp op1 = newTemp(Ity_D128);
9561 IRTemp op2 = newTemp(Ity_D128);
9562 IRTemp cc_vex = newTemp(Ity_I32);
9563 IRTemp cc_s390 = newTemp(Ity_I32);
9564
9565 vassert(s390_host_has_dfp);
9566 assign(op1, get_dpr_pair(r1));
9567 assign(op2, get_dpr_pair(r2));
9568 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9569
9570 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9571 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9572
9573 return "cextr";
9574}
9575
9576static const HChar *
florian5f034622013-01-13 02:29:05 +00009577s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9578 UChar r1, UChar r2)
9579{
9580 vassert(s390_host_has_dfp);
9581
9582 if (! s390_host_has_fpext) {
9583 emulation_failure(EmFail_S390X_fpext);
9584 } else {
9585 IRTemp op = newTemp(Ity_D64);
9586 IRTemp result = newTemp(Ity_I32);
9587 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9588
9589 assign(op, get_dpr_dw0(r2));
9590 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9591 mkexpr(op)));
9592 put_gpr_w1(r1, mkexpr(result));
9593 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9594 }
9595 return "clfdtr";
9596}
9597
9598static const HChar *
9599s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9600 UChar r1, UChar r2)
9601{
9602 vassert(s390_host_has_dfp);
9603
9604 if (! s390_host_has_fpext) {
9605 emulation_failure(EmFail_S390X_fpext);
9606 } else {
9607 IRTemp op = newTemp(Ity_D128);
9608 IRTemp result = newTemp(Ity_I32);
9609 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9610
9611 assign(op, get_dpr_pair(r2));
9612 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9613 mkexpr(op)));
9614 put_gpr_w1(r1, mkexpr(result));
9615 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9616 }
9617 return "clfxtr";
9618}
9619
9620static const HChar *
9621s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9622 UChar r1, UChar r2)
9623{
9624 vassert(s390_host_has_dfp);
9625
9626 if (! s390_host_has_fpext) {
9627 emulation_failure(EmFail_S390X_fpext);
9628 } else {
9629 IRTemp op = newTemp(Ity_D64);
9630 IRTemp result = newTemp(Ity_I64);
9631 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9632
9633 assign(op, get_dpr_dw0(r2));
9634 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
9635 mkexpr(op)));
9636 put_gpr_dw0(r1, mkexpr(result));
9637 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
9638 }
9639 return "clgdtr";
9640}
9641
9642static const HChar *
9643s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
9644 UChar r1, UChar r2)
9645{
9646 vassert(s390_host_has_dfp);
9647
9648 if (! s390_host_has_fpext) {
9649 emulation_failure(EmFail_S390X_fpext);
9650 } else {
9651 IRTemp op = newTemp(Ity_D128);
9652 IRTemp result = newTemp(Ity_I64);
9653 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9654
9655 assign(op, get_dpr_pair(r2));
9656 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
9657 mkexpr(op)));
9658 put_gpr_dw0(r1, mkexpr(result));
9659 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
9660 rounding_mode);
9661 }
9662 return "clgxtr";
9663}
9664
9665static const HChar *
florian12390202012-11-10 22:34:14 +00009666s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9667{
9668 IRTemp op1 = newTemp(Ity_D64);
9669 IRTemp op2 = newTemp(Ity_D64);
9670 IRTemp result = newTemp(Ity_D64);
9671 IRTemp rounding_mode;
9672
9673 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009674
9675 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9676 emulation_warning(EmWarn_S390X_fpext_rounding);
9677 m4 = S390_DFP_ROUND_PER_FPC_0;
9678 }
9679
florian12390202012-11-10 22:34:14 +00009680 rounding_mode = encode_dfp_rounding_mode(m4);
9681 assign(op1, get_dpr_dw0(r2));
9682 assign(op2, get_dpr_dw0(r3));
9683 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9684 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009685 put_dpr_dw0(r1, mkexpr(result));
9686
9687 return (m4 == 0) ? "ddtr" : "ddtra";
9688}
9689
florian55085f82012-11-21 00:36:55 +00009690static const HChar *
floriane38f6412012-12-21 17:32:12 +00009691s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9692{
9693 IRTemp op1 = newTemp(Ity_D128);
9694 IRTemp op2 = newTemp(Ity_D128);
9695 IRTemp result = newTemp(Ity_D128);
9696 IRTemp rounding_mode;
9697
9698 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009699
9700 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9701 emulation_warning(EmWarn_S390X_fpext_rounding);
9702 m4 = S390_DFP_ROUND_PER_FPC_0;
9703 }
9704
floriane38f6412012-12-21 17:32:12 +00009705 rounding_mode = encode_dfp_rounding_mode(m4);
9706 assign(op1, get_dpr_pair(r2));
9707 assign(op2, get_dpr_pair(r3));
9708 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9709 mkexpr(op2)));
9710 put_dpr_pair(r1, mkexpr(result));
9711
9712 return (m4 == 0) ? "dxtr" : "dxtra";
9713}
9714
9715static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009716s390_irgen_ESDTR(UChar r1, UChar r2)
9717{
9718 vassert(s390_host_has_dfp);
9719 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
9720 return "esdtr";
9721}
9722
9723static const HChar *
9724s390_irgen_ESXTR(UChar r1, UChar r2)
9725{
9726 vassert(s390_host_has_dfp);
9727 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
9728 return "esxtr";
9729}
9730
9731static const HChar *
floriane38f6412012-12-21 17:32:12 +00009732s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9733{
9734 IRTemp op = newTemp(Ity_D32);
9735
9736 vassert(s390_host_has_dfp);
9737
9738 assign(op, get_dpr_w0(r2));
9739 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
9740
9741 return "ldetr";
9742}
9743
9744static const HChar *
9745s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9746{
9747 IRTemp op = newTemp(Ity_D64);
9748
9749 assign(op, get_dpr_dw0(r2));
9750 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
9751
9752 return "lxdtr";
9753}
9754
9755static const HChar *
9756s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
9757 UChar r1, UChar r2)
9758{
9759 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009760
9761 /* If fpext is not installed and m3 is in 1:7,
9762 rounding mode performed is unpredictable */
9763 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +00009764 emulation_warning(EmWarn_S390X_fpext_rounding);
9765 m3 = S390_DFP_ROUND_PER_FPC_0;
9766 }
9767 IRTemp result = newTemp(Ity_D64);
9768
9769 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
9770 get_dpr_pair(r2)));
9771 put_dpr_dw0(r1, mkexpr(result));
9772
9773 return "ldxtr";
9774}
9775
9776static const HChar *
9777s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
9778 UChar r1, UChar r2)
9779{
9780 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009781
9782 /* If fpext is not installed and m3 is in 1:7,
9783 rounding mode performed is unpredictable */
9784 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +00009785 emulation_warning(EmWarn_S390X_fpext_rounding);
9786 m3 = S390_DFP_ROUND_PER_FPC_0;
9787 }
9788 IRTemp op = newTemp(Ity_D64);
9789
9790 assign(op, get_dpr_dw0(r2));
9791 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
9792 mkexpr(op)));
9793
9794 return "ledtr";
9795}
9796
9797static const HChar *
9798s390_irgen_LTDTR(UChar r1, UChar r2)
9799{
9800 IRTemp result = newTemp(Ity_D64);
9801
9802 assign(result, get_dpr_dw0(r2));
9803 put_dpr_dw0(r1, mkexpr(result));
9804 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9805
9806 return "ltdtr";
9807}
9808
9809static const HChar *
9810s390_irgen_LTXTR(UChar r1, UChar r2)
9811{
9812 IRTemp result = newTemp(Ity_D128);
9813
9814 assign(result, get_dpr_pair(r2));
9815 put_dpr_pair(r1, mkexpr(result));
9816 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9817
9818 return "ltxtr";
9819}
9820
9821static const HChar *
florian12390202012-11-10 22:34:14 +00009822s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9823{
9824 IRTemp op1 = newTemp(Ity_D64);
9825 IRTemp op2 = newTemp(Ity_D64);
9826 IRTemp result = newTemp(Ity_D64);
9827 IRTemp rounding_mode;
9828
9829 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009830
9831 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9832 emulation_warning(EmWarn_S390X_fpext_rounding);
9833 m4 = S390_DFP_ROUND_PER_FPC_0;
9834 }
9835
florian12390202012-11-10 22:34:14 +00009836 rounding_mode = encode_dfp_rounding_mode(m4);
9837 assign(op1, get_dpr_dw0(r2));
9838 assign(op2, get_dpr_dw0(r3));
9839 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9840 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009841 put_dpr_dw0(r1, mkexpr(result));
9842
9843 return (m4 == 0) ? "mdtr" : "mdtra";
9844}
9845
florian55085f82012-11-21 00:36:55 +00009846static const HChar *
floriane38f6412012-12-21 17:32:12 +00009847s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9848{
9849 IRTemp op1 = newTemp(Ity_D128);
9850 IRTemp op2 = newTemp(Ity_D128);
9851 IRTemp result = newTemp(Ity_D128);
9852 IRTemp rounding_mode;
9853
9854 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009855
9856 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9857 emulation_warning(EmWarn_S390X_fpext_rounding);
9858 m4 = S390_DFP_ROUND_PER_FPC_0;
9859 }
9860
floriane38f6412012-12-21 17:32:12 +00009861 rounding_mode = encode_dfp_rounding_mode(m4);
9862 assign(op1, get_dpr_pair(r2));
9863 assign(op2, get_dpr_pair(r3));
9864 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
9865 mkexpr(op2)));
9866 put_dpr_pair(r1, mkexpr(result));
9867
9868 return (m4 == 0) ? "mxtr" : "mxtra";
9869}
9870
9871static const HChar *
florian12390202012-11-10 22:34:14 +00009872s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9873{
9874 IRTemp op1 = newTemp(Ity_D64);
9875 IRTemp op2 = newTemp(Ity_D64);
9876 IRTemp result = newTemp(Ity_D64);
9877 IRTemp rounding_mode;
9878
9879 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009880
9881 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9882 emulation_warning(EmWarn_S390X_fpext_rounding);
9883 m4 = S390_DFP_ROUND_PER_FPC_0;
9884 }
9885
florian12390202012-11-10 22:34:14 +00009886 rounding_mode = encode_dfp_rounding_mode(m4);
9887 assign(op1, get_dpr_dw0(r2));
9888 assign(op2, get_dpr_dw0(r3));
9889 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9890 mkexpr(op2)));
9891 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9892 put_dpr_dw0(r1, mkexpr(result));
9893
9894 return (m4 == 0) ? "sdtr" : "sdtra";
9895}
9896
floriane38f6412012-12-21 17:32:12 +00009897static const HChar *
9898s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9899{
9900 IRTemp op1 = newTemp(Ity_D128);
9901 IRTemp op2 = newTemp(Ity_D128);
9902 IRTemp result = newTemp(Ity_D128);
9903 IRTemp rounding_mode;
9904
9905 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009906
9907 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9908 emulation_warning(EmWarn_S390X_fpext_rounding);
9909 m4 = S390_DFP_ROUND_PER_FPC_0;
9910 }
9911
floriane38f6412012-12-21 17:32:12 +00009912 rounding_mode = encode_dfp_rounding_mode(m4);
9913 assign(op1, get_dpr_pair(r2));
9914 assign(op2, get_dpr_pair(r3));
9915 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
9916 mkexpr(op2)));
9917 put_dpr_pair(r1, mkexpr(result));
9918
9919 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9920
9921 return (m4 == 0) ? "sxtr" : "sxtra";
9922}
sewardj2019a972011-03-07 16:04:07 +00009923
florian55085f82012-11-21 00:36:55 +00009924static const HChar *
florian1b901d42013-01-01 22:19:24 +00009925s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
9926{
9927 IRTemp op = newTemp(Ity_D64);
9928
9929 vassert(s390_host_has_dfp);
9930
9931 assign(op, get_dpr_dw0(r3));
9932 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
9933 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9934
9935 return "sldt";
9936}
9937
9938static const HChar *
9939s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
9940{
9941 IRTemp op = newTemp(Ity_D128);
9942
9943 vassert(s390_host_has_dfp);
9944
9945 assign(op, get_dpr_pair(r3));
9946 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
9947 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9948
9949 return "slxt";
9950}
9951
9952static const HChar *
9953s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
9954{
9955 IRTemp op = newTemp(Ity_D64);
9956
9957 vassert(s390_host_has_dfp);
9958
9959 assign(op, get_dpr_dw0(r3));
9960 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
9961 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9962
9963 return "srdt";
9964}
9965
9966static const HChar *
9967s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
9968{
9969 IRTemp op = newTemp(Ity_D128);
9970
9971 vassert(s390_host_has_dfp);
9972
9973 assign(op, get_dpr_pair(r3));
9974 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
9975 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9976
9977 return "srxt";
9978}
9979
9980static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009981s390_irgen_TDCET(UChar r1, IRTemp op2addr)
9982{
9983 IRTemp value = newTemp(Ity_D32);
9984
9985 vassert(s390_host_has_dfp);
9986 assign(value, get_dpr_w0(r1));
9987
9988 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
9989
9990 return "tdcet";
9991}
9992
9993static const HChar *
9994s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
9995{
9996 IRTemp value = newTemp(Ity_D64);
9997
9998 vassert(s390_host_has_dfp);
9999 assign(value, get_dpr_dw0(r1));
10000
10001 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10002
10003 return "tdcdt";
10004}
10005
10006static const HChar *
10007s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10008{
10009 IRTemp value = newTemp(Ity_D128);
10010
10011 vassert(s390_host_has_dfp);
10012 assign(value, get_dpr_pair(r1));
10013
10014 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10015
10016 return "tdcxt";
10017}
10018
10019static const HChar *
10020s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10021{
10022 IRTemp value = newTemp(Ity_D32);
10023
10024 vassert(s390_host_has_dfp);
10025 assign(value, get_dpr_w0(r1));
10026
10027 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10028
10029 return "tdget";
10030}
10031
10032static const HChar *
10033s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10034{
10035 IRTemp value = newTemp(Ity_D64);
10036
10037 vassert(s390_host_has_dfp);
10038 assign(value, get_dpr_dw0(r1));
10039
10040 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10041
10042 return "tdgdt";
10043}
10044
10045static const HChar *
10046s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10047{
10048 IRTemp value = newTemp(Ity_D128);
10049
10050 vassert(s390_host_has_dfp);
10051 assign(value, get_dpr_pair(r1));
10052
10053 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10054
10055 return "tdgxt";
10056}
10057
10058static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010059s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10060{
florian79e839e2012-05-05 02:20:30 +000010061 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010062
florian79e839e2012-05-05 02:20:30 +000010063 assign(len, mkU64(length));
10064 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010065
10066 return "clc";
10067}
10068
florian55085f82012-11-21 00:36:55 +000010069static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010070s390_irgen_CLCL(UChar r1, UChar r2)
10071{
10072 IRTemp addr1 = newTemp(Ity_I64);
10073 IRTemp addr2 = newTemp(Ity_I64);
10074 IRTemp addr1_load = newTemp(Ity_I64);
10075 IRTemp addr2_load = newTemp(Ity_I64);
10076 IRTemp len1 = newTemp(Ity_I32);
10077 IRTemp len2 = newTemp(Ity_I32);
10078 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10079 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10080 IRTemp single1 = newTemp(Ity_I8);
10081 IRTemp single2 = newTemp(Ity_I8);
10082 IRTemp pad = newTemp(Ity_I8);
10083
10084 assign(addr1, get_gpr_dw0(r1));
10085 assign(r1p1, get_gpr_w1(r1 + 1));
10086 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10087 assign(addr2, get_gpr_dw0(r2));
10088 assign(r2p1, get_gpr_w1(r2 + 1));
10089 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10090 assign(pad, get_gpr_b4(r2 + 1));
10091
10092 /* len1 == 0 and len2 == 0? Exit */
10093 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010094 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10095 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010096
10097 /* Because mkite evaluates both the then-clause and the else-clause
10098 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10099 may be NULL and loading from there would segfault. So we provide a
10100 valid dummy address in that case. Loading from there does no harm and
10101 the value will be discarded at runtime. */
10102 assign(addr1_load,
10103 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10104 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10105 assign(single1,
10106 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10107 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10108
10109 assign(addr2_load,
10110 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10111 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10112 assign(single2,
10113 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10114 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10115
10116 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10117 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010118 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010119
10120 /* Update len1 and addr1, unless len1 == 0. */
10121 put_gpr_dw0(r1,
10122 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10123 mkexpr(addr1),
10124 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10125
10126 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10127 put_gpr_w1(r1 + 1,
10128 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10129 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10130 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10131
10132 /* Update len2 and addr2, unless len2 == 0. */
10133 put_gpr_dw0(r2,
10134 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10135 mkexpr(addr2),
10136 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10137
10138 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10139 put_gpr_w1(r2 + 1,
10140 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10141 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10142 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10143
florian6820ba52012-07-26 02:01:50 +000010144 iterate();
florianb0c9a132011-09-08 15:37:39 +000010145
10146 return "clcl";
10147}
10148
florian55085f82012-11-21 00:36:55 +000010149static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010150s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10151{
10152 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10153
10154 addr1 = newTemp(Ity_I64);
10155 addr3 = newTemp(Ity_I64);
10156 addr1_load = newTemp(Ity_I64);
10157 addr3_load = newTemp(Ity_I64);
10158 len1 = newTemp(Ity_I64);
10159 len3 = newTemp(Ity_I64);
10160 single1 = newTemp(Ity_I8);
10161 single3 = newTemp(Ity_I8);
10162
10163 assign(addr1, get_gpr_dw0(r1));
10164 assign(len1, get_gpr_dw0(r1 + 1));
10165 assign(addr3, get_gpr_dw0(r3));
10166 assign(len3, get_gpr_dw0(r3 + 1));
10167
10168 /* len1 == 0 and len3 == 0? Exit */
10169 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010170 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10171 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010172
10173 /* A mux requires both ways to be possible. This is a way to prevent clcle
10174 from reading from addr1 if it should read from the pad. Since the pad
10175 has no address, just read from the instruction, we discard that anyway */
10176 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010177 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10178 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010179
10180 /* same for addr3 */
10181 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010182 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10183 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010184
10185 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010186 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10187 unop(Iop_64to8, mkexpr(pad2)),
10188 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010189
10190 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010191 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10192 unop(Iop_64to8, mkexpr(pad2)),
10193 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010194
10195 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10196 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010197 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010198
10199 /* If a length in 0 we must not change this length and the address */
10200 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010201 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10202 mkexpr(addr1),
10203 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010204
10205 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010206 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10207 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010208
10209 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010210 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10211 mkexpr(addr3),
10212 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010213
10214 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010215 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10216 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010217
florian6820ba52012-07-26 02:01:50 +000010218 iterate();
sewardj2019a972011-03-07 16:04:07 +000010219
10220 return "clcle";
10221}
floriana64c2432011-07-16 02:11:50 +000010222
florianb0bf6602012-05-05 00:01:16 +000010223
sewardj2019a972011-03-07 16:04:07 +000010224static void
10225s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10226{
florianb0bf6602012-05-05 00:01:16 +000010227 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10228}
sewardj2019a972011-03-07 16:04:07 +000010229
sewardj2019a972011-03-07 16:04:07 +000010230
florianb0bf6602012-05-05 00:01:16 +000010231static void
10232s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10233{
10234 s390_irgen_xonc(Iop_And8, length, start1, start2);
10235}
sewardj2019a972011-03-07 16:04:07 +000010236
sewardj2019a972011-03-07 16:04:07 +000010237
florianb0bf6602012-05-05 00:01:16 +000010238static void
10239s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10240{
10241 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010242}
10243
10244
10245static void
10246s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10247{
10248 IRTemp current1 = newTemp(Ity_I8);
10249 IRTemp current2 = newTemp(Ity_I8);
10250 IRTemp counter = newTemp(Ity_I64);
10251
10252 assign(counter, get_counter_dw0());
10253 put_counter_dw0(mkU64(0));
10254
10255 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10256 mkexpr(counter))));
10257 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10258 mkexpr(counter))));
10259 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10260 False);
10261
10262 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010263 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010264
10265 /* Check for end of field */
10266 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010267 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010268 put_counter_dw0(mkU64(0));
10269}
10270
10271static void
10272s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10273{
10274 IRTemp counter = newTemp(Ity_I64);
10275
10276 assign(counter, get_counter_dw0());
10277
10278 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10279 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10280
10281 /* Check for end of field */
10282 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010283 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010284 put_counter_dw0(mkU64(0));
10285}
10286
florianf87d4fb2012-05-05 02:55:24 +000010287static void
10288s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10289{
10290 IRTemp op = newTemp(Ity_I8);
10291 IRTemp op1 = newTemp(Ity_I8);
10292 IRTemp result = newTemp(Ity_I64);
10293 IRTemp counter = newTemp(Ity_I64);
10294
10295 assign(counter, get_counter_dw0());
10296
10297 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10298
10299 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10300
10301 assign(op1, load(Ity_I8, mkexpr(result)));
10302 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10303
10304 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010305 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010306 put_counter_dw0(mkU64(0));
10307}
sewardj2019a972011-03-07 16:04:07 +000010308
10309
10310static void
10311s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010312 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010313 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010314{
10315 struct SS {
10316 unsigned int op : 8;
10317 unsigned int l : 8;
10318 unsigned int b1 : 4;
10319 unsigned int d1 : 12;
10320 unsigned int b2 : 4;
10321 unsigned int d2 : 12;
10322 };
10323 union {
10324 struct SS dec;
10325 unsigned long bytes;
10326 } ss;
10327 IRTemp cond;
10328 IRDirty *d;
10329 IRTemp torun;
10330
10331 IRTemp start1 = newTemp(Ity_I64);
10332 IRTemp start2 = newTemp(Ity_I64);
10333 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10334 cond = newTemp(Ity_I1);
10335 torun = newTemp(Ity_I64);
10336
10337 assign(torun, load(Ity_I64, mkexpr(addr2)));
10338 /* Start with a check that the saved code is still correct */
10339 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10340 /* If not, save the new value */
10341 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10342 mkIRExprVec_1(mkexpr(torun)));
10343 d->guard = mkexpr(cond);
10344 stmt(IRStmt_Dirty(d));
10345
10346 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010347 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10348 mkU64(guest_IA_curr_instr)));
10349 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010350 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010351
10352 ss.bytes = last_execute_target;
10353 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10354 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10355 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10356 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10357 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10358 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10359 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010360
sewardj2019a972011-03-07 16:04:07 +000010361 last_execute_target = 0;
10362}
10363
florian55085f82012-11-21 00:36:55 +000010364static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010365s390_irgen_EX(UChar r1, IRTemp addr2)
10366{
10367 switch(last_execute_target & 0xff00000000000000ULL) {
10368 case 0:
10369 {
10370 /* no code information yet */
10371 IRDirty *d;
10372
10373 /* so safe the code... */
10374 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10375 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10376 stmt(IRStmt_Dirty(d));
10377 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010378 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10379 mkU64(guest_IA_curr_instr)));
10380 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010381 restart_if(IRExpr_Const(IRConst_U1(True)));
10382
sewardj2019a972011-03-07 16:04:07 +000010383 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010384 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010385 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000010386 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000010387 break;
10388 }
10389
10390 case 0xd200000000000000ULL:
10391 /* special case MVC */
10392 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010393 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010394
10395 case 0xd500000000000000ULL:
10396 /* special case CLC */
10397 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010398 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010399
10400 case 0xd700000000000000ULL:
10401 /* special case XC */
10402 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010403 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010404
florianb0bf6602012-05-05 00:01:16 +000010405 case 0xd600000000000000ULL:
10406 /* special case OC */
10407 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010408 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010409
10410 case 0xd400000000000000ULL:
10411 /* special case NC */
10412 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010413 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010414
florianf87d4fb2012-05-05 02:55:24 +000010415 case 0xdc00000000000000ULL:
10416 /* special case TR */
10417 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010418 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010419
sewardj2019a972011-03-07 16:04:07 +000010420 default:
10421 {
10422 /* everything else will get a self checking prefix that also checks the
10423 register content */
10424 IRDirty *d;
10425 UChar *bytes;
10426 IRTemp cond;
10427 IRTemp orperand;
10428 IRTemp torun;
10429
10430 cond = newTemp(Ity_I1);
10431 orperand = newTemp(Ity_I64);
10432 torun = newTemp(Ity_I64);
10433
10434 if (r1 == 0)
10435 assign(orperand, mkU64(0));
10436 else
10437 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10438 /* This code is going to be translated */
10439 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10440 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10441
10442 /* Start with a check that saved code is still correct */
10443 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10444 mkU64(last_execute_target)));
10445 /* If not, save the new value */
10446 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10447 mkIRExprVec_1(mkexpr(torun)));
10448 d->guard = mkexpr(cond);
10449 stmt(IRStmt_Dirty(d));
10450
10451 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010452 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10453 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010454 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010455
10456 /* Now comes the actual translation */
10457 bytes = (UChar *) &last_execute_target;
10458 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10459 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010460 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010461 vex_printf(" which was executed by\n");
10462 /* dont make useless translations in the next execute */
10463 last_execute_target = 0;
10464 }
10465 }
10466 return "ex";
10467}
10468
florian55085f82012-11-21 00:36:55 +000010469static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010470s390_irgen_EXRL(UChar r1, UInt offset)
10471{
10472 IRTemp addr = newTemp(Ity_I64);
10473 /* we might save one round trip because we know the target */
10474 if (!last_execute_target)
10475 last_execute_target = *(ULong *)(HWord)
10476 (guest_IA_curr_instr + offset * 2UL);
10477 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10478 s390_irgen_EX(r1, addr);
10479 return "exrl";
10480}
10481
florian55085f82012-11-21 00:36:55 +000010482static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010483s390_irgen_IPM(UChar r1)
10484{
10485 // As long as we dont support SPM, lets just assume 0 as program mask
10486 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
10487 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
10488
10489 return "ipm";
10490}
10491
10492
florian55085f82012-11-21 00:36:55 +000010493static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010494s390_irgen_SRST(UChar r1, UChar r2)
10495{
10496 IRTemp address = newTemp(Ity_I64);
10497 IRTemp next = newTemp(Ity_I64);
10498 IRTemp delim = newTemp(Ity_I8);
10499 IRTemp counter = newTemp(Ity_I64);
10500 IRTemp byte = newTemp(Ity_I8);
10501
10502 assign(address, get_gpr_dw0(r2));
10503 assign(next, get_gpr_dw0(r1));
10504
10505 assign(counter, get_counter_dw0());
10506 put_counter_dw0(mkU64(0));
10507
10508 // start = next? CC=2 and out r1 and r2 unchanged
10509 s390_cc_set(2);
10510 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010511 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000010512
10513 assign(byte, load(Ity_I8, mkexpr(address)));
10514 assign(delim, get_gpr_b7(0));
10515
10516 // byte = delim? CC=1, R1=address
10517 s390_cc_set(1);
10518 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000010519 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010520
10521 // else: all equal, no end yet, loop
10522 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10523 put_gpr_dw0(r1, mkexpr(next));
10524 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010525
florian6820ba52012-07-26 02:01:50 +000010526 iterate();
sewardj2019a972011-03-07 16:04:07 +000010527
10528 return "srst";
10529}
10530
florian55085f82012-11-21 00:36:55 +000010531static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010532s390_irgen_CLST(UChar r1, UChar r2)
10533{
10534 IRTemp address1 = newTemp(Ity_I64);
10535 IRTemp address2 = newTemp(Ity_I64);
10536 IRTemp end = newTemp(Ity_I8);
10537 IRTemp counter = newTemp(Ity_I64);
10538 IRTemp byte1 = newTemp(Ity_I8);
10539 IRTemp byte2 = newTemp(Ity_I8);
10540
10541 assign(address1, get_gpr_dw0(r1));
10542 assign(address2, get_gpr_dw0(r2));
10543 assign(end, get_gpr_b7(0));
10544 assign(counter, get_counter_dw0());
10545 put_counter_dw0(mkU64(0));
10546 assign(byte1, load(Ity_I8, mkexpr(address1)));
10547 assign(byte2, load(Ity_I8, mkexpr(address2)));
10548
10549 // end in both? all equal, reset r1 and r2 to start values
10550 s390_cc_set(0);
10551 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
10552 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010553 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10554 binop(Iop_Or8,
10555 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10556 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010557
10558 put_gpr_dw0(r1, mkexpr(address1));
10559 put_gpr_dw0(r2, mkexpr(address2));
10560
10561 // End found in string1
10562 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010563 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010564
10565 // End found in string2
10566 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010567 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010568
10569 // string1 < string2
10570 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010571 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10572 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010573
10574 // string2 < string1
10575 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010576 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10577 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010578
10579 // else: all equal, no end yet, loop
10580 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10581 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10582 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010583
florian6820ba52012-07-26 02:01:50 +000010584 iterate();
sewardj2019a972011-03-07 16:04:07 +000010585
10586 return "clst";
10587}
10588
10589static void
10590s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10591{
10592 UChar reg;
10593 IRTemp addr = newTemp(Ity_I64);
10594
10595 assign(addr, mkexpr(op2addr));
10596 reg = r1;
10597 do {
10598 IRTemp old = addr;
10599
10600 reg %= 16;
10601 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10602 addr = newTemp(Ity_I64);
10603 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10604 reg++;
10605 } while (reg != (r3 + 1));
10606}
10607
florian55085f82012-11-21 00:36:55 +000010608static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010609s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10610{
10611 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10612
10613 return "lm";
10614}
10615
florian55085f82012-11-21 00:36:55 +000010616static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010617s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
10618{
10619 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10620
10621 return "lmy";
10622}
10623
florian55085f82012-11-21 00:36:55 +000010624static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010625s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
10626{
10627 UChar reg;
10628 IRTemp addr = newTemp(Ity_I64);
10629
10630 assign(addr, mkexpr(op2addr));
10631 reg = r1;
10632 do {
10633 IRTemp old = addr;
10634
10635 reg %= 16;
10636 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
10637 addr = newTemp(Ity_I64);
10638 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10639 reg++;
10640 } while (reg != (r3 + 1));
10641
10642 return "lmh";
10643}
10644
florian55085f82012-11-21 00:36:55 +000010645static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010646s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
10647{
10648 UChar reg;
10649 IRTemp addr = newTemp(Ity_I64);
10650
10651 assign(addr, mkexpr(op2addr));
10652 reg = r1;
10653 do {
10654 IRTemp old = addr;
10655
10656 reg %= 16;
10657 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
10658 addr = newTemp(Ity_I64);
10659 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10660 reg++;
10661 } while (reg != (r3 + 1));
10662
10663 return "lmg";
10664}
10665
10666static void
10667s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10668{
10669 UChar reg;
10670 IRTemp addr = newTemp(Ity_I64);
10671
10672 assign(addr, mkexpr(op2addr));
10673 reg = r1;
10674 do {
10675 IRTemp old = addr;
10676
10677 reg %= 16;
10678 store(mkexpr(addr), get_gpr_w1(reg));
10679 addr = newTemp(Ity_I64);
10680 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10681 reg++;
10682 } while( reg != (r3 + 1));
10683}
10684
florian55085f82012-11-21 00:36:55 +000010685static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010686s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
10687{
10688 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10689
10690 return "stm";
10691}
10692
florian55085f82012-11-21 00:36:55 +000010693static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010694s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
10695{
10696 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10697
10698 return "stmy";
10699}
10700
florian55085f82012-11-21 00:36:55 +000010701static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010702s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
10703{
10704 UChar reg;
10705 IRTemp addr = newTemp(Ity_I64);
10706
10707 assign(addr, mkexpr(op2addr));
10708 reg = r1;
10709 do {
10710 IRTemp old = addr;
10711
10712 reg %= 16;
10713 store(mkexpr(addr), get_gpr_w0(reg));
10714 addr = newTemp(Ity_I64);
10715 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10716 reg++;
10717 } while( reg != (r3 + 1));
10718
10719 return "stmh";
10720}
10721
florian55085f82012-11-21 00:36:55 +000010722static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010723s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
10724{
10725 UChar reg;
10726 IRTemp addr = newTemp(Ity_I64);
10727
10728 assign(addr, mkexpr(op2addr));
10729 reg = r1;
10730 do {
10731 IRTemp old = addr;
10732
10733 reg %= 16;
10734 store(mkexpr(addr), get_gpr_dw0(reg));
10735 addr = newTemp(Ity_I64);
10736 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10737 reg++;
10738 } while( reg != (r3 + 1));
10739
10740 return "stmg";
10741}
10742
10743static void
florianb0bf6602012-05-05 00:01:16 +000010744s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000010745{
10746 IRTemp old1 = newTemp(Ity_I8);
10747 IRTemp old2 = newTemp(Ity_I8);
10748 IRTemp new1 = newTemp(Ity_I8);
10749 IRTemp counter = newTemp(Ity_I32);
10750 IRTemp addr1 = newTemp(Ity_I64);
10751
10752 assign(counter, get_counter_w0());
10753
10754 assign(addr1, binop(Iop_Add64, mkexpr(start1),
10755 unop(Iop_32Uto64, mkexpr(counter))));
10756
10757 assign(old1, load(Ity_I8, mkexpr(addr1)));
10758 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10759 unop(Iop_32Uto64,mkexpr(counter)))));
10760 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
10761
10762 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000010763 if (op == Iop_Xor8) {
10764 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000010765 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
10766 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000010767 } else
10768 store(mkexpr(addr1), mkexpr(new1));
10769 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
10770 get_counter_w1()));
10771
10772 /* Check for end of field */
10773 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010774 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010775 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
10776 False);
10777 put_counter_dw0(mkU64(0));
10778}
10779
florian55085f82012-11-21 00:36:55 +000010780static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010781s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
10782{
florianb0bf6602012-05-05 00:01:16 +000010783 IRTemp len = newTemp(Ity_I32);
10784
10785 assign(len, mkU32(length));
10786 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010787
10788 return "xc";
10789}
10790
sewardjb63967e2011-03-24 08:50:04 +000010791static void
10792s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
10793{
10794 IRTemp counter = newTemp(Ity_I32);
10795 IRTemp start = newTemp(Ity_I64);
10796 IRTemp addr = newTemp(Ity_I64);
10797
10798 assign(start,
10799 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
10800
10801 if (length < 8) {
10802 UInt i;
10803
10804 for (i = 0; i <= length; ++i) {
10805 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
10806 }
10807 } else {
10808 assign(counter, get_counter_w0());
10809
10810 assign(addr, binop(Iop_Add64, mkexpr(start),
10811 unop(Iop_32Uto64, mkexpr(counter))));
10812
10813 store(mkexpr(addr), mkU8(0));
10814
10815 /* Check for end of field */
10816 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010817 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000010818
10819 /* Reset counter */
10820 put_counter_dw0(mkU64(0));
10821 }
10822
10823 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
10824
sewardj7ee97522011-05-09 21:45:04 +000010825 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000010826 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
10827}
10828
florian55085f82012-11-21 00:36:55 +000010829static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010830s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
10831{
florianb0bf6602012-05-05 00:01:16 +000010832 IRTemp len = newTemp(Ity_I32);
10833
10834 assign(len, mkU32(length));
10835 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010836
10837 return "nc";
10838}
10839
florian55085f82012-11-21 00:36:55 +000010840static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010841s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
10842{
florianb0bf6602012-05-05 00:01:16 +000010843 IRTemp len = newTemp(Ity_I32);
10844
10845 assign(len, mkU32(length));
10846 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010847
10848 return "oc";
10849}
10850
10851
florian55085f82012-11-21 00:36:55 +000010852static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010853s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
10854{
florian79e839e2012-05-05 02:20:30 +000010855 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010856
florian79e839e2012-05-05 02:20:30 +000010857 assign(len, mkU64(length));
10858 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010859
10860 return "mvc";
10861}
10862
florian55085f82012-11-21 00:36:55 +000010863static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010864s390_irgen_MVCL(UChar r1, UChar r2)
10865{
10866 IRTemp addr1 = newTemp(Ity_I64);
10867 IRTemp addr2 = newTemp(Ity_I64);
10868 IRTemp addr2_load = newTemp(Ity_I64);
10869 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10870 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10871 IRTemp len1 = newTemp(Ity_I32);
10872 IRTemp len2 = newTemp(Ity_I32);
10873 IRTemp pad = newTemp(Ity_I8);
10874 IRTemp single = newTemp(Ity_I8);
10875
10876 assign(addr1, get_gpr_dw0(r1));
10877 assign(r1p1, get_gpr_w1(r1 + 1));
10878 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10879 assign(addr2, get_gpr_dw0(r2));
10880 assign(r2p1, get_gpr_w1(r2 + 1));
10881 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10882 assign(pad, get_gpr_b4(r2 + 1));
10883
10884 /* len1 == 0 ? */
10885 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010886 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010887
10888 /* Check for destructive overlap:
10889 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
10890 s390_cc_set(3);
10891 IRTemp cond1 = newTemp(Ity_I32);
10892 assign(cond1, unop(Iop_1Uto32,
10893 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
10894 IRTemp cond2 = newTemp(Ity_I32);
10895 assign(cond2, unop(Iop_1Uto32,
10896 binop(Iop_CmpLT64U, mkexpr(addr1),
10897 binop(Iop_Add64, mkexpr(addr2),
10898 unop(Iop_32Uto64, mkexpr(len1))))));
10899 IRTemp cond3 = newTemp(Ity_I32);
10900 assign(cond3, unop(Iop_1Uto32,
10901 binop(Iop_CmpLT64U,
10902 mkexpr(addr1),
10903 binop(Iop_Add64, mkexpr(addr2),
10904 unop(Iop_32Uto64, mkexpr(len2))))));
10905
florian6820ba52012-07-26 02:01:50 +000010906 next_insn_if(binop(Iop_CmpEQ32,
10907 binop(Iop_And32,
10908 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10909 mkexpr(cond3)),
10910 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010911
10912 /* See s390_irgen_CLCL for explanation why we cannot load directly
10913 and need two steps. */
10914 assign(addr2_load,
10915 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10916 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10917 assign(single,
10918 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10919 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10920
10921 store(mkexpr(addr1), mkexpr(single));
10922
10923 /* Update addr1 and len1 */
10924 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10925 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10926
10927 /* Update addr2 and len2 */
10928 put_gpr_dw0(r2,
10929 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10930 mkexpr(addr2),
10931 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10932
10933 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10934 put_gpr_w1(r2 + 1,
10935 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10936 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10937 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10938
10939 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010940 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010941
10942 return "mvcl";
10943}
10944
10945
florian55085f82012-11-21 00:36:55 +000010946static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010947s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10948{
10949 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10950
10951 addr1 = newTemp(Ity_I64);
10952 addr3 = newTemp(Ity_I64);
10953 addr3_load = newTemp(Ity_I64);
10954 len1 = newTemp(Ity_I64);
10955 len3 = newTemp(Ity_I64);
10956 single = newTemp(Ity_I8);
10957
10958 assign(addr1, get_gpr_dw0(r1));
10959 assign(len1, get_gpr_dw0(r1 + 1));
10960 assign(addr3, get_gpr_dw0(r3));
10961 assign(len3, get_gpr_dw0(r3 + 1));
10962
10963 // len1 == 0 ?
10964 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010965 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010966
10967 /* This is a hack to prevent mvcle from reading from addr3 if it
10968 should read from the pad. Since the pad has no address, just
10969 read from the instruction, we discard that anyway */
10970 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010971 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10972 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010973
10974 assign(single,
florian6ad49522011-09-09 02:38:55 +000010975 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10976 unop(Iop_64to8, mkexpr(pad2)),
10977 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010978 store(mkexpr(addr1), mkexpr(single));
10979
10980 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10981
10982 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10983
10984 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010985 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10986 mkexpr(addr3),
10987 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010988
10989 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010990 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10991 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010992
sewardj2019a972011-03-07 16:04:07 +000010993 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010994 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010995
10996 return "mvcle";
10997}
10998
florian55085f82012-11-21 00:36:55 +000010999static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011000s390_irgen_MVST(UChar r1, UChar r2)
11001{
11002 IRTemp addr1 = newTemp(Ity_I64);
11003 IRTemp addr2 = newTemp(Ity_I64);
11004 IRTemp end = newTemp(Ity_I8);
11005 IRTemp byte = newTemp(Ity_I8);
11006 IRTemp counter = newTemp(Ity_I64);
11007
11008 assign(addr1, get_gpr_dw0(r1));
11009 assign(addr2, get_gpr_dw0(r2));
11010 assign(counter, get_counter_dw0());
11011 assign(end, get_gpr_b7(0));
11012 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11013 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11014
11015 // We use unlimited as cpu-determined number
11016 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011017 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011018
11019 // and always set cc=1 at the end + update r1
11020 s390_cc_set(1);
11021 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11022 put_counter_dw0(mkU64(0));
11023
11024 return "mvst";
11025}
11026
11027static void
11028s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11029{
11030 IRTemp op1 = newTemp(Ity_I64);
11031 IRTemp result = newTemp(Ity_I64);
11032
11033 assign(op1, binop(Iop_32HLto64,
11034 get_gpr_w1(r1), // high 32 bits
11035 get_gpr_w1(r1 + 1))); // low 32 bits
11036 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11037 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11038 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11039}
11040
11041static void
11042s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11043{
11044 IRTemp op1 = newTemp(Ity_I128);
11045 IRTemp result = newTemp(Ity_I128);
11046
11047 assign(op1, binop(Iop_64HLto128,
11048 get_gpr_dw0(r1), // high 64 bits
11049 get_gpr_dw0(r1 + 1))); // low 64 bits
11050 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11051 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11052 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11053}
11054
11055static void
11056s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11057{
11058 IRTemp op1 = newTemp(Ity_I64);
11059 IRTemp result = newTemp(Ity_I128);
11060
11061 assign(op1, get_gpr_dw0(r1 + 1));
11062 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11063 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11064 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11065}
11066
florian55085f82012-11-21 00:36:55 +000011067static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011068s390_irgen_DR(UChar r1, UChar r2)
11069{
11070 IRTemp op2 = newTemp(Ity_I32);
11071
11072 assign(op2, get_gpr_w1(r2));
11073
11074 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11075
11076 return "dr";
11077}
11078
florian55085f82012-11-21 00:36:55 +000011079static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011080s390_irgen_D(UChar r1, IRTemp op2addr)
11081{
11082 IRTemp op2 = newTemp(Ity_I32);
11083
11084 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11085
11086 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11087
11088 return "d";
11089}
11090
florian55085f82012-11-21 00:36:55 +000011091static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011092s390_irgen_DLR(UChar r1, UChar r2)
11093{
11094 IRTemp op2 = newTemp(Ity_I32);
11095
11096 assign(op2, get_gpr_w1(r2));
11097
11098 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11099
florian7cd1cde2012-08-16 23:57:43 +000011100 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011101}
11102
florian55085f82012-11-21 00:36:55 +000011103static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011104s390_irgen_DL(UChar r1, IRTemp op2addr)
11105{
11106 IRTemp op2 = newTemp(Ity_I32);
11107
11108 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11109
11110 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11111
11112 return "dl";
11113}
11114
florian55085f82012-11-21 00:36:55 +000011115static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011116s390_irgen_DLG(UChar r1, IRTemp op2addr)
11117{
11118 IRTemp op2 = newTemp(Ity_I64);
11119
11120 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11121
11122 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11123
11124 return "dlg";
11125}
11126
florian55085f82012-11-21 00:36:55 +000011127static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011128s390_irgen_DLGR(UChar r1, UChar r2)
11129{
11130 IRTemp op2 = newTemp(Ity_I64);
11131
11132 assign(op2, get_gpr_dw0(r2));
11133
11134 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11135
11136 return "dlgr";
11137}
11138
florian55085f82012-11-21 00:36:55 +000011139static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011140s390_irgen_DSGR(UChar r1, UChar r2)
11141{
11142 IRTemp op2 = newTemp(Ity_I64);
11143
11144 assign(op2, get_gpr_dw0(r2));
11145
11146 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11147
11148 return "dsgr";
11149}
11150
florian55085f82012-11-21 00:36:55 +000011151static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011152s390_irgen_DSG(UChar r1, IRTemp op2addr)
11153{
11154 IRTemp op2 = newTemp(Ity_I64);
11155
11156 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11157
11158 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11159
11160 return "dsg";
11161}
11162
florian55085f82012-11-21 00:36:55 +000011163static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011164s390_irgen_DSGFR(UChar r1, UChar r2)
11165{
11166 IRTemp op2 = newTemp(Ity_I64);
11167
11168 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11169
11170 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11171
11172 return "dsgfr";
11173}
11174
florian55085f82012-11-21 00:36:55 +000011175static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011176s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11177{
11178 IRTemp op2 = newTemp(Ity_I64);
11179
11180 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11181
11182 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11183
11184 return "dsgf";
11185}
11186
11187static void
11188s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11189{
11190 UChar reg;
11191 IRTemp addr = newTemp(Ity_I64);
11192
11193 assign(addr, mkexpr(op2addr));
11194 reg = r1;
11195 do {
11196 IRTemp old = addr;
11197
11198 reg %= 16;
11199 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11200 addr = newTemp(Ity_I64);
11201 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11202 reg++;
11203 } while (reg != (r3 + 1));
11204}
11205
florian55085f82012-11-21 00:36:55 +000011206static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011207s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11208{
11209 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11210
11211 return "lam";
11212}
11213
florian55085f82012-11-21 00:36:55 +000011214static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011215s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11216{
11217 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11218
11219 return "lamy";
11220}
11221
11222static void
11223s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11224{
11225 UChar reg;
11226 IRTemp addr = newTemp(Ity_I64);
11227
11228 assign(addr, mkexpr(op2addr));
11229 reg = r1;
11230 do {
11231 IRTemp old = addr;
11232
11233 reg %= 16;
11234 store(mkexpr(addr), get_ar_w0(reg));
11235 addr = newTemp(Ity_I64);
11236 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11237 reg++;
11238 } while (reg != (r3 + 1));
11239}
11240
florian55085f82012-11-21 00:36:55 +000011241static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011242s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11243{
11244 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11245
11246 return "stam";
11247}
11248
florian55085f82012-11-21 00:36:55 +000011249static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011250s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11251{
11252 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11253
11254 return "stamy";
11255}
11256
11257
11258/* Implementation for 32-bit compare-and-swap */
11259static void
11260s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11261{
11262 IRCAS *cas;
11263 IRTemp op1 = newTemp(Ity_I32);
11264 IRTemp old_mem = newTemp(Ity_I32);
11265 IRTemp op3 = newTemp(Ity_I32);
11266 IRTemp result = newTemp(Ity_I32);
11267 IRTemp nequal = newTemp(Ity_I1);
11268
11269 assign(op1, get_gpr_w1(r1));
11270 assign(op3, get_gpr_w1(r3));
11271
11272 /* The first and second operands are compared. If they are equal,
11273 the third operand is stored at the second- operand location. */
11274 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11275 Iend_BE, mkexpr(op2addr),
11276 NULL, mkexpr(op1), /* expected value */
11277 NULL, mkexpr(op3) /* new value */);
11278 stmt(IRStmt_CAS(cas));
11279
11280 /* Set CC. Operands compared equal -> 0, else 1. */
11281 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11282 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11283
11284 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11285 Otherwise, store the old_value from memory in r1 and yield. */
11286 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11287 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011288 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011289}
11290
florian55085f82012-11-21 00:36:55 +000011291static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011292s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11293{
11294 s390_irgen_cas_32(r1, r3, op2addr);
11295
11296 return "cs";
11297}
11298
florian55085f82012-11-21 00:36:55 +000011299static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011300s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11301{
11302 s390_irgen_cas_32(r1, r3, op2addr);
11303
11304 return "csy";
11305}
11306
florian55085f82012-11-21 00:36:55 +000011307static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011308s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11309{
11310 IRCAS *cas;
11311 IRTemp op1 = newTemp(Ity_I64);
11312 IRTemp old_mem = newTemp(Ity_I64);
11313 IRTemp op3 = newTemp(Ity_I64);
11314 IRTemp result = newTemp(Ity_I64);
11315 IRTemp nequal = newTemp(Ity_I1);
11316
11317 assign(op1, get_gpr_dw0(r1));
11318 assign(op3, get_gpr_dw0(r3));
11319
11320 /* The first and second operands are compared. If they are equal,
11321 the third operand is stored at the second- operand location. */
11322 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11323 Iend_BE, mkexpr(op2addr),
11324 NULL, mkexpr(op1), /* expected value */
11325 NULL, mkexpr(op3) /* new value */);
11326 stmt(IRStmt_CAS(cas));
11327
11328 /* Set CC. Operands compared equal -> 0, else 1. */
11329 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11330 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11331
11332 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11333 Otherwise, store the old_value from memory in r1 and yield. */
11334 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11335 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011336 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011337
11338 return "csg";
11339}
11340
florian448cbba2012-06-06 02:26:01 +000011341/* Implementation for 32-bit compare-double-and-swap */
11342static void
11343s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11344{
11345 IRCAS *cas;
11346 IRTemp op1_high = newTemp(Ity_I32);
11347 IRTemp op1_low = newTemp(Ity_I32);
11348 IRTemp old_mem_high = newTemp(Ity_I32);
11349 IRTemp old_mem_low = newTemp(Ity_I32);
11350 IRTemp op3_high = newTemp(Ity_I32);
11351 IRTemp op3_low = newTemp(Ity_I32);
11352 IRTemp result = newTemp(Ity_I32);
11353 IRTemp nequal = newTemp(Ity_I1);
11354
11355 assign(op1_high, get_gpr_w1(r1));
11356 assign(op1_low, get_gpr_w1(r1+1));
11357 assign(op3_high, get_gpr_w1(r3));
11358 assign(op3_low, get_gpr_w1(r3+1));
11359
11360 /* The first and second operands are compared. If they are equal,
11361 the third operand is stored at the second-operand location. */
11362 cas = mkIRCAS(old_mem_high, old_mem_low,
11363 Iend_BE, mkexpr(op2addr),
11364 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11365 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11366 stmt(IRStmt_CAS(cas));
11367
11368 /* Set CC. Operands compared equal -> 0, else 1. */
11369 assign(result, unop(Iop_1Uto32,
11370 binop(Iop_CmpNE32,
11371 binop(Iop_Or32,
11372 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11373 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11374 mkU32(0))));
11375
11376 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11377
11378 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11379 Otherwise, store the old_value from memory in r1 and yield. */
11380 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11381 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11382 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011383 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011384}
11385
florian55085f82012-11-21 00:36:55 +000011386static const HChar *
florian448cbba2012-06-06 02:26:01 +000011387s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11388{
11389 s390_irgen_cdas_32(r1, r3, op2addr);
11390
11391 return "cds";
11392}
11393
florian55085f82012-11-21 00:36:55 +000011394static const HChar *
florian448cbba2012-06-06 02:26:01 +000011395s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11396{
11397 s390_irgen_cdas_32(r1, r3, op2addr);
11398
11399 return "cdsy";
11400}
11401
florian55085f82012-11-21 00:36:55 +000011402static const HChar *
florian448cbba2012-06-06 02:26:01 +000011403s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11404{
11405 IRCAS *cas;
11406 IRTemp op1_high = newTemp(Ity_I64);
11407 IRTemp op1_low = newTemp(Ity_I64);
11408 IRTemp old_mem_high = newTemp(Ity_I64);
11409 IRTemp old_mem_low = newTemp(Ity_I64);
11410 IRTemp op3_high = newTemp(Ity_I64);
11411 IRTemp op3_low = newTemp(Ity_I64);
11412 IRTemp result = newTemp(Ity_I64);
11413 IRTemp nequal = newTemp(Ity_I1);
11414
11415 assign(op1_high, get_gpr_dw0(r1));
11416 assign(op1_low, get_gpr_dw0(r1+1));
11417 assign(op3_high, get_gpr_dw0(r3));
11418 assign(op3_low, get_gpr_dw0(r3+1));
11419
11420 /* The first and second operands are compared. If they are equal,
11421 the third operand is stored at the second-operand location. */
11422 cas = mkIRCAS(old_mem_high, old_mem_low,
11423 Iend_BE, mkexpr(op2addr),
11424 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11425 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11426 stmt(IRStmt_CAS(cas));
11427
11428 /* Set CC. Operands compared equal -> 0, else 1. */
11429 assign(result, unop(Iop_1Uto64,
11430 binop(Iop_CmpNE64,
11431 binop(Iop_Or64,
11432 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11433 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11434 mkU64(0))));
11435
11436 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11437
11438 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11439 Otherwise, store the old_value from memory in r1 and yield. */
11440 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11441 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11442 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011443 yield_if(mkexpr(nequal));
11444
florian448cbba2012-06-06 02:26:01 +000011445 return "cdsg";
11446}
11447
sewardj2019a972011-03-07 16:04:07 +000011448
11449/* Binary floating point */
11450
florian55085f82012-11-21 00:36:55 +000011451static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011452s390_irgen_AXBR(UChar r1, UChar r2)
11453{
11454 IRTemp op1 = newTemp(Ity_F128);
11455 IRTemp op2 = newTemp(Ity_F128);
11456 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011457 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011458
11459 assign(op1, get_fpr_pair(r1));
11460 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011461 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011462 mkexpr(op2)));
11463 put_fpr_pair(r1, mkexpr(result));
11464
11465 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11466
11467 return "axbr";
11468}
11469
florian55085f82012-11-21 00:36:55 +000011470static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011471s390_irgen_CEBR(UChar r1, UChar r2)
11472{
11473 IRTemp op1 = newTemp(Ity_F32);
11474 IRTemp op2 = newTemp(Ity_F32);
11475 IRTemp cc_vex = newTemp(Ity_I32);
11476 IRTemp cc_s390 = newTemp(Ity_I32);
11477
11478 assign(op1, get_fpr_w0(r1));
11479 assign(op2, get_fpr_w0(r2));
11480 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11481
florian2d3d87f2012-12-21 21:05:17 +000011482 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011483 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11484
11485 return "cebr";
11486}
11487
florian55085f82012-11-21 00:36:55 +000011488static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011489s390_irgen_CDBR(UChar r1, UChar r2)
11490{
11491 IRTemp op1 = newTemp(Ity_F64);
11492 IRTemp op2 = newTemp(Ity_F64);
11493 IRTemp cc_vex = newTemp(Ity_I32);
11494 IRTemp cc_s390 = newTemp(Ity_I32);
11495
11496 assign(op1, get_fpr_dw0(r1));
11497 assign(op2, get_fpr_dw0(r2));
11498 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11499
florian2d3d87f2012-12-21 21:05:17 +000011500 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011501 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11502
11503 return "cdbr";
11504}
11505
florian55085f82012-11-21 00:36:55 +000011506static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011507s390_irgen_CXBR(UChar r1, UChar r2)
11508{
11509 IRTemp op1 = newTemp(Ity_F128);
11510 IRTemp op2 = newTemp(Ity_F128);
11511 IRTemp cc_vex = newTemp(Ity_I32);
11512 IRTemp cc_s390 = newTemp(Ity_I32);
11513
11514 assign(op1, get_fpr_pair(r1));
11515 assign(op2, get_fpr_pair(r2));
11516 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
11517
florian2d3d87f2012-12-21 21:05:17 +000011518 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011519 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11520
11521 return "cxbr";
11522}
11523
florian55085f82012-11-21 00:36:55 +000011524static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011525s390_irgen_CEB(UChar r1, IRTemp op2addr)
11526{
11527 IRTemp op1 = newTemp(Ity_F32);
11528 IRTemp op2 = newTemp(Ity_F32);
11529 IRTemp cc_vex = newTemp(Ity_I32);
11530 IRTemp cc_s390 = newTemp(Ity_I32);
11531
11532 assign(op1, get_fpr_w0(r1));
11533 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11534 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11535
florian2d3d87f2012-12-21 21:05:17 +000011536 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011537 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11538
11539 return "ceb";
11540}
11541
florian55085f82012-11-21 00:36:55 +000011542static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011543s390_irgen_CDB(UChar r1, IRTemp op2addr)
11544{
11545 IRTemp op1 = newTemp(Ity_F64);
11546 IRTemp op2 = newTemp(Ity_F64);
11547 IRTemp cc_vex = newTemp(Ity_I32);
11548 IRTemp cc_s390 = newTemp(Ity_I32);
11549
11550 assign(op1, get_fpr_dw0(r1));
11551 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11552 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11553
florian2d3d87f2012-12-21 21:05:17 +000011554 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011555 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11556
11557 return "cdb";
11558}
11559
florian55085f82012-11-21 00:36:55 +000011560static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011561s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11562 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011563{
11564 IRTemp op2 = newTemp(Ity_I32);
11565
11566 assign(op2, get_gpr_w1(r2));
11567 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11568
11569 return "cxfbr";
11570}
11571
florian55085f82012-11-21 00:36:55 +000011572static const HChar *
floriand2129202012-09-01 20:01:39 +000011573s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11574 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011575{
floriane75dafa2012-09-01 17:54:09 +000011576 if (! s390_host_has_fpext) {
11577 emulation_failure(EmFail_S390X_fpext);
11578 } else {
11579 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011580
floriane75dafa2012-09-01 17:54:09 +000011581 assign(op2, get_gpr_w1(r2));
11582 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11583 }
florian1c8f7ff2012-09-01 00:12:11 +000011584 return "cxlfbr";
11585}
11586
11587
florian55085f82012-11-21 00:36:55 +000011588static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011589s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11590 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011591{
11592 IRTemp op2 = newTemp(Ity_I64);
11593
11594 assign(op2, get_gpr_dw0(r2));
11595 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11596
11597 return "cxgbr";
11598}
11599
florian55085f82012-11-21 00:36:55 +000011600static const HChar *
floriand2129202012-09-01 20:01:39 +000011601s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11602 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011603{
floriane75dafa2012-09-01 17:54:09 +000011604 if (! s390_host_has_fpext) {
11605 emulation_failure(EmFail_S390X_fpext);
11606 } else {
11607 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011608
floriane75dafa2012-09-01 17:54:09 +000011609 assign(op2, get_gpr_dw0(r2));
11610 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11611 }
florian1c8f7ff2012-09-01 00:12:11 +000011612 return "cxlgbr";
11613}
11614
florian55085f82012-11-21 00:36:55 +000011615static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011616s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11617 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011618{
11619 IRTemp op = newTemp(Ity_F128);
11620 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011621 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011622
11623 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011624 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011625 mkexpr(op)));
11626 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011627 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011628
11629 return "cfxbr";
11630}
11631
florian55085f82012-11-21 00:36:55 +000011632static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011633s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
11634 UChar r1, UChar r2)
11635{
floriane75dafa2012-09-01 17:54:09 +000011636 if (! s390_host_has_fpext) {
11637 emulation_failure(EmFail_S390X_fpext);
11638 } else {
11639 IRTemp op = newTemp(Ity_F128);
11640 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011641 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011642
floriane75dafa2012-09-01 17:54:09 +000011643 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011644 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011645 mkexpr(op)));
11646 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011647 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011648 }
florian1c8f7ff2012-09-01 00:12:11 +000011649 return "clfxbr";
11650}
11651
11652
florian55085f82012-11-21 00:36:55 +000011653static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011654s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
11655 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011656{
11657 IRTemp op = newTemp(Ity_F128);
11658 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011659 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011660
11661 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011662 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011663 mkexpr(op)));
11664 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011665 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011666
11667 return "cgxbr";
11668}
11669
florian55085f82012-11-21 00:36:55 +000011670static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011671s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
11672 UChar r1, UChar r2)
11673{
floriane75dafa2012-09-01 17:54:09 +000011674 if (! s390_host_has_fpext) {
11675 emulation_failure(EmFail_S390X_fpext);
11676 } else {
11677 IRTemp op = newTemp(Ity_F128);
11678 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011679 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011680
floriane75dafa2012-09-01 17:54:09 +000011681 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011682 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011683 mkexpr(op)));
11684 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011685 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
11686 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011687 }
florian1c8f7ff2012-09-01 00:12:11 +000011688 return "clgxbr";
11689}
11690
florian55085f82012-11-21 00:36:55 +000011691static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011692s390_irgen_DXBR(UChar r1, UChar r2)
11693{
11694 IRTemp op1 = newTemp(Ity_F128);
11695 IRTemp op2 = newTemp(Ity_F128);
11696 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011697 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011698
11699 assign(op1, get_fpr_pair(r1));
11700 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011701 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011702 mkexpr(op2)));
11703 put_fpr_pair(r1, mkexpr(result));
11704
11705 return "dxbr";
11706}
11707
florian55085f82012-11-21 00:36:55 +000011708static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011709s390_irgen_LTXBR(UChar r1, UChar r2)
11710{
11711 IRTemp result = newTemp(Ity_F128);
11712
11713 assign(result, get_fpr_pair(r2));
11714 put_fpr_pair(r1, mkexpr(result));
11715 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11716
11717 return "ltxbr";
11718}
11719
florian55085f82012-11-21 00:36:55 +000011720static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011721s390_irgen_LCXBR(UChar r1, UChar r2)
11722{
11723 IRTemp result = newTemp(Ity_F128);
11724
11725 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
11726 put_fpr_pair(r1, mkexpr(result));
11727 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11728
11729 return "lcxbr";
11730}
11731
florian55085f82012-11-21 00:36:55 +000011732static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011733s390_irgen_LXDBR(UChar r1, UChar r2)
11734{
11735 IRTemp op = newTemp(Ity_F64);
11736
11737 assign(op, get_fpr_dw0(r2));
11738 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11739
11740 return "lxdbr";
11741}
11742
florian55085f82012-11-21 00:36:55 +000011743static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011744s390_irgen_LXEBR(UChar r1, UChar r2)
11745{
11746 IRTemp op = newTemp(Ity_F32);
11747
11748 assign(op, get_fpr_w0(r2));
11749 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11750
11751 return "lxebr";
11752}
11753
florian55085f82012-11-21 00:36:55 +000011754static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011755s390_irgen_LXDB(UChar r1, IRTemp op2addr)
11756{
11757 IRTemp op = newTemp(Ity_F64);
11758
11759 assign(op, load(Ity_F64, mkexpr(op2addr)));
11760 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11761
11762 return "lxdb";
11763}
11764
florian55085f82012-11-21 00:36:55 +000011765static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011766s390_irgen_LXEB(UChar r1, IRTemp op2addr)
11767{
11768 IRTemp op = newTemp(Ity_F32);
11769
11770 assign(op, load(Ity_F32, mkexpr(op2addr)));
11771 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11772
11773 return "lxeb";
11774}
11775
florian55085f82012-11-21 00:36:55 +000011776static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011777s390_irgen_LNEBR(UChar r1, UChar r2)
11778{
11779 IRTemp result = newTemp(Ity_F32);
11780
11781 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
11782 put_fpr_w0(r1, mkexpr(result));
11783 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11784
11785 return "lnebr";
11786}
11787
florian55085f82012-11-21 00:36:55 +000011788static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011789s390_irgen_LNDBR(UChar r1, UChar r2)
11790{
11791 IRTemp result = newTemp(Ity_F64);
11792
11793 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11794 put_fpr_dw0(r1, mkexpr(result));
11795 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11796
11797 return "lndbr";
11798}
11799
florian55085f82012-11-21 00:36:55 +000011800static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011801s390_irgen_LNXBR(UChar r1, UChar r2)
11802{
11803 IRTemp result = newTemp(Ity_F128);
11804
11805 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
11806 put_fpr_pair(r1, mkexpr(result));
11807 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11808
11809 return "lnxbr";
11810}
11811
florian55085f82012-11-21 00:36:55 +000011812static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011813s390_irgen_LPEBR(UChar r1, UChar r2)
11814{
11815 IRTemp result = newTemp(Ity_F32);
11816
11817 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
11818 put_fpr_w0(r1, mkexpr(result));
11819 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11820
11821 return "lpebr";
11822}
11823
florian55085f82012-11-21 00:36:55 +000011824static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011825s390_irgen_LPDBR(UChar r1, UChar r2)
11826{
11827 IRTemp result = newTemp(Ity_F64);
11828
11829 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11830 put_fpr_dw0(r1, mkexpr(result));
11831 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11832
11833 return "lpdbr";
11834}
11835
florian55085f82012-11-21 00:36:55 +000011836static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011837s390_irgen_LPXBR(UChar r1, UChar r2)
11838{
11839 IRTemp result = newTemp(Ity_F128);
11840
11841 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
11842 put_fpr_pair(r1, mkexpr(result));
11843 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11844
11845 return "lpxbr";
11846}
11847
florian55085f82012-11-21 00:36:55 +000011848static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011849s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
11850 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011851{
florian125e20d2012-10-07 15:42:37 +000011852 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011853 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011854 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011855 }
sewardj2019a972011-03-07 16:04:07 +000011856 IRTemp result = newTemp(Ity_F64);
11857
floriandb4fcaa2012-09-05 19:54:08 +000011858 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011859 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011860 put_fpr_dw0(r1, mkexpr(result));
11861
11862 return "ldxbr";
11863}
11864
florian55085f82012-11-21 00:36:55 +000011865static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011866s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11867 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011868{
florian125e20d2012-10-07 15:42:37 +000011869 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011870 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011871 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011872 }
sewardj2019a972011-03-07 16:04:07 +000011873 IRTemp result = newTemp(Ity_F32);
11874
floriandb4fcaa2012-09-05 19:54:08 +000011875 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011876 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011877 put_fpr_w0(r1, mkexpr(result));
11878
11879 return "lexbr";
11880}
11881
florian55085f82012-11-21 00:36:55 +000011882static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011883s390_irgen_MXBR(UChar r1, UChar r2)
11884{
11885 IRTemp op1 = newTemp(Ity_F128);
11886 IRTemp op2 = newTemp(Ity_F128);
11887 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011888 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011889
11890 assign(op1, get_fpr_pair(r1));
11891 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011892 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011893 mkexpr(op2)));
11894 put_fpr_pair(r1, mkexpr(result));
11895
11896 return "mxbr";
11897}
11898
florian55085f82012-11-21 00:36:55 +000011899static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011900s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11901{
florian125e20d2012-10-07 15:42:37 +000011902 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011903
floriandb4fcaa2012-09-05 19:54:08 +000011904 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011905 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011906
11907 return "maebr";
11908}
11909
florian55085f82012-11-21 00:36:55 +000011910static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011911s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11912{
florian125e20d2012-10-07 15:42:37 +000011913 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011914
floriandb4fcaa2012-09-05 19:54:08 +000011915 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011916 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011917
11918 return "madbr";
11919}
11920
florian55085f82012-11-21 00:36:55 +000011921static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011922s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11923{
11924 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011925 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011926
floriandb4fcaa2012-09-05 19:54:08 +000011927 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011928 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011929
11930 return "maeb";
11931}
11932
florian55085f82012-11-21 00:36:55 +000011933static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011934s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11935{
11936 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011937 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011938
floriandb4fcaa2012-09-05 19:54:08 +000011939 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011940 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011941
11942 return "madb";
11943}
11944
florian55085f82012-11-21 00:36:55 +000011945static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011946s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11947{
florian125e20d2012-10-07 15:42:37 +000011948 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011949
floriandb4fcaa2012-09-05 19:54:08 +000011950 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011951 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011952
11953 return "msebr";
11954}
11955
florian55085f82012-11-21 00:36:55 +000011956static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011957s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11958{
florian125e20d2012-10-07 15:42:37 +000011959 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011960
floriandb4fcaa2012-09-05 19:54:08 +000011961 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011962 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011963
11964 return "msdbr";
11965}
11966
florian55085f82012-11-21 00:36:55 +000011967static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011968s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11969{
11970 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011971 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011972
floriandb4fcaa2012-09-05 19:54:08 +000011973 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011974 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011975
11976 return "mseb";
11977}
11978
florian55085f82012-11-21 00:36:55 +000011979static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011980s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11981{
11982 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011983 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011984
floriandb4fcaa2012-09-05 19:54:08 +000011985 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011986 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011987
11988 return "msdb";
11989}
11990
florian55085f82012-11-21 00:36:55 +000011991static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011992s390_irgen_SQEBR(UChar r1, UChar r2)
11993{
11994 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011995 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011996
floriandb4fcaa2012-09-05 19:54:08 +000011997 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011998 put_fpr_w0(r1, mkexpr(result));
11999
12000 return "sqebr";
12001}
12002
florian55085f82012-11-21 00:36:55 +000012003static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012004s390_irgen_SQDBR(UChar r1, UChar r2)
12005{
12006 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012007 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012008
floriandb4fcaa2012-09-05 19:54:08 +000012009 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012010 put_fpr_dw0(r1, mkexpr(result));
12011
12012 return "sqdbr";
12013}
12014
florian55085f82012-11-21 00:36:55 +000012015static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012016s390_irgen_SQXBR(UChar r1, UChar r2)
12017{
12018 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012019 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012020
floriandb4fcaa2012-09-05 19:54:08 +000012021 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12022 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012023 put_fpr_pair(r1, mkexpr(result));
12024
12025 return "sqxbr";
12026}
12027
florian55085f82012-11-21 00:36:55 +000012028static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012029s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12030{
12031 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012032 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012033
12034 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012035 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012036
12037 return "sqeb";
12038}
12039
florian55085f82012-11-21 00:36:55 +000012040static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012041s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12042{
12043 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012044 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012045
12046 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012047 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012048
12049 return "sqdb";
12050}
12051
florian55085f82012-11-21 00:36:55 +000012052static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012053s390_irgen_SXBR(UChar r1, UChar r2)
12054{
12055 IRTemp op1 = newTemp(Ity_F128);
12056 IRTemp op2 = newTemp(Ity_F128);
12057 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012058 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012059
12060 assign(op1, get_fpr_pair(r1));
12061 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012062 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012063 mkexpr(op2)));
12064 put_fpr_pair(r1, mkexpr(result));
12065 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12066
12067 return "sxbr";
12068}
12069
florian55085f82012-11-21 00:36:55 +000012070static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012071s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12072{
12073 IRTemp value = newTemp(Ity_F32);
12074
12075 assign(value, get_fpr_w0(r1));
12076
12077 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12078
12079 return "tceb";
12080}
12081
florian55085f82012-11-21 00:36:55 +000012082static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012083s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12084{
12085 IRTemp value = newTemp(Ity_F64);
12086
12087 assign(value, get_fpr_dw0(r1));
12088
12089 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12090
12091 return "tcdb";
12092}
12093
florian55085f82012-11-21 00:36:55 +000012094static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012095s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12096{
12097 IRTemp value = newTemp(Ity_F128);
12098
12099 assign(value, get_fpr_pair(r1));
12100
12101 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12102
12103 return "tcxb";
12104}
12105
florian55085f82012-11-21 00:36:55 +000012106static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012107s390_irgen_LCDFR(UChar r1, UChar r2)
12108{
12109 IRTemp result = newTemp(Ity_F64);
12110
12111 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12112 put_fpr_dw0(r1, mkexpr(result));
12113
12114 return "lcdfr";
12115}
12116
florian55085f82012-11-21 00:36:55 +000012117static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012118s390_irgen_LNDFR(UChar r1, UChar r2)
12119{
12120 IRTemp result = newTemp(Ity_F64);
12121
12122 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12123 put_fpr_dw0(r1, mkexpr(result));
12124
12125 return "lndfr";
12126}
12127
florian55085f82012-11-21 00:36:55 +000012128static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012129s390_irgen_LPDFR(UChar r1, UChar r2)
12130{
12131 IRTemp result = newTemp(Ity_F64);
12132
12133 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12134 put_fpr_dw0(r1, mkexpr(result));
12135
12136 return "lpdfr";
12137}
12138
florian55085f82012-11-21 00:36:55 +000012139static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012140s390_irgen_LDGR(UChar r1, UChar r2)
12141{
12142 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12143
12144 return "ldgr";
12145}
12146
florian55085f82012-11-21 00:36:55 +000012147static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012148s390_irgen_LGDR(UChar r1, UChar r2)
12149{
12150 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12151
12152 return "lgdr";
12153}
12154
12155
florian55085f82012-11-21 00:36:55 +000012156static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012157s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12158{
12159 IRTemp sign = newTemp(Ity_I64);
12160 IRTemp value = newTemp(Ity_I64);
12161
12162 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12163 mkU64(1ULL << 63)));
12164 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12165 mkU64((1ULL << 63) - 1)));
12166 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12167 mkexpr(sign))));
12168
12169 return "cpsdr";
12170}
12171
12172
sewardj2019a972011-03-07 16:04:07 +000012173static IRExpr *
12174s390_call_cvb(IRExpr *in)
12175{
12176 IRExpr **args, *call;
12177
12178 args = mkIRExprVec_1(in);
12179 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12180 "s390_do_cvb", &s390_do_cvb, args);
12181
12182 /* Nothing is excluded from definedness checking. */
12183 call->Iex.CCall.cee->mcx_mask = 0;
12184
12185 return call;
12186}
12187
florian55085f82012-11-21 00:36:55 +000012188static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012189s390_irgen_CVB(UChar r1, IRTemp op2addr)
12190{
12191 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12192
12193 return "cvb";
12194}
12195
florian55085f82012-11-21 00:36:55 +000012196static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012197s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12198{
12199 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12200
12201 return "cvby";
12202}
12203
12204
sewardj2019a972011-03-07 16:04:07 +000012205static IRExpr *
12206s390_call_cvd(IRExpr *in)
12207{
12208 IRExpr **args, *call;
12209
12210 args = mkIRExprVec_1(in);
12211 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12212 "s390_do_cvd", &s390_do_cvd, args);
12213
12214 /* Nothing is excluded from definedness checking. */
12215 call->Iex.CCall.cee->mcx_mask = 0;
12216
12217 return call;
12218}
12219
florian55085f82012-11-21 00:36:55 +000012220static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012221s390_irgen_CVD(UChar r1, IRTemp op2addr)
12222{
florian11b8ee82012-08-06 13:35:33 +000012223 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012224
12225 return "cvd";
12226}
12227
florian55085f82012-11-21 00:36:55 +000012228static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012229s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12230{
12231 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12232
12233 return "cvdy";
12234}
12235
florian55085f82012-11-21 00:36:55 +000012236static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012237s390_irgen_FLOGR(UChar r1, UChar r2)
12238{
12239 IRTemp input = newTemp(Ity_I64);
12240 IRTemp not_zero = newTemp(Ity_I64);
12241 IRTemp tmpnum = newTemp(Ity_I64);
12242 IRTemp num = newTemp(Ity_I64);
12243 IRTemp shift_amount = newTemp(Ity_I8);
12244
12245 /* We use the "count leading zeroes" operator because the number of
12246 leading zeroes is identical with the bit position of the first '1' bit.
12247 However, that operator does not work when the input value is zero.
12248 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12249 the modified value. If input == 0, then the result is 64. Otherwise,
12250 the result of Clz64 is what we want. */
12251
12252 assign(input, get_gpr_dw0(r2));
12253 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12254 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12255
12256 /* num = (input == 0) ? 64 : tmpnum */
12257 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12258 /* == 0 */ mkU64(64),
12259 /* != 0 */ mkexpr(tmpnum)));
12260
12261 put_gpr_dw0(r1, mkexpr(num));
12262
12263 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12264 is to first shift the input value by NUM + 1 bits to the left which
12265 causes the leftmost '1' bit to disappear. Then we shift logically to
12266 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12267 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12268 the width of the value-to-be-shifted, we need to special case
12269 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12270 For both such INPUT values the result will be 0. */
12271
12272 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12273 mkU64(1))));
12274
12275 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012276 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12277 /* == 0 || == 1*/ mkU64(0),
12278 /* otherwise */
12279 binop(Iop_Shr64,
12280 binop(Iop_Shl64, mkexpr(input),
12281 mkexpr(shift_amount)),
12282 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012283
12284 /* Compare the original value as an unsigned integer with 0. */
12285 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12286 mktemp(Ity_I64, mkU64(0)), False);
12287
12288 return "flogr";
12289}
12290
florian55085f82012-11-21 00:36:55 +000012291static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012292s390_irgen_STCK(IRTemp op2addr)
12293{
12294 IRDirty *d;
12295 IRTemp cc = newTemp(Ity_I64);
12296
12297 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12298 &s390x_dirtyhelper_STCK,
12299 mkIRExprVec_1(mkexpr(op2addr)));
12300 d->mFx = Ifx_Write;
12301 d->mAddr = mkexpr(op2addr);
12302 d->mSize = 8;
12303 stmt(IRStmt_Dirty(d));
12304 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12305 mkexpr(cc), mkU64(0), mkU64(0));
12306 return "stck";
12307}
12308
florian55085f82012-11-21 00:36:55 +000012309static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012310s390_irgen_STCKF(IRTemp op2addr)
12311{
florianc5c669b2012-08-26 14:32:28 +000012312 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012313 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012314 } else {
12315 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012316
florianc5c669b2012-08-26 14:32:28 +000012317 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12318 &s390x_dirtyhelper_STCKF,
12319 mkIRExprVec_1(mkexpr(op2addr)));
12320 d->mFx = Ifx_Write;
12321 d->mAddr = mkexpr(op2addr);
12322 d->mSize = 8;
12323 stmt(IRStmt_Dirty(d));
12324 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12325 mkexpr(cc), mkU64(0), mkU64(0));
12326 }
sewardj1e5fea62011-05-17 16:18:36 +000012327 return "stckf";
12328}
12329
florian55085f82012-11-21 00:36:55 +000012330static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012331s390_irgen_STCKE(IRTemp op2addr)
12332{
12333 IRDirty *d;
12334 IRTemp cc = newTemp(Ity_I64);
12335
12336 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12337 &s390x_dirtyhelper_STCKE,
12338 mkIRExprVec_1(mkexpr(op2addr)));
12339 d->mFx = Ifx_Write;
12340 d->mAddr = mkexpr(op2addr);
12341 d->mSize = 16;
12342 stmt(IRStmt_Dirty(d));
12343 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12344 mkexpr(cc), mkU64(0), mkU64(0));
12345 return "stcke";
12346}
12347
florian55085f82012-11-21 00:36:55 +000012348static const HChar *
florian933065d2011-07-11 01:48:02 +000012349s390_irgen_STFLE(IRTemp op2addr)
12350{
florian4e0083e2012-08-26 03:41:56 +000012351 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012352 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012353 return "stfle";
12354 }
12355
florian933065d2011-07-11 01:48:02 +000012356 IRDirty *d;
12357 IRTemp cc = newTemp(Ity_I64);
12358
12359 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12360 &s390x_dirtyhelper_STFLE,
12361 mkIRExprVec_1(mkexpr(op2addr)));
12362
12363 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
12364
sewardjc9069f22012-06-01 16:09:50 +000012365 d->nFxState = 1;
12366 vex_bzero(&d->fxState, sizeof(d->fxState));
12367
florian933065d2011-07-11 01:48:02 +000012368 d->fxState[0].fx = Ifx_Modify; /* read then write */
12369 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12370 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012371
12372 d->mAddr = mkexpr(op2addr);
12373 /* Pretend all double words are written */
12374 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12375 d->mFx = Ifx_Write;
12376
12377 stmt(IRStmt_Dirty(d));
12378
12379 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12380
12381 return "stfle";
12382}
12383
florian55085f82012-11-21 00:36:55 +000012384static const HChar *
floriana4384a32011-08-11 16:58:45 +000012385s390_irgen_CKSM(UChar r1,UChar r2)
12386{
12387 IRTemp addr = newTemp(Ity_I64);
12388 IRTemp op = newTemp(Ity_I32);
12389 IRTemp len = newTemp(Ity_I64);
12390 IRTemp oldval = newTemp(Ity_I32);
12391 IRTemp mask = newTemp(Ity_I32);
12392 IRTemp newop = newTemp(Ity_I32);
12393 IRTemp result = newTemp(Ity_I32);
12394 IRTemp result1 = newTemp(Ity_I32);
12395 IRTemp inc = newTemp(Ity_I64);
12396
12397 assign(oldval, get_gpr_w1(r1));
12398 assign(addr, get_gpr_dw0(r2));
12399 assign(len, get_gpr_dw0(r2+1));
12400
12401 /* Condition code is always zero. */
12402 s390_cc_set(0);
12403
12404 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012405 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012406
12407 /* Assiging the increment variable to adjust address and length
12408 later on. */
12409 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12410 mkexpr(len), mkU64(4)));
12411
12412 /* If length < 4 the final 4-byte 2nd operand value is computed by
12413 appending the remaining bytes to the right with 0. This is done
12414 by AND'ing the 4 bytes loaded from memory with an appropriate
12415 mask. If length >= 4, that mask is simply 0xffffffff. */
12416
12417 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12418 /* Mask computation when len < 4:
12419 0xffffffff << (32 - (len % 4)*8) */
12420 binop(Iop_Shl32, mkU32(0xffffffff),
12421 unop(Iop_32to8,
12422 binop(Iop_Sub32, mkU32(32),
12423 binop(Iop_Shl32,
12424 unop(Iop_64to32,
12425 binop(Iop_And64,
12426 mkexpr(len), mkU64(3))),
12427 mkU8(3))))),
12428 mkU32(0xffffffff)));
12429
12430 assign(op, load(Ity_I32, mkexpr(addr)));
12431 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12432 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12433
12434 /* Checking for carry */
12435 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12436 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12437 mkexpr(result)));
12438
12439 put_gpr_w1(r1, mkexpr(result1));
12440 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12441 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12442
florian6820ba52012-07-26 02:01:50 +000012443 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012444
12445 return "cksm";
12446}
12447
florian55085f82012-11-21 00:36:55 +000012448static const HChar *
florian9af37692012-01-15 21:01:16 +000012449s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12450{
12451 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12452 src_addr = newTemp(Ity_I64);
12453 des_addr = newTemp(Ity_I64);
12454 tab_addr = newTemp(Ity_I64);
12455 test_byte = newTemp(Ity_I8);
12456 src_len = newTemp(Ity_I64);
12457
12458 assign(src_addr, get_gpr_dw0(r2));
12459 assign(des_addr, get_gpr_dw0(r1));
12460 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012461 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012462 assign(test_byte, get_gpr_b7(0));
12463
12464 IRTemp op = newTemp(Ity_I8);
12465 IRTemp op1 = newTemp(Ity_I8);
12466 IRTemp result = newTemp(Ity_I64);
12467
12468 /* End of source string? We're done; proceed to next insn */
12469 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012470 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012471
12472 /* Load character from source string, index translation table and
12473 store translated character in op1. */
12474 assign(op, load(Ity_I8, mkexpr(src_addr)));
12475
12476 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12477 mkexpr(tab_addr)));
12478 assign(op1, load(Ity_I8, mkexpr(result)));
12479
12480 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12481 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012482 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000012483 }
12484 store(get_gpr_dw0(r1), mkexpr(op1));
12485
12486 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12487 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12488 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12489
florian6820ba52012-07-26 02:01:50 +000012490 iterate();
florian9af37692012-01-15 21:01:16 +000012491
12492 return "troo";
12493}
12494
florian55085f82012-11-21 00:36:55 +000012495static const HChar *
florian730448f2012-02-04 17:07:07 +000012496s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
12497{
12498 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12499 src_addr = newTemp(Ity_I64);
12500 des_addr = newTemp(Ity_I64);
12501 tab_addr = newTemp(Ity_I64);
12502 test_byte = newTemp(Ity_I8);
12503 src_len = newTemp(Ity_I64);
12504
12505 assign(src_addr, get_gpr_dw0(r2));
12506 assign(des_addr, get_gpr_dw0(r1));
12507 assign(tab_addr, get_gpr_dw0(1));
12508 assign(src_len, get_gpr_dw0(r1+1));
12509 assign(test_byte, get_gpr_b7(0));
12510
12511 IRTemp op = newTemp(Ity_I16);
12512 IRTemp op1 = newTemp(Ity_I8);
12513 IRTemp result = newTemp(Ity_I64);
12514
12515 /* End of source string? We're done; proceed to next insn */
12516 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012517 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012518
12519 /* Load character from source string, index translation table and
12520 store translated character in op1. */
12521 assign(op, load(Ity_I16, mkexpr(src_addr)));
12522
12523 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12524 mkexpr(tab_addr)));
12525
12526 assign(op1, load(Ity_I8, mkexpr(result)));
12527
12528 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12529 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012530 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012531 }
12532 store(get_gpr_dw0(r1), mkexpr(op1));
12533
12534 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12535 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12536 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12537
florian6820ba52012-07-26 02:01:50 +000012538 iterate();
florian730448f2012-02-04 17:07:07 +000012539
12540 return "trto";
12541}
12542
florian55085f82012-11-21 00:36:55 +000012543static const HChar *
florian730448f2012-02-04 17:07:07 +000012544s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
12545{
12546 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12547 src_addr = newTemp(Ity_I64);
12548 des_addr = newTemp(Ity_I64);
12549 tab_addr = newTemp(Ity_I64);
12550 test_byte = newTemp(Ity_I16);
12551 src_len = newTemp(Ity_I64);
12552
12553 assign(src_addr, get_gpr_dw0(r2));
12554 assign(des_addr, get_gpr_dw0(r1));
12555 assign(tab_addr, get_gpr_dw0(1));
12556 assign(src_len, get_gpr_dw0(r1+1));
12557 assign(test_byte, get_gpr_hw3(0));
12558
12559 IRTemp op = newTemp(Ity_I8);
12560 IRTemp op1 = newTemp(Ity_I16);
12561 IRTemp result = newTemp(Ity_I64);
12562
12563 /* End of source string? We're done; proceed to next insn */
12564 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012565 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012566
12567 /* Load character from source string, index translation table and
12568 store translated character in op1. */
12569 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12570
12571 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12572 mkexpr(tab_addr)));
12573 assign(op1, load(Ity_I16, mkexpr(result)));
12574
12575 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12576 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012577 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012578 }
12579 store(get_gpr_dw0(r1), mkexpr(op1));
12580
12581 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12582 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12583 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12584
florian6820ba52012-07-26 02:01:50 +000012585 iterate();
florian730448f2012-02-04 17:07:07 +000012586
12587 return "trot";
12588}
12589
florian55085f82012-11-21 00:36:55 +000012590static const HChar *
florian730448f2012-02-04 17:07:07 +000012591s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12592{
12593 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12594 src_addr = newTemp(Ity_I64);
12595 des_addr = newTemp(Ity_I64);
12596 tab_addr = newTemp(Ity_I64);
12597 test_byte = newTemp(Ity_I16);
12598 src_len = newTemp(Ity_I64);
12599
12600 assign(src_addr, get_gpr_dw0(r2));
12601 assign(des_addr, get_gpr_dw0(r1));
12602 assign(tab_addr, get_gpr_dw0(1));
12603 assign(src_len, get_gpr_dw0(r1+1));
12604 assign(test_byte, get_gpr_hw3(0));
12605
12606 IRTemp op = newTemp(Ity_I16);
12607 IRTemp op1 = newTemp(Ity_I16);
12608 IRTemp result = newTemp(Ity_I64);
12609
12610 /* End of source string? We're done; proceed to next insn */
12611 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012612 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012613
12614 /* Load character from source string, index translation table and
12615 store translated character in op1. */
12616 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12617
12618 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12619 mkexpr(tab_addr)));
12620 assign(op1, load(Ity_I16, mkexpr(result)));
12621
12622 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12623 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012624 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012625 }
12626
12627 store(get_gpr_dw0(r1), mkexpr(op1));
12628
12629 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12630 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12631 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12632
florian6820ba52012-07-26 02:01:50 +000012633 iterate();
florian730448f2012-02-04 17:07:07 +000012634
12635 return "trtt";
12636}
12637
florian55085f82012-11-21 00:36:55 +000012638static const HChar *
florian730448f2012-02-04 17:07:07 +000012639s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
12640{
florianf87d4fb2012-05-05 02:55:24 +000012641 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000012642
florianf87d4fb2012-05-05 02:55:24 +000012643 assign(len, mkU64(length));
12644 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000012645
12646 return "tr";
12647}
12648
florian55085f82012-11-21 00:36:55 +000012649static const HChar *
florian730448f2012-02-04 17:07:07 +000012650s390_irgen_TRE(UChar r1,UChar r2)
12651{
12652 IRTemp src_addr, tab_addr, src_len, test_byte;
12653 src_addr = newTemp(Ity_I64);
12654 tab_addr = newTemp(Ity_I64);
12655 src_len = newTemp(Ity_I64);
12656 test_byte = newTemp(Ity_I8);
12657
12658 assign(src_addr, get_gpr_dw0(r1));
12659 assign(src_len, get_gpr_dw0(r1+1));
12660 assign(tab_addr, get_gpr_dw0(r2));
12661 assign(test_byte, get_gpr_b7(0));
12662
12663 IRTemp op = newTemp(Ity_I8);
12664 IRTemp op1 = newTemp(Ity_I8);
12665 IRTemp result = newTemp(Ity_I64);
12666
12667 /* End of source string? We're done; proceed to next insn */
12668 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012669 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012670
12671 /* Load character from source string and compare with test byte */
12672 assign(op, load(Ity_I8, mkexpr(src_addr)));
12673
12674 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012675 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012676
12677 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12678 mkexpr(tab_addr)));
12679
12680 assign(op1, load(Ity_I8, mkexpr(result)));
12681
12682 store(get_gpr_dw0(r1), mkexpr(op1));
12683 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12684 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12685
florian6820ba52012-07-26 02:01:50 +000012686 iterate();
florian730448f2012-02-04 17:07:07 +000012687
12688 return "tre";
12689}
12690
floriana0100c92012-07-20 00:06:35 +000012691static IRExpr *
12692s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
12693{
12694 IRExpr **args, *call;
12695 args = mkIRExprVec_2(srcval, low_surrogate);
12696 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12697 "s390_do_cu21", &s390_do_cu21, args);
12698
12699 /* Nothing is excluded from definedness checking. */
12700 call->Iex.CCall.cee->mcx_mask = 0;
12701
12702 return call;
12703}
12704
florian55085f82012-11-21 00:36:55 +000012705static const HChar *
floriana0100c92012-07-20 00:06:35 +000012706s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
12707{
12708 IRTemp addr1 = newTemp(Ity_I64);
12709 IRTemp addr2 = newTemp(Ity_I64);
12710 IRTemp len1 = newTemp(Ity_I64);
12711 IRTemp len2 = newTemp(Ity_I64);
12712
12713 assign(addr1, get_gpr_dw0(r1));
12714 assign(addr2, get_gpr_dw0(r2));
12715 assign(len1, get_gpr_dw0(r1 + 1));
12716 assign(len2, get_gpr_dw0(r2 + 1));
12717
12718 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12719 there are less than 2 bytes left, then the 2nd operand is exhausted
12720 and we're done here. cc = 0 */
12721 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012722 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000012723
12724 /* There are at least two bytes there. Read them. */
12725 IRTemp srcval = newTemp(Ity_I32);
12726 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12727
12728 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12729 inside the interval [0xd800 - 0xdbff] */
12730 IRTemp is_high_surrogate = newTemp(Ity_I32);
12731 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12732 mkU32(1), mkU32(0));
12733 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12734 mkU32(1), mkU32(0));
12735 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12736
12737 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12738 then the 2nd operand is exhausted and we're done here. cc = 0 */
12739 IRExpr *not_enough_bytes =
12740 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12741
florian6820ba52012-07-26 02:01:50 +000012742 next_insn_if(binop(Iop_CmpEQ32,
12743 binop(Iop_And32, mkexpr(is_high_surrogate),
12744 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000012745
12746 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12747 surrogate, read the next two bytes (low surrogate). */
12748 IRTemp low_surrogate = newTemp(Ity_I32);
12749 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12750
12751 assign(low_surrogate,
12752 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12753 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12754 mkU32(0))); // any value is fine; it will not be used
12755
12756 /* Call the helper */
12757 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012758 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
12759 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000012760
12761 /* Before we can test whether the 1st operand is exhausted we need to
12762 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12763 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12764 IRExpr *invalid_low_surrogate =
12765 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12766
12767 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012768 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000012769 }
12770
12771 /* Now test whether the 1st operand is exhausted */
12772 IRTemp num_bytes = newTemp(Ity_I64);
12773 assign(num_bytes, binop(Iop_And64,
12774 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12775 mkU64(0xff)));
12776 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012777 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000012778
12779 /* Extract the bytes to be stored at addr1 */
12780 IRTemp data = newTemp(Ity_I64);
12781 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12782
12783 /* To store the bytes construct 4 dirty helper calls. The helper calls
12784 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12785 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012786 UInt i;
floriana0100c92012-07-20 00:06:35 +000012787 for (i = 1; i <= 4; ++i) {
12788 IRDirty *d;
12789
12790 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12791 &s390x_dirtyhelper_CUxy,
12792 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12793 mkexpr(num_bytes)));
12794 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12795 d->mFx = Ifx_Write;
12796 d->mAddr = mkexpr(addr1);
12797 d->mSize = i;
12798 stmt(IRStmt_Dirty(d));
12799 }
12800
12801 /* Update source address and length */
12802 IRTemp num_src_bytes = newTemp(Ity_I64);
12803 assign(num_src_bytes,
12804 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12805 mkU64(4), mkU64(2)));
12806 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12807 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12808
12809 /* Update destination address and length */
12810 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12811 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12812
florian6820ba52012-07-26 02:01:50 +000012813 iterate();
floriana0100c92012-07-20 00:06:35 +000012814
12815 return "cu21";
12816}
12817
florian2a415a12012-07-21 17:41:36 +000012818static IRExpr *
12819s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
12820{
12821 IRExpr **args, *call;
12822 args = mkIRExprVec_2(srcval, low_surrogate);
12823 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12824 "s390_do_cu24", &s390_do_cu24, args);
12825
12826 /* Nothing is excluded from definedness checking. */
12827 call->Iex.CCall.cee->mcx_mask = 0;
12828
12829 return call;
12830}
12831
florian55085f82012-11-21 00:36:55 +000012832static const HChar *
florian2a415a12012-07-21 17:41:36 +000012833s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
12834{
12835 IRTemp addr1 = newTemp(Ity_I64);
12836 IRTemp addr2 = newTemp(Ity_I64);
12837 IRTemp len1 = newTemp(Ity_I64);
12838 IRTemp len2 = newTemp(Ity_I64);
12839
12840 assign(addr1, get_gpr_dw0(r1));
12841 assign(addr2, get_gpr_dw0(r2));
12842 assign(len1, get_gpr_dw0(r1 + 1));
12843 assign(len2, get_gpr_dw0(r2 + 1));
12844
12845 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12846 there are less than 2 bytes left, then the 2nd operand is exhausted
12847 and we're done here. cc = 0 */
12848 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012849 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000012850
12851 /* There are at least two bytes there. Read them. */
12852 IRTemp srcval = newTemp(Ity_I32);
12853 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12854
12855 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12856 inside the interval [0xd800 - 0xdbff] */
12857 IRTemp is_high_surrogate = newTemp(Ity_I32);
12858 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12859 mkU32(1), mkU32(0));
12860 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12861 mkU32(1), mkU32(0));
12862 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12863
12864 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12865 then the 2nd operand is exhausted and we're done here. cc = 0 */
12866 IRExpr *not_enough_bytes =
12867 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12868
florian6820ba52012-07-26 02:01:50 +000012869 next_insn_if(binop(Iop_CmpEQ32,
12870 binop(Iop_And32, mkexpr(is_high_surrogate),
12871 not_enough_bytes),
12872 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012873
12874 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12875 surrogate, read the next two bytes (low surrogate). */
12876 IRTemp low_surrogate = newTemp(Ity_I32);
12877 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12878
12879 assign(low_surrogate,
12880 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12881 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12882 mkU32(0))); // any value is fine; it will not be used
12883
12884 /* Call the helper */
12885 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012886 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12887 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012888
12889 /* Before we can test whether the 1st operand is exhausted we need to
12890 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12891 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12892 IRExpr *invalid_low_surrogate =
12893 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12894
12895 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012896 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012897 }
12898
12899 /* Now test whether the 1st operand is exhausted */
12900 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012901 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012902
12903 /* Extract the bytes to be stored at addr1 */
12904 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12905
12906 store(mkexpr(addr1), data);
12907
12908 /* Update source address and length */
12909 IRTemp num_src_bytes = newTemp(Ity_I64);
12910 assign(num_src_bytes,
12911 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12912 mkU64(4), mkU64(2)));
12913 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12914 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12915
12916 /* Update destination address and length */
12917 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12918 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12919
florian6820ba52012-07-26 02:01:50 +000012920 iterate();
florian2a415a12012-07-21 17:41:36 +000012921
12922 return "cu24";
12923}
floriana4384a32011-08-11 16:58:45 +000012924
florian956194b2012-07-28 22:18:32 +000012925static IRExpr *
12926s390_call_cu42(IRExpr *srcval)
12927{
12928 IRExpr **args, *call;
12929 args = mkIRExprVec_1(srcval);
12930 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12931 "s390_do_cu42", &s390_do_cu42, args);
12932
12933 /* Nothing is excluded from definedness checking. */
12934 call->Iex.CCall.cee->mcx_mask = 0;
12935
12936 return call;
12937}
12938
florian55085f82012-11-21 00:36:55 +000012939static const HChar *
florian956194b2012-07-28 22:18:32 +000012940s390_irgen_CU42(UChar r1, UChar r2)
12941{
12942 IRTemp addr1 = newTemp(Ity_I64);
12943 IRTemp addr2 = newTemp(Ity_I64);
12944 IRTemp len1 = newTemp(Ity_I64);
12945 IRTemp len2 = newTemp(Ity_I64);
12946
12947 assign(addr1, get_gpr_dw0(r1));
12948 assign(addr2, get_gpr_dw0(r2));
12949 assign(len1, get_gpr_dw0(r1 + 1));
12950 assign(len2, get_gpr_dw0(r2 + 1));
12951
12952 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12953 there are less than 4 bytes left, then the 2nd operand is exhausted
12954 and we're done here. cc = 0 */
12955 s390_cc_set(0);
12956 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12957
12958 /* Read the 2nd operand. */
12959 IRTemp srcval = newTemp(Ity_I32);
12960 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12961
12962 /* Call the helper */
12963 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012964 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012965
12966 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12967 cc=2 outranks cc=1 (1st operand exhausted) */
12968 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12969
12970 s390_cc_set(2);
12971 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12972
12973 /* Now test whether the 1st operand is exhausted */
12974 IRTemp num_bytes = newTemp(Ity_I64);
12975 assign(num_bytes, binop(Iop_And64,
12976 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12977 mkU64(0xff)));
12978 s390_cc_set(1);
12979 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12980
12981 /* Extract the bytes to be stored at addr1 */
12982 IRTemp data = newTemp(Ity_I64);
12983 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12984
12985 /* To store the bytes construct 2 dirty helper calls. The helper calls
12986 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12987 that only one of them will be called at runtime. */
12988
12989 Int i;
12990 for (i = 2; i <= 4; ++i) {
12991 IRDirty *d;
12992
12993 if (i == 3) continue; // skip this one
12994
12995 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12996 &s390x_dirtyhelper_CUxy,
12997 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12998 mkexpr(num_bytes)));
12999 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13000 d->mFx = Ifx_Write;
13001 d->mAddr = mkexpr(addr1);
13002 d->mSize = i;
13003 stmt(IRStmt_Dirty(d));
13004 }
13005
13006 /* Update source address and length */
13007 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13008 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13009
13010 /* Update destination address and length */
13011 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13012 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13013
13014 iterate();
13015
13016 return "cu42";
13017}
13018
florian6d9b9b22012-08-03 18:35:39 +000013019static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013020s390_call_cu41(IRExpr *srcval)
13021{
13022 IRExpr **args, *call;
13023 args = mkIRExprVec_1(srcval);
13024 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13025 "s390_do_cu41", &s390_do_cu41, args);
13026
13027 /* Nothing is excluded from definedness checking. */
13028 call->Iex.CCall.cee->mcx_mask = 0;
13029
13030 return call;
13031}
13032
florian55085f82012-11-21 00:36:55 +000013033static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013034s390_irgen_CU41(UChar r1, UChar r2)
13035{
13036 IRTemp addr1 = newTemp(Ity_I64);
13037 IRTemp addr2 = newTemp(Ity_I64);
13038 IRTemp len1 = newTemp(Ity_I64);
13039 IRTemp len2 = newTemp(Ity_I64);
13040
13041 assign(addr1, get_gpr_dw0(r1));
13042 assign(addr2, get_gpr_dw0(r2));
13043 assign(len1, get_gpr_dw0(r1 + 1));
13044 assign(len2, get_gpr_dw0(r2 + 1));
13045
13046 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13047 there are less than 4 bytes left, then the 2nd operand is exhausted
13048 and we're done here. cc = 0 */
13049 s390_cc_set(0);
13050 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13051
13052 /* Read the 2nd operand. */
13053 IRTemp srcval = newTemp(Ity_I32);
13054 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13055
13056 /* Call the helper */
13057 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013058 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013059
13060 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13061 cc=2 outranks cc=1 (1st operand exhausted) */
13062 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13063
13064 s390_cc_set(2);
13065 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13066
13067 /* Now test whether the 1st operand is exhausted */
13068 IRTemp num_bytes = newTemp(Ity_I64);
13069 assign(num_bytes, binop(Iop_And64,
13070 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13071 mkU64(0xff)));
13072 s390_cc_set(1);
13073 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13074
13075 /* Extract the bytes to be stored at addr1 */
13076 IRTemp data = newTemp(Ity_I64);
13077 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13078
13079 /* To store the bytes construct 4 dirty helper calls. The helper calls
13080 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13081 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013082 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013083 for (i = 1; i <= 4; ++i) {
13084 IRDirty *d;
13085
13086 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13087 &s390x_dirtyhelper_CUxy,
13088 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13089 mkexpr(num_bytes)));
13090 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13091 d->mFx = Ifx_Write;
13092 d->mAddr = mkexpr(addr1);
13093 d->mSize = i;
13094 stmt(IRStmt_Dirty(d));
13095 }
13096
13097 /* Update source address and length */
13098 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13099 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13100
13101 /* Update destination address and length */
13102 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13103 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13104
13105 iterate();
13106
13107 return "cu41";
13108}
13109
13110static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013111s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013112{
13113 IRExpr **args, *call;
13114 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013115 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13116 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013117
13118 /* Nothing is excluded from definedness checking. */
13119 call->Iex.CCall.cee->mcx_mask = 0;
13120
13121 return call;
13122}
13123
13124static IRExpr *
13125s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13126 IRExpr *byte4, IRExpr *stuff)
13127{
13128 IRExpr **args, *call;
13129 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13130 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13131 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13132
13133 /* Nothing is excluded from definedness checking. */
13134 call->Iex.CCall.cee->mcx_mask = 0;
13135
13136 return call;
13137}
13138
florian3f8a96a2012-08-05 02:59:55 +000013139static IRExpr *
13140s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13141 IRExpr *byte4, IRExpr *stuff)
13142{
13143 IRExpr **args, *call;
13144 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13145 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13146 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13147
13148 /* Nothing is excluded from definedness checking. */
13149 call->Iex.CCall.cee->mcx_mask = 0;
13150
13151 return call;
13152}
13153
13154static void
13155s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013156{
13157 IRTemp addr1 = newTemp(Ity_I64);
13158 IRTemp addr2 = newTemp(Ity_I64);
13159 IRTemp len1 = newTemp(Ity_I64);
13160 IRTemp len2 = newTemp(Ity_I64);
13161
13162 assign(addr1, get_gpr_dw0(r1));
13163 assign(addr2, get_gpr_dw0(r2));
13164 assign(len1, get_gpr_dw0(r1 + 1));
13165 assign(len2, get_gpr_dw0(r2 + 1));
13166
13167 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13168
13169 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13170 there is less than 1 byte left, then the 2nd operand is exhausted
13171 and we're done here. cc = 0 */
13172 s390_cc_set(0);
13173 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13174
13175 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013176 IRTemp byte1 = newTemp(Ity_I64);
13177 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013178
13179 /* Call the helper to get number of bytes and invalid byte indicator */
13180 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013181 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013182 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013183
13184 /* Check for invalid 1st byte */
13185 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13186 s390_cc_set(2);
13187 next_insn_if(is_invalid);
13188
13189 /* How many bytes do we have to read? */
13190 IRTemp num_src_bytes = newTemp(Ity_I64);
13191 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13192
13193 /* Now test whether the 2nd operand is exhausted */
13194 s390_cc_set(0);
13195 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13196
13197 /* Read the remaining bytes */
13198 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13199
13200 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13201 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013202 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013203 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13204 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013205 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013206 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13207 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013208 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013209
13210 /* Call the helper to get the converted value and invalid byte indicator.
13211 We can pass at most 5 arguments; therefore some encoding is needed
13212 here */
13213 IRExpr *stuff = binop(Iop_Or64,
13214 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13215 mkU64(extended_checking));
13216 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013217
13218 if (is_cu12) {
13219 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13220 byte4, stuff));
13221 } else {
13222 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13223 byte4, stuff));
13224 }
florian6d9b9b22012-08-03 18:35:39 +000013225
13226 /* Check for invalid character */
13227 s390_cc_set(2);
13228 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13229 next_insn_if(is_invalid);
13230
13231 /* Now test whether the 1st operand is exhausted */
13232 IRTemp num_bytes = newTemp(Ity_I64);
13233 assign(num_bytes, binop(Iop_And64,
13234 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13235 mkU64(0xff)));
13236 s390_cc_set(1);
13237 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13238
13239 /* Extract the bytes to be stored at addr1 */
13240 IRTemp data = newTemp(Ity_I64);
13241 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13242
florian3f8a96a2012-08-05 02:59:55 +000013243 if (is_cu12) {
13244 /* To store the bytes construct 2 dirty helper calls. The helper calls
13245 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13246 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013247
florian3f8a96a2012-08-05 02:59:55 +000013248 Int i;
13249 for (i = 2; i <= 4; ++i) {
13250 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013251
florian3f8a96a2012-08-05 02:59:55 +000013252 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013253
florian3f8a96a2012-08-05 02:59:55 +000013254 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13255 &s390x_dirtyhelper_CUxy,
13256 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13257 mkexpr(num_bytes)));
13258 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13259 d->mFx = Ifx_Write;
13260 d->mAddr = mkexpr(addr1);
13261 d->mSize = i;
13262 stmt(IRStmt_Dirty(d));
13263 }
13264 } else {
13265 // cu14
13266 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013267 }
13268
13269 /* Update source address and length */
13270 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13271 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13272
13273 /* Update destination address and length */
13274 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13275 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13276
13277 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013278}
13279
florian55085f82012-11-21 00:36:55 +000013280static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013281s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13282{
13283 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013284
13285 return "cu12";
13286}
13287
florian55085f82012-11-21 00:36:55 +000013288static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013289s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13290{
13291 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13292
13293 return "cu14";
13294}
13295
florian8c88cb62012-08-26 18:58:13 +000013296static IRExpr *
13297s390_call_ecag(IRExpr *op2addr)
13298{
13299 IRExpr **args, *call;
13300
13301 args = mkIRExprVec_1(op2addr);
13302 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13303 "s390_do_ecag", &s390_do_ecag, args);
13304
13305 /* Nothing is excluded from definedness checking. */
13306 call->Iex.CCall.cee->mcx_mask = 0;
13307
13308 return call;
13309}
13310
florian55085f82012-11-21 00:36:55 +000013311static const HChar *
floriand2129202012-09-01 20:01:39 +000013312s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013313{
13314 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013315 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013316 } else {
13317 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13318 }
13319
13320 return "ecag";
13321}
13322
13323
florianb7def222012-12-04 04:45:32 +000013324/* New insns are added here.
13325 If an insn is contingent on a facility being installed also
13326 check whether the list of supported facilities in function
13327 s390x_dirtyhelper_STFLE needs updating */
13328
sewardj2019a972011-03-07 16:04:07 +000013329/*------------------------------------------------------------*/
13330/*--- Build IR for special instructions ---*/
13331/*------------------------------------------------------------*/
13332
florianb4df7682011-07-05 02:09:01 +000013333static void
sewardj2019a972011-03-07 16:04:07 +000013334s390_irgen_client_request(void)
13335{
13336 if (0)
13337 vex_printf("%%R3 = client_request ( %%R2 )\n");
13338
florianf9e1ed72012-04-17 02:41:56 +000013339 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13340 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013341
florianf9e1ed72012-04-17 02:41:56 +000013342 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013343 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013344
13345 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013346}
13347
florianb4df7682011-07-05 02:09:01 +000013348static void
sewardj2019a972011-03-07 16:04:07 +000013349s390_irgen_guest_NRADDR(void)
13350{
13351 if (0)
13352 vex_printf("%%R3 = guest_NRADDR\n");
13353
floriane88b3c92011-07-05 02:48:39 +000013354 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013355}
13356
florianb4df7682011-07-05 02:09:01 +000013357static void
sewardj2019a972011-03-07 16:04:07 +000013358s390_irgen_call_noredir(void)
13359{
florianf9e1ed72012-04-17 02:41:56 +000013360 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13361 + S390_SPECIAL_OP_SIZE;
13362
sewardj2019a972011-03-07 16:04:07 +000013363 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013364 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013365
13366 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013367 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013368
13369 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013370 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013371}
13372
13373/* Force proper alignment for the structures below. */
13374#pragma pack(1)
13375
13376
13377static s390_decode_t
13378s390_decode_2byte_and_irgen(UChar *bytes)
13379{
13380 typedef union {
13381 struct {
13382 unsigned int op : 16;
13383 } E;
13384 struct {
13385 unsigned int op : 8;
13386 unsigned int i : 8;
13387 } I;
13388 struct {
13389 unsigned int op : 8;
13390 unsigned int r1 : 4;
13391 unsigned int r2 : 4;
13392 } RR;
13393 } formats;
13394 union {
13395 formats fmt;
13396 UShort value;
13397 } ovl;
13398
13399 vassert(sizeof(formats) == 2);
13400
florianffbd84d2012-12-09 02:06:29 +000013401 ((UChar *)(&ovl.value))[0] = bytes[0];
13402 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013403
13404 switch (ovl.value & 0xffff) {
13405 case 0x0101: /* PR */ goto unimplemented;
13406 case 0x0102: /* UPT */ goto unimplemented;
13407 case 0x0104: /* PTFF */ goto unimplemented;
13408 case 0x0107: /* SCKPF */ goto unimplemented;
13409 case 0x010a: /* PFPO */ goto unimplemented;
13410 case 0x010b: /* TAM */ goto unimplemented;
13411 case 0x010c: /* SAM24 */ goto unimplemented;
13412 case 0x010d: /* SAM31 */ goto unimplemented;
13413 case 0x010e: /* SAM64 */ goto unimplemented;
13414 case 0x01ff: /* TRAP2 */ goto unimplemented;
13415 }
13416
13417 switch ((ovl.value & 0xff00) >> 8) {
13418 case 0x04: /* SPM */ goto unimplemented;
13419 case 0x05: /* BALR */ goto unimplemented;
13420 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13421 goto ok;
13422 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13423 goto ok;
13424 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13425 case 0x0b: /* BSM */ goto unimplemented;
13426 case 0x0c: /* BASSM */ goto unimplemented;
13427 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13428 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013429 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13430 goto ok;
13431 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13432 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013433 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13434 goto ok;
13435 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13436 goto ok;
13437 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13438 goto ok;
13439 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13440 goto ok;
13441 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13442 goto ok;
13443 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13444 goto ok;
13445 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13446 goto ok;
13447 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13448 goto ok;
13449 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13450 goto ok;
13451 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13452 goto ok;
13453 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13454 goto ok;
13455 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13456 goto ok;
13457 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13458 goto ok;
13459 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13460 goto ok;
13461 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13462 goto ok;
13463 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13464 goto ok;
13465 case 0x20: /* LPDR */ goto unimplemented;
13466 case 0x21: /* LNDR */ goto unimplemented;
13467 case 0x22: /* LTDR */ goto unimplemented;
13468 case 0x23: /* LCDR */ goto unimplemented;
13469 case 0x24: /* HDR */ goto unimplemented;
13470 case 0x25: /* LDXR */ goto unimplemented;
13471 case 0x26: /* MXR */ goto unimplemented;
13472 case 0x27: /* MXDR */ goto unimplemented;
13473 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13474 goto ok;
13475 case 0x29: /* CDR */ goto unimplemented;
13476 case 0x2a: /* ADR */ goto unimplemented;
13477 case 0x2b: /* SDR */ goto unimplemented;
13478 case 0x2c: /* MDR */ goto unimplemented;
13479 case 0x2d: /* DDR */ goto unimplemented;
13480 case 0x2e: /* AWR */ goto unimplemented;
13481 case 0x2f: /* SWR */ goto unimplemented;
13482 case 0x30: /* LPER */ goto unimplemented;
13483 case 0x31: /* LNER */ goto unimplemented;
13484 case 0x32: /* LTER */ goto unimplemented;
13485 case 0x33: /* LCER */ goto unimplemented;
13486 case 0x34: /* HER */ goto unimplemented;
13487 case 0x35: /* LEDR */ goto unimplemented;
13488 case 0x36: /* AXR */ goto unimplemented;
13489 case 0x37: /* SXR */ goto unimplemented;
13490 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13491 goto ok;
13492 case 0x39: /* CER */ goto unimplemented;
13493 case 0x3a: /* AER */ goto unimplemented;
13494 case 0x3b: /* SER */ goto unimplemented;
13495 case 0x3c: /* MDER */ goto unimplemented;
13496 case 0x3d: /* DER */ goto unimplemented;
13497 case 0x3e: /* AUR */ goto unimplemented;
13498 case 0x3f: /* SUR */ goto unimplemented;
13499 }
13500
13501 return S390_DECODE_UNKNOWN_INSN;
13502
13503ok:
13504 return S390_DECODE_OK;
13505
13506unimplemented:
13507 return S390_DECODE_UNIMPLEMENTED_INSN;
13508}
13509
13510static s390_decode_t
13511s390_decode_4byte_and_irgen(UChar *bytes)
13512{
13513 typedef union {
13514 struct {
13515 unsigned int op1 : 8;
13516 unsigned int r1 : 4;
13517 unsigned int op2 : 4;
13518 unsigned int i2 : 16;
13519 } RI;
13520 struct {
13521 unsigned int op : 16;
13522 unsigned int : 8;
13523 unsigned int r1 : 4;
13524 unsigned int r2 : 4;
13525 } RRE;
13526 struct {
13527 unsigned int op : 16;
13528 unsigned int r1 : 4;
13529 unsigned int : 4;
13530 unsigned int r3 : 4;
13531 unsigned int r2 : 4;
13532 } RRF;
13533 struct {
13534 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000013535 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000013536 unsigned int m4 : 4;
13537 unsigned int r1 : 4;
13538 unsigned int r2 : 4;
13539 } RRF2;
13540 struct {
13541 unsigned int op : 16;
13542 unsigned int r3 : 4;
13543 unsigned int : 4;
13544 unsigned int r1 : 4;
13545 unsigned int r2 : 4;
13546 } RRF3;
13547 struct {
13548 unsigned int op : 16;
13549 unsigned int r3 : 4;
13550 unsigned int : 4;
13551 unsigned int r1 : 4;
13552 unsigned int r2 : 4;
13553 } RRR;
13554 struct {
13555 unsigned int op : 16;
13556 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013557 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013558 unsigned int r1 : 4;
13559 unsigned int r2 : 4;
13560 } RRF4;
13561 struct {
floriane38f6412012-12-21 17:32:12 +000013562 unsigned int op : 16;
13563 unsigned int : 4;
13564 unsigned int m4 : 4;
13565 unsigned int r1 : 4;
13566 unsigned int r2 : 4;
13567 } RRF5;
13568 struct {
sewardj2019a972011-03-07 16:04:07 +000013569 unsigned int op : 8;
13570 unsigned int r1 : 4;
13571 unsigned int r3 : 4;
13572 unsigned int b2 : 4;
13573 unsigned int d2 : 12;
13574 } RS;
13575 struct {
13576 unsigned int op : 8;
13577 unsigned int r1 : 4;
13578 unsigned int r3 : 4;
13579 unsigned int i2 : 16;
13580 } RSI;
13581 struct {
13582 unsigned int op : 8;
13583 unsigned int r1 : 4;
13584 unsigned int x2 : 4;
13585 unsigned int b2 : 4;
13586 unsigned int d2 : 12;
13587 } RX;
13588 struct {
13589 unsigned int op : 16;
13590 unsigned int b2 : 4;
13591 unsigned int d2 : 12;
13592 } S;
13593 struct {
13594 unsigned int op : 8;
13595 unsigned int i2 : 8;
13596 unsigned int b1 : 4;
13597 unsigned int d1 : 12;
13598 } SI;
13599 } formats;
13600 union {
13601 formats fmt;
13602 UInt value;
13603 } ovl;
13604
13605 vassert(sizeof(formats) == 4);
13606
florianffbd84d2012-12-09 02:06:29 +000013607 ((UChar *)(&ovl.value))[0] = bytes[0];
13608 ((UChar *)(&ovl.value))[1] = bytes[1];
13609 ((UChar *)(&ovl.value))[2] = bytes[2];
13610 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013611
13612 switch ((ovl.value & 0xff0f0000) >> 16) {
13613 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13614 ovl.fmt.RI.i2); goto ok;
13615 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13616 ovl.fmt.RI.i2); goto ok;
13617 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
13618 ovl.fmt.RI.i2); goto ok;
13619 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
13620 ovl.fmt.RI.i2); goto ok;
13621 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
13622 ovl.fmt.RI.i2); goto ok;
13623 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
13624 ovl.fmt.RI.i2); goto ok;
13625 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
13626 ovl.fmt.RI.i2); goto ok;
13627 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
13628 ovl.fmt.RI.i2); goto ok;
13629 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
13630 ovl.fmt.RI.i2); goto ok;
13631 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
13632 ovl.fmt.RI.i2); goto ok;
13633 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
13634 ovl.fmt.RI.i2); goto ok;
13635 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
13636 ovl.fmt.RI.i2); goto ok;
13637 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
13638 ovl.fmt.RI.i2); goto ok;
13639 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
13640 ovl.fmt.RI.i2); goto ok;
13641 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
13642 ovl.fmt.RI.i2); goto ok;
13643 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
13644 ovl.fmt.RI.i2); goto ok;
13645 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
13646 ovl.fmt.RI.i2); goto ok;
13647 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
13648 ovl.fmt.RI.i2); goto ok;
13649 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
13650 ovl.fmt.RI.i2); goto ok;
13651 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
13652 ovl.fmt.RI.i2); goto ok;
13653 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13654 goto ok;
13655 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
13656 ovl.fmt.RI.i2); goto ok;
13657 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
13658 ovl.fmt.RI.i2); goto ok;
13659 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
13660 ovl.fmt.RI.i2); goto ok;
13661 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13662 goto ok;
13663 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
13664 ovl.fmt.RI.i2); goto ok;
13665 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13666 goto ok;
13667 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
13668 ovl.fmt.RI.i2); goto ok;
13669 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13670 goto ok;
13671 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
13672 ovl.fmt.RI.i2); goto ok;
13673 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13674 goto ok;
13675 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
13676 ovl.fmt.RI.i2); goto ok;
13677 }
13678
13679 switch ((ovl.value & 0xffff0000) >> 16) {
13680 case 0x8000: /* SSM */ goto unimplemented;
13681 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013682 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013683 case 0xb202: /* STIDP */ goto unimplemented;
13684 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013685 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
13686 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013687 case 0xb206: /* SCKC */ goto unimplemented;
13688 case 0xb207: /* STCKC */ goto unimplemented;
13689 case 0xb208: /* SPT */ goto unimplemented;
13690 case 0xb209: /* STPT */ goto unimplemented;
13691 case 0xb20a: /* SPKA */ goto unimplemented;
13692 case 0xb20b: /* IPK */ goto unimplemented;
13693 case 0xb20d: /* PTLB */ goto unimplemented;
13694 case 0xb210: /* SPX */ goto unimplemented;
13695 case 0xb211: /* STPX */ goto unimplemented;
13696 case 0xb212: /* STAP */ goto unimplemented;
13697 case 0xb214: /* SIE */ goto unimplemented;
13698 case 0xb218: /* PC */ goto unimplemented;
13699 case 0xb219: /* SAC */ goto unimplemented;
13700 case 0xb21a: /* CFC */ goto unimplemented;
13701 case 0xb221: /* IPTE */ goto unimplemented;
13702 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
13703 case 0xb223: /* IVSK */ goto unimplemented;
13704 case 0xb224: /* IAC */ goto unimplemented;
13705 case 0xb225: /* SSAR */ goto unimplemented;
13706 case 0xb226: /* EPAR */ goto unimplemented;
13707 case 0xb227: /* ESAR */ goto unimplemented;
13708 case 0xb228: /* PT */ goto unimplemented;
13709 case 0xb229: /* ISKE */ goto unimplemented;
13710 case 0xb22a: /* RRBE */ goto unimplemented;
13711 case 0xb22b: /* SSKE */ goto unimplemented;
13712 case 0xb22c: /* TB */ goto unimplemented;
13713 case 0xb22d: /* DXR */ goto unimplemented;
13714 case 0xb22e: /* PGIN */ goto unimplemented;
13715 case 0xb22f: /* PGOUT */ goto unimplemented;
13716 case 0xb230: /* CSCH */ goto unimplemented;
13717 case 0xb231: /* HSCH */ goto unimplemented;
13718 case 0xb232: /* MSCH */ goto unimplemented;
13719 case 0xb233: /* SSCH */ goto unimplemented;
13720 case 0xb234: /* STSCH */ goto unimplemented;
13721 case 0xb235: /* TSCH */ goto unimplemented;
13722 case 0xb236: /* TPI */ goto unimplemented;
13723 case 0xb237: /* SAL */ goto unimplemented;
13724 case 0xb238: /* RSCH */ goto unimplemented;
13725 case 0xb239: /* STCRW */ goto unimplemented;
13726 case 0xb23a: /* STCPS */ goto unimplemented;
13727 case 0xb23b: /* RCHP */ goto unimplemented;
13728 case 0xb23c: /* SCHM */ goto unimplemented;
13729 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000013730 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
13731 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013732 case 0xb244: /* SQDR */ goto unimplemented;
13733 case 0xb245: /* SQER */ goto unimplemented;
13734 case 0xb246: /* STURA */ goto unimplemented;
13735 case 0xb247: /* MSTA */ goto unimplemented;
13736 case 0xb248: /* PALB */ goto unimplemented;
13737 case 0xb249: /* EREG */ goto unimplemented;
13738 case 0xb24a: /* ESTA */ goto unimplemented;
13739 case 0xb24b: /* LURA */ goto unimplemented;
13740 case 0xb24c: /* TAR */ goto unimplemented;
13741 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
13742 ovl.fmt.RRE.r2); goto ok;
13743 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13744 goto ok;
13745 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13746 goto ok;
13747 case 0xb250: /* CSP */ goto unimplemented;
13748 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
13749 ovl.fmt.RRE.r2); goto ok;
13750 case 0xb254: /* MVPG */ goto unimplemented;
13751 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
13752 ovl.fmt.RRE.r2); goto ok;
13753 case 0xb257: /* CUSE */ goto unimplemented;
13754 case 0xb258: /* BSG */ goto unimplemented;
13755 case 0xb25a: /* BSA */ goto unimplemented;
13756 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
13757 ovl.fmt.RRE.r2); goto ok;
13758 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
13759 ovl.fmt.RRE.r2); goto ok;
13760 case 0xb263: /* CMPSC */ goto unimplemented;
13761 case 0xb274: /* SIGA */ goto unimplemented;
13762 case 0xb276: /* XSCH */ goto unimplemented;
13763 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013764 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 +000013765 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013766 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 +000013767 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013768 case 0xb280: /* LPP */ goto unimplemented;
13769 case 0xb284: /* LCCTL */ goto unimplemented;
13770 case 0xb285: /* LPCTL */ goto unimplemented;
13771 case 0xb286: /* QSI */ goto unimplemented;
13772 case 0xb287: /* LSCTL */ goto unimplemented;
13773 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013774 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
13775 goto ok;
13776 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13777 goto ok;
13778 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13779 goto ok;
florian730448f2012-02-04 17:07:07 +000013780 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 +000013781 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
13782 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13783 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000013784 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
13785 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13786 goto ok;
florian933065d2011-07-11 01:48:02 +000013787 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
13788 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013789 case 0xb2b1: /* STFL */ goto unimplemented;
13790 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000013791 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
13792 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013793 case 0xb2b9: /* SRNMT */ goto unimplemented;
13794 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013795 case 0xb2e0: /* SCCTR */ goto unimplemented;
13796 case 0xb2e1: /* SPCTR */ goto unimplemented;
13797 case 0xb2e4: /* ECCTR */ goto unimplemented;
13798 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013799 case 0xb2e8: /* PPA */ goto unimplemented;
13800 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013801 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013802 case 0xb2f8: /* TEND */ goto unimplemented;
13803 case 0xb2fa: /* NIAI */ goto unimplemented;
13804 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013805 case 0xb2ff: /* TRAP4 */ goto unimplemented;
13806 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
13807 ovl.fmt.RRE.r2); goto ok;
13808 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
13809 ovl.fmt.RRE.r2); goto ok;
13810 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
13811 ovl.fmt.RRE.r2); goto ok;
13812 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
13813 ovl.fmt.RRE.r2); goto ok;
13814 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
13815 ovl.fmt.RRE.r2); goto ok;
13816 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
13817 ovl.fmt.RRE.r2); goto ok;
13818 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
13819 ovl.fmt.RRE.r2); goto ok;
13820 case 0xb307: /* MXDBR */ goto unimplemented;
13821 case 0xb308: /* KEBR */ goto unimplemented;
13822 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
13823 ovl.fmt.RRE.r2); goto ok;
13824 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
13825 ovl.fmt.RRE.r2); goto ok;
13826 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
13827 ovl.fmt.RRE.r2); goto ok;
13828 case 0xb30c: /* MDEBR */ goto unimplemented;
13829 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
13830 ovl.fmt.RRE.r2); goto ok;
13831 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
13832 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13833 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
13834 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13835 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
13836 ovl.fmt.RRE.r2); goto ok;
13837 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
13838 ovl.fmt.RRE.r2); goto ok;
13839 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
13840 ovl.fmt.RRE.r2); goto ok;
13841 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
13842 ovl.fmt.RRE.r2); goto ok;
13843 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
13844 ovl.fmt.RRE.r2); goto ok;
13845 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
13846 ovl.fmt.RRE.r2); goto ok;
13847 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
13848 ovl.fmt.RRE.r2); goto ok;
13849 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
13850 ovl.fmt.RRE.r2); goto ok;
13851 case 0xb318: /* KDBR */ goto unimplemented;
13852 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
13853 ovl.fmt.RRE.r2); goto ok;
13854 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
13855 ovl.fmt.RRE.r2); goto ok;
13856 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
13857 ovl.fmt.RRE.r2); goto ok;
13858 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
13859 ovl.fmt.RRE.r2); goto ok;
13860 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
13861 ovl.fmt.RRE.r2); goto ok;
13862 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
13863 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13864 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
13865 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13866 case 0xb324: /* LDER */ goto unimplemented;
13867 case 0xb325: /* LXDR */ goto unimplemented;
13868 case 0xb326: /* LXER */ goto unimplemented;
13869 case 0xb32e: /* MAER */ goto unimplemented;
13870 case 0xb32f: /* MSER */ goto unimplemented;
13871 case 0xb336: /* SQXR */ goto unimplemented;
13872 case 0xb337: /* MEER */ goto unimplemented;
13873 case 0xb338: /* MAYLR */ goto unimplemented;
13874 case 0xb339: /* MYLR */ goto unimplemented;
13875 case 0xb33a: /* MAYR */ goto unimplemented;
13876 case 0xb33b: /* MYR */ goto unimplemented;
13877 case 0xb33c: /* MAYHR */ goto unimplemented;
13878 case 0xb33d: /* MYHR */ goto unimplemented;
13879 case 0xb33e: /* MADR */ goto unimplemented;
13880 case 0xb33f: /* MSDR */ goto unimplemented;
13881 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
13882 ovl.fmt.RRE.r2); goto ok;
13883 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
13884 ovl.fmt.RRE.r2); goto ok;
13885 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
13886 ovl.fmt.RRE.r2); goto ok;
13887 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
13888 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013889 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13890 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13891 ovl.fmt.RRF2.r2); goto ok;
13892 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13893 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13894 ovl.fmt.RRF2.r2); goto ok;
13895 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13896 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13897 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013898 case 0xb347: /* FIXBR */ goto unimplemented;
13899 case 0xb348: /* KXBR */ goto unimplemented;
13900 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13901 ovl.fmt.RRE.r2); goto ok;
13902 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13903 ovl.fmt.RRE.r2); goto ok;
13904 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13905 ovl.fmt.RRE.r2); goto ok;
13906 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13907 ovl.fmt.RRE.r2); goto ok;
13908 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13909 ovl.fmt.RRE.r2); goto ok;
13910 case 0xb350: /* TBEDR */ goto unimplemented;
13911 case 0xb351: /* TBDR */ goto unimplemented;
13912 case 0xb353: /* DIEBR */ goto unimplemented;
13913 case 0xb357: /* FIEBR */ goto unimplemented;
13914 case 0xb358: /* THDER */ goto unimplemented;
13915 case 0xb359: /* THDR */ goto unimplemented;
13916 case 0xb35b: /* DIDBR */ goto unimplemented;
13917 case 0xb35f: /* FIDBR */ goto unimplemented;
13918 case 0xb360: /* LPXR */ goto unimplemented;
13919 case 0xb361: /* LNXR */ goto unimplemented;
13920 case 0xb362: /* LTXR */ goto unimplemented;
13921 case 0xb363: /* LCXR */ goto unimplemented;
13922 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13923 ovl.fmt.RRE.r2); goto ok;
13924 case 0xb366: /* LEXR */ goto unimplemented;
13925 case 0xb367: /* FIXR */ goto unimplemented;
13926 case 0xb369: /* CXR */ goto unimplemented;
13927 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13928 ovl.fmt.RRE.r2); goto ok;
13929 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13930 ovl.fmt.RRE.r2); goto ok;
13931 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13932 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13933 goto ok;
13934 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13935 ovl.fmt.RRE.r2); goto ok;
13936 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13937 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13938 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13939 case 0xb377: /* FIER */ goto unimplemented;
13940 case 0xb37f: /* FIDR */ goto unimplemented;
13941 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13942 case 0xb385: /* SFASR */ goto unimplemented;
13943 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013944 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13945 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13946 ovl.fmt.RRF2.r2); goto ok;
13947 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13948 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13949 ovl.fmt.RRF2.r2); goto ok;
13950 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13951 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13952 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013953 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13954 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13955 ovl.fmt.RRF2.r2); goto ok;
13956 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13957 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13958 ovl.fmt.RRF2.r2); goto ok;
13959 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13960 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13961 ovl.fmt.RRF2.r2); goto ok;
13962 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13963 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13964 ovl.fmt.RRF2.r2); goto ok;
13965 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13966 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13967 ovl.fmt.RRF2.r2); goto ok;
13968 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13969 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13970 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013971 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13972 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13973 ovl.fmt.RRF2.r2); goto ok;
13974 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13975 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13976 ovl.fmt.RRF2.r2); goto ok;
13977 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13978 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13979 ovl.fmt.RRF2.r2); goto ok;
13980 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13981 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13982 ovl.fmt.RRF2.r2); goto ok;
13983 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13984 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13985 ovl.fmt.RRF2.r2); goto ok;
13986 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13987 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13988 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013989 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13990 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13991 ovl.fmt.RRF2.r2); goto ok;
13992 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13993 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13994 ovl.fmt.RRF2.r2); goto ok;
13995 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13996 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13997 ovl.fmt.RRF2.r2); goto ok;
13998 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13999 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14000 ovl.fmt.RRF2.r2); goto ok;
14001 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14002 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14003 ovl.fmt.RRF2.r2); goto ok;
14004 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14005 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14006 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014007 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14008 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14009 ovl.fmt.RRF2.r2); goto ok;
14010 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14011 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14012 ovl.fmt.RRF2.r2); goto ok;
14013 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14014 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14015 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014016 case 0xb3b4: /* CEFR */ goto unimplemented;
14017 case 0xb3b5: /* CDFR */ goto unimplemented;
14018 case 0xb3b6: /* CXFR */ goto unimplemented;
14019 case 0xb3b8: /* CFER */ goto unimplemented;
14020 case 0xb3b9: /* CFDR */ goto unimplemented;
14021 case 0xb3ba: /* CFXR */ goto unimplemented;
14022 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14023 ovl.fmt.RRE.r2); goto ok;
14024 case 0xb3c4: /* CEGR */ goto unimplemented;
14025 case 0xb3c5: /* CDGR */ goto unimplemented;
14026 case 0xb3c6: /* CXGR */ goto unimplemented;
14027 case 0xb3c8: /* CGER */ goto unimplemented;
14028 case 0xb3c9: /* CGDR */ goto unimplemented;
14029 case 0xb3ca: /* CGXR */ goto unimplemented;
14030 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14031 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014032 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14033 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14034 ovl.fmt.RRF4.r2); goto ok;
14035 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14036 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14037 ovl.fmt.RRF4.r2); goto ok;
14038 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14039 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14040 ovl.fmt.RRF4.r2); goto ok;
14041 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14042 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14043 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014044 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14045 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14046 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14047 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14048 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014049 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14050 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014051 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014052 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14053 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14054 ovl.fmt.RRF4.r2); goto ok;
14055 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14056 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14057 ovl.fmt.RRF4.r2); goto ok;
14058 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14059 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14060 ovl.fmt.RRF4.r2); goto ok;
14061 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14062 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14063 ovl.fmt.RRF4.r2); goto ok;
14064 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14065 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14066 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14067 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14068 ovl.fmt.RRF2.r2); goto ok;
14069 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14070 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014071 case 0xb3df: /* FIXTR */ goto unimplemented;
14072 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014073 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14074 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14075 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014076 case 0xb3e2: /* CUDTR */ goto unimplemented;
14077 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014078 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14079 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014080 case 0xb3e5: /* EEDTR */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000014081 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14082 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014083 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014084 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14085 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14086 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014087 case 0xb3ea: /* CUXTR */ goto unimplemented;
14088 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014089 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14090 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014091 case 0xb3ed: /* EEXTR */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000014092 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14093 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014094 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14095 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14096 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014097 case 0xb3f2: /* CDUTR */ goto unimplemented;
14098 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014099 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14100 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014101 case 0xb3f5: /* QADTR */ goto unimplemented;
14102 case 0xb3f6: /* IEDTR */ goto unimplemented;
14103 case 0xb3f7: /* RRDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014104 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14105 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14106 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014107 case 0xb3fa: /* CXUTR */ goto unimplemented;
14108 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014109 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14110 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014111 case 0xb3fd: /* QAXTR */ goto unimplemented;
14112 case 0xb3fe: /* IEXTR */ goto unimplemented;
14113 case 0xb3ff: /* RRXTR */ goto unimplemented;
14114 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14115 ovl.fmt.RRE.r2); goto ok;
14116 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14117 ovl.fmt.RRE.r2); goto ok;
14118 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14119 ovl.fmt.RRE.r2); goto ok;
14120 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14121 ovl.fmt.RRE.r2); goto ok;
14122 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14123 ovl.fmt.RRE.r2); goto ok;
14124 case 0xb905: /* LURAG */ goto unimplemented;
14125 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14126 ovl.fmt.RRE.r2); goto ok;
14127 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14128 ovl.fmt.RRE.r2); goto ok;
14129 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14130 ovl.fmt.RRE.r2); goto ok;
14131 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14132 ovl.fmt.RRE.r2); goto ok;
14133 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14134 ovl.fmt.RRE.r2); goto ok;
14135 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14136 ovl.fmt.RRE.r2); goto ok;
14137 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14138 ovl.fmt.RRE.r2); goto ok;
14139 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14140 ovl.fmt.RRE.r2); goto ok;
14141 case 0xb90e: /* EREGG */ goto unimplemented;
14142 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14143 ovl.fmt.RRE.r2); goto ok;
14144 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14145 ovl.fmt.RRE.r2); goto ok;
14146 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14147 ovl.fmt.RRE.r2); goto ok;
14148 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14149 ovl.fmt.RRE.r2); goto ok;
14150 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14151 ovl.fmt.RRE.r2); goto ok;
14152 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14153 ovl.fmt.RRE.r2); goto ok;
14154 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14155 ovl.fmt.RRE.r2); goto ok;
14156 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14157 ovl.fmt.RRE.r2); goto ok;
14158 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14159 ovl.fmt.RRE.r2); goto ok;
14160 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14161 ovl.fmt.RRE.r2); goto ok;
14162 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14163 ovl.fmt.RRE.r2); goto ok;
14164 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14165 ovl.fmt.RRE.r2); goto ok;
14166 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14167 ovl.fmt.RRE.r2); goto ok;
14168 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14169 ovl.fmt.RRE.r2); goto ok;
14170 case 0xb91e: /* KMAC */ goto unimplemented;
14171 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14172 ovl.fmt.RRE.r2); goto ok;
14173 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14174 ovl.fmt.RRE.r2); goto ok;
14175 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14176 ovl.fmt.RRE.r2); goto ok;
14177 case 0xb925: /* STURG */ goto unimplemented;
14178 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14179 ovl.fmt.RRE.r2); goto ok;
14180 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14181 ovl.fmt.RRE.r2); goto ok;
14182 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014183 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014184 case 0xb92b: /* KMO */ goto unimplemented;
14185 case 0xb92c: /* PCC */ goto unimplemented;
14186 case 0xb92d: /* KMCTR */ goto unimplemented;
14187 case 0xb92e: /* KM */ goto unimplemented;
14188 case 0xb92f: /* KMC */ goto unimplemented;
14189 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14190 ovl.fmt.RRE.r2); goto ok;
14191 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14192 ovl.fmt.RRE.r2); goto ok;
14193 case 0xb93e: /* KIMD */ goto unimplemented;
14194 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014195 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14196 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14197 ovl.fmt.RRF2.r2); goto ok;
14198 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14199 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14200 ovl.fmt.RRF2.r2); goto ok;
14201 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14202 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14203 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014204 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14205 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014206 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14207 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14208 ovl.fmt.RRF2.r2); goto ok;
14209 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14210 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14211 ovl.fmt.RRF2.r2); goto ok;
14212 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14213 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14214 ovl.fmt.RRF2.r2); goto ok;
14215 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14216 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14217 ovl.fmt.RRF2.r2); goto ok;
14218 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14219 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14220 ovl.fmt.RRF2.r2); goto ok;
14221 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14222 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14223 ovl.fmt.RRF2.r2); goto ok;
14224 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14225 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14226 ovl.fmt.RRF2.r2); goto ok;
14227 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14228 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14229 ovl.fmt.RRF2.r2); goto ok;
14230 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14231 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14232 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014233 case 0xb960: /* CGRT */ goto unimplemented;
14234 case 0xb961: /* CLGRT */ goto unimplemented;
14235 case 0xb972: /* CRT */ goto unimplemented;
14236 case 0xb973: /* CLRT */ goto unimplemented;
14237 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14238 ovl.fmt.RRE.r2); goto ok;
14239 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14240 ovl.fmt.RRE.r2); goto ok;
14241 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14242 ovl.fmt.RRE.r2); goto ok;
14243 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14244 ovl.fmt.RRE.r2); goto ok;
14245 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14246 ovl.fmt.RRE.r2); goto ok;
14247 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14248 ovl.fmt.RRE.r2); goto ok;
14249 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14250 ovl.fmt.RRE.r2); goto ok;
14251 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14252 ovl.fmt.RRE.r2); goto ok;
14253 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14254 ovl.fmt.RRE.r2); goto ok;
14255 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14256 ovl.fmt.RRE.r2); goto ok;
14257 case 0xb98a: /* CSPG */ goto unimplemented;
14258 case 0xb98d: /* EPSW */ goto unimplemented;
14259 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014260 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014261 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14262 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14263 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14264 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14265 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14266 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014267 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14268 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014269 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14270 ovl.fmt.RRE.r2); goto ok;
14271 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14272 ovl.fmt.RRE.r2); goto ok;
14273 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14274 ovl.fmt.RRE.r2); goto ok;
14275 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14276 ovl.fmt.RRE.r2); goto ok;
14277 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14278 ovl.fmt.RRE.r2); goto ok;
14279 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14280 ovl.fmt.RRE.r2); goto ok;
14281 case 0xb99a: /* EPAIR */ goto unimplemented;
14282 case 0xb99b: /* ESAIR */ goto unimplemented;
14283 case 0xb99d: /* ESEA */ goto unimplemented;
14284 case 0xb99e: /* PTI */ goto unimplemented;
14285 case 0xb99f: /* SSAIR */ goto unimplemented;
14286 case 0xb9a2: /* PTF */ goto unimplemented;
14287 case 0xb9aa: /* LPTEA */ goto unimplemented;
14288 case 0xb9ae: /* RRBM */ goto unimplemented;
14289 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014290 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14291 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14292 goto ok;
florian2a415a12012-07-21 17:41:36 +000014293 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14294 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14295 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014296 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14297 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014298 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14299 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014300 case 0xb9bd: /* TRTRE */ goto unimplemented;
14301 case 0xb9be: /* SRSTU */ goto unimplemented;
14302 case 0xb9bf: /* TRTE */ goto unimplemented;
14303 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14304 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14305 goto ok;
14306 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14307 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14308 goto ok;
14309 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14310 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14311 goto ok;
14312 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14313 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14314 goto ok;
14315 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14316 ovl.fmt.RRE.r2); goto ok;
14317 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14318 ovl.fmt.RRE.r2); goto ok;
14319 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14320 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14321 goto ok;
14322 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14323 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14324 goto ok;
14325 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14326 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14327 goto ok;
14328 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14329 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14330 goto ok;
14331 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14332 ovl.fmt.RRE.r2); goto ok;
14333 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14334 ovl.fmt.RRE.r2); goto ok;
14335 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014336 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14337 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14338 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014339 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14340 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14341 goto ok;
14342 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14343 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14344 goto ok;
14345 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14346 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14347 goto ok;
14348 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14349 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14350 goto ok;
14351 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14352 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14353 goto ok;
14354 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14355 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14356 goto ok;
14357 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14358 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14359 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014360 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14361 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14362 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014363 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14364 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14365 goto ok;
14366 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14367 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14368 goto ok;
14369 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14370 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14371 goto ok;
14372 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14373 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14374 goto ok;
14375 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14376 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14377 goto ok;
14378 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14379 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14380 goto ok;
14381 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14382 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14383 goto ok;
14384 }
14385
14386 switch ((ovl.value & 0xff000000) >> 24) {
14387 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14388 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14389 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14390 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14391 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14392 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14393 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14394 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14395 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14396 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14397 case 0x45: /* BAL */ goto unimplemented;
14398 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14399 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14400 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14401 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14402 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14403 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14404 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14405 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14406 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14407 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14408 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14409 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14410 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14411 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14412 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14413 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14414 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14415 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14416 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14417 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14418 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14419 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14420 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14421 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14422 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14423 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14424 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14425 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14426 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14427 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14428 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14429 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14430 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14431 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14432 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14433 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14434 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14435 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14436 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14437 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14438 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14439 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14440 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14441 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14442 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14443 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14444 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14445 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14446 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14447 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14448 case 0x67: /* MXD */ goto unimplemented;
14449 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14450 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14451 case 0x69: /* CD */ goto unimplemented;
14452 case 0x6a: /* AD */ goto unimplemented;
14453 case 0x6b: /* SD */ goto unimplemented;
14454 case 0x6c: /* MD */ goto unimplemented;
14455 case 0x6d: /* DD */ goto unimplemented;
14456 case 0x6e: /* AW */ goto unimplemented;
14457 case 0x6f: /* SW */ goto unimplemented;
14458 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14459 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14460 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14461 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14462 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14463 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14464 case 0x79: /* CE */ goto unimplemented;
14465 case 0x7a: /* AE */ goto unimplemented;
14466 case 0x7b: /* SE */ goto unimplemented;
14467 case 0x7c: /* MDE */ goto unimplemented;
14468 case 0x7d: /* DE */ goto unimplemented;
14469 case 0x7e: /* AU */ goto unimplemented;
14470 case 0x7f: /* SU */ goto unimplemented;
14471 case 0x83: /* DIAG */ goto unimplemented;
14472 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
14473 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14474 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
14475 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14476 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14477 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14478 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14479 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14480 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14481 ovl.fmt.RS.d2); goto ok;
14482 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14483 ovl.fmt.RS.d2); goto ok;
14484 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14485 ovl.fmt.RS.d2); goto ok;
14486 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14487 ovl.fmt.RS.d2); goto ok;
14488 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14489 ovl.fmt.RS.d2); goto ok;
14490 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14491 ovl.fmt.RS.d2); goto ok;
14492 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14493 ovl.fmt.RS.d2); goto ok;
14494 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14495 ovl.fmt.RS.d2); goto ok;
14496 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14497 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14498 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14499 ovl.fmt.SI.d1); goto ok;
14500 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14501 ovl.fmt.SI.d1); goto ok;
14502 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14503 ovl.fmt.SI.d1); goto ok;
14504 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14505 ovl.fmt.SI.d1); goto ok;
14506 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14507 ovl.fmt.SI.d1); goto ok;
14508 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14509 ovl.fmt.SI.d1); goto ok;
14510 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14511 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14512 case 0x99: /* TRACE */ goto unimplemented;
14513 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14514 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14515 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14516 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14517 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
14518 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14519 goto ok;
14520 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
14521 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14522 goto ok;
14523 case 0xac: /* STNSM */ goto unimplemented;
14524 case 0xad: /* STOSM */ goto unimplemented;
14525 case 0xae: /* SIGP */ goto unimplemented;
14526 case 0xaf: /* MC */ goto unimplemented;
14527 case 0xb1: /* LRA */ goto unimplemented;
14528 case 0xb6: /* STCTL */ goto unimplemented;
14529 case 0xb7: /* LCTL */ goto unimplemented;
14530 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14531 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014532 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14533 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014534 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14535 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14536 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14537 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14538 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14539 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14540 }
14541
14542 return S390_DECODE_UNKNOWN_INSN;
14543
14544ok:
14545 return S390_DECODE_OK;
14546
14547unimplemented:
14548 return S390_DECODE_UNIMPLEMENTED_INSN;
14549}
14550
14551static s390_decode_t
14552s390_decode_6byte_and_irgen(UChar *bytes)
14553{
14554 typedef union {
14555 struct {
14556 unsigned int op1 : 8;
14557 unsigned int r1 : 4;
14558 unsigned int r3 : 4;
14559 unsigned int i2 : 16;
14560 unsigned int : 8;
14561 unsigned int op2 : 8;
14562 } RIE;
14563 struct {
14564 unsigned int op1 : 8;
14565 unsigned int r1 : 4;
14566 unsigned int r2 : 4;
14567 unsigned int i3 : 8;
14568 unsigned int i4 : 8;
14569 unsigned int i5 : 8;
14570 unsigned int op2 : 8;
14571 } RIE_RRUUU;
14572 struct {
14573 unsigned int op1 : 8;
14574 unsigned int r1 : 4;
14575 unsigned int : 4;
14576 unsigned int i2 : 16;
14577 unsigned int m3 : 4;
14578 unsigned int : 4;
14579 unsigned int op2 : 8;
14580 } RIEv1;
14581 struct {
14582 unsigned int op1 : 8;
14583 unsigned int r1 : 4;
14584 unsigned int r2 : 4;
14585 unsigned int i4 : 16;
14586 unsigned int m3 : 4;
14587 unsigned int : 4;
14588 unsigned int op2 : 8;
14589 } RIE_RRPU;
14590 struct {
14591 unsigned int op1 : 8;
14592 unsigned int r1 : 4;
14593 unsigned int m3 : 4;
14594 unsigned int i4 : 16;
14595 unsigned int i2 : 8;
14596 unsigned int op2 : 8;
14597 } RIEv3;
14598 struct {
14599 unsigned int op1 : 8;
14600 unsigned int r1 : 4;
14601 unsigned int op2 : 4;
14602 unsigned int i2 : 32;
14603 } RIL;
14604 struct {
14605 unsigned int op1 : 8;
14606 unsigned int r1 : 4;
14607 unsigned int m3 : 4;
14608 unsigned int b4 : 4;
14609 unsigned int d4 : 12;
14610 unsigned int i2 : 8;
14611 unsigned int op2 : 8;
14612 } RIS;
14613 struct {
14614 unsigned int op1 : 8;
14615 unsigned int r1 : 4;
14616 unsigned int r2 : 4;
14617 unsigned int b4 : 4;
14618 unsigned int d4 : 12;
14619 unsigned int m3 : 4;
14620 unsigned int : 4;
14621 unsigned int op2 : 8;
14622 } RRS;
14623 struct {
14624 unsigned int op1 : 8;
14625 unsigned int l1 : 4;
14626 unsigned int : 4;
14627 unsigned int b1 : 4;
14628 unsigned int d1 : 12;
14629 unsigned int : 8;
14630 unsigned int op2 : 8;
14631 } RSL;
14632 struct {
14633 unsigned int op1 : 8;
14634 unsigned int r1 : 4;
14635 unsigned int r3 : 4;
14636 unsigned int b2 : 4;
14637 unsigned int dl2 : 12;
14638 unsigned int dh2 : 8;
14639 unsigned int op2 : 8;
14640 } RSY;
14641 struct {
14642 unsigned int op1 : 8;
14643 unsigned int r1 : 4;
14644 unsigned int x2 : 4;
14645 unsigned int b2 : 4;
14646 unsigned int d2 : 12;
14647 unsigned int : 8;
14648 unsigned int op2 : 8;
14649 } RXE;
14650 struct {
14651 unsigned int op1 : 8;
14652 unsigned int r3 : 4;
14653 unsigned int x2 : 4;
14654 unsigned int b2 : 4;
14655 unsigned int d2 : 12;
14656 unsigned int r1 : 4;
14657 unsigned int : 4;
14658 unsigned int op2 : 8;
14659 } RXF;
14660 struct {
14661 unsigned int op1 : 8;
14662 unsigned int r1 : 4;
14663 unsigned int x2 : 4;
14664 unsigned int b2 : 4;
14665 unsigned int dl2 : 12;
14666 unsigned int dh2 : 8;
14667 unsigned int op2 : 8;
14668 } RXY;
14669 struct {
14670 unsigned int op1 : 8;
14671 unsigned int i2 : 8;
14672 unsigned int b1 : 4;
14673 unsigned int dl1 : 12;
14674 unsigned int dh1 : 8;
14675 unsigned int op2 : 8;
14676 } SIY;
14677 struct {
14678 unsigned int op : 8;
14679 unsigned int l : 8;
14680 unsigned int b1 : 4;
14681 unsigned int d1 : 12;
14682 unsigned int b2 : 4;
14683 unsigned int d2 : 12;
14684 } SS;
14685 struct {
14686 unsigned int op : 8;
14687 unsigned int l1 : 4;
14688 unsigned int l2 : 4;
14689 unsigned int b1 : 4;
14690 unsigned int d1 : 12;
14691 unsigned int b2 : 4;
14692 unsigned int d2 : 12;
14693 } SS_LLRDRD;
14694 struct {
14695 unsigned int op : 8;
14696 unsigned int r1 : 4;
14697 unsigned int r3 : 4;
14698 unsigned int b2 : 4;
14699 unsigned int d2 : 12;
14700 unsigned int b4 : 4;
14701 unsigned int d4 : 12;
14702 } SS_RRRDRD2;
14703 struct {
14704 unsigned int op : 16;
14705 unsigned int b1 : 4;
14706 unsigned int d1 : 12;
14707 unsigned int b2 : 4;
14708 unsigned int d2 : 12;
14709 } SSE;
14710 struct {
14711 unsigned int op1 : 8;
14712 unsigned int r3 : 4;
14713 unsigned int op2 : 4;
14714 unsigned int b1 : 4;
14715 unsigned int d1 : 12;
14716 unsigned int b2 : 4;
14717 unsigned int d2 : 12;
14718 } SSF;
14719 struct {
14720 unsigned int op : 16;
14721 unsigned int b1 : 4;
14722 unsigned int d1 : 12;
14723 unsigned int i2 : 16;
14724 } SIL;
14725 } formats;
14726 union {
14727 formats fmt;
14728 ULong value;
14729 } ovl;
14730
14731 vassert(sizeof(formats) == 6);
14732
florianffbd84d2012-12-09 02:06:29 +000014733 ((UChar *)(&ovl.value))[0] = bytes[0];
14734 ((UChar *)(&ovl.value))[1] = bytes[1];
14735 ((UChar *)(&ovl.value))[2] = bytes[2];
14736 ((UChar *)(&ovl.value))[3] = bytes[3];
14737 ((UChar *)(&ovl.value))[4] = bytes[4];
14738 ((UChar *)(&ovl.value))[5] = bytes[5];
14739 ((UChar *)(&ovl.value))[6] = 0x0;
14740 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000014741
14742 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
14743 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, 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 0xe30000000003ULL: /* LRAG */ goto unimplemented;
14748 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, 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 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, 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 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
14757 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14758 ovl.fmt.RXY.dl2,
14759 ovl.fmt.RXY.dh2); goto ok;
14760 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
14761 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14762 ovl.fmt.RXY.dl2,
14763 ovl.fmt.RXY.dh2); goto ok;
14764 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
14765 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14766 ovl.fmt.RXY.dl2,
14767 ovl.fmt.RXY.dh2); goto ok;
14768 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
14769 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14770 ovl.fmt.RXY.dl2,
14771 ovl.fmt.RXY.dh2); goto ok;
14772 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
14773 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14774 ovl.fmt.RXY.dl2,
14775 ovl.fmt.RXY.dh2); goto ok;
14776 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
14777 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14778 ovl.fmt.RXY.dl2,
14779 ovl.fmt.RXY.dh2); goto ok;
14780 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
14781 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, 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 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, 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 0xe30000000013ULL: /* LRAY */ goto unimplemented;
14790 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
14791 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14792 ovl.fmt.RXY.dl2,
14793 ovl.fmt.RXY.dh2); goto ok;
14794 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
14795 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14796 ovl.fmt.RXY.dl2,
14797 ovl.fmt.RXY.dh2); goto ok;
14798 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
14799 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14800 ovl.fmt.RXY.dl2,
14801 ovl.fmt.RXY.dh2); goto ok;
14802 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
14803 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14804 ovl.fmt.RXY.dl2,
14805 ovl.fmt.RXY.dh2); goto ok;
14806 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
14807 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14808 ovl.fmt.RXY.dl2,
14809 ovl.fmt.RXY.dh2); goto ok;
14810 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
14811 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14812 ovl.fmt.RXY.dl2,
14813 ovl.fmt.RXY.dh2); goto ok;
14814 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
14815 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14816 ovl.fmt.RXY.dl2,
14817 ovl.fmt.RXY.dh2); goto ok;
14818 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, 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 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
14823 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14824 ovl.fmt.RXY.dl2,
14825 ovl.fmt.RXY.dh2); goto ok;
14826 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
14827 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14828 ovl.fmt.RXY.dl2,
14829 ovl.fmt.RXY.dh2); goto ok;
14830 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
14831 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14832 ovl.fmt.RXY.dl2,
14833 ovl.fmt.RXY.dh2); goto ok;
14834 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
14835 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14836 ovl.fmt.RXY.dl2,
14837 ovl.fmt.RXY.dh2); goto ok;
14838 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
14839 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14840 ovl.fmt.RXY.dl2,
14841 ovl.fmt.RXY.dh2); goto ok;
14842 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
14843 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14844 ovl.fmt.RXY.dl2,
14845 ovl.fmt.RXY.dh2); goto ok;
14846 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
14847 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14848 ovl.fmt.RXY.dl2,
14849 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014850 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014851 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
14852 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14853 ovl.fmt.RXY.dl2,
14854 ovl.fmt.RXY.dh2); goto ok;
14855 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
14856 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
14857 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14858 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14859 ovl.fmt.RXY.dh2); goto ok;
14860 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
14861 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14862 ovl.fmt.RXY.dl2,
14863 ovl.fmt.RXY.dh2); goto ok;
14864 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
14865 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14866 ovl.fmt.RXY.dl2,
14867 ovl.fmt.RXY.dh2); goto ok;
14868 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
14869 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14870 ovl.fmt.RXY.dl2,
14871 ovl.fmt.RXY.dh2); goto ok;
14872 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
14873 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14874 ovl.fmt.RXY.dl2,
14875 ovl.fmt.RXY.dh2); goto ok;
14876 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
14877 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14878 ovl.fmt.RXY.dl2,
14879 ovl.fmt.RXY.dh2); goto ok;
14880 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
14881 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14882 ovl.fmt.RXY.dl2,
14883 ovl.fmt.RXY.dh2); goto ok;
14884 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
14885 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14886 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14887 ovl.fmt.RXY.dh2); goto ok;
14888 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
14889 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14890 ovl.fmt.RXY.dl2,
14891 ovl.fmt.RXY.dh2); goto ok;
14892 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
14893 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14894 ovl.fmt.RXY.dl2,
14895 ovl.fmt.RXY.dh2); goto ok;
14896 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
14897 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14898 ovl.fmt.RXY.dl2,
14899 ovl.fmt.RXY.dh2); goto ok;
14900 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
14901 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14902 ovl.fmt.RXY.dl2,
14903 ovl.fmt.RXY.dh2); goto ok;
14904 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
14905 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14906 ovl.fmt.RXY.dl2,
14907 ovl.fmt.RXY.dh2); goto ok;
14908 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
14909 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14910 ovl.fmt.RXY.dl2,
14911 ovl.fmt.RXY.dh2); goto ok;
14912 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
14913 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14914 ovl.fmt.RXY.dl2,
14915 ovl.fmt.RXY.dh2); goto ok;
14916 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
14917 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14918 ovl.fmt.RXY.dl2,
14919 ovl.fmt.RXY.dh2); goto ok;
14920 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
14921 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14922 ovl.fmt.RXY.dl2,
14923 ovl.fmt.RXY.dh2); goto ok;
14924 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
14925 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14926 ovl.fmt.RXY.dl2,
14927 ovl.fmt.RXY.dh2); goto ok;
14928 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
14929 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14930 ovl.fmt.RXY.dl2,
14931 ovl.fmt.RXY.dh2); goto ok;
14932 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
14933 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14934 ovl.fmt.RXY.dl2,
14935 ovl.fmt.RXY.dh2); goto ok;
14936 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
14937 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14938 ovl.fmt.RXY.dl2,
14939 ovl.fmt.RXY.dh2); goto ok;
14940 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
14941 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14942 ovl.fmt.RXY.dl2,
14943 ovl.fmt.RXY.dh2); goto ok;
14944 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
14945 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14946 ovl.fmt.RXY.dl2,
14947 ovl.fmt.RXY.dh2); goto ok;
14948 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
14949 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14950 ovl.fmt.RXY.dl2,
14951 ovl.fmt.RXY.dh2); goto ok;
14952 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
14953 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14954 ovl.fmt.RXY.dl2,
14955 ovl.fmt.RXY.dh2); goto ok;
14956 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
14957 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14958 ovl.fmt.RXY.dl2,
14959 ovl.fmt.RXY.dh2); goto ok;
14960 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
14961 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14962 ovl.fmt.RXY.dl2,
14963 ovl.fmt.RXY.dh2); goto ok;
14964 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
14965 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14966 ovl.fmt.RXY.dl2,
14967 ovl.fmt.RXY.dh2); goto ok;
14968 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
14969 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14970 ovl.fmt.RXY.dl2,
14971 ovl.fmt.RXY.dh2); goto ok;
14972 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, 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 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, 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 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, 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 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, 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 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, 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 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, 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 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, 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 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, 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;
florian2289cd42012-12-05 04:23:42 +000015004 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015005 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15006 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15007 ovl.fmt.RXY.dl2,
15008 ovl.fmt.RXY.dh2); goto ok;
15009 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15010 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15011 ovl.fmt.RXY.dl2,
15012 ovl.fmt.RXY.dh2); goto ok;
15013 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15014 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15015 ovl.fmt.RXY.dl2,
15016 ovl.fmt.RXY.dh2); goto ok;
15017 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15018 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15019 ovl.fmt.RXY.dl2,
15020 ovl.fmt.RXY.dh2); goto ok;
15021 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15022 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15023 ovl.fmt.RXY.dl2,
15024 ovl.fmt.RXY.dh2); goto ok;
15025 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15026 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15027 ovl.fmt.RXY.dl2,
15028 ovl.fmt.RXY.dh2); goto ok;
15029 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15030 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15031 ovl.fmt.RXY.dl2,
15032 ovl.fmt.RXY.dh2); goto ok;
15033 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15034 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15035 ovl.fmt.RXY.dl2,
15036 ovl.fmt.RXY.dh2); goto ok;
15037 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15038 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15039 ovl.fmt.RXY.dl2,
15040 ovl.fmt.RXY.dh2); goto ok;
15041 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15042 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15043 ovl.fmt.RXY.dl2,
15044 ovl.fmt.RXY.dh2); goto ok;
15045 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15046 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15047 ovl.fmt.RXY.dl2,
15048 ovl.fmt.RXY.dh2); goto ok;
15049 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15050 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15051 ovl.fmt.RXY.dl2,
15052 ovl.fmt.RXY.dh2); goto ok;
15053 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15054 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15055 ovl.fmt.RXY.dl2,
15056 ovl.fmt.RXY.dh2); goto ok;
15057 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15058 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15059 ovl.fmt.RXY.dl2,
15060 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015061 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15062 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15063 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015064 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, 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 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, 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 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15073 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15074 ovl.fmt.RXY.dl2,
15075 ovl.fmt.RXY.dh2); goto ok;
15076 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15077 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15078 ovl.fmt.RXY.dl2,
15079 ovl.fmt.RXY.dh2); goto ok;
15080 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15081 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15082 ovl.fmt.RXY.dl2,
15083 ovl.fmt.RXY.dh2); goto ok;
15084 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15085 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15086 ovl.fmt.RXY.dl2,
15087 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015088 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015089 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15090 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15091 ovl.fmt.RXY.dl2,
15092 ovl.fmt.RXY.dh2); goto ok;
15093 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15094 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15095 ovl.fmt.RXY.dl2,
15096 ovl.fmt.RXY.dh2); goto ok;
15097 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15098 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15099 ovl.fmt.RXY.dl2,
15100 ovl.fmt.RXY.dh2); goto ok;
15101 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15102 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15103 ovl.fmt.RXY.dl2,
15104 ovl.fmt.RXY.dh2); goto ok;
15105 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, 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 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, 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;
15113 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15114 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15115 ovl.fmt.RSY.dl2,
15116 ovl.fmt.RSY.dh2); goto ok;
15117 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15118 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15119 ovl.fmt.RSY.dl2,
15120 ovl.fmt.RSY.dh2); goto ok;
15121 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15122 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15123 ovl.fmt.RSY.dl2,
15124 ovl.fmt.RSY.dh2); goto ok;
15125 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15126 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15127 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15128 ovl.fmt.RSY.dl2,
15129 ovl.fmt.RSY.dh2); goto ok;
15130 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15131 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15132 ovl.fmt.RSY.dl2,
15133 ovl.fmt.RSY.dh2); goto ok;
15134 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15135 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15136 ovl.fmt.RSY.dl2,
15137 ovl.fmt.RSY.dh2); goto ok;
15138 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15139 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15140 ovl.fmt.RSY.dl2,
15141 ovl.fmt.RSY.dh2); goto ok;
15142 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15143 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15144 ovl.fmt.RSY.dl2,
15145 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015146 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015147 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15148 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15149 ovl.fmt.RSY.dl2,
15150 ovl.fmt.RSY.dh2); goto ok;
15151 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15152 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15153 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15154 ovl.fmt.RSY.dl2,
15155 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015156 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015157 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15158 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15159 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15160 ovl.fmt.RSY.dh2); goto ok;
15161 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15162 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15163 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15164 ovl.fmt.RSY.dh2); goto ok;
15165 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15166 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15167 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15168 ovl.fmt.RSY.dl2,
15169 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015170 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15171 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15172 ovl.fmt.RSY.dl2,
15173 ovl.fmt.RSY.dh2); goto ok;
15174 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15175 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15176 ovl.fmt.RSY.dl2,
15177 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015178 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15179 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15180 ovl.fmt.RSY.dl2,
15181 ovl.fmt.RSY.dh2); goto ok;
15182 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15183 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15184 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15185 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015186 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15187 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15188 ovl.fmt.RSY.dl2,
15189 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015190 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15191 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15192 ovl.fmt.SIY.dh1); goto ok;
15193 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15194 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15195 ovl.fmt.SIY.dh1); goto ok;
15196 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15197 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15198 ovl.fmt.SIY.dh1); goto ok;
15199 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15200 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15201 ovl.fmt.SIY.dh1); goto ok;
15202 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15203 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15204 ovl.fmt.SIY.dh1); goto ok;
15205 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15206 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15207 ovl.fmt.SIY.dh1); goto ok;
15208 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15209 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15210 ovl.fmt.SIY.dh1); goto ok;
15211 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15212 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15213 ovl.fmt.SIY.dh1); goto ok;
15214 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15215 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15216 ovl.fmt.SIY.dh1); goto ok;
15217 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15218 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15219 ovl.fmt.SIY.dh1); goto ok;
15220 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15221 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15222 ovl.fmt.RSY.dl2,
15223 ovl.fmt.RSY.dh2); goto ok;
15224 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15225 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15226 ovl.fmt.RSY.dl2,
15227 ovl.fmt.RSY.dh2); goto ok;
15228 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15229 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15230 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, 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;
15234 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15235 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15236 ovl.fmt.RSY.dl2,
15237 ovl.fmt.RSY.dh2); goto ok;
15238 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15239 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15240 ovl.fmt.RSY.dl2,
15241 ovl.fmt.RSY.dh2); goto ok;
15242 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15243 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15244 ovl.fmt.RSY.dl2,
15245 ovl.fmt.RSY.dh2); goto ok;
15246 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15247 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15248 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15249 ovl.fmt.RSY.dh2); goto ok;
15250 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15251 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15252 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15253 ovl.fmt.RSY.dl2,
15254 ovl.fmt.RSY.dh2); goto ok;
15255 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15256 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15257 ovl.fmt.RSY.dl2,
15258 ovl.fmt.RSY.dh2); goto ok;
15259 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15260 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15261 ovl.fmt.RSY.dl2,
15262 ovl.fmt.RSY.dh2); goto ok;
15263 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15264 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15265 ovl.fmt.RSY.dl2,
15266 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015267 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15268 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15269 ovl.fmt.RSY.dl2,
15270 ovl.fmt.RSY.dh2,
15271 S390_XMNM_LOCG); goto ok;
15272 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15273 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15274 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15275 ovl.fmt.RSY.dh2,
15276 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015277 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15278 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15279 ovl.fmt.RSY.dl2,
15280 ovl.fmt.RSY.dh2); goto ok;
15281 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15282 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15283 ovl.fmt.RSY.dl2,
15284 ovl.fmt.RSY.dh2); goto ok;
15285 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15286 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15287 ovl.fmt.RSY.dl2,
15288 ovl.fmt.RSY.dh2); goto ok;
15289 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15290 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15291 ovl.fmt.RSY.dl2,
15292 ovl.fmt.RSY.dh2); goto ok;
15293 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15294 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15295 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15296 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015297 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15298 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15299 ovl.fmt.RSY.dl2,
15300 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15301 goto ok;
15302 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15303 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15304 ovl.fmt.RSY.dl2,
15305 ovl.fmt.RSY.dh2,
15306 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015307 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15308 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15309 ovl.fmt.RSY.dl2,
15310 ovl.fmt.RSY.dh2); goto ok;
15311 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15312 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15313 ovl.fmt.RSY.dl2,
15314 ovl.fmt.RSY.dh2); goto ok;
15315 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15316 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15317 ovl.fmt.RSY.dl2,
15318 ovl.fmt.RSY.dh2); goto ok;
15319 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15320 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15321 ovl.fmt.RSY.dl2,
15322 ovl.fmt.RSY.dh2); goto ok;
15323 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15324 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15325 ovl.fmt.RSY.dl2,
15326 ovl.fmt.RSY.dh2); goto ok;
15327 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15328 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15329 goto ok;
15330 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15331 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15332 goto ok;
15333 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15334 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15335 ovl.fmt.RIE_RRUUU.r1,
15336 ovl.fmt.RIE_RRUUU.r2,
15337 ovl.fmt.RIE_RRUUU.i3,
15338 ovl.fmt.RIE_RRUUU.i4,
15339 ovl.fmt.RIE_RRUUU.i5);
15340 goto ok;
15341 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15342 ovl.fmt.RIE_RRUUU.r1,
15343 ovl.fmt.RIE_RRUUU.r2,
15344 ovl.fmt.RIE_RRUUU.i3,
15345 ovl.fmt.RIE_RRUUU.i4,
15346 ovl.fmt.RIE_RRUUU.i5);
15347 goto ok;
15348 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15349 ovl.fmt.RIE_RRUUU.r1,
15350 ovl.fmt.RIE_RRUUU.r2,
15351 ovl.fmt.RIE_RRUUU.i3,
15352 ovl.fmt.RIE_RRUUU.i4,
15353 ovl.fmt.RIE_RRUUU.i5);
15354 goto ok;
15355 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15356 ovl.fmt.RIE_RRUUU.r1,
15357 ovl.fmt.RIE_RRUUU.r2,
15358 ovl.fmt.RIE_RRUUU.i3,
15359 ovl.fmt.RIE_RRUUU.i4,
15360 ovl.fmt.RIE_RRUUU.i5);
15361 goto ok;
florian2289cd42012-12-05 04:23:42 +000015362 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015363 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15364 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15365 ovl.fmt.RIE_RRPU.r1,
15366 ovl.fmt.RIE_RRPU.r2,
15367 ovl.fmt.RIE_RRPU.i4,
15368 ovl.fmt.RIE_RRPU.m3); goto ok;
15369 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15370 ovl.fmt.RIE_RRPU.r1,
15371 ovl.fmt.RIE_RRPU.r2,
15372 ovl.fmt.RIE_RRPU.i4,
15373 ovl.fmt.RIE_RRPU.m3); goto ok;
15374 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15375 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15376 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15377 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15378 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15379 ovl.fmt.RIE_RRPU.r1,
15380 ovl.fmt.RIE_RRPU.r2,
15381 ovl.fmt.RIE_RRPU.i4,
15382 ovl.fmt.RIE_RRPU.m3); goto ok;
15383 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15384 ovl.fmt.RIE_RRPU.r1,
15385 ovl.fmt.RIE_RRPU.r2,
15386 ovl.fmt.RIE_RRPU.i4,
15387 ovl.fmt.RIE_RRPU.m3); goto ok;
15388 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15389 ovl.fmt.RIEv3.r1,
15390 ovl.fmt.RIEv3.m3,
15391 ovl.fmt.RIEv3.i4,
15392 ovl.fmt.RIEv3.i2); goto ok;
15393 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15394 ovl.fmt.RIEv3.r1,
15395 ovl.fmt.RIEv3.m3,
15396 ovl.fmt.RIEv3.i4,
15397 ovl.fmt.RIEv3.i2); goto ok;
15398 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15399 ovl.fmt.RIEv3.r1,
15400 ovl.fmt.RIEv3.m3,
15401 ovl.fmt.RIEv3.i4,
15402 ovl.fmt.RIEv3.i2); goto ok;
15403 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15404 ovl.fmt.RIEv3.r1,
15405 ovl.fmt.RIEv3.m3,
15406 ovl.fmt.RIEv3.i4,
15407 ovl.fmt.RIEv3.i2); goto ok;
15408 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15409 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15410 goto ok;
15411 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15412 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15413 ovl.fmt.RIE.i2); goto ok;
15414 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15415 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15416 ovl.fmt.RIE.i2); goto ok;
15417 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15418 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15419 ovl.fmt.RIE.i2); goto ok;
15420 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15421 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15422 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15423 goto ok;
15424 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15425 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15426 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15427 goto ok;
15428 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15429 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15430 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15431 goto ok;
15432 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15433 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15434 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15435 goto ok;
15436 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15437 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15438 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15439 ovl.fmt.RIS.i2); goto ok;
15440 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15441 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15442 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15443 ovl.fmt.RIS.i2); goto ok;
15444 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15445 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15446 ovl.fmt.RIS.d4,
15447 ovl.fmt.RIS.i2); goto ok;
15448 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15449 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15450 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15451 ovl.fmt.RIS.i2); goto ok;
15452 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15453 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15454 ovl.fmt.RXE.d2); goto ok;
15455 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15456 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15457 ovl.fmt.RXE.d2); goto ok;
15458 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15459 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15460 ovl.fmt.RXE.d2); goto ok;
15461 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15462 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15463 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15464 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15465 ovl.fmt.RXE.d2); goto ok;
15466 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15467 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15468 ovl.fmt.RXE.d2); goto ok;
15469 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
15470 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15471 ovl.fmt.RXE.d2); goto ok;
15472 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
15473 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
15474 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15475 ovl.fmt.RXE.d2); goto ok;
15476 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
15477 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15478 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15479 ovl.fmt.RXF.r1); goto ok;
15480 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
15481 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15482 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15483 ovl.fmt.RXF.r1); goto ok;
15484 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
15485 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15486 ovl.fmt.RXE.d2); goto ok;
15487 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
15488 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15489 ovl.fmt.RXE.d2); goto ok;
15490 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
15491 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15492 ovl.fmt.RXE.d2); goto ok;
15493 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
15494 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15495 ovl.fmt.RXE.d2); goto ok;
15496 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
15497 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15498 ovl.fmt.RXE.d2); goto ok;
15499 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
15500 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15501 ovl.fmt.RXE.d2); goto ok;
15502 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
15503 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
15504 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15505 ovl.fmt.RXE.d2); goto ok;
15506 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
15507 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15508 ovl.fmt.RXE.d2); goto ok;
15509 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
15510 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15511 ovl.fmt.RXE.d2); goto ok;
15512 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
15513 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15514 ovl.fmt.RXE.d2); goto ok;
15515 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
15516 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15517 ovl.fmt.RXE.d2); goto ok;
15518 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
15519 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15520 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15521 ovl.fmt.RXF.r1); goto ok;
15522 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
15523 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15524 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15525 ovl.fmt.RXF.r1); goto ok;
15526 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
15527 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
15528 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
15529 case 0xed000000002eULL: /* MAE */ goto unimplemented;
15530 case 0xed000000002fULL: /* MSE */ goto unimplemented;
15531 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
15532 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
15533 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
15534 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
15535 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
15536 case 0xed000000003aULL: /* MAY */ goto unimplemented;
15537 case 0xed000000003bULL: /* MY */ goto unimplemented;
15538 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
15539 case 0xed000000003dULL: /* MYH */ goto unimplemented;
15540 case 0xed000000003eULL: /* MAD */ goto unimplemented;
15541 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000015542 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
15543 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15544 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15545 ovl.fmt.RXF.r1); goto ok;
15546 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
15547 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15548 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15549 ovl.fmt.RXF.r1); goto ok;
15550 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
15551 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15552 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15553 ovl.fmt.RXF.r1); goto ok;
15554 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
15555 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15556 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15557 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000015558 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
15559 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15560 ovl.fmt.RXE.d2); goto ok;
15561 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
15562 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15563 ovl.fmt.RXE.d2); goto ok;
15564 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
15565 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15566 ovl.fmt.RXE.d2); goto ok;
15567 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
15568 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15569 ovl.fmt.RXE.d2); goto ok;
15570 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
15571 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15572 ovl.fmt.RXE.d2); goto ok;
15573 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
15574 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15575 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015576 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
15577 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15578 ovl.fmt.RXY.dl2,
15579 ovl.fmt.RXY.dh2); goto ok;
15580 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
15581 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15582 ovl.fmt.RXY.dl2,
15583 ovl.fmt.RXY.dh2); goto ok;
15584 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
15585 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15586 ovl.fmt.RXY.dl2,
15587 ovl.fmt.RXY.dh2); goto ok;
15588 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
15589 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15590 ovl.fmt.RXY.dl2,
15591 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015592 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
15593 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
15594 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
15595 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015596 }
15597
15598 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
15599 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
15600 ovl.fmt.RIL.i2); goto ok;
15601 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
15602 ovl.fmt.RIL.i2); goto ok;
15603 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
15604 ovl.fmt.RIL.i2); goto ok;
15605 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
15606 ovl.fmt.RIL.i2); goto ok;
15607 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
15608 ovl.fmt.RIL.i2); goto ok;
15609 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
15610 ovl.fmt.RIL.i2); goto ok;
15611 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
15612 ovl.fmt.RIL.i2); goto ok;
15613 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
15614 ovl.fmt.RIL.i2); goto ok;
15615 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
15616 ovl.fmt.RIL.i2); goto ok;
15617 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
15618 ovl.fmt.RIL.i2); goto ok;
15619 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
15620 ovl.fmt.RIL.i2); goto ok;
15621 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
15622 ovl.fmt.RIL.i2); goto ok;
15623 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
15624 ovl.fmt.RIL.i2); goto ok;
15625 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
15626 ovl.fmt.RIL.i2); goto ok;
15627 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
15628 ovl.fmt.RIL.i2); goto ok;
15629 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
15630 ovl.fmt.RIL.i2); goto ok;
15631 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
15632 ovl.fmt.RIL.i2); goto ok;
15633 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
15634 ovl.fmt.RIL.i2); goto ok;
15635 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
15636 ovl.fmt.RIL.i2); goto ok;
15637 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
15638 ovl.fmt.RIL.i2); goto ok;
15639 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
15640 ovl.fmt.RIL.i2); goto ok;
15641 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
15642 ovl.fmt.RIL.i2); goto ok;
15643 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
15644 ovl.fmt.RIL.i2); goto ok;
15645 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
15646 ovl.fmt.RIL.i2); goto ok;
15647 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
15648 ovl.fmt.RIL.i2); goto ok;
15649 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
15650 ovl.fmt.RIL.i2); goto ok;
15651 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
15652 ovl.fmt.RIL.i2); goto ok;
15653 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
15654 ovl.fmt.RIL.i2); goto ok;
15655 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
15656 ovl.fmt.RIL.i2); goto ok;
15657 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
15658 ovl.fmt.RIL.i2); goto ok;
15659 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
15660 ovl.fmt.RIL.i2); goto ok;
15661 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
15662 ovl.fmt.RIL.i2); goto ok;
15663 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
15664 ovl.fmt.RIL.i2); goto ok;
15665 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
15666 ovl.fmt.RIL.i2); goto ok;
15667 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
15668 ovl.fmt.RIL.i2); goto ok;
15669 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
15670 ovl.fmt.RIL.i2); goto ok;
15671 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
15672 ovl.fmt.RIL.i2); goto ok;
15673 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
15674 ovl.fmt.RIL.i2); goto ok;
15675 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
15676 ovl.fmt.RIL.i2); goto ok;
15677 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
15678 ovl.fmt.RIL.i2); goto ok;
15679 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
15680 ovl.fmt.RIL.i2); goto ok;
15681 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
15682 ovl.fmt.RIL.i2); goto ok;
15683 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
15684 ovl.fmt.RIL.i2); goto ok;
15685 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
15686 ovl.fmt.RIL.i2); goto ok;
15687 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
15688 ovl.fmt.RIL.i2); goto ok;
15689 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
15690 ovl.fmt.RIL.i2); goto ok;
15691 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
15692 ovl.fmt.RIL.i2); goto ok;
15693 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
15694 ovl.fmt.RIL.i2); goto ok;
15695 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
15696 ovl.fmt.RIL.i2); goto ok;
15697 case 0xc800ULL: /* MVCOS */ goto unimplemented;
15698 case 0xc801ULL: /* ECTG */ goto unimplemented;
15699 case 0xc802ULL: /* CSST */ goto unimplemented;
15700 case 0xc804ULL: /* LPD */ goto unimplemented;
15701 case 0xc805ULL: /* LPDG */ goto unimplemented;
15702 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
15703 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
15704 ovl.fmt.RIL.i2); goto ok;
15705 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
15706 ovl.fmt.RIL.i2); goto ok;
15707 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
15708 ovl.fmt.RIL.i2); goto ok;
15709 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
15710 ovl.fmt.RIL.i2); goto ok;
15711 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
15712 ovl.fmt.RIL.i2); goto ok;
15713 }
15714
15715 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000015716 case 0xc5ULL: /* BPRP */ goto unimplemented;
15717 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015718 case 0xd0ULL: /* TRTR */ goto unimplemented;
15719 case 0xd1ULL: /* MVN */ goto unimplemented;
15720 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
15721 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15722 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15723 case 0xd3ULL: /* MVZ */ goto unimplemented;
15724 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
15725 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15726 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15727 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
15728 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15729 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15730 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
15731 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15732 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000015733 case 0xd7ULL:
15734 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
15735 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
15736 else
15737 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
15738 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15739 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
15740 goto ok;
sewardj2019a972011-03-07 16:04:07 +000015741 case 0xd9ULL: /* MVCK */ goto unimplemented;
15742 case 0xdaULL: /* MVCP */ goto unimplemented;
15743 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015744 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
15745 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15746 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015747 case 0xddULL: /* TRT */ goto unimplemented;
15748 case 0xdeULL: /* ED */ goto unimplemented;
15749 case 0xdfULL: /* EDMK */ goto unimplemented;
15750 case 0xe1ULL: /* PKU */ goto unimplemented;
15751 case 0xe2ULL: /* UNPKU */ goto unimplemented;
15752 case 0xe8ULL: /* MVCIN */ goto unimplemented;
15753 case 0xe9ULL: /* PKA */ goto unimplemented;
15754 case 0xeaULL: /* UNPKA */ goto unimplemented;
15755 case 0xeeULL: /* PLO */ goto unimplemented;
15756 case 0xefULL: /* LMD */ goto unimplemented;
15757 case 0xf0ULL: /* SRP */ goto unimplemented;
15758 case 0xf1ULL: /* MVO */ goto unimplemented;
15759 case 0xf2ULL: /* PACK */ goto unimplemented;
15760 case 0xf3ULL: /* UNPK */ goto unimplemented;
15761 case 0xf8ULL: /* ZAP */ goto unimplemented;
15762 case 0xf9ULL: /* CP */ goto unimplemented;
15763 case 0xfaULL: /* AP */ goto unimplemented;
15764 case 0xfbULL: /* SP */ goto unimplemented;
15765 case 0xfcULL: /* MP */ goto unimplemented;
15766 case 0xfdULL: /* DP */ goto unimplemented;
15767 }
15768
15769 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
15770 case 0xe500ULL: /* LASP */ goto unimplemented;
15771 case 0xe501ULL: /* TPROT */ goto unimplemented;
15772 case 0xe502ULL: /* STRAG */ goto unimplemented;
15773 case 0xe50eULL: /* MVCSK */ goto unimplemented;
15774 case 0xe50fULL: /* MVCDK */ goto unimplemented;
15775 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
15776 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15777 goto ok;
15778 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
15779 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15780 goto ok;
15781 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
15782 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15783 goto ok;
15784 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
15785 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15786 goto ok;
15787 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
15788 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15789 goto ok;
15790 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
15791 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15792 goto ok;
15793 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
15794 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15795 goto ok;
15796 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
15797 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15798 goto ok;
15799 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
15800 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15801 goto ok;
florian2289cd42012-12-05 04:23:42 +000015802 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
15803 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015804 }
15805
15806 return S390_DECODE_UNKNOWN_INSN;
15807
15808ok:
15809 return S390_DECODE_OK;
15810
15811unimplemented:
15812 return S390_DECODE_UNIMPLEMENTED_INSN;
15813}
15814
15815/* Handle "special" instructions. */
15816static s390_decode_t
15817s390_decode_special_and_irgen(UChar *bytes)
15818{
15819 s390_decode_t status = S390_DECODE_OK;
15820
15821 /* Got a "Special" instruction preamble. Which one is it? */
15822 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
15823 s390_irgen_client_request();
15824 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
15825 s390_irgen_guest_NRADDR();
15826 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
15827 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000015828 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
15829 vex_inject_ir(irsb, Iend_BE);
15830
15831 /* Invalidate the current insn. The reason is that the IRop we're
15832 injecting here can change. In which case the translation has to
15833 be redone. For ease of handling, we simply invalidate all the
15834 time. */
15835 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
15836 mkU64(guest_IA_curr_instr)));
15837 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
15838 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
15839 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
15840 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
15841
15842 put_IA(mkaddr_expr(guest_IA_next_instr));
15843 dis_res->whatNext = Dis_StopHere;
15844 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000015845 } else {
15846 /* We don't know what it is. */
15847 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
15848 }
15849
15850 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15851
15852 return status;
15853}
15854
15855
15856/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000015857static UInt
sewardj2019a972011-03-07 16:04:07 +000015858s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
15859{
15860 s390_decode_t status;
15861
15862 dis_res = dres;
15863
15864 /* Spot the 8-byte preamble: 18ff lr r15,r15
15865 1811 lr r1,r1
15866 1822 lr r2,r2
15867 1833 lr r3,r3 */
15868 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
15869 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
15870 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
15871
15872 /* Handle special instruction that follows that preamble. */
15873 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000015874
15875 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15876 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15877
15878 status =
15879 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000015880 } else {
15881 /* Handle normal instructions. */
15882 switch (insn_length) {
15883 case 2:
15884 status = s390_decode_2byte_and_irgen(bytes);
15885 break;
15886
15887 case 4:
15888 status = s390_decode_4byte_and_irgen(bytes);
15889 break;
15890
15891 case 6:
15892 status = s390_decode_6byte_and_irgen(bytes);
15893 break;
15894
15895 default:
15896 status = S390_DECODE_ERROR;
15897 break;
15898 }
15899 }
florian5fcbba22011-07-27 20:40:22 +000015900 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000015901 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
15902 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000015903 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000015904 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000015905 }
15906
15907 if (status == S390_DECODE_OK) return insn_length; /* OK */
15908
15909 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000015910 if (sigill_diag) {
15911 vex_printf("vex s390->IR: ");
15912 switch (status) {
15913 case S390_DECODE_UNKNOWN_INSN:
15914 vex_printf("unknown insn: ");
15915 break;
sewardj2019a972011-03-07 16:04:07 +000015916
sewardj442e51a2012-12-06 18:08:04 +000015917 case S390_DECODE_UNIMPLEMENTED_INSN:
15918 vex_printf("unimplemented insn: ");
15919 break;
sewardj2019a972011-03-07 16:04:07 +000015920
sewardj442e51a2012-12-06 18:08:04 +000015921 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
15922 vex_printf("unimplemented special insn: ");
15923 break;
sewardj2019a972011-03-07 16:04:07 +000015924
sewardj442e51a2012-12-06 18:08:04 +000015925 default:
15926 case S390_DECODE_ERROR:
15927 vex_printf("decoding error: ");
15928 break;
15929 }
15930
15931 vex_printf("%02x%02x", bytes[0], bytes[1]);
15932 if (insn_length > 2) {
15933 vex_printf(" %02x%02x", bytes[2], bytes[3]);
15934 }
15935 if (insn_length > 4) {
15936 vex_printf(" %02x%02x", bytes[4], bytes[5]);
15937 }
15938 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000015939 }
15940
sewardj2019a972011-03-07 16:04:07 +000015941 return 0; /* Failed */
15942}
15943
15944
sewardj2019a972011-03-07 16:04:07 +000015945/* Disassemble a single instruction INSN into IR. */
15946static DisResult
florian420c5012011-07-22 02:12:28 +000015947disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000015948{
15949 UChar byte;
15950 UInt insn_length;
15951 DisResult dres;
15952
15953 /* ---------------------------------------------------- */
15954 /* --- Compute instruction length -- */
15955 /* ---------------------------------------------------- */
15956
15957 /* Get the first byte of the insn. */
15958 byte = insn[0];
15959
15960 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
15961 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
15962 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
15963
15964 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15965
15966 /* ---------------------------------------------------- */
15967 /* --- Initialise the DisResult data -- */
15968 /* ---------------------------------------------------- */
15969 dres.whatNext = Dis_Continue;
15970 dres.len = insn_length;
15971 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000015972 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000015973
floriana99f20e2011-07-17 14:16:41 +000015974 /* fixs390: consider chasing of conditional jumps */
15975
sewardj2019a972011-03-07 16:04:07 +000015976 /* Normal and special instruction handling starts here. */
15977 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
15978 /* All decode failures end up here. The decoder has already issued an
15979 error message.
15980 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000015981 not been executed, and (is currently) the next to be executed.
15982 The insn address in the guest state needs to be set to
15983 guest_IA_curr_instr, otherwise the complaint will report an
15984 incorrect address. */
15985 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000015986
florian8844a632012-04-13 04:04:06 +000015987 dres.whatNext = Dis_StopHere;
15988 dres.jk_StopHere = Ijk_NoDecode;
15989 dres.continueAt = 0;
15990 dres.len = 0;
15991 } else {
15992 /* Decode success */
15993 switch (dres.whatNext) {
15994 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015995 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015996 break;
15997 case Dis_ResteerU:
15998 case Dis_ResteerC:
15999 put_IA(mkaddr_expr(dres.continueAt));
16000 break;
16001 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016002 if (dres.jk_StopHere == Ijk_EmWarn ||
16003 dres.jk_StopHere == Ijk_EmFail) {
16004 /* We assume here, that emulation warnings are not given for
16005 insns that transfer control. There is no good way to
16006 do that. */
16007 put_IA(mkaddr_expr(guest_IA_next_instr));
16008 }
florian8844a632012-04-13 04:04:06 +000016009 break;
16010 default:
16011 vassert(0);
16012 }
sewardj2019a972011-03-07 16:04:07 +000016013 }
16014
16015 return dres;
16016}
16017
16018
16019/*------------------------------------------------------------*/
16020/*--- Top-level fn ---*/
16021/*------------------------------------------------------------*/
16022
16023/* Disassemble a single instruction into IR. The instruction
16024 is located in host memory at &guest_code[delta]. */
16025
16026DisResult
16027disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000016028 Bool (*resteerOkFn)(void *, Addr64),
16029 Bool resteerCisOk,
16030 void *callback_opaque,
16031 UChar *guest_code,
16032 Long delta,
16033 Addr64 guest_IP,
16034 VexArch guest_arch,
16035 VexArchInfo *archinfo,
16036 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000016037 Bool host_bigendian,
16038 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016039{
16040 vassert(guest_arch == VexArchS390X);
16041
16042 /* The instruction decoder requires a big-endian machine. */
16043 vassert(host_bigendian == True);
16044
16045 /* Set globals (see top of this file) */
16046 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016047 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016048 resteer_fn = resteerOkFn;
16049 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016050 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016051
florian420c5012011-07-22 02:12:28 +000016052 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016053}
16054
16055/*---------------------------------------------------------------*/
16056/*--- end guest_s390_toIR.c ---*/
16057/*---------------------------------------------------------------*/