blob: 5e086587a2c19a39024295b24825a73a6a87ad81 [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
243 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
635 op = mkU64(opc);
636 dep1 = mkexpr(d1);
637 dep2 = mkU64(0);
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, dep1, dep2, ndep);
641}
642
643
644/* Write a floating point value and an integer into the flags thunk. The
645 integer value is zero-extended first. */
646static void
647s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
648{
649 IRExpr *op, *dep1, *dep2, *ndep;
650
651 op = mkU64(opc);
652 dep1 = mkexpr(d1);
653 dep2 = s390_cc_widen(d2, False);
654 ndep = mkU64(0);
655
656 s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a 128-bit floating point value into the flags thunk. This is
661 done by splitting the value into two 64-bits values. */
662static void
663s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
664{
665 IRExpr *op, *hi, *lo, *ndep;
666
667 op = mkU64(opc);
668 hi = unop(Iop_F128HItoF64, mkexpr(d1));
669 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, hi, lo, ndep);
673}
674
675
676/* Write a 128-bit floating point value and an integer into the flags thunk.
677 The integer value is zero-extended first. */
678static void
679s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
680{
681 IRExpr *op, *hi, *lo, *lox, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
686 ndep = s390_cc_widen(nd, False);
687
688 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
689
690 s390_cc_thunk_fill(op, hi, lox, ndep);
691}
692
693
floriane38f6412012-12-21 17:32:12 +0000694/* Write a 128-bit decimal floating point value into the flags thunk.
695 This is done by splitting the value into two 64-bits values. */
696static void
697s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
698{
699 IRExpr *op, *hi, *lo, *ndep;
700
701 op = mkU64(opc);
702 hi = unop(Iop_D128HItoD64, mkexpr(d1));
703 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
704 ndep = mkU64(0);
705
706 s390_cc_thunk_fill(op, hi, lo, ndep);
707}
708
709
floriance9e3db2012-12-27 20:14:03 +0000710/* Write a 128-bit decimal floating point value and an integer into the flags
711 thunk. The integer value is zero-extended first. */
712static void
713s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
714{
715 IRExpr *op, *hi, *lo, *lox, *ndep;
716
717 op = mkU64(opc);
718 hi = unop(Iop_D128HItoD64, mkexpr(d1));
719 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
720 ndep = s390_cc_widen(nd, False);
721
722 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
723
724 s390_cc_thunk_fill(op, hi, lox, ndep);
725}
726
727
sewardj2019a972011-03-07 16:04:07 +0000728static void
729s390_cc_set(UInt val)
730{
731 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
732 mkU64(val), mkU64(0), mkU64(0));
733}
734
735/* Build IR to calculate the condition code from flags thunk.
736 Returns an expression of type Ity_I32 */
737static IRExpr *
738s390_call_calculate_cc(void)
739{
740 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
741
florian428dfdd2012-03-27 03:09:49 +0000742 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
743 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
744 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
745 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000746
747 args = mkIRExprVec_4(op, dep1, dep2, ndep);
748 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
749 "s390_calculate_cc", &s390_calculate_cc, args);
750
751 /* Exclude OP and NDEP from definedness checking. We're only
752 interested in DEP1 and DEP2. */
753 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
754
755 return call;
756}
757
758/* Build IR to calculate the internal condition code for a "compare and branch"
759 insn. Returns an expression of type Ity_I32 */
760static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000761s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000762{
florianff9613f2012-05-12 15:26:44 +0000763 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000764
florianff9613f2012-05-12 15:26:44 +0000765 switch (opc) {
766 case S390_CC_OP_SIGNED_COMPARE:
767 dep1 = s390_cc_widen(op1, True);
768 dep2 = s390_cc_widen(op2, True);
769 break;
770
771 case S390_CC_OP_UNSIGNED_COMPARE:
772 dep1 = s390_cc_widen(op1, False);
773 dep2 = s390_cc_widen(op2, False);
774 break;
775
776 default:
777 vpanic("s390_call_calculate_icc");
778 }
779
780 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000781 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000782
florianff9613f2012-05-12 15:26:44 +0000783 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000784 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000785 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000786
florianff9613f2012-05-12 15:26:44 +0000787 /* Exclude the requested condition, OP and NDEP from definedness
788 checking. We're only interested in DEP1 and DEP2. */
789 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000790
791 return call;
792}
793
794/* Build IR to calculate the condition code from flags thunk.
795 Returns an expression of type Ity_I32 */
796static IRExpr *
797s390_call_calculate_cond(UInt m)
798{
799 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
800
801 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000802 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
803 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
804 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
805 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000806
807 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
808 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
809 "s390_calculate_cond", &s390_calculate_cond, args);
810
811 /* Exclude the requested condition, OP and NDEP from definedness
812 checking. We're only interested in DEP1 and DEP2. */
813 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
814
815 return call;
816}
817
818#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
819#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
820#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
821#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
822#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
823#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
824#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
825 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
826#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
827 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000828
829
sewardj2019a972011-03-07 16:04:07 +0000830
831
832/*------------------------------------------------------------*/
833/*--- Guest register access ---*/
834/*------------------------------------------------------------*/
835
836
837/*------------------------------------------------------------*/
838/*--- ar registers ---*/
839/*------------------------------------------------------------*/
840
841/* Return the guest state offset of a ar register. */
842static UInt
843ar_offset(UInt archreg)
844{
845 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000846 S390X_GUEST_OFFSET(guest_a0),
847 S390X_GUEST_OFFSET(guest_a1),
848 S390X_GUEST_OFFSET(guest_a2),
849 S390X_GUEST_OFFSET(guest_a3),
850 S390X_GUEST_OFFSET(guest_a4),
851 S390X_GUEST_OFFSET(guest_a5),
852 S390X_GUEST_OFFSET(guest_a6),
853 S390X_GUEST_OFFSET(guest_a7),
854 S390X_GUEST_OFFSET(guest_a8),
855 S390X_GUEST_OFFSET(guest_a9),
856 S390X_GUEST_OFFSET(guest_a10),
857 S390X_GUEST_OFFSET(guest_a11),
858 S390X_GUEST_OFFSET(guest_a12),
859 S390X_GUEST_OFFSET(guest_a13),
860 S390X_GUEST_OFFSET(guest_a14),
861 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000862 };
863
864 vassert(archreg < 16);
865
866 return offset[archreg];
867}
868
869
870/* Return the guest state offset of word #0 of a ar register. */
871static __inline__ UInt
872ar_w0_offset(UInt archreg)
873{
874 return ar_offset(archreg) + 0;
875}
876
877/* Write word #0 of a ar to the guest state. */
878static __inline__ void
879put_ar_w0(UInt archreg, IRExpr *expr)
880{
881 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
882
883 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
884}
885
886/* Read word #0 of a ar register. */
887static __inline__ IRExpr *
888get_ar_w0(UInt archreg)
889{
890 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
891}
892
893
894/*------------------------------------------------------------*/
895/*--- fpr registers ---*/
896/*------------------------------------------------------------*/
897
898/* Return the guest state offset of a fpr register. */
899static UInt
900fpr_offset(UInt archreg)
901{
902 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000903 S390X_GUEST_OFFSET(guest_f0),
904 S390X_GUEST_OFFSET(guest_f1),
905 S390X_GUEST_OFFSET(guest_f2),
906 S390X_GUEST_OFFSET(guest_f3),
907 S390X_GUEST_OFFSET(guest_f4),
908 S390X_GUEST_OFFSET(guest_f5),
909 S390X_GUEST_OFFSET(guest_f6),
910 S390X_GUEST_OFFSET(guest_f7),
911 S390X_GUEST_OFFSET(guest_f8),
912 S390X_GUEST_OFFSET(guest_f9),
913 S390X_GUEST_OFFSET(guest_f10),
914 S390X_GUEST_OFFSET(guest_f11),
915 S390X_GUEST_OFFSET(guest_f12),
916 S390X_GUEST_OFFSET(guest_f13),
917 S390X_GUEST_OFFSET(guest_f14),
918 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000919 };
920
921 vassert(archreg < 16);
922
923 return offset[archreg];
924}
925
926
927/* Return the guest state offset of word #0 of a fpr register. */
928static __inline__ UInt
929fpr_w0_offset(UInt archreg)
930{
931 return fpr_offset(archreg) + 0;
932}
933
934/* Write word #0 of a fpr to the guest state. */
935static __inline__ void
936put_fpr_w0(UInt archreg, IRExpr *expr)
937{
938 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
939
940 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
941}
942
943/* Read word #0 of a fpr register. */
944static __inline__ IRExpr *
945get_fpr_w0(UInt archreg)
946{
947 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
948}
949
950/* Return the guest state offset of double word #0 of a fpr register. */
951static __inline__ UInt
952fpr_dw0_offset(UInt archreg)
953{
954 return fpr_offset(archreg) + 0;
955}
956
957/* Write double word #0 of a fpr to the guest state. */
958static __inline__ void
959put_fpr_dw0(UInt archreg, IRExpr *expr)
960{
961 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
962
963 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
964}
965
966/* Read double word #0 of a fpr register. */
967static __inline__ IRExpr *
968get_fpr_dw0(UInt archreg)
969{
970 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
971}
972
floriane38f6412012-12-21 17:32:12 +0000973/* Write word #0 of a dpr to the guest state. */
974static __inline__ void
975put_dpr_w0(UInt archreg, IRExpr *expr)
976{
977 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
978
979 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
980}
981
982/* Read word #0 of a dpr register. */
983static __inline__ IRExpr *
984get_dpr_w0(UInt archreg)
985{
986 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
987}
988
florian12390202012-11-10 22:34:14 +0000989/* Write double word #0 of a fpr containg DFP value to the guest state. */
990static __inline__ void
991put_dpr_dw0(UInt archreg, IRExpr *expr)
992{
993 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
994
995 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
996}
997
998/* Read double word #0 of a fpr register containing DFP value. */
999static __inline__ IRExpr *
1000get_dpr_dw0(UInt archreg)
1001{
1002 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1003}
sewardj2019a972011-03-07 16:04:07 +00001004
1005/*------------------------------------------------------------*/
1006/*--- gpr registers ---*/
1007/*------------------------------------------------------------*/
1008
1009/* Return the guest state offset of a gpr register. */
1010static UInt
1011gpr_offset(UInt archreg)
1012{
1013 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001014 S390X_GUEST_OFFSET(guest_r0),
1015 S390X_GUEST_OFFSET(guest_r1),
1016 S390X_GUEST_OFFSET(guest_r2),
1017 S390X_GUEST_OFFSET(guest_r3),
1018 S390X_GUEST_OFFSET(guest_r4),
1019 S390X_GUEST_OFFSET(guest_r5),
1020 S390X_GUEST_OFFSET(guest_r6),
1021 S390X_GUEST_OFFSET(guest_r7),
1022 S390X_GUEST_OFFSET(guest_r8),
1023 S390X_GUEST_OFFSET(guest_r9),
1024 S390X_GUEST_OFFSET(guest_r10),
1025 S390X_GUEST_OFFSET(guest_r11),
1026 S390X_GUEST_OFFSET(guest_r12),
1027 S390X_GUEST_OFFSET(guest_r13),
1028 S390X_GUEST_OFFSET(guest_r14),
1029 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001030 };
1031
1032 vassert(archreg < 16);
1033
1034 return offset[archreg];
1035}
1036
1037
1038/* Return the guest state offset of word #0 of a gpr register. */
1039static __inline__ UInt
1040gpr_w0_offset(UInt archreg)
1041{
1042 return gpr_offset(archreg) + 0;
1043}
1044
1045/* Write word #0 of a gpr to the guest state. */
1046static __inline__ void
1047put_gpr_w0(UInt archreg, IRExpr *expr)
1048{
1049 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1050
1051 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1052}
1053
1054/* Read word #0 of a gpr register. */
1055static __inline__ IRExpr *
1056get_gpr_w0(UInt archreg)
1057{
1058 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1059}
1060
1061/* Return the guest state offset of double word #0 of a gpr register. */
1062static __inline__ UInt
1063gpr_dw0_offset(UInt archreg)
1064{
1065 return gpr_offset(archreg) + 0;
1066}
1067
1068/* Write double word #0 of a gpr to the guest state. */
1069static __inline__ void
1070put_gpr_dw0(UInt archreg, IRExpr *expr)
1071{
1072 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1073
1074 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1075}
1076
1077/* Read double word #0 of a gpr register. */
1078static __inline__ IRExpr *
1079get_gpr_dw0(UInt archreg)
1080{
1081 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1082}
1083
1084/* Return the guest state offset of half word #1 of a gpr register. */
1085static __inline__ UInt
1086gpr_hw1_offset(UInt archreg)
1087{
1088 return gpr_offset(archreg) + 2;
1089}
1090
1091/* Write half word #1 of a gpr to the guest state. */
1092static __inline__ void
1093put_gpr_hw1(UInt archreg, IRExpr *expr)
1094{
1095 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1096
1097 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1098}
1099
1100/* Read half word #1 of a gpr register. */
1101static __inline__ IRExpr *
1102get_gpr_hw1(UInt archreg)
1103{
1104 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1105}
1106
1107/* Return the guest state offset of byte #6 of a gpr register. */
1108static __inline__ UInt
1109gpr_b6_offset(UInt archreg)
1110{
1111 return gpr_offset(archreg) + 6;
1112}
1113
1114/* Write byte #6 of a gpr to the guest state. */
1115static __inline__ void
1116put_gpr_b6(UInt archreg, IRExpr *expr)
1117{
1118 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1119
1120 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1121}
1122
1123/* Read byte #6 of a gpr register. */
1124static __inline__ IRExpr *
1125get_gpr_b6(UInt archreg)
1126{
1127 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1128}
1129
1130/* Return the guest state offset of byte #3 of a gpr register. */
1131static __inline__ UInt
1132gpr_b3_offset(UInt archreg)
1133{
1134 return gpr_offset(archreg) + 3;
1135}
1136
1137/* Write byte #3 of a gpr to the guest state. */
1138static __inline__ void
1139put_gpr_b3(UInt archreg, IRExpr *expr)
1140{
1141 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1142
1143 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1144}
1145
1146/* Read byte #3 of a gpr register. */
1147static __inline__ IRExpr *
1148get_gpr_b3(UInt archreg)
1149{
1150 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1151}
1152
1153/* Return the guest state offset of byte #0 of a gpr register. */
1154static __inline__ UInt
1155gpr_b0_offset(UInt archreg)
1156{
1157 return gpr_offset(archreg) + 0;
1158}
1159
1160/* Write byte #0 of a gpr to the guest state. */
1161static __inline__ void
1162put_gpr_b0(UInt archreg, IRExpr *expr)
1163{
1164 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1165
1166 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1167}
1168
1169/* Read byte #0 of a gpr register. */
1170static __inline__ IRExpr *
1171get_gpr_b0(UInt archreg)
1172{
1173 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1174}
1175
1176/* Return the guest state offset of word #1 of a gpr register. */
1177static __inline__ UInt
1178gpr_w1_offset(UInt archreg)
1179{
1180 return gpr_offset(archreg) + 4;
1181}
1182
1183/* Write word #1 of a gpr to the guest state. */
1184static __inline__ void
1185put_gpr_w1(UInt archreg, IRExpr *expr)
1186{
1187 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1188
1189 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1190}
1191
1192/* Read word #1 of a gpr register. */
1193static __inline__ IRExpr *
1194get_gpr_w1(UInt archreg)
1195{
1196 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1197}
1198
1199/* Return the guest state offset of half word #3 of a gpr register. */
1200static __inline__ UInt
1201gpr_hw3_offset(UInt archreg)
1202{
1203 return gpr_offset(archreg) + 6;
1204}
1205
1206/* Write half word #3 of a gpr to the guest state. */
1207static __inline__ void
1208put_gpr_hw3(UInt archreg, IRExpr *expr)
1209{
1210 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1211
1212 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1213}
1214
1215/* Read half word #3 of a gpr register. */
1216static __inline__ IRExpr *
1217get_gpr_hw3(UInt archreg)
1218{
1219 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1220}
1221
1222/* Return the guest state offset of byte #7 of a gpr register. */
1223static __inline__ UInt
1224gpr_b7_offset(UInt archreg)
1225{
1226 return gpr_offset(archreg) + 7;
1227}
1228
1229/* Write byte #7 of a gpr to the guest state. */
1230static __inline__ void
1231put_gpr_b7(UInt archreg, IRExpr *expr)
1232{
1233 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1234
1235 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1236}
1237
1238/* Read byte #7 of a gpr register. */
1239static __inline__ IRExpr *
1240get_gpr_b7(UInt archreg)
1241{
1242 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1243}
1244
1245/* Return the guest state offset of half word #0 of a gpr register. */
1246static __inline__ UInt
1247gpr_hw0_offset(UInt archreg)
1248{
1249 return gpr_offset(archreg) + 0;
1250}
1251
1252/* Write half word #0 of a gpr to the guest state. */
1253static __inline__ void
1254put_gpr_hw0(UInt archreg, IRExpr *expr)
1255{
1256 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1257
1258 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1259}
1260
1261/* Read half word #0 of a gpr register. */
1262static __inline__ IRExpr *
1263get_gpr_hw0(UInt archreg)
1264{
1265 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1266}
1267
1268/* Return the guest state offset of byte #4 of a gpr register. */
1269static __inline__ UInt
1270gpr_b4_offset(UInt archreg)
1271{
1272 return gpr_offset(archreg) + 4;
1273}
1274
1275/* Write byte #4 of a gpr to the guest state. */
1276static __inline__ void
1277put_gpr_b4(UInt archreg, IRExpr *expr)
1278{
1279 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1280
1281 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1282}
1283
1284/* Read byte #4 of a gpr register. */
1285static __inline__ IRExpr *
1286get_gpr_b4(UInt archreg)
1287{
1288 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1289}
1290
1291/* Return the guest state offset of byte #1 of a gpr register. */
1292static __inline__ UInt
1293gpr_b1_offset(UInt archreg)
1294{
1295 return gpr_offset(archreg) + 1;
1296}
1297
1298/* Write byte #1 of a gpr to the guest state. */
1299static __inline__ void
1300put_gpr_b1(UInt archreg, IRExpr *expr)
1301{
1302 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1303
1304 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1305}
1306
1307/* Read byte #1 of a gpr register. */
1308static __inline__ IRExpr *
1309get_gpr_b1(UInt archreg)
1310{
1311 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1312}
1313
1314/* Return the guest state offset of half word #2 of a gpr register. */
1315static __inline__ UInt
1316gpr_hw2_offset(UInt archreg)
1317{
1318 return gpr_offset(archreg) + 4;
1319}
1320
1321/* Write half word #2 of a gpr to the guest state. */
1322static __inline__ void
1323put_gpr_hw2(UInt archreg, IRExpr *expr)
1324{
1325 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1326
1327 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1328}
1329
1330/* Read half word #2 of a gpr register. */
1331static __inline__ IRExpr *
1332get_gpr_hw2(UInt archreg)
1333{
1334 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1335}
1336
1337/* Return the guest state offset of byte #5 of a gpr register. */
1338static __inline__ UInt
1339gpr_b5_offset(UInt archreg)
1340{
1341 return gpr_offset(archreg) + 5;
1342}
1343
1344/* Write byte #5 of a gpr to the guest state. */
1345static __inline__ void
1346put_gpr_b5(UInt archreg, IRExpr *expr)
1347{
1348 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1349
1350 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1351}
1352
1353/* Read byte #5 of a gpr register. */
1354static __inline__ IRExpr *
1355get_gpr_b5(UInt archreg)
1356{
1357 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1358}
1359
1360/* Return the guest state offset of byte #2 of a gpr register. */
1361static __inline__ UInt
1362gpr_b2_offset(UInt archreg)
1363{
1364 return gpr_offset(archreg) + 2;
1365}
1366
1367/* Write byte #2 of a gpr to the guest state. */
1368static __inline__ void
1369put_gpr_b2(UInt archreg, IRExpr *expr)
1370{
1371 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1372
1373 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1374}
1375
1376/* Read byte #2 of a gpr register. */
1377static __inline__ IRExpr *
1378get_gpr_b2(UInt archreg)
1379{
1380 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1381}
1382
1383/* Return the guest state offset of the counter register. */
1384static UInt
1385counter_offset(void)
1386{
floriane88b3c92011-07-05 02:48:39 +00001387 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001388}
1389
1390/* Return the guest state offset of double word #0 of the counter register. */
1391static __inline__ UInt
1392counter_dw0_offset(void)
1393{
1394 return counter_offset() + 0;
1395}
1396
1397/* Write double word #0 of the counter to the guest state. */
1398static __inline__ void
1399put_counter_dw0(IRExpr *expr)
1400{
1401 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1402
1403 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1404}
1405
1406/* Read double word #0 of the counter register. */
1407static __inline__ IRExpr *
1408get_counter_dw0(void)
1409{
1410 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1411}
1412
1413/* Return the guest state offset of word #0 of the counter register. */
1414static __inline__ UInt
1415counter_w0_offset(void)
1416{
1417 return counter_offset() + 0;
1418}
1419
1420/* Return the guest state offset of word #1 of the counter register. */
1421static __inline__ UInt
1422counter_w1_offset(void)
1423{
1424 return counter_offset() + 4;
1425}
1426
1427/* Write word #0 of the counter to the guest state. */
1428static __inline__ void
1429put_counter_w0(IRExpr *expr)
1430{
1431 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1432
1433 stmt(IRStmt_Put(counter_w0_offset(), expr));
1434}
1435
1436/* Read word #0 of the counter register. */
1437static __inline__ IRExpr *
1438get_counter_w0(void)
1439{
1440 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1441}
1442
1443/* Write word #1 of the counter to the guest state. */
1444static __inline__ void
1445put_counter_w1(IRExpr *expr)
1446{
1447 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1448
1449 stmt(IRStmt_Put(counter_w1_offset(), expr));
1450}
1451
1452/* Read word #1 of the counter register. */
1453static __inline__ IRExpr *
1454get_counter_w1(void)
1455{
1456 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1457}
1458
1459/* Return the guest state offset of the fpc register. */
1460static UInt
1461fpc_offset(void)
1462{
floriane88b3c92011-07-05 02:48:39 +00001463 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001464}
1465
1466/* Return the guest state offset of word #0 of the fpc register. */
1467static __inline__ UInt
1468fpc_w0_offset(void)
1469{
1470 return fpc_offset() + 0;
1471}
1472
1473/* Write word #0 of the fpc to the guest state. */
1474static __inline__ void
1475put_fpc_w0(IRExpr *expr)
1476{
1477 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1478
1479 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1480}
1481
1482/* Read word #0 of the fpc register. */
1483static __inline__ IRExpr *
1484get_fpc_w0(void)
1485{
1486 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1487}
1488
1489
1490/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001491/*--- Rounding modes ---*/
1492/*------------------------------------------------------------*/
1493
florian125e20d2012-10-07 15:42:37 +00001494/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001495 IRRoundingMode:
1496
1497 rounding mode | s390 | IR
1498 -------------------------
1499 to nearest | 00 | 00
1500 to zero | 01 | 11
1501 to +infinity | 10 | 10
1502 to -infinity | 11 | 01
1503
1504 So: IR = (4 - s390) & 3
1505*/
1506static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001507get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001508{
1509 IRTemp fpc_bits = newTemp(Ity_I32);
1510
1511 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1512 Prior to that bits [30:31] contained the bfp rounding mode with
1513 bit 29 being unused and having a value of 0. So we can always
1514 extract the least significant 3 bits. */
1515 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1516
1517 /* fixs390:
1518
1519
1520 if (! s390_host_has_fpext && rounding_mode > 3) {
1521 emulation warning @ runtime and
1522 set fpc to round nearest
1523 }
1524 */
1525
1526 /* For now silently adjust an unsupported rounding mode to "nearest" */
1527 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1528 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001529 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001530
1531 // rm_IR = (4 - rm_s390) & 3;
1532 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1533}
1534
1535/* Encode the s390 rounding mode as it appears in the m3 field of certain
1536 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1537 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1538 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1539 considers the default rounding mode (4.3.3). */
1540static IRTemp
1541encode_bfp_rounding_mode(UChar mode)
1542{
1543 IRExpr *rm;
1544
1545 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001546 case S390_BFP_ROUND_PER_FPC:
1547 rm = get_bfp_rounding_mode_from_fpc();
1548 break;
1549 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1550 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1551 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1552 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1553 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1554 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001555 default:
1556 vpanic("encode_bfp_rounding_mode");
1557 }
1558
1559 return mktemp(Ity_I32, rm);
1560}
1561
florianc8e4f562012-10-27 16:19:31 +00001562/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1563 IRRoundingMode:
1564
1565 rounding mode | s390 | IR
1566 ------------------------------------------------
1567 to nearest, ties to even | 000 | 000
1568 to zero | 001 | 011
1569 to +infinity | 010 | 010
1570 to -infinity | 011 | 001
1571 to nearest, ties away from 0 | 100 | 100
1572 to nearest, ties toward 0 | 101 | 111
1573 to away from 0 | 110 | 110
1574 to prepare for shorter precision | 111 | 101
1575
1576 So: IR = (s390 ^ ((s390 << 1) & 2))
1577*/
florianc8e4f562012-10-27 16:19:31 +00001578static IRExpr *
1579get_dfp_rounding_mode_from_fpc(void)
1580{
1581 IRTemp fpc_bits = newTemp(Ity_I32);
1582
1583 /* The dfp rounding mode is stored in bits [25:27].
1584 extract the bits at 25:27 and right shift 4 times. */
1585 assign(fpc_bits, binop(Iop_Shr32,
1586 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1587 mkU8(4)));
1588
1589 IRExpr *rm_s390 = mkexpr(fpc_bits);
1590 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1591
1592 return binop(Iop_Xor32, rm_s390,
1593 binop( Iop_And32,
1594 binop(Iop_Shl32, rm_s390, mkU8(1)),
1595 mkU32(2)));
1596}
1597
1598/* Encode the s390 rounding mode as it appears in the m3 field of certain
1599 instructions to VEX's IRRoundingMode. */
1600static IRTemp
1601encode_dfp_rounding_mode(UChar mode)
1602{
1603 IRExpr *rm;
1604
1605 switch (mode) {
1606 case S390_DFP_ROUND_PER_FPC_0:
1607 case S390_DFP_ROUND_PER_FPC_2:
1608 rm = get_dfp_rounding_mode_from_fpc(); break;
1609 case S390_DFP_ROUND_NEAREST_EVEN_4:
1610 case S390_DFP_ROUND_NEAREST_EVEN_8:
1611 rm = mkU32(Irrm_DFP_NEAREST); break;
1612 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1613 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1614 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1615 case S390_DFP_ROUND_PREPARE_SHORT_3:
1616 case S390_DFP_ROUND_PREPARE_SHORT_15:
1617 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1618 case S390_DFP_ROUND_ZERO_5:
1619 case S390_DFP_ROUND_ZERO_9:
1620 rm = mkU32(Irrm_DFP_ZERO ); break;
1621 case S390_DFP_ROUND_POSINF_6:
1622 case S390_DFP_ROUND_POSINF_10:
1623 rm = mkU32(Irrm_DFP_PosINF); break;
1624 case S390_DFP_ROUND_NEGINF_7:
1625 case S390_DFP_ROUND_NEGINF_11:
1626 rm = mkU32(Irrm_DFP_NegINF); break;
1627 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1628 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1629 case S390_DFP_ROUND_AWAY_0:
1630 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1631 default:
1632 vpanic("encode_dfp_rounding_mode");
1633 }
1634
1635 return mktemp(Ity_I32, rm);
1636}
florian12390202012-11-10 22:34:14 +00001637
florianc8e4f562012-10-27 16:19:31 +00001638
florian2c74d242012-09-12 19:38:42 +00001639/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001640/*--- Condition code helpers ---*/
1641/*------------------------------------------------------------*/
1642
1643/* The result of a Iop_CmpFxx operation is a condition code. It is
1644 encoded using the values defined in type IRCmpFxxResult.
1645 Before we can store the condition code into the guest state (or do
1646 anything else with it for that matter) we need to convert it to
1647 the encoding that s390 uses. This is what this function does.
1648
1649 s390 VEX b6 b2 b0 cc.1 cc.0
1650 0 0x40 EQ 1 0 0 0 0
1651 1 0x01 LT 0 0 1 0 1
1652 2 0x00 GT 0 0 0 1 0
1653 3 0x45 Unordered 1 1 1 1 1
1654
1655 The following bits from the VEX encoding are interesting:
1656 b0, b2, b6 with b0 being the LSB. We observe:
1657
1658 cc.0 = b0;
1659 cc.1 = b2 | (~b0 & ~b6)
1660
1661 with cc being the s390 condition code.
1662*/
1663static IRExpr *
1664convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1665{
1666 IRTemp cc0 = newTemp(Ity_I32);
1667 IRTemp cc1 = newTemp(Ity_I32);
1668 IRTemp b0 = newTemp(Ity_I32);
1669 IRTemp b2 = newTemp(Ity_I32);
1670 IRTemp b6 = newTemp(Ity_I32);
1671
1672 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1673 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1674 mkU32(1)));
1675 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1676 mkU32(1)));
1677
1678 assign(cc0, mkexpr(b0));
1679 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1680 binop(Iop_And32,
1681 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1682 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1683 )));
1684
1685 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1686}
1687
1688
1689/* The result of a Iop_CmpDxx operation is a condition code. It is
1690 encoded using the values defined in type IRCmpDxxResult.
1691 Before we can store the condition code into the guest state (or do
1692 anything else with it for that matter) we need to convert it to
1693 the encoding that s390 uses. This is what this function does. */
1694static IRExpr *
1695convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1696{
1697 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1698 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001699 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001700}
1701
1702
1703/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001704/*--- Build IR for formats ---*/
1705/*------------------------------------------------------------*/
1706static void
florian55085f82012-11-21 00:36:55 +00001707s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001708 UChar i)
1709{
florian55085f82012-11-21 00:36:55 +00001710 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001711
sewardj7ee97522011-05-09 21:45:04 +00001712 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001713 s390_disasm(ENC2(MNM, UINT), mnm, i);
1714}
1715
1716static void
florian55085f82012-11-21 00:36:55 +00001717s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001718 UChar r1, UShort i2)
1719{
1720 irgen(r1, i2);
1721}
1722
1723static void
florian55085f82012-11-21 00:36:55 +00001724s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001725 UChar r1, UShort i2)
1726{
florian55085f82012-11-21 00:36:55 +00001727 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001728
sewardj7ee97522011-05-09 21:45:04 +00001729 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001730 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1731}
1732
1733static void
florian55085f82012-11-21 00:36:55 +00001734s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001735 UChar r1, UShort i2)
1736{
florian55085f82012-11-21 00:36:55 +00001737 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001738
sewardj7ee97522011-05-09 21:45:04 +00001739 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001740 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1741}
1742
1743static void
florian55085f82012-11-21 00:36:55 +00001744s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001745 UChar r1, UShort i2)
1746{
florian55085f82012-11-21 00:36:55 +00001747 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001748
sewardj7ee97522011-05-09 21:45:04 +00001749 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001750 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1751}
1752
1753static void
florian55085f82012-11-21 00:36:55 +00001754s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001755 UChar r1, UChar r3, UShort i2)
1756{
florian55085f82012-11-21 00:36:55 +00001757 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001758
sewardj7ee97522011-05-09 21:45:04 +00001759 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001760 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1761}
1762
1763static void
florian55085f82012-11-21 00:36:55 +00001764s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001765 UChar r1, UChar r3, UShort i2)
1766{
florian55085f82012-11-21 00:36:55 +00001767 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001768
sewardj7ee97522011-05-09 21:45:04 +00001769 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001770 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1771}
1772
1773static void
florian55085f82012-11-21 00:36:55 +00001774s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1775 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001776 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1777{
florian55085f82012-11-21 00:36:55 +00001778 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001779
sewardj7ee97522011-05-09 21:45:04 +00001780 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001781 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1782 i5);
1783}
1784
1785static void
florian55085f82012-11-21 00:36:55 +00001786s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1787 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001788 UChar r1, UChar r2, UShort i4, UChar m3)
1789{
florian55085f82012-11-21 00:36:55 +00001790 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001791
sewardj7ee97522011-05-09 21:45:04 +00001792 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001793 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1794 r2, m3, (Int)(Short)i4);
1795}
1796
1797static void
florian55085f82012-11-21 00:36:55 +00001798s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1799 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001800 UChar r1, UChar m3, UShort i4, UChar i2)
1801{
florian55085f82012-11-21 00:36:55 +00001802 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001803
sewardj7ee97522011-05-09 21:45:04 +00001804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001805 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1806 r1, i2, m3, (Int)(Short)i4);
1807}
1808
1809static void
florian55085f82012-11-21 00:36:55 +00001810s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1811 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001812 UChar r1, UChar m3, UShort i4, UChar i2)
1813{
florian55085f82012-11-21 00:36:55 +00001814 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001815
sewardj7ee97522011-05-09 21:45:04 +00001816 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001817 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1818 (Int)(Char)i2, m3, (Int)(Short)i4);
1819}
1820
1821static void
florian55085f82012-11-21 00:36:55 +00001822s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001823 UChar r1, UInt i2)
1824{
1825 irgen(r1, i2);
1826}
1827
1828static void
florian55085f82012-11-21 00:36:55 +00001829s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001830 UChar r1, UInt i2)
1831{
florian55085f82012-11-21 00:36:55 +00001832 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001833
sewardj7ee97522011-05-09 21:45:04 +00001834 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001835 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1836}
1837
1838static void
florian55085f82012-11-21 00:36:55 +00001839s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001840 UChar r1, UInt i2)
1841{
florian55085f82012-11-21 00:36:55 +00001842 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001843
sewardj7ee97522011-05-09 21:45:04 +00001844 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001845 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1846}
1847
1848static void
florian55085f82012-11-21 00:36:55 +00001849s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001850 UChar r1, UInt i2)
1851{
florian55085f82012-11-21 00:36:55 +00001852 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001853
sewardj7ee97522011-05-09 21:45:04 +00001854 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001855 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1856}
1857
1858static void
florian55085f82012-11-21 00:36:55 +00001859s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001860 UChar r1, UInt i2)
1861{
florian55085f82012-11-21 00:36:55 +00001862 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001863
sewardj7ee97522011-05-09 21:45:04 +00001864 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001865 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1866}
1867
1868static void
florian55085f82012-11-21 00:36:55 +00001869s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001870 IRTemp op4addr),
1871 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1872{
florian55085f82012-11-21 00:36:55 +00001873 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001874 IRTemp op4addr = newTemp(Ity_I64);
1875
1876 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1877 mkU64(0)));
1878
1879 mnm = irgen(r1, m3, i2, op4addr);
1880
sewardj7ee97522011-05-09 21:45:04 +00001881 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001882 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1883 (Int)(Char)i2, m3, d4, 0, b4);
1884}
1885
1886static void
florian55085f82012-11-21 00:36:55 +00001887s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001888 IRTemp op4addr),
1889 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1890{
florian55085f82012-11-21 00:36:55 +00001891 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001892 IRTemp op4addr = newTemp(Ity_I64);
1893
1894 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1895 mkU64(0)));
1896
1897 mnm = irgen(r1, m3, i2, op4addr);
1898
sewardj7ee97522011-05-09 21:45:04 +00001899 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001900 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1901 i2, m3, d4, 0, b4);
1902}
1903
1904static void
florian55085f82012-11-21 00:36:55 +00001905s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001906 UChar r1, UChar r2)
1907{
1908 irgen(r1, r2);
1909}
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001913 UChar r1, UChar r2)
1914{
florian55085f82012-11-21 00:36:55 +00001915 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001916
sewardj7ee97522011-05-09 21:45:04 +00001917 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001918 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1919}
1920
1921static void
florian55085f82012-11-21 00:36:55 +00001922s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001923 UChar r1, UChar r2)
1924{
florian55085f82012-11-21 00:36:55 +00001925 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001926
sewardj7ee97522011-05-09 21:45:04 +00001927 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001928 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1929}
1930
1931static void
florian55085f82012-11-21 00:36:55 +00001932s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001933 UChar r1, UChar r2)
1934{
1935 irgen(r1, r2);
1936}
1937
1938static void
florian55085f82012-11-21 00:36:55 +00001939s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001940 UChar r1, UChar r2)
1941{
florian55085f82012-11-21 00:36:55 +00001942 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001943
sewardj7ee97522011-05-09 21:45:04 +00001944 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001945 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1946}
1947
1948static void
florian55085f82012-11-21 00:36:55 +00001949s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001950 UChar r1, UChar r2)
1951{
florian55085f82012-11-21 00:36:55 +00001952 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001953
sewardj7ee97522011-05-09 21:45:04 +00001954 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001955 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1956}
1957
1958static void
florian55085f82012-11-21 00:36:55 +00001959s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001960 UChar r1, UChar r2)
1961{
florian55085f82012-11-21 00:36:55 +00001962 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001963
sewardj7ee97522011-05-09 21:45:04 +00001964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001965 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1966}
1967
1968static void
florian55085f82012-11-21 00:36:55 +00001969s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001970 UChar r1, UChar r2)
1971{
florian55085f82012-11-21 00:36:55 +00001972 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001973
sewardj7ee97522011-05-09 21:45:04 +00001974 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001975 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1976}
1977
1978static void
florian55085f82012-11-21 00:36:55 +00001979s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001980 UChar r1)
1981{
florian55085f82012-11-21 00:36:55 +00001982 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001983
sewardj7ee97522011-05-09 21:45:04 +00001984 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001985 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1986}
1987
1988static void
florian55085f82012-11-21 00:36:55 +00001989s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001990 UChar r1)
1991{
florian55085f82012-11-21 00:36:55 +00001992 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001993
sewardj7ee97522011-05-09 21:45:04 +00001994 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001995 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1996}
1997
1998static void
florian55085f82012-11-21 00:36:55 +00001999s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002000 UChar m3, UChar r1, UChar r2)
2001{
florian55085f82012-11-21 00:36:55 +00002002 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002003
2004 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002005 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002006}
2007
2008static void
florian55085f82012-11-21 00:36:55 +00002009s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002010 UChar r1, UChar r3, UChar r2)
2011{
florian55085f82012-11-21 00:36:55 +00002012 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002013
sewardj7ee97522011-05-09 21:45:04 +00002014 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002015 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2016}
2017
2018static void
florian55085f82012-11-21 00:36:55 +00002019s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2020 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002021 UChar m3, UChar m4, UChar r1, UChar r2)
2022{
florian55085f82012-11-21 00:36:55 +00002023 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002024
2025 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2026 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2027}
2028
2029static void
floriane38f6412012-12-21 17:32:12 +00002030s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2031 UChar m4, UChar r1, UChar r2)
2032{
2033 const HChar *mnm = irgen(m4, r1, r2);
2034
2035 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2036 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2037}
2038
2039static void
florian55085f82012-11-21 00:36:55 +00002040s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2041 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002042 UChar m3, UChar m4, UChar r1, UChar r2)
2043{
florian55085f82012-11-21 00:36:55 +00002044 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002045
2046 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2047 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2048}
2049
2050static void
florian55085f82012-11-21 00:36:55 +00002051s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2052 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002053 UChar m3, UChar m4, UChar r1, UChar r2)
2054{
florian55085f82012-11-21 00:36:55 +00002055 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002056
2057 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2058 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2059}
2060
2061
2062static void
florian55085f82012-11-21 00:36:55 +00002063s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002064 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2065{
2066 irgen(m3, r1, r2);
2067
sewardj7ee97522011-05-09 21:45:04 +00002068 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002069 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2070}
2071
2072static void
florian55085f82012-11-21 00:36:55 +00002073s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002074 UChar r3, UChar r1, UChar r2)
2075{
florian55085f82012-11-21 00:36:55 +00002076 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002077
sewardj7ee97522011-05-09 21:45:04 +00002078 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002079 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2080}
2081
2082static void
florian55085f82012-11-21 00:36:55 +00002083s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002084 UChar r3, UChar m4, UChar r1, UChar r2)
2085{
florian55085f82012-11-21 00:36:55 +00002086 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002087
2088 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2089 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2090}
2091
2092static void
florian55085f82012-11-21 00:36:55 +00002093s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002094 UChar r3, UChar r1, UChar r2)
2095{
florian55085f82012-11-21 00:36:55 +00002096 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002097
sewardj7ee97522011-05-09 21:45:04 +00002098 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002099 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2100}
2101
2102static void
florian55085f82012-11-21 00:36:55 +00002103s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2104 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002105 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2106{
florian55085f82012-11-21 00:36:55 +00002107 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002108 IRTemp op4addr = newTemp(Ity_I64);
2109
2110 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2111 mkU64(0)));
2112
2113 mnm = irgen(r1, r2, m3, op4addr);
2114
sewardj7ee97522011-05-09 21:45:04 +00002115 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002116 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2117 r2, m3, d4, 0, b4);
2118}
2119
2120static void
florian55085f82012-11-21 00:36:55 +00002121s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002122 UChar r1, UChar b2, UShort d2)
2123{
florian55085f82012-11-21 00:36:55 +00002124 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002125 IRTemp op2addr = newTemp(Ity_I64);
2126
2127 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2128 mkU64(0)));
2129
2130 mnm = irgen(r1, op2addr);
2131
sewardj7ee97522011-05-09 21:45:04 +00002132 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002133 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2134}
2135
2136static void
florian55085f82012-11-21 00:36:55 +00002137s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002138 UChar r1, UChar r3, UChar b2, UShort d2)
2139{
florian55085f82012-11-21 00:36:55 +00002140 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002141 IRTemp op2addr = newTemp(Ity_I64);
2142
2143 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2144 mkU64(0)));
2145
2146 mnm = irgen(r1, r3, op2addr);
2147
sewardj7ee97522011-05-09 21:45:04 +00002148 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002149 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2150}
2151
2152static void
florian55085f82012-11-21 00:36:55 +00002153s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002154 UChar r1, UChar r3, UChar b2, UShort d2)
2155{
florian55085f82012-11-21 00:36:55 +00002156 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002157 IRTemp op2addr = newTemp(Ity_I64);
2158
2159 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2160 mkU64(0)));
2161
2162 mnm = irgen(r1, r3, op2addr);
2163
sewardj7ee97522011-05-09 21:45:04 +00002164 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002165 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2166}
2167
2168static void
florian55085f82012-11-21 00:36:55 +00002169s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002170 UChar r1, UChar r3, UChar b2, UShort d2)
2171{
florian55085f82012-11-21 00:36:55 +00002172 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002173 IRTemp op2addr = newTemp(Ity_I64);
2174
2175 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2176 mkU64(0)));
2177
2178 mnm = irgen(r1, r3, op2addr);
2179
sewardj7ee97522011-05-09 21:45:04 +00002180 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002181 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2182}
2183
2184static void
florian55085f82012-11-21 00:36:55 +00002185s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002186 UChar r1, UChar r3, UShort i2)
2187{
florian55085f82012-11-21 00:36:55 +00002188 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002189
sewardj7ee97522011-05-09 21:45:04 +00002190 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002191 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2192}
2193
2194static void
florian55085f82012-11-21 00:36:55 +00002195s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002196 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2197{
florian55085f82012-11-21 00:36:55 +00002198 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002199 IRTemp op2addr = newTemp(Ity_I64);
2200 IRTemp d2 = newTemp(Ity_I64);
2201
2202 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2203 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2204 mkU64(0)));
2205
2206 mnm = irgen(r1, r3, op2addr);
2207
sewardj7ee97522011-05-09 21:45:04 +00002208 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002209 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2210}
2211
2212static void
florian55085f82012-11-21 00:36:55 +00002213s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002214 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2215{
florian55085f82012-11-21 00:36:55 +00002216 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002217 IRTemp op2addr = newTemp(Ity_I64);
2218 IRTemp d2 = newTemp(Ity_I64);
2219
2220 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2221 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2222 mkU64(0)));
2223
2224 mnm = irgen(r1, r3, op2addr);
2225
sewardj7ee97522011-05-09 21:45:04 +00002226 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002227 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2228}
2229
2230static void
florian55085f82012-11-21 00:36:55 +00002231s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002232 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2233{
florian55085f82012-11-21 00:36:55 +00002234 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002235 IRTemp op2addr = newTemp(Ity_I64);
2236 IRTemp d2 = newTemp(Ity_I64);
2237
2238 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2239 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2240 mkU64(0)));
2241
2242 mnm = irgen(r1, r3, op2addr);
2243
sewardj7ee97522011-05-09 21:45:04 +00002244 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002245 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2246}
2247
2248static void
florian55085f82012-11-21 00:36:55 +00002249s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002250 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2251 Int xmnm_kind)
2252{
2253 IRTemp op2addr = newTemp(Ity_I64);
2254 IRTemp d2 = newTemp(Ity_I64);
2255
florian6820ba52012-07-26 02:01:50 +00002256 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2257
sewardjd7bde722011-04-05 13:19:33 +00002258 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2259 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2260 mkU64(0)));
2261
2262 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002263
2264 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002265
sewardj7ee97522011-05-09 21:45:04 +00002266 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002267 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2268}
2269
2270static void
florian55085f82012-11-21 00:36:55 +00002271s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002272 IRTemp op2addr),
2273 UChar r1, UChar x2, UChar b2, UShort d2)
2274{
2275 IRTemp op2addr = newTemp(Ity_I64);
2276
2277 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2278 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2279 mkU64(0)));
2280
2281 irgen(r1, x2, b2, d2, op2addr);
2282}
2283
2284static void
florian55085f82012-11-21 00:36:55 +00002285s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002286 UChar r1, UChar x2, UChar b2, UShort d2)
2287{
florian55085f82012-11-21 00:36:55 +00002288 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002289 IRTemp op2addr = newTemp(Ity_I64);
2290
2291 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2292 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2293 mkU64(0)));
2294
2295 mnm = irgen(r1, op2addr);
2296
sewardj7ee97522011-05-09 21:45:04 +00002297 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002298 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2299}
2300
2301static void
florian55085f82012-11-21 00:36:55 +00002302s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002303 UChar r1, UChar x2, UChar b2, UShort d2)
2304{
florian55085f82012-11-21 00:36:55 +00002305 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002306 IRTemp op2addr = newTemp(Ity_I64);
2307
2308 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2309 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2310 mkU64(0)));
2311
2312 mnm = irgen(r1, op2addr);
2313
sewardj7ee97522011-05-09 21:45:04 +00002314 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002315 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2316}
2317
2318static void
florian55085f82012-11-21 00:36:55 +00002319s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002320 UChar r1, UChar x2, UChar b2, UShort d2)
2321{
florian55085f82012-11-21 00:36:55 +00002322 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002323 IRTemp op2addr = newTemp(Ity_I64);
2324
2325 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2326 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2327 mkU64(0)));
2328
2329 mnm = irgen(r1, op2addr);
2330
sewardj7ee97522011-05-09 21:45:04 +00002331 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002332 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2333}
2334
2335static void
florian55085f82012-11-21 00:36:55 +00002336s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002337 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2338{
florian55085f82012-11-21 00:36:55 +00002339 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002340 IRTemp op2addr = newTemp(Ity_I64);
2341
2342 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2343 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2344 mkU64(0)));
2345
2346 mnm = irgen(r3, op2addr, r1);
2347
sewardj7ee97522011-05-09 21:45:04 +00002348 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002349 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2350}
2351
2352static void
florian55085f82012-11-21 00:36:55 +00002353s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002354 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2355{
florian55085f82012-11-21 00:36:55 +00002356 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002357 IRTemp op2addr = newTemp(Ity_I64);
2358 IRTemp d2 = newTemp(Ity_I64);
2359
2360 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2361 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2362 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2363 mkU64(0)));
2364
2365 mnm = irgen(r1, op2addr);
2366
sewardj7ee97522011-05-09 21:45:04 +00002367 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002368 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2369}
2370
2371static void
florian55085f82012-11-21 00:36:55 +00002372s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002373 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2374{
florian55085f82012-11-21 00:36:55 +00002375 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002376 IRTemp op2addr = newTemp(Ity_I64);
2377 IRTemp d2 = newTemp(Ity_I64);
2378
2379 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2380 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2381 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2382 mkU64(0)));
2383
2384 mnm = irgen(r1, op2addr);
2385
sewardj7ee97522011-05-09 21:45:04 +00002386 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002387 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2388}
2389
2390static void
florian55085f82012-11-21 00:36:55 +00002391s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002392 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2393{
florian55085f82012-11-21 00:36:55 +00002394 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002395 IRTemp op2addr = newTemp(Ity_I64);
2396 IRTemp d2 = newTemp(Ity_I64);
2397
2398 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2399 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2400 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2401 mkU64(0)));
2402
2403 mnm = irgen();
2404
sewardj7ee97522011-05-09 21:45:04 +00002405 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002406 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2407}
2408
2409static void
florian55085f82012-11-21 00:36:55 +00002410s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002411 UChar b2, UShort d2)
2412{
florian55085f82012-11-21 00:36:55 +00002413 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002414 IRTemp op2addr = newTemp(Ity_I64);
2415
2416 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2417 mkU64(0)));
2418
2419 mnm = irgen(op2addr);
2420
sewardj7ee97522011-05-09 21:45:04 +00002421 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002422 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2423}
2424
2425static void
florian55085f82012-11-21 00:36:55 +00002426s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002427 UChar i2, UChar b1, UShort d1)
2428{
florian55085f82012-11-21 00:36:55 +00002429 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002430 IRTemp op1addr = newTemp(Ity_I64);
2431
2432 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2433 mkU64(0)));
2434
2435 mnm = irgen(i2, op1addr);
2436
sewardj7ee97522011-05-09 21:45:04 +00002437 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002438 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2439}
2440
2441static void
florian55085f82012-11-21 00:36:55 +00002442s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002443 UChar i2, UChar b1, UShort dl1, UChar dh1)
2444{
florian55085f82012-11-21 00:36:55 +00002445 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002446 IRTemp op1addr = newTemp(Ity_I64);
2447 IRTemp d1 = newTemp(Ity_I64);
2448
2449 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2450 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2451 mkU64(0)));
2452
2453 mnm = irgen(i2, op1addr);
2454
sewardj7ee97522011-05-09 21:45:04 +00002455 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002456 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2457}
2458
2459static void
florian55085f82012-11-21 00:36:55 +00002460s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002461 UChar i2, UChar b1, UShort dl1, UChar dh1)
2462{
florian55085f82012-11-21 00:36:55 +00002463 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002464 IRTemp op1addr = newTemp(Ity_I64);
2465 IRTemp d1 = newTemp(Ity_I64);
2466
2467 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2468 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2469 mkU64(0)));
2470
2471 mnm = irgen(i2, op1addr);
2472
sewardj7ee97522011-05-09 21:45:04 +00002473 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002474 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2475}
2476
2477static void
florian55085f82012-11-21 00:36:55 +00002478s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002479 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2480{
florian55085f82012-11-21 00:36:55 +00002481 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002482 IRTemp op1addr = newTemp(Ity_I64);
2483 IRTemp op2addr = newTemp(Ity_I64);
2484
2485 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2486 mkU64(0)));
2487 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2488 mkU64(0)));
2489
2490 mnm = irgen(l, op1addr, op2addr);
2491
sewardj7ee97522011-05-09 21:45:04 +00002492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002493 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2494}
2495
2496static void
florian55085f82012-11-21 00:36:55 +00002497s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002498 UChar b1, UShort d1, UShort i2)
2499{
florian55085f82012-11-21 00:36:55 +00002500 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002501 IRTemp op1addr = newTemp(Ity_I64);
2502
2503 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2504 mkU64(0)));
2505
2506 mnm = irgen(i2, op1addr);
2507
sewardj7ee97522011-05-09 21:45:04 +00002508 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002509 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2510}
2511
2512static void
florian55085f82012-11-21 00:36:55 +00002513s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002514 UChar b1, UShort d1, UShort i2)
2515{
florian55085f82012-11-21 00:36:55 +00002516 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002517 IRTemp op1addr = newTemp(Ity_I64);
2518
2519 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2520 mkU64(0)));
2521
2522 mnm = irgen(i2, op1addr);
2523
sewardj7ee97522011-05-09 21:45:04 +00002524 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002525 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2526}
2527
2528
2529
2530/*------------------------------------------------------------*/
2531/*--- Build IR for opcodes ---*/
2532/*------------------------------------------------------------*/
2533
florian55085f82012-11-21 00:36:55 +00002534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002535s390_irgen_AR(UChar r1, UChar r2)
2536{
2537 IRTemp op1 = newTemp(Ity_I32);
2538 IRTemp op2 = newTemp(Ity_I32);
2539 IRTemp result = newTemp(Ity_I32);
2540
2541 assign(op1, get_gpr_w1(r1));
2542 assign(op2, get_gpr_w1(r2));
2543 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2544 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2545 put_gpr_w1(r1, mkexpr(result));
2546
2547 return "ar";
2548}
2549
florian55085f82012-11-21 00:36:55 +00002550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002551s390_irgen_AGR(UChar r1, UChar r2)
2552{
2553 IRTemp op1 = newTemp(Ity_I64);
2554 IRTemp op2 = newTemp(Ity_I64);
2555 IRTemp result = newTemp(Ity_I64);
2556
2557 assign(op1, get_gpr_dw0(r1));
2558 assign(op2, get_gpr_dw0(r2));
2559 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2560 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2561 put_gpr_dw0(r1, mkexpr(result));
2562
2563 return "agr";
2564}
2565
florian55085f82012-11-21 00:36:55 +00002566static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002567s390_irgen_AGFR(UChar r1, UChar r2)
2568{
2569 IRTemp op1 = newTemp(Ity_I64);
2570 IRTemp op2 = newTemp(Ity_I64);
2571 IRTemp result = newTemp(Ity_I64);
2572
2573 assign(op1, get_gpr_dw0(r1));
2574 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2575 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2576 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2577 put_gpr_dw0(r1, mkexpr(result));
2578
2579 return "agfr";
2580}
2581
florian55085f82012-11-21 00:36:55 +00002582static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002583s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2584{
2585 IRTemp op2 = newTemp(Ity_I32);
2586 IRTemp op3 = newTemp(Ity_I32);
2587 IRTemp result = newTemp(Ity_I32);
2588
2589 assign(op2, get_gpr_w1(r2));
2590 assign(op3, get_gpr_w1(r3));
2591 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2592 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2593 put_gpr_w1(r1, mkexpr(result));
2594
2595 return "ark";
2596}
2597
florian55085f82012-11-21 00:36:55 +00002598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002599s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2600{
2601 IRTemp op2 = newTemp(Ity_I64);
2602 IRTemp op3 = newTemp(Ity_I64);
2603 IRTemp result = newTemp(Ity_I64);
2604
2605 assign(op2, get_gpr_dw0(r2));
2606 assign(op3, get_gpr_dw0(r3));
2607 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2608 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2609 put_gpr_dw0(r1, mkexpr(result));
2610
2611 return "agrk";
2612}
2613
florian55085f82012-11-21 00:36:55 +00002614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002615s390_irgen_A(UChar r1, IRTemp op2addr)
2616{
2617 IRTemp op1 = newTemp(Ity_I32);
2618 IRTemp op2 = newTemp(Ity_I32);
2619 IRTemp result = newTemp(Ity_I32);
2620
2621 assign(op1, get_gpr_w1(r1));
2622 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2623 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2624 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2625 put_gpr_w1(r1, mkexpr(result));
2626
2627 return "a";
2628}
2629
florian55085f82012-11-21 00:36:55 +00002630static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002631s390_irgen_AY(UChar r1, IRTemp op2addr)
2632{
2633 IRTemp op1 = newTemp(Ity_I32);
2634 IRTemp op2 = newTemp(Ity_I32);
2635 IRTemp result = newTemp(Ity_I32);
2636
2637 assign(op1, get_gpr_w1(r1));
2638 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2639 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2640 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2641 put_gpr_w1(r1, mkexpr(result));
2642
2643 return "ay";
2644}
2645
florian55085f82012-11-21 00:36:55 +00002646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002647s390_irgen_AG(UChar r1, IRTemp op2addr)
2648{
2649 IRTemp op1 = newTemp(Ity_I64);
2650 IRTemp op2 = newTemp(Ity_I64);
2651 IRTemp result = newTemp(Ity_I64);
2652
2653 assign(op1, get_gpr_dw0(r1));
2654 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2655 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2656 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2657 put_gpr_dw0(r1, mkexpr(result));
2658
2659 return "ag";
2660}
2661
florian55085f82012-11-21 00:36:55 +00002662static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002663s390_irgen_AGF(UChar r1, IRTemp op2addr)
2664{
2665 IRTemp op1 = newTemp(Ity_I64);
2666 IRTemp op2 = newTemp(Ity_I64);
2667 IRTemp result = newTemp(Ity_I64);
2668
2669 assign(op1, get_gpr_dw0(r1));
2670 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2671 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2672 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2673 put_gpr_dw0(r1, mkexpr(result));
2674
2675 return "agf";
2676}
2677
florian55085f82012-11-21 00:36:55 +00002678static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002679s390_irgen_AFI(UChar r1, UInt i2)
2680{
2681 IRTemp op1 = newTemp(Ity_I32);
2682 Int op2;
2683 IRTemp result = newTemp(Ity_I32);
2684
2685 assign(op1, get_gpr_w1(r1));
2686 op2 = (Int)i2;
2687 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2688 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2689 mkU32((UInt)op2)));
2690 put_gpr_w1(r1, mkexpr(result));
2691
2692 return "afi";
2693}
2694
florian55085f82012-11-21 00:36:55 +00002695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002696s390_irgen_AGFI(UChar r1, UInt i2)
2697{
2698 IRTemp op1 = newTemp(Ity_I64);
2699 Long op2;
2700 IRTemp result = newTemp(Ity_I64);
2701
2702 assign(op1, get_gpr_dw0(r1));
2703 op2 = (Long)(Int)i2;
2704 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2705 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2706 mkU64((ULong)op2)));
2707 put_gpr_dw0(r1, mkexpr(result));
2708
2709 return "agfi";
2710}
2711
florian55085f82012-11-21 00:36:55 +00002712static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002713s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2714{
2715 Int op2;
2716 IRTemp op3 = newTemp(Ity_I32);
2717 IRTemp result = newTemp(Ity_I32);
2718
2719 op2 = (Int)(Short)i2;
2720 assign(op3, get_gpr_w1(r3));
2721 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2722 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2723 op2)), op3);
2724 put_gpr_w1(r1, mkexpr(result));
2725
2726 return "ahik";
2727}
2728
florian55085f82012-11-21 00:36:55 +00002729static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002730s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2731{
2732 Long op2;
2733 IRTemp op3 = newTemp(Ity_I64);
2734 IRTemp result = newTemp(Ity_I64);
2735
2736 op2 = (Long)(Short)i2;
2737 assign(op3, get_gpr_dw0(r3));
2738 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2739 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2740 op2)), op3);
2741 put_gpr_dw0(r1, mkexpr(result));
2742
2743 return "aghik";
2744}
2745
florian55085f82012-11-21 00:36:55 +00002746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002747s390_irgen_ASI(UChar i2, IRTemp op1addr)
2748{
2749 IRTemp op1 = newTemp(Ity_I32);
2750 Int op2;
2751 IRTemp result = newTemp(Ity_I32);
2752
2753 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2754 op2 = (Int)(Char)i2;
2755 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2756 store(mkexpr(op1addr), mkexpr(result));
2757 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2758 mkU32((UInt)op2)));
2759
2760 return "asi";
2761}
2762
florian55085f82012-11-21 00:36:55 +00002763static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002764s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2765{
2766 IRTemp op1 = newTemp(Ity_I64);
2767 Long op2;
2768 IRTemp result = newTemp(Ity_I64);
2769
2770 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2771 op2 = (Long)(Char)i2;
2772 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2773 store(mkexpr(op1addr), mkexpr(result));
2774 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2775 mkU64((ULong)op2)));
2776
2777 return "agsi";
2778}
2779
florian55085f82012-11-21 00:36:55 +00002780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002781s390_irgen_AH(UChar r1, IRTemp op2addr)
2782{
2783 IRTemp op1 = newTemp(Ity_I32);
2784 IRTemp op2 = newTemp(Ity_I32);
2785 IRTemp result = newTemp(Ity_I32);
2786
2787 assign(op1, get_gpr_w1(r1));
2788 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2789 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2790 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2791 put_gpr_w1(r1, mkexpr(result));
2792
2793 return "ah";
2794}
2795
florian55085f82012-11-21 00:36:55 +00002796static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002797s390_irgen_AHY(UChar r1, IRTemp op2addr)
2798{
2799 IRTemp op1 = newTemp(Ity_I32);
2800 IRTemp op2 = newTemp(Ity_I32);
2801 IRTemp result = newTemp(Ity_I32);
2802
2803 assign(op1, get_gpr_w1(r1));
2804 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2805 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2806 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2807 put_gpr_w1(r1, mkexpr(result));
2808
2809 return "ahy";
2810}
2811
florian55085f82012-11-21 00:36:55 +00002812static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002813s390_irgen_AHI(UChar r1, UShort i2)
2814{
2815 IRTemp op1 = newTemp(Ity_I32);
2816 Int op2;
2817 IRTemp result = newTemp(Ity_I32);
2818
2819 assign(op1, get_gpr_w1(r1));
2820 op2 = (Int)(Short)i2;
2821 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2822 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2823 mkU32((UInt)op2)));
2824 put_gpr_w1(r1, mkexpr(result));
2825
2826 return "ahi";
2827}
2828
florian55085f82012-11-21 00:36:55 +00002829static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002830s390_irgen_AGHI(UChar r1, UShort i2)
2831{
2832 IRTemp op1 = newTemp(Ity_I64);
2833 Long op2;
2834 IRTemp result = newTemp(Ity_I64);
2835
2836 assign(op1, get_gpr_dw0(r1));
2837 op2 = (Long)(Short)i2;
2838 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2839 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2840 mkU64((ULong)op2)));
2841 put_gpr_dw0(r1, mkexpr(result));
2842
2843 return "aghi";
2844}
2845
florian55085f82012-11-21 00:36:55 +00002846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002847s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2848{
2849 IRTemp op2 = newTemp(Ity_I32);
2850 IRTemp op3 = newTemp(Ity_I32);
2851 IRTemp result = newTemp(Ity_I32);
2852
2853 assign(op2, get_gpr_w0(r2));
2854 assign(op3, get_gpr_w0(r3));
2855 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2856 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2857 put_gpr_w0(r1, mkexpr(result));
2858
2859 return "ahhhr";
2860}
2861
florian55085f82012-11-21 00:36:55 +00002862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002863s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2864{
2865 IRTemp op2 = newTemp(Ity_I32);
2866 IRTemp op3 = newTemp(Ity_I32);
2867 IRTemp result = newTemp(Ity_I32);
2868
2869 assign(op2, get_gpr_w0(r2));
2870 assign(op3, get_gpr_w1(r3));
2871 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2872 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2873 put_gpr_w0(r1, mkexpr(result));
2874
2875 return "ahhlr";
2876}
2877
florian55085f82012-11-21 00:36:55 +00002878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002879s390_irgen_AIH(UChar r1, UInt i2)
2880{
2881 IRTemp op1 = newTemp(Ity_I32);
2882 Int op2;
2883 IRTemp result = newTemp(Ity_I32);
2884
2885 assign(op1, get_gpr_w0(r1));
2886 op2 = (Int)i2;
2887 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2888 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2889 mkU32((UInt)op2)));
2890 put_gpr_w0(r1, mkexpr(result));
2891
2892 return "aih";
2893}
2894
florian55085f82012-11-21 00:36:55 +00002895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002896s390_irgen_ALR(UChar r1, UChar r2)
2897{
2898 IRTemp op1 = newTemp(Ity_I32);
2899 IRTemp op2 = newTemp(Ity_I32);
2900 IRTemp result = newTemp(Ity_I32);
2901
2902 assign(op1, get_gpr_w1(r1));
2903 assign(op2, get_gpr_w1(r2));
2904 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2905 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2906 put_gpr_w1(r1, mkexpr(result));
2907
2908 return "alr";
2909}
2910
florian55085f82012-11-21 00:36:55 +00002911static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002912s390_irgen_ALGR(UChar r1, UChar r2)
2913{
2914 IRTemp op1 = newTemp(Ity_I64);
2915 IRTemp op2 = newTemp(Ity_I64);
2916 IRTemp result = newTemp(Ity_I64);
2917
2918 assign(op1, get_gpr_dw0(r1));
2919 assign(op2, get_gpr_dw0(r2));
2920 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2921 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2922 put_gpr_dw0(r1, mkexpr(result));
2923
2924 return "algr";
2925}
2926
florian55085f82012-11-21 00:36:55 +00002927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002928s390_irgen_ALGFR(UChar r1, UChar r2)
2929{
2930 IRTemp op1 = newTemp(Ity_I64);
2931 IRTemp op2 = newTemp(Ity_I64);
2932 IRTemp result = newTemp(Ity_I64);
2933
2934 assign(op1, get_gpr_dw0(r1));
2935 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2936 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2937 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2938 put_gpr_dw0(r1, mkexpr(result));
2939
2940 return "algfr";
2941}
2942
florian55085f82012-11-21 00:36:55 +00002943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002944s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2945{
2946 IRTemp op2 = newTemp(Ity_I32);
2947 IRTemp op3 = newTemp(Ity_I32);
2948 IRTemp result = newTemp(Ity_I32);
2949
2950 assign(op2, get_gpr_w1(r2));
2951 assign(op3, get_gpr_w1(r3));
2952 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2953 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2954 put_gpr_w1(r1, mkexpr(result));
2955
2956 return "alrk";
2957}
2958
florian55085f82012-11-21 00:36:55 +00002959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002960s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2961{
2962 IRTemp op2 = newTemp(Ity_I64);
2963 IRTemp op3 = newTemp(Ity_I64);
2964 IRTemp result = newTemp(Ity_I64);
2965
2966 assign(op2, get_gpr_dw0(r2));
2967 assign(op3, get_gpr_dw0(r3));
2968 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2969 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2970 put_gpr_dw0(r1, mkexpr(result));
2971
2972 return "algrk";
2973}
2974
florian55085f82012-11-21 00:36:55 +00002975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002976s390_irgen_AL(UChar r1, IRTemp op2addr)
2977{
2978 IRTemp op1 = newTemp(Ity_I32);
2979 IRTemp op2 = newTemp(Ity_I32);
2980 IRTemp result = newTemp(Ity_I32);
2981
2982 assign(op1, get_gpr_w1(r1));
2983 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2984 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2985 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2986 put_gpr_w1(r1, mkexpr(result));
2987
2988 return "al";
2989}
2990
florian55085f82012-11-21 00:36:55 +00002991static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002992s390_irgen_ALY(UChar r1, IRTemp op2addr)
2993{
2994 IRTemp op1 = newTemp(Ity_I32);
2995 IRTemp op2 = newTemp(Ity_I32);
2996 IRTemp result = newTemp(Ity_I32);
2997
2998 assign(op1, get_gpr_w1(r1));
2999 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3000 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3001 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3002 put_gpr_w1(r1, mkexpr(result));
3003
3004 return "aly";
3005}
3006
florian55085f82012-11-21 00:36:55 +00003007static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003008s390_irgen_ALG(UChar r1, IRTemp op2addr)
3009{
3010 IRTemp op1 = newTemp(Ity_I64);
3011 IRTemp op2 = newTemp(Ity_I64);
3012 IRTemp result = newTemp(Ity_I64);
3013
3014 assign(op1, get_gpr_dw0(r1));
3015 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3016 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3017 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3018 put_gpr_dw0(r1, mkexpr(result));
3019
3020 return "alg";
3021}
3022
florian55085f82012-11-21 00:36:55 +00003023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003024s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3025{
3026 IRTemp op1 = newTemp(Ity_I64);
3027 IRTemp op2 = newTemp(Ity_I64);
3028 IRTemp result = newTemp(Ity_I64);
3029
3030 assign(op1, get_gpr_dw0(r1));
3031 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3032 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3033 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3034 put_gpr_dw0(r1, mkexpr(result));
3035
3036 return "algf";
3037}
3038
florian55085f82012-11-21 00:36:55 +00003039static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003040s390_irgen_ALFI(UChar r1, UInt i2)
3041{
3042 IRTemp op1 = newTemp(Ity_I32);
3043 UInt op2;
3044 IRTemp result = newTemp(Ity_I32);
3045
3046 assign(op1, get_gpr_w1(r1));
3047 op2 = i2;
3048 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3049 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3050 mkU32(op2)));
3051 put_gpr_w1(r1, mkexpr(result));
3052
3053 return "alfi";
3054}
3055
florian55085f82012-11-21 00:36:55 +00003056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003057s390_irgen_ALGFI(UChar r1, UInt i2)
3058{
3059 IRTemp op1 = newTemp(Ity_I64);
3060 ULong op2;
3061 IRTemp result = newTemp(Ity_I64);
3062
3063 assign(op1, get_gpr_dw0(r1));
3064 op2 = (ULong)i2;
3065 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3066 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3067 mkU64(op2)));
3068 put_gpr_dw0(r1, mkexpr(result));
3069
3070 return "algfi";
3071}
3072
florian55085f82012-11-21 00:36:55 +00003073static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003074s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3075{
3076 IRTemp op2 = newTemp(Ity_I32);
3077 IRTemp op3 = newTemp(Ity_I32);
3078 IRTemp result = newTemp(Ity_I32);
3079
3080 assign(op2, get_gpr_w0(r2));
3081 assign(op3, get_gpr_w0(r3));
3082 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3083 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3084 put_gpr_w0(r1, mkexpr(result));
3085
3086 return "alhhhr";
3087}
3088
florian55085f82012-11-21 00:36:55 +00003089static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003090s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3091{
3092 IRTemp op2 = newTemp(Ity_I32);
3093 IRTemp op3 = newTemp(Ity_I32);
3094 IRTemp result = newTemp(Ity_I32);
3095
3096 assign(op2, get_gpr_w0(r2));
3097 assign(op3, get_gpr_w1(r3));
3098 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3099 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3100 put_gpr_w0(r1, mkexpr(result));
3101
3102 return "alhhlr";
3103}
3104
florian55085f82012-11-21 00:36:55 +00003105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003106s390_irgen_ALCR(UChar r1, UChar r2)
3107{
3108 IRTemp op1 = newTemp(Ity_I32);
3109 IRTemp op2 = newTemp(Ity_I32);
3110 IRTemp result = newTemp(Ity_I32);
3111 IRTemp carry_in = newTemp(Ity_I32);
3112
3113 assign(op1, get_gpr_w1(r1));
3114 assign(op2, get_gpr_w1(r2));
3115 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3116 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3117 mkexpr(carry_in)));
3118 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3119 put_gpr_w1(r1, mkexpr(result));
3120
3121 return "alcr";
3122}
3123
florian55085f82012-11-21 00:36:55 +00003124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003125s390_irgen_ALCGR(UChar r1, UChar r2)
3126{
3127 IRTemp op1 = newTemp(Ity_I64);
3128 IRTemp op2 = newTemp(Ity_I64);
3129 IRTemp result = newTemp(Ity_I64);
3130 IRTemp carry_in = newTemp(Ity_I64);
3131
3132 assign(op1, get_gpr_dw0(r1));
3133 assign(op2, get_gpr_dw0(r2));
3134 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3135 mkU8(1))));
3136 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3137 mkexpr(carry_in)));
3138 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3139 put_gpr_dw0(r1, mkexpr(result));
3140
3141 return "alcgr";
3142}
3143
florian55085f82012-11-21 00:36:55 +00003144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003145s390_irgen_ALC(UChar r1, IRTemp op2addr)
3146{
3147 IRTemp op1 = newTemp(Ity_I32);
3148 IRTemp op2 = newTemp(Ity_I32);
3149 IRTemp result = newTemp(Ity_I32);
3150 IRTemp carry_in = newTemp(Ity_I32);
3151
3152 assign(op1, get_gpr_w1(r1));
3153 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3154 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3155 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3156 mkexpr(carry_in)));
3157 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3158 put_gpr_w1(r1, mkexpr(result));
3159
3160 return "alc";
3161}
3162
florian55085f82012-11-21 00:36:55 +00003163static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003164s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3165{
3166 IRTemp op1 = newTemp(Ity_I64);
3167 IRTemp op2 = newTemp(Ity_I64);
3168 IRTemp result = newTemp(Ity_I64);
3169 IRTemp carry_in = newTemp(Ity_I64);
3170
3171 assign(op1, get_gpr_dw0(r1));
3172 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3173 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3174 mkU8(1))));
3175 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3176 mkexpr(carry_in)));
3177 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3178 put_gpr_dw0(r1, mkexpr(result));
3179
3180 return "alcg";
3181}
3182
florian55085f82012-11-21 00:36:55 +00003183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003184s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3185{
3186 IRTemp op1 = newTemp(Ity_I32);
3187 UInt op2;
3188 IRTemp result = newTemp(Ity_I32);
3189
3190 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3191 op2 = (UInt)(Int)(Char)i2;
3192 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3193 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3194 mkU32(op2)));
3195 store(mkexpr(op1addr), mkexpr(result));
3196
3197 return "alsi";
3198}
3199
florian55085f82012-11-21 00:36:55 +00003200static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003201s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3202{
3203 IRTemp op1 = newTemp(Ity_I64);
3204 ULong op2;
3205 IRTemp result = newTemp(Ity_I64);
3206
3207 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3208 op2 = (ULong)(Long)(Char)i2;
3209 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3210 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3211 mkU64(op2)));
3212 store(mkexpr(op1addr), mkexpr(result));
3213
3214 return "algsi";
3215}
3216
florian55085f82012-11-21 00:36:55 +00003217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003218s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3219{
3220 UInt op2;
3221 IRTemp op3 = newTemp(Ity_I32);
3222 IRTemp result = newTemp(Ity_I32);
3223
3224 op2 = (UInt)(Int)(Short)i2;
3225 assign(op3, get_gpr_w1(r3));
3226 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3227 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3228 op3);
3229 put_gpr_w1(r1, mkexpr(result));
3230
3231 return "alhsik";
3232}
3233
florian55085f82012-11-21 00:36:55 +00003234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003235s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3236{
3237 ULong op2;
3238 IRTemp op3 = newTemp(Ity_I64);
3239 IRTemp result = newTemp(Ity_I64);
3240
3241 op2 = (ULong)(Long)(Short)i2;
3242 assign(op3, get_gpr_dw0(r3));
3243 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3244 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3245 op3);
3246 put_gpr_dw0(r1, mkexpr(result));
3247
3248 return "alghsik";
3249}
3250
florian55085f82012-11-21 00:36:55 +00003251static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003252s390_irgen_ALSIH(UChar r1, UInt i2)
3253{
3254 IRTemp op1 = newTemp(Ity_I32);
3255 UInt op2;
3256 IRTemp result = newTemp(Ity_I32);
3257
3258 assign(op1, get_gpr_w0(r1));
3259 op2 = i2;
3260 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3261 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3262 mkU32(op2)));
3263 put_gpr_w0(r1, mkexpr(result));
3264
3265 return "alsih";
3266}
3267
florian55085f82012-11-21 00:36:55 +00003268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003269s390_irgen_ALSIHN(UChar r1, UInt i2)
3270{
3271 IRTemp op1 = newTemp(Ity_I32);
3272 UInt op2;
3273 IRTemp result = newTemp(Ity_I32);
3274
3275 assign(op1, get_gpr_w0(r1));
3276 op2 = i2;
3277 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3278 put_gpr_w0(r1, mkexpr(result));
3279
3280 return "alsihn";
3281}
3282
florian55085f82012-11-21 00:36:55 +00003283static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003284s390_irgen_NR(UChar r1, UChar r2)
3285{
3286 IRTemp op1 = newTemp(Ity_I32);
3287 IRTemp op2 = newTemp(Ity_I32);
3288 IRTemp result = newTemp(Ity_I32);
3289
3290 assign(op1, get_gpr_w1(r1));
3291 assign(op2, get_gpr_w1(r2));
3292 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3293 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3294 put_gpr_w1(r1, mkexpr(result));
3295
3296 return "nr";
3297}
3298
florian55085f82012-11-21 00:36:55 +00003299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003300s390_irgen_NGR(UChar r1, UChar r2)
3301{
3302 IRTemp op1 = newTemp(Ity_I64);
3303 IRTemp op2 = newTemp(Ity_I64);
3304 IRTemp result = newTemp(Ity_I64);
3305
3306 assign(op1, get_gpr_dw0(r1));
3307 assign(op2, get_gpr_dw0(r2));
3308 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3309 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3310 put_gpr_dw0(r1, mkexpr(result));
3311
3312 return "ngr";
3313}
3314
florian55085f82012-11-21 00:36:55 +00003315static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003316s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3317{
3318 IRTemp op2 = newTemp(Ity_I32);
3319 IRTemp op3 = newTemp(Ity_I32);
3320 IRTemp result = newTemp(Ity_I32);
3321
3322 assign(op2, get_gpr_w1(r2));
3323 assign(op3, get_gpr_w1(r3));
3324 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3325 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3326 put_gpr_w1(r1, mkexpr(result));
3327
3328 return "nrk";
3329}
3330
florian55085f82012-11-21 00:36:55 +00003331static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003332s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3333{
3334 IRTemp op2 = newTemp(Ity_I64);
3335 IRTemp op3 = newTemp(Ity_I64);
3336 IRTemp result = newTemp(Ity_I64);
3337
3338 assign(op2, get_gpr_dw0(r2));
3339 assign(op3, get_gpr_dw0(r3));
3340 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3341 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3342 put_gpr_dw0(r1, mkexpr(result));
3343
3344 return "ngrk";
3345}
3346
florian55085f82012-11-21 00:36:55 +00003347static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003348s390_irgen_N(UChar r1, IRTemp op2addr)
3349{
3350 IRTemp op1 = newTemp(Ity_I32);
3351 IRTemp op2 = newTemp(Ity_I32);
3352 IRTemp result = newTemp(Ity_I32);
3353
3354 assign(op1, get_gpr_w1(r1));
3355 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3356 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3357 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3358 put_gpr_w1(r1, mkexpr(result));
3359
3360 return "n";
3361}
3362
florian55085f82012-11-21 00:36:55 +00003363static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003364s390_irgen_NY(UChar r1, IRTemp op2addr)
3365{
3366 IRTemp op1 = newTemp(Ity_I32);
3367 IRTemp op2 = newTemp(Ity_I32);
3368 IRTemp result = newTemp(Ity_I32);
3369
3370 assign(op1, get_gpr_w1(r1));
3371 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3372 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3373 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3374 put_gpr_w1(r1, mkexpr(result));
3375
3376 return "ny";
3377}
3378
florian55085f82012-11-21 00:36:55 +00003379static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003380s390_irgen_NG(UChar r1, IRTemp op2addr)
3381{
3382 IRTemp op1 = newTemp(Ity_I64);
3383 IRTemp op2 = newTemp(Ity_I64);
3384 IRTemp result = newTemp(Ity_I64);
3385
3386 assign(op1, get_gpr_dw0(r1));
3387 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3388 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3389 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3390 put_gpr_dw0(r1, mkexpr(result));
3391
3392 return "ng";
3393}
3394
florian55085f82012-11-21 00:36:55 +00003395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003396s390_irgen_NI(UChar i2, IRTemp op1addr)
3397{
3398 IRTemp op1 = newTemp(Ity_I8);
3399 UChar op2;
3400 IRTemp result = newTemp(Ity_I8);
3401
3402 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3403 op2 = i2;
3404 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3405 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3406 store(mkexpr(op1addr), mkexpr(result));
3407
3408 return "ni";
3409}
3410
florian55085f82012-11-21 00:36:55 +00003411static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003412s390_irgen_NIY(UChar i2, IRTemp op1addr)
3413{
3414 IRTemp op1 = newTemp(Ity_I8);
3415 UChar op2;
3416 IRTemp result = newTemp(Ity_I8);
3417
3418 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3419 op2 = i2;
3420 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3421 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3422 store(mkexpr(op1addr), mkexpr(result));
3423
3424 return "niy";
3425}
3426
florian55085f82012-11-21 00:36:55 +00003427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003428s390_irgen_NIHF(UChar r1, UInt i2)
3429{
3430 IRTemp op1 = newTemp(Ity_I32);
3431 UInt op2;
3432 IRTemp result = newTemp(Ity_I32);
3433
3434 assign(op1, get_gpr_w0(r1));
3435 op2 = i2;
3436 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3437 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3438 put_gpr_w0(r1, mkexpr(result));
3439
3440 return "nihf";
3441}
3442
florian55085f82012-11-21 00:36:55 +00003443static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003444s390_irgen_NIHH(UChar r1, UShort i2)
3445{
3446 IRTemp op1 = newTemp(Ity_I16);
3447 UShort op2;
3448 IRTemp result = newTemp(Ity_I16);
3449
3450 assign(op1, get_gpr_hw0(r1));
3451 op2 = i2;
3452 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3453 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3454 put_gpr_hw0(r1, mkexpr(result));
3455
3456 return "nihh";
3457}
3458
florian55085f82012-11-21 00:36:55 +00003459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003460s390_irgen_NIHL(UChar r1, UShort i2)
3461{
3462 IRTemp op1 = newTemp(Ity_I16);
3463 UShort op2;
3464 IRTemp result = newTemp(Ity_I16);
3465
3466 assign(op1, get_gpr_hw1(r1));
3467 op2 = i2;
3468 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3469 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3470 put_gpr_hw1(r1, mkexpr(result));
3471
3472 return "nihl";
3473}
3474
florian55085f82012-11-21 00:36:55 +00003475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003476s390_irgen_NILF(UChar r1, UInt i2)
3477{
3478 IRTemp op1 = newTemp(Ity_I32);
3479 UInt op2;
3480 IRTemp result = newTemp(Ity_I32);
3481
3482 assign(op1, get_gpr_w1(r1));
3483 op2 = i2;
3484 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3485 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3486 put_gpr_w1(r1, mkexpr(result));
3487
3488 return "nilf";
3489}
3490
florian55085f82012-11-21 00:36:55 +00003491static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003492s390_irgen_NILH(UChar r1, UShort i2)
3493{
3494 IRTemp op1 = newTemp(Ity_I16);
3495 UShort op2;
3496 IRTemp result = newTemp(Ity_I16);
3497
3498 assign(op1, get_gpr_hw2(r1));
3499 op2 = i2;
3500 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3501 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3502 put_gpr_hw2(r1, mkexpr(result));
3503
3504 return "nilh";
3505}
3506
florian55085f82012-11-21 00:36:55 +00003507static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003508s390_irgen_NILL(UChar r1, UShort i2)
3509{
3510 IRTemp op1 = newTemp(Ity_I16);
3511 UShort op2;
3512 IRTemp result = newTemp(Ity_I16);
3513
3514 assign(op1, get_gpr_hw3(r1));
3515 op2 = i2;
3516 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3517 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3518 put_gpr_hw3(r1, mkexpr(result));
3519
3520 return "nill";
3521}
3522
florian55085f82012-11-21 00:36:55 +00003523static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003524s390_irgen_BASR(UChar r1, UChar r2)
3525{
3526 IRTemp target = newTemp(Ity_I64);
3527
3528 if (r2 == 0) {
3529 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3530 } else {
3531 if (r1 != r2) {
3532 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3533 call_function(get_gpr_dw0(r2));
3534 } else {
3535 assign(target, get_gpr_dw0(r2));
3536 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3537 call_function(mkexpr(target));
3538 }
3539 }
3540
3541 return "basr";
3542}
3543
florian55085f82012-11-21 00:36:55 +00003544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003545s390_irgen_BAS(UChar r1, IRTemp op2addr)
3546{
3547 IRTemp target = newTemp(Ity_I64);
3548
3549 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3550 assign(target, mkexpr(op2addr));
3551 call_function(mkexpr(target));
3552
3553 return "bas";
3554}
3555
florian55085f82012-11-21 00:36:55 +00003556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003557s390_irgen_BCR(UChar r1, UChar r2)
3558{
3559 IRTemp cond = newTemp(Ity_I32);
3560
sewardja52e37e2011-04-28 18:48:06 +00003561 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3562 stmt(IRStmt_MBE(Imbe_Fence));
3563 }
3564
sewardj2019a972011-03-07 16:04:07 +00003565 if ((r2 == 0) || (r1 == 0)) {
3566 } else {
3567 if (r1 == 15) {
3568 return_from_function(get_gpr_dw0(r2));
3569 } else {
3570 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003571 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3572 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003573 }
3574 }
sewardj7ee97522011-05-09 21:45:04 +00003575 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003576 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3577
3578 return "bcr";
3579}
3580
florian55085f82012-11-21 00:36:55 +00003581static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003582s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3583{
3584 IRTemp cond = newTemp(Ity_I32);
3585
3586 if (r1 == 0) {
3587 } else {
3588 if (r1 == 15) {
3589 always_goto(mkexpr(op2addr));
3590 } else {
3591 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003592 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3593 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003594 }
3595 }
sewardj7ee97522011-05-09 21:45:04 +00003596 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003597 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3598
3599 return "bc";
3600}
3601
florian55085f82012-11-21 00:36:55 +00003602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003603s390_irgen_BCTR(UChar r1, UChar r2)
3604{
3605 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3606 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003607 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3608 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003609 }
3610
3611 return "bctr";
3612}
3613
florian55085f82012-11-21 00:36:55 +00003614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003615s390_irgen_BCTGR(UChar r1, UChar r2)
3616{
3617 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3618 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003619 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3620 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003621 }
3622
3623 return "bctgr";
3624}
3625
florian55085f82012-11-21 00:36:55 +00003626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003627s390_irgen_BCT(UChar r1, IRTemp op2addr)
3628{
3629 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003630 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3631 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003632
3633 return "bct";
3634}
3635
florian55085f82012-11-21 00:36:55 +00003636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003637s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3638{
3639 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003640 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3641 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003642
3643 return "bctg";
3644}
3645
florian55085f82012-11-21 00:36:55 +00003646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003647s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3648{
3649 IRTemp value = newTemp(Ity_I32);
3650
3651 assign(value, get_gpr_w1(r3 | 1));
3652 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003653 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3654 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003655
3656 return "bxh";
3657}
3658
florian55085f82012-11-21 00:36:55 +00003659static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003660s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3661{
3662 IRTemp value = newTemp(Ity_I64);
3663
3664 assign(value, get_gpr_dw0(r3 | 1));
3665 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003666 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3667 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003668
3669 return "bxhg";
3670}
3671
florian55085f82012-11-21 00:36:55 +00003672static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003673s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3674{
3675 IRTemp value = newTemp(Ity_I32);
3676
3677 assign(value, get_gpr_w1(r3 | 1));
3678 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003679 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3680 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003681
3682 return "bxle";
3683}
3684
florian55085f82012-11-21 00:36:55 +00003685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003686s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3687{
3688 IRTemp value = newTemp(Ity_I64);
3689
3690 assign(value, get_gpr_dw0(r3 | 1));
3691 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003692 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3693 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003694
3695 return "bxleg";
3696}
3697
florian55085f82012-11-21 00:36:55 +00003698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003699s390_irgen_BRAS(UChar r1, UShort i2)
3700{
3701 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003702 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003703
3704 return "bras";
3705}
3706
florian55085f82012-11-21 00:36:55 +00003707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003708s390_irgen_BRASL(UChar r1, UInt i2)
3709{
3710 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003711 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003712
3713 return "brasl";
3714}
3715
florian55085f82012-11-21 00:36:55 +00003716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003717s390_irgen_BRC(UChar r1, UShort i2)
3718{
3719 IRTemp cond = newTemp(Ity_I32);
3720
3721 if (r1 == 0) {
3722 } else {
3723 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003724 always_goto_and_chase(
3725 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003726 } else {
3727 assign(cond, s390_call_calculate_cond(r1));
3728 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3729 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3730
3731 }
3732 }
sewardj7ee97522011-05-09 21:45:04 +00003733 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003734 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3735
3736 return "brc";
3737}
3738
florian55085f82012-11-21 00:36:55 +00003739static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003740s390_irgen_BRCL(UChar r1, UInt i2)
3741{
3742 IRTemp cond = newTemp(Ity_I32);
3743
3744 if (r1 == 0) {
3745 } else {
3746 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003747 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003748 } else {
3749 assign(cond, s390_call_calculate_cond(r1));
3750 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3751 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3752 }
3753 }
sewardj7ee97522011-05-09 21:45:04 +00003754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003755 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3756
3757 return "brcl";
3758}
3759
florian55085f82012-11-21 00:36:55 +00003760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003761s390_irgen_BRCT(UChar r1, UShort i2)
3762{
3763 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3764 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3765 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3766
3767 return "brct";
3768}
3769
florian55085f82012-11-21 00:36:55 +00003770static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003771s390_irgen_BRCTG(UChar r1, UShort i2)
3772{
3773 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3774 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3775 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3776
3777 return "brctg";
3778}
3779
florian55085f82012-11-21 00:36:55 +00003780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003781s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3782{
3783 IRTemp value = newTemp(Ity_I32);
3784
3785 assign(value, get_gpr_w1(r3 | 1));
3786 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3787 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3788 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3789
3790 return "brxh";
3791}
3792
florian55085f82012-11-21 00:36:55 +00003793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003794s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3795{
3796 IRTemp value = newTemp(Ity_I64);
3797
3798 assign(value, get_gpr_dw0(r3 | 1));
3799 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3800 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3801 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3802
3803 return "brxhg";
3804}
3805
florian55085f82012-11-21 00:36:55 +00003806static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003807s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3808{
3809 IRTemp value = newTemp(Ity_I32);
3810
3811 assign(value, get_gpr_w1(r3 | 1));
3812 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3813 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3814 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3815
3816 return "brxle";
3817}
3818
florian55085f82012-11-21 00:36:55 +00003819static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003820s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3821{
3822 IRTemp value = newTemp(Ity_I64);
3823
3824 assign(value, get_gpr_dw0(r3 | 1));
3825 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3826 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3827 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3828
3829 return "brxlg";
3830}
3831
florian55085f82012-11-21 00:36:55 +00003832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003833s390_irgen_CR(UChar r1, UChar r2)
3834{
3835 IRTemp op1 = newTemp(Ity_I32);
3836 IRTemp op2 = newTemp(Ity_I32);
3837
3838 assign(op1, get_gpr_w1(r1));
3839 assign(op2, get_gpr_w1(r2));
3840 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3841
3842 return "cr";
3843}
3844
florian55085f82012-11-21 00:36:55 +00003845static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003846s390_irgen_CGR(UChar r1, UChar r2)
3847{
3848 IRTemp op1 = newTemp(Ity_I64);
3849 IRTemp op2 = newTemp(Ity_I64);
3850
3851 assign(op1, get_gpr_dw0(r1));
3852 assign(op2, get_gpr_dw0(r2));
3853 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3854
3855 return "cgr";
3856}
3857
florian55085f82012-11-21 00:36:55 +00003858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003859s390_irgen_CGFR(UChar r1, UChar r2)
3860{
3861 IRTemp op1 = newTemp(Ity_I64);
3862 IRTemp op2 = newTemp(Ity_I64);
3863
3864 assign(op1, get_gpr_dw0(r1));
3865 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3866 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3867
3868 return "cgfr";
3869}
3870
florian55085f82012-11-21 00:36:55 +00003871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003872s390_irgen_C(UChar r1, IRTemp op2addr)
3873{
3874 IRTemp op1 = newTemp(Ity_I32);
3875 IRTemp op2 = newTemp(Ity_I32);
3876
3877 assign(op1, get_gpr_w1(r1));
3878 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3879 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3880
3881 return "c";
3882}
3883
florian55085f82012-11-21 00:36:55 +00003884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003885s390_irgen_CY(UChar r1, IRTemp op2addr)
3886{
3887 IRTemp op1 = newTemp(Ity_I32);
3888 IRTemp op2 = newTemp(Ity_I32);
3889
3890 assign(op1, get_gpr_w1(r1));
3891 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3892 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3893
3894 return "cy";
3895}
3896
florian55085f82012-11-21 00:36:55 +00003897static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003898s390_irgen_CG(UChar r1, IRTemp op2addr)
3899{
3900 IRTemp op1 = newTemp(Ity_I64);
3901 IRTemp op2 = newTemp(Ity_I64);
3902
3903 assign(op1, get_gpr_dw0(r1));
3904 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3905 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3906
3907 return "cg";
3908}
3909
florian55085f82012-11-21 00:36:55 +00003910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003911s390_irgen_CGF(UChar r1, IRTemp op2addr)
3912{
3913 IRTemp op1 = newTemp(Ity_I64);
3914 IRTemp op2 = newTemp(Ity_I64);
3915
3916 assign(op1, get_gpr_dw0(r1));
3917 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3918 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3919
3920 return "cgf";
3921}
3922
florian55085f82012-11-21 00:36:55 +00003923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003924s390_irgen_CFI(UChar r1, UInt i2)
3925{
3926 IRTemp op1 = newTemp(Ity_I32);
3927 Int op2;
3928
3929 assign(op1, get_gpr_w1(r1));
3930 op2 = (Int)i2;
3931 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3932 mkU32((UInt)op2)));
3933
3934 return "cfi";
3935}
3936
florian55085f82012-11-21 00:36:55 +00003937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003938s390_irgen_CGFI(UChar r1, UInt i2)
3939{
3940 IRTemp op1 = newTemp(Ity_I64);
3941 Long op2;
3942
3943 assign(op1, get_gpr_dw0(r1));
3944 op2 = (Long)(Int)i2;
3945 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3946 mkU64((ULong)op2)));
3947
3948 return "cgfi";
3949}
3950
florian55085f82012-11-21 00:36:55 +00003951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003952s390_irgen_CRL(UChar r1, UInt i2)
3953{
3954 IRTemp op1 = newTemp(Ity_I32);
3955 IRTemp op2 = newTemp(Ity_I32);
3956
3957 assign(op1, get_gpr_w1(r1));
3958 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3959 i2 << 1))));
3960 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3961
3962 return "crl";
3963}
3964
florian55085f82012-11-21 00:36:55 +00003965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003966s390_irgen_CGRL(UChar r1, UInt i2)
3967{
3968 IRTemp op1 = newTemp(Ity_I64);
3969 IRTemp op2 = newTemp(Ity_I64);
3970
3971 assign(op1, get_gpr_dw0(r1));
3972 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3973 i2 << 1))));
3974 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3975
3976 return "cgrl";
3977}
3978
florian55085f82012-11-21 00:36:55 +00003979static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003980s390_irgen_CGFRL(UChar r1, UInt i2)
3981{
3982 IRTemp op1 = newTemp(Ity_I64);
3983 IRTemp op2 = newTemp(Ity_I64);
3984
3985 assign(op1, get_gpr_dw0(r1));
3986 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3987 ((ULong)(Long)(Int)i2 << 1)))));
3988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3989
3990 return "cgfrl";
3991}
3992
florian55085f82012-11-21 00:36:55 +00003993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003994s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3995{
3996 IRTemp op1 = newTemp(Ity_I32);
3997 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003998 IRTemp cond = newTemp(Ity_I32);
3999
4000 if (m3 == 0) {
4001 } else {
4002 if (m3 == 14) {
4003 always_goto(mkexpr(op4addr));
4004 } else {
4005 assign(op1, get_gpr_w1(r1));
4006 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004007 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4008 op1, op2));
florianf321da72012-07-21 20:32:57 +00004009 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4010 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004011 }
4012 }
4013
4014 return "crb";
4015}
4016
florian55085f82012-11-21 00:36:55 +00004017static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004018s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4019{
4020 IRTemp op1 = newTemp(Ity_I64);
4021 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004022 IRTemp cond = newTemp(Ity_I32);
4023
4024 if (m3 == 0) {
4025 } else {
4026 if (m3 == 14) {
4027 always_goto(mkexpr(op4addr));
4028 } else {
4029 assign(op1, get_gpr_dw0(r1));
4030 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004031 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4032 op1, op2));
florianf321da72012-07-21 20:32:57 +00004033 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4034 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004035 }
4036 }
4037
4038 return "cgrb";
4039}
4040
florian55085f82012-11-21 00:36:55 +00004041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004042s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4043{
4044 IRTemp op1 = newTemp(Ity_I32);
4045 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004046 IRTemp cond = newTemp(Ity_I32);
4047
4048 if (m3 == 0) {
4049 } else {
4050 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004051 always_goto_and_chase(
4052 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004053 } else {
4054 assign(op1, get_gpr_w1(r1));
4055 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004056 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4057 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004058 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4059 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4060
4061 }
4062 }
4063
4064 return "crj";
4065}
4066
florian55085f82012-11-21 00:36:55 +00004067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004068s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4069{
4070 IRTemp op1 = newTemp(Ity_I64);
4071 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004072 IRTemp cond = newTemp(Ity_I32);
4073
4074 if (m3 == 0) {
4075 } else {
4076 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004077 always_goto_and_chase(
4078 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004079 } else {
4080 assign(op1, get_gpr_dw0(r1));
4081 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004082 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4083 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004084 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4085 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4086
4087 }
4088 }
4089
4090 return "cgrj";
4091}
4092
florian55085f82012-11-21 00:36:55 +00004093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004094s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4095{
4096 IRTemp op1 = newTemp(Ity_I32);
4097 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004098 IRTemp cond = newTemp(Ity_I32);
4099
4100 if (m3 == 0) {
4101 } else {
4102 if (m3 == 14) {
4103 always_goto(mkexpr(op4addr));
4104 } else {
4105 assign(op1, get_gpr_w1(r1));
4106 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004107 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4108 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004109 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4110 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004111 }
4112 }
4113
4114 return "cib";
4115}
4116
florian55085f82012-11-21 00:36:55 +00004117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004118s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4119{
4120 IRTemp op1 = newTemp(Ity_I64);
4121 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004122 IRTemp cond = newTemp(Ity_I32);
4123
4124 if (m3 == 0) {
4125 } else {
4126 if (m3 == 14) {
4127 always_goto(mkexpr(op4addr));
4128 } else {
4129 assign(op1, get_gpr_dw0(r1));
4130 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004131 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4132 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004133 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4134 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004135 }
4136 }
4137
4138 return "cgib";
4139}
4140
florian55085f82012-11-21 00:36:55 +00004141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004142s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4143{
4144 IRTemp op1 = newTemp(Ity_I32);
4145 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004146 IRTemp cond = newTemp(Ity_I32);
4147
4148 if (m3 == 0) {
4149 } else {
4150 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004151 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004152 } else {
4153 assign(op1, get_gpr_w1(r1));
4154 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004155 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4156 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004157 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4158 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4159
4160 }
4161 }
4162
4163 return "cij";
4164}
4165
florian55085f82012-11-21 00:36:55 +00004166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004167s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4168{
4169 IRTemp op1 = newTemp(Ity_I64);
4170 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004171 IRTemp cond = newTemp(Ity_I32);
4172
4173 if (m3 == 0) {
4174 } else {
4175 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004176 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004177 } else {
4178 assign(op1, get_gpr_dw0(r1));
4179 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004180 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4181 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004182 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4183 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4184
4185 }
4186 }
4187
4188 return "cgij";
4189}
4190
florian55085f82012-11-21 00:36:55 +00004191static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004192s390_irgen_CH(UChar r1, IRTemp op2addr)
4193{
4194 IRTemp op1 = newTemp(Ity_I32);
4195 IRTemp op2 = newTemp(Ity_I32);
4196
4197 assign(op1, get_gpr_w1(r1));
4198 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4199 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4200
4201 return "ch";
4202}
4203
florian55085f82012-11-21 00:36:55 +00004204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004205s390_irgen_CHY(UChar r1, IRTemp op2addr)
4206{
4207 IRTemp op1 = newTemp(Ity_I32);
4208 IRTemp op2 = newTemp(Ity_I32);
4209
4210 assign(op1, get_gpr_w1(r1));
4211 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4212 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4213
4214 return "chy";
4215}
4216
florian55085f82012-11-21 00:36:55 +00004217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004218s390_irgen_CGH(UChar r1, IRTemp op2addr)
4219{
4220 IRTemp op1 = newTemp(Ity_I64);
4221 IRTemp op2 = newTemp(Ity_I64);
4222
4223 assign(op1, get_gpr_dw0(r1));
4224 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4225 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4226
4227 return "cgh";
4228}
4229
florian55085f82012-11-21 00:36:55 +00004230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004231s390_irgen_CHI(UChar r1, UShort i2)
4232{
4233 IRTemp op1 = newTemp(Ity_I32);
4234 Int op2;
4235
4236 assign(op1, get_gpr_w1(r1));
4237 op2 = (Int)(Short)i2;
4238 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4239 mkU32((UInt)op2)));
4240
4241 return "chi";
4242}
4243
florian55085f82012-11-21 00:36:55 +00004244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004245s390_irgen_CGHI(UChar r1, UShort i2)
4246{
4247 IRTemp op1 = newTemp(Ity_I64);
4248 Long op2;
4249
4250 assign(op1, get_gpr_dw0(r1));
4251 op2 = (Long)(Short)i2;
4252 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4253 mkU64((ULong)op2)));
4254
4255 return "cghi";
4256}
4257
florian55085f82012-11-21 00:36:55 +00004258static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004259s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4260{
4261 IRTemp op1 = newTemp(Ity_I16);
4262 Short op2;
4263
4264 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4265 op2 = (Short)i2;
4266 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4267 mkU16((UShort)op2)));
4268
4269 return "chhsi";
4270}
4271
florian55085f82012-11-21 00:36:55 +00004272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004273s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4274{
4275 IRTemp op1 = newTemp(Ity_I32);
4276 Int op2;
4277
4278 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4279 op2 = (Int)(Short)i2;
4280 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4281 mkU32((UInt)op2)));
4282
4283 return "chsi";
4284}
4285
florian55085f82012-11-21 00:36:55 +00004286static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004287s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4288{
4289 IRTemp op1 = newTemp(Ity_I64);
4290 Long op2;
4291
4292 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4293 op2 = (Long)(Short)i2;
4294 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4295 mkU64((ULong)op2)));
4296
4297 return "cghsi";
4298}
4299
florian55085f82012-11-21 00:36:55 +00004300static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004301s390_irgen_CHRL(UChar r1, UInt i2)
4302{
4303 IRTemp op1 = newTemp(Ity_I32);
4304 IRTemp op2 = newTemp(Ity_I32);
4305
4306 assign(op1, get_gpr_w1(r1));
4307 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4308 ((ULong)(Long)(Int)i2 << 1)))));
4309 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4310
4311 return "chrl";
4312}
4313
florian55085f82012-11-21 00:36:55 +00004314static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004315s390_irgen_CGHRL(UChar r1, UInt i2)
4316{
4317 IRTemp op1 = newTemp(Ity_I64);
4318 IRTemp op2 = newTemp(Ity_I64);
4319
4320 assign(op1, get_gpr_dw0(r1));
4321 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4322 ((ULong)(Long)(Int)i2 << 1)))));
4323 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4324
4325 return "cghrl";
4326}
4327
florian55085f82012-11-21 00:36:55 +00004328static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004329s390_irgen_CHHR(UChar r1, UChar r2)
4330{
4331 IRTemp op1 = newTemp(Ity_I32);
4332 IRTemp op2 = newTemp(Ity_I32);
4333
4334 assign(op1, get_gpr_w0(r1));
4335 assign(op2, get_gpr_w0(r2));
4336 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4337
4338 return "chhr";
4339}
4340
florian55085f82012-11-21 00:36:55 +00004341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004342s390_irgen_CHLR(UChar r1, UChar r2)
4343{
4344 IRTemp op1 = newTemp(Ity_I32);
4345 IRTemp op2 = newTemp(Ity_I32);
4346
4347 assign(op1, get_gpr_w0(r1));
4348 assign(op2, get_gpr_w1(r2));
4349 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4350
4351 return "chlr";
4352}
4353
florian55085f82012-11-21 00:36:55 +00004354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004355s390_irgen_CHF(UChar r1, IRTemp op2addr)
4356{
4357 IRTemp op1 = newTemp(Ity_I32);
4358 IRTemp op2 = newTemp(Ity_I32);
4359
4360 assign(op1, get_gpr_w0(r1));
4361 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4362 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4363
4364 return "chf";
4365}
4366
florian55085f82012-11-21 00:36:55 +00004367static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004368s390_irgen_CIH(UChar r1, UInt i2)
4369{
4370 IRTemp op1 = newTemp(Ity_I32);
4371 Int op2;
4372
4373 assign(op1, get_gpr_w0(r1));
4374 op2 = (Int)i2;
4375 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4376 mkU32((UInt)op2)));
4377
4378 return "cih";
4379}
4380
florian55085f82012-11-21 00:36:55 +00004381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004382s390_irgen_CLR(UChar r1, UChar r2)
4383{
4384 IRTemp op1 = newTemp(Ity_I32);
4385 IRTemp op2 = newTemp(Ity_I32);
4386
4387 assign(op1, get_gpr_w1(r1));
4388 assign(op2, get_gpr_w1(r2));
4389 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4390
4391 return "clr";
4392}
4393
florian55085f82012-11-21 00:36:55 +00004394static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004395s390_irgen_CLGR(UChar r1, UChar r2)
4396{
4397 IRTemp op1 = newTemp(Ity_I64);
4398 IRTemp op2 = newTemp(Ity_I64);
4399
4400 assign(op1, get_gpr_dw0(r1));
4401 assign(op2, get_gpr_dw0(r2));
4402 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4403
4404 return "clgr";
4405}
4406
florian55085f82012-11-21 00:36:55 +00004407static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004408s390_irgen_CLGFR(UChar r1, UChar r2)
4409{
4410 IRTemp op1 = newTemp(Ity_I64);
4411 IRTemp op2 = newTemp(Ity_I64);
4412
4413 assign(op1, get_gpr_dw0(r1));
4414 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4415 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4416
4417 return "clgfr";
4418}
4419
florian55085f82012-11-21 00:36:55 +00004420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004421s390_irgen_CL(UChar r1, IRTemp op2addr)
4422{
4423 IRTemp op1 = newTemp(Ity_I32);
4424 IRTemp op2 = newTemp(Ity_I32);
4425
4426 assign(op1, get_gpr_w1(r1));
4427 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4428 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4429
4430 return "cl";
4431}
4432
florian55085f82012-11-21 00:36:55 +00004433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004434s390_irgen_CLY(UChar r1, IRTemp op2addr)
4435{
4436 IRTemp op1 = newTemp(Ity_I32);
4437 IRTemp op2 = newTemp(Ity_I32);
4438
4439 assign(op1, get_gpr_w1(r1));
4440 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4441 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4442
4443 return "cly";
4444}
4445
florian55085f82012-11-21 00:36:55 +00004446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004447s390_irgen_CLG(UChar r1, IRTemp op2addr)
4448{
4449 IRTemp op1 = newTemp(Ity_I64);
4450 IRTemp op2 = newTemp(Ity_I64);
4451
4452 assign(op1, get_gpr_dw0(r1));
4453 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4454 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4455
4456 return "clg";
4457}
4458
florian55085f82012-11-21 00:36:55 +00004459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004460s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4461{
4462 IRTemp op1 = newTemp(Ity_I64);
4463 IRTemp op2 = newTemp(Ity_I64);
4464
4465 assign(op1, get_gpr_dw0(r1));
4466 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4467 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4468
4469 return "clgf";
4470}
4471
florian55085f82012-11-21 00:36:55 +00004472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004473s390_irgen_CLFI(UChar r1, UInt i2)
4474{
4475 IRTemp op1 = newTemp(Ity_I32);
4476 UInt op2;
4477
4478 assign(op1, get_gpr_w1(r1));
4479 op2 = i2;
4480 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4481 mkU32(op2)));
4482
4483 return "clfi";
4484}
4485
florian55085f82012-11-21 00:36:55 +00004486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004487s390_irgen_CLGFI(UChar r1, UInt i2)
4488{
4489 IRTemp op1 = newTemp(Ity_I64);
4490 ULong op2;
4491
4492 assign(op1, get_gpr_dw0(r1));
4493 op2 = (ULong)i2;
4494 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4495 mkU64(op2)));
4496
4497 return "clgfi";
4498}
4499
florian55085f82012-11-21 00:36:55 +00004500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004501s390_irgen_CLI(UChar i2, IRTemp op1addr)
4502{
4503 IRTemp op1 = newTemp(Ity_I8);
4504 UChar op2;
4505
4506 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4507 op2 = i2;
4508 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4509 mkU8(op2)));
4510
4511 return "cli";
4512}
4513
florian55085f82012-11-21 00:36:55 +00004514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004515s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4516{
4517 IRTemp op1 = newTemp(Ity_I8);
4518 UChar op2;
4519
4520 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4521 op2 = i2;
4522 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4523 mkU8(op2)));
4524
4525 return "cliy";
4526}
4527
florian55085f82012-11-21 00:36:55 +00004528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004529s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4530{
4531 IRTemp op1 = newTemp(Ity_I32);
4532 UInt op2;
4533
4534 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4535 op2 = (UInt)i2;
4536 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4537 mkU32(op2)));
4538
4539 return "clfhsi";
4540}
4541
florian55085f82012-11-21 00:36:55 +00004542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004543s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4544{
4545 IRTemp op1 = newTemp(Ity_I64);
4546 ULong op2;
4547
4548 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4549 op2 = (ULong)i2;
4550 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4551 mkU64(op2)));
4552
4553 return "clghsi";
4554}
4555
florian55085f82012-11-21 00:36:55 +00004556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004557s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4558{
4559 IRTemp op1 = newTemp(Ity_I16);
4560 UShort op2;
4561
4562 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4563 op2 = i2;
4564 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4565 mkU16(op2)));
4566
4567 return "clhhsi";
4568}
4569
florian55085f82012-11-21 00:36:55 +00004570static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004571s390_irgen_CLRL(UChar r1, UInt i2)
4572{
4573 IRTemp op1 = newTemp(Ity_I32);
4574 IRTemp op2 = newTemp(Ity_I32);
4575
4576 assign(op1, get_gpr_w1(r1));
4577 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4578 i2 << 1))));
4579 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4580
4581 return "clrl";
4582}
4583
florian55085f82012-11-21 00:36:55 +00004584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004585s390_irgen_CLGRL(UChar r1, UInt i2)
4586{
4587 IRTemp op1 = newTemp(Ity_I64);
4588 IRTemp op2 = newTemp(Ity_I64);
4589
4590 assign(op1, get_gpr_dw0(r1));
4591 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4592 i2 << 1))));
4593 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4594
4595 return "clgrl";
4596}
4597
florian55085f82012-11-21 00:36:55 +00004598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004599s390_irgen_CLGFRL(UChar r1, UInt i2)
4600{
4601 IRTemp op1 = newTemp(Ity_I64);
4602 IRTemp op2 = newTemp(Ity_I64);
4603
4604 assign(op1, get_gpr_dw0(r1));
4605 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4606 ((ULong)(Long)(Int)i2 << 1)))));
4607 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4608
4609 return "clgfrl";
4610}
4611
florian55085f82012-11-21 00:36:55 +00004612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004613s390_irgen_CLHRL(UChar r1, UInt i2)
4614{
4615 IRTemp op1 = newTemp(Ity_I32);
4616 IRTemp op2 = newTemp(Ity_I32);
4617
4618 assign(op1, get_gpr_w1(r1));
4619 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4620 ((ULong)(Long)(Int)i2 << 1)))));
4621 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4622
4623 return "clhrl";
4624}
4625
florian55085f82012-11-21 00:36:55 +00004626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004627s390_irgen_CLGHRL(UChar r1, UInt i2)
4628{
4629 IRTemp op1 = newTemp(Ity_I64);
4630 IRTemp op2 = newTemp(Ity_I64);
4631
4632 assign(op1, get_gpr_dw0(r1));
4633 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4634 ((ULong)(Long)(Int)i2 << 1)))));
4635 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4636
4637 return "clghrl";
4638}
4639
florian55085f82012-11-21 00:36:55 +00004640static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004641s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4642{
4643 IRTemp op1 = newTemp(Ity_I32);
4644 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004645 IRTemp cond = newTemp(Ity_I32);
4646
4647 if (m3 == 0) {
4648 } else {
4649 if (m3 == 14) {
4650 always_goto(mkexpr(op4addr));
4651 } else {
4652 assign(op1, get_gpr_w1(r1));
4653 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004654 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4655 op1, op2));
florianf321da72012-07-21 20:32:57 +00004656 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4657 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004658 }
4659 }
4660
4661 return "clrb";
4662}
4663
florian55085f82012-11-21 00:36:55 +00004664static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004665s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4666{
4667 IRTemp op1 = newTemp(Ity_I64);
4668 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004669 IRTemp cond = newTemp(Ity_I32);
4670
4671 if (m3 == 0) {
4672 } else {
4673 if (m3 == 14) {
4674 always_goto(mkexpr(op4addr));
4675 } else {
4676 assign(op1, get_gpr_dw0(r1));
4677 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004678 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4679 op1, op2));
florianf321da72012-07-21 20:32:57 +00004680 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4681 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004682 }
4683 }
4684
4685 return "clgrb";
4686}
4687
florian55085f82012-11-21 00:36:55 +00004688static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004689s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4690{
4691 IRTemp op1 = newTemp(Ity_I32);
4692 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004693 IRTemp cond = newTemp(Ity_I32);
4694
4695 if (m3 == 0) {
4696 } else {
4697 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004698 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004699 } else {
4700 assign(op1, get_gpr_w1(r1));
4701 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004702 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4703 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004704 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4705 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4706
4707 }
4708 }
4709
4710 return "clrj";
4711}
4712
florian55085f82012-11-21 00:36:55 +00004713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004714s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4715{
4716 IRTemp op1 = newTemp(Ity_I64);
4717 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004718 IRTemp cond = newTemp(Ity_I32);
4719
4720 if (m3 == 0) {
4721 } else {
4722 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004723 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004724 } else {
4725 assign(op1, get_gpr_dw0(r1));
4726 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004727 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4728 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004729 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4730 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4731
4732 }
4733 }
4734
4735 return "clgrj";
4736}
4737
florian55085f82012-11-21 00:36:55 +00004738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004739s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4740{
4741 IRTemp op1 = newTemp(Ity_I32);
4742 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004743 IRTemp cond = newTemp(Ity_I32);
4744
4745 if (m3 == 0) {
4746 } else {
4747 if (m3 == 14) {
4748 always_goto(mkexpr(op4addr));
4749 } else {
4750 assign(op1, get_gpr_w1(r1));
4751 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004752 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4753 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004754 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4755 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004756 }
4757 }
4758
4759 return "clib";
4760}
4761
florian55085f82012-11-21 00:36:55 +00004762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004763s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4764{
4765 IRTemp op1 = newTemp(Ity_I64);
4766 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004767 IRTemp cond = newTemp(Ity_I32);
4768
4769 if (m3 == 0) {
4770 } else {
4771 if (m3 == 14) {
4772 always_goto(mkexpr(op4addr));
4773 } else {
4774 assign(op1, get_gpr_dw0(r1));
4775 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004776 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4777 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004778 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4779 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004780 }
4781 }
4782
4783 return "clgib";
4784}
4785
florian55085f82012-11-21 00:36:55 +00004786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004787s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4788{
4789 IRTemp op1 = newTemp(Ity_I32);
4790 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004791 IRTemp cond = newTemp(Ity_I32);
4792
4793 if (m3 == 0) {
4794 } else {
4795 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004796 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004797 } else {
4798 assign(op1, get_gpr_w1(r1));
4799 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004800 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4801 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004802 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4803 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4804
4805 }
4806 }
4807
4808 return "clij";
4809}
4810
florian55085f82012-11-21 00:36:55 +00004811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004812s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4813{
4814 IRTemp op1 = newTemp(Ity_I64);
4815 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004816 IRTemp cond = newTemp(Ity_I32);
4817
4818 if (m3 == 0) {
4819 } else {
4820 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004821 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004822 } else {
4823 assign(op1, get_gpr_dw0(r1));
4824 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004825 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4826 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004827 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4828 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4829
4830 }
4831 }
4832
4833 return "clgij";
4834}
4835
florian55085f82012-11-21 00:36:55 +00004836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004837s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4838{
4839 IRTemp op1 = newTemp(Ity_I32);
4840 IRTemp op2 = newTemp(Ity_I32);
4841 IRTemp b0 = newTemp(Ity_I32);
4842 IRTemp b1 = newTemp(Ity_I32);
4843 IRTemp b2 = newTemp(Ity_I32);
4844 IRTemp b3 = newTemp(Ity_I32);
4845 IRTemp c0 = newTemp(Ity_I32);
4846 IRTemp c1 = newTemp(Ity_I32);
4847 IRTemp c2 = newTemp(Ity_I32);
4848 IRTemp c3 = newTemp(Ity_I32);
4849 UChar n;
4850
4851 n = 0;
4852 if ((r3 & 8) != 0) {
4853 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4854 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4855 n = n + 1;
4856 } else {
4857 assign(b0, mkU32(0));
4858 assign(c0, mkU32(0));
4859 }
4860 if ((r3 & 4) != 0) {
4861 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4862 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4863 mkU64(n)))));
4864 n = n + 1;
4865 } else {
4866 assign(b1, mkU32(0));
4867 assign(c1, mkU32(0));
4868 }
4869 if ((r3 & 2) != 0) {
4870 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4871 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4872 mkU64(n)))));
4873 n = n + 1;
4874 } else {
4875 assign(b2, mkU32(0));
4876 assign(c2, mkU32(0));
4877 }
4878 if ((r3 & 1) != 0) {
4879 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4880 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4881 mkU64(n)))));
4882 n = n + 1;
4883 } else {
4884 assign(b3, mkU32(0));
4885 assign(c3, mkU32(0));
4886 }
4887 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4888 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4889 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4890 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4891 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4892 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4893 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4894
4895 return "clm";
4896}
4897
florian55085f82012-11-21 00:36:55 +00004898static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004899s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4900{
4901 IRTemp op1 = newTemp(Ity_I32);
4902 IRTemp op2 = newTemp(Ity_I32);
4903 IRTemp b0 = newTemp(Ity_I32);
4904 IRTemp b1 = newTemp(Ity_I32);
4905 IRTemp b2 = newTemp(Ity_I32);
4906 IRTemp b3 = newTemp(Ity_I32);
4907 IRTemp c0 = newTemp(Ity_I32);
4908 IRTemp c1 = newTemp(Ity_I32);
4909 IRTemp c2 = newTemp(Ity_I32);
4910 IRTemp c3 = newTemp(Ity_I32);
4911 UChar n;
4912
4913 n = 0;
4914 if ((r3 & 8) != 0) {
4915 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4916 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4917 n = n + 1;
4918 } else {
4919 assign(b0, mkU32(0));
4920 assign(c0, mkU32(0));
4921 }
4922 if ((r3 & 4) != 0) {
4923 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4924 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4925 mkU64(n)))));
4926 n = n + 1;
4927 } else {
4928 assign(b1, mkU32(0));
4929 assign(c1, mkU32(0));
4930 }
4931 if ((r3 & 2) != 0) {
4932 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4933 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4934 mkU64(n)))));
4935 n = n + 1;
4936 } else {
4937 assign(b2, mkU32(0));
4938 assign(c2, mkU32(0));
4939 }
4940 if ((r3 & 1) != 0) {
4941 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4942 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4943 mkU64(n)))));
4944 n = n + 1;
4945 } else {
4946 assign(b3, mkU32(0));
4947 assign(c3, mkU32(0));
4948 }
4949 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4950 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4951 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4952 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4953 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4954 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4955 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4956
4957 return "clmy";
4958}
4959
florian55085f82012-11-21 00:36:55 +00004960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004961s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4962{
4963 IRTemp op1 = newTemp(Ity_I32);
4964 IRTemp op2 = newTemp(Ity_I32);
4965 IRTemp b0 = newTemp(Ity_I32);
4966 IRTemp b1 = newTemp(Ity_I32);
4967 IRTemp b2 = newTemp(Ity_I32);
4968 IRTemp b3 = newTemp(Ity_I32);
4969 IRTemp c0 = newTemp(Ity_I32);
4970 IRTemp c1 = newTemp(Ity_I32);
4971 IRTemp c2 = newTemp(Ity_I32);
4972 IRTemp c3 = newTemp(Ity_I32);
4973 UChar n;
4974
4975 n = 0;
4976 if ((r3 & 8) != 0) {
4977 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4978 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4979 n = n + 1;
4980 } else {
4981 assign(b0, mkU32(0));
4982 assign(c0, mkU32(0));
4983 }
4984 if ((r3 & 4) != 0) {
4985 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4986 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4987 mkU64(n)))));
4988 n = n + 1;
4989 } else {
4990 assign(b1, mkU32(0));
4991 assign(c1, mkU32(0));
4992 }
4993 if ((r3 & 2) != 0) {
4994 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4995 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4996 mkU64(n)))));
4997 n = n + 1;
4998 } else {
4999 assign(b2, mkU32(0));
5000 assign(c2, mkU32(0));
5001 }
5002 if ((r3 & 1) != 0) {
5003 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5004 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5005 mkU64(n)))));
5006 n = n + 1;
5007 } else {
5008 assign(b3, mkU32(0));
5009 assign(c3, mkU32(0));
5010 }
5011 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5012 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5013 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5014 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5015 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5016 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5017 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5018
5019 return "clmh";
5020}
5021
florian55085f82012-11-21 00:36:55 +00005022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005023s390_irgen_CLHHR(UChar r1, UChar r2)
5024{
5025 IRTemp op1 = newTemp(Ity_I32);
5026 IRTemp op2 = newTemp(Ity_I32);
5027
5028 assign(op1, get_gpr_w0(r1));
5029 assign(op2, get_gpr_w0(r2));
5030 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5031
5032 return "clhhr";
5033}
5034
florian55085f82012-11-21 00:36:55 +00005035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005036s390_irgen_CLHLR(UChar r1, UChar r2)
5037{
5038 IRTemp op1 = newTemp(Ity_I32);
5039 IRTemp op2 = newTemp(Ity_I32);
5040
5041 assign(op1, get_gpr_w0(r1));
5042 assign(op2, get_gpr_w1(r2));
5043 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5044
5045 return "clhlr";
5046}
5047
florian55085f82012-11-21 00:36:55 +00005048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005049s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5050{
5051 IRTemp op1 = newTemp(Ity_I32);
5052 IRTemp op2 = newTemp(Ity_I32);
5053
5054 assign(op1, get_gpr_w0(r1));
5055 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5056 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5057
5058 return "clhf";
5059}
5060
florian55085f82012-11-21 00:36:55 +00005061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005062s390_irgen_CLIH(UChar r1, UInt i2)
5063{
5064 IRTemp op1 = newTemp(Ity_I32);
5065 UInt op2;
5066
5067 assign(op1, get_gpr_w0(r1));
5068 op2 = i2;
5069 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5070 mkU32(op2)));
5071
5072 return "clih";
5073}
5074
florian55085f82012-11-21 00:36:55 +00005075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005076s390_irgen_CPYA(UChar r1, UChar r2)
5077{
5078 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005079 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005080 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5081
5082 return "cpya";
5083}
5084
florian55085f82012-11-21 00:36:55 +00005085static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005086s390_irgen_XR(UChar r1, UChar r2)
5087{
5088 IRTemp op1 = newTemp(Ity_I32);
5089 IRTemp op2 = newTemp(Ity_I32);
5090 IRTemp result = newTemp(Ity_I32);
5091
5092 if (r1 == r2) {
5093 assign(result, mkU32(0));
5094 } else {
5095 assign(op1, get_gpr_w1(r1));
5096 assign(op2, get_gpr_w1(r2));
5097 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5098 }
5099 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5100 put_gpr_w1(r1, mkexpr(result));
5101
5102 return "xr";
5103}
5104
florian55085f82012-11-21 00:36:55 +00005105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005106s390_irgen_XGR(UChar r1, UChar r2)
5107{
5108 IRTemp op1 = newTemp(Ity_I64);
5109 IRTemp op2 = newTemp(Ity_I64);
5110 IRTemp result = newTemp(Ity_I64);
5111
5112 if (r1 == r2) {
5113 assign(result, mkU64(0));
5114 } else {
5115 assign(op1, get_gpr_dw0(r1));
5116 assign(op2, get_gpr_dw0(r2));
5117 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5118 }
5119 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5120 put_gpr_dw0(r1, mkexpr(result));
5121
5122 return "xgr";
5123}
5124
florian55085f82012-11-21 00:36:55 +00005125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005126s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5127{
5128 IRTemp op2 = newTemp(Ity_I32);
5129 IRTemp op3 = newTemp(Ity_I32);
5130 IRTemp result = newTemp(Ity_I32);
5131
5132 assign(op2, get_gpr_w1(r2));
5133 assign(op3, get_gpr_w1(r3));
5134 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5135 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5136 put_gpr_w1(r1, mkexpr(result));
5137
5138 return "xrk";
5139}
5140
florian55085f82012-11-21 00:36:55 +00005141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005142s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5143{
5144 IRTemp op2 = newTemp(Ity_I64);
5145 IRTemp op3 = newTemp(Ity_I64);
5146 IRTemp result = newTemp(Ity_I64);
5147
5148 assign(op2, get_gpr_dw0(r2));
5149 assign(op3, get_gpr_dw0(r3));
5150 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5151 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5152 put_gpr_dw0(r1, mkexpr(result));
5153
5154 return "xgrk";
5155}
5156
florian55085f82012-11-21 00:36:55 +00005157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005158s390_irgen_X(UChar r1, IRTemp op2addr)
5159{
5160 IRTemp op1 = newTemp(Ity_I32);
5161 IRTemp op2 = newTemp(Ity_I32);
5162 IRTemp result = newTemp(Ity_I32);
5163
5164 assign(op1, get_gpr_w1(r1));
5165 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5166 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5167 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5168 put_gpr_w1(r1, mkexpr(result));
5169
5170 return "x";
5171}
5172
florian55085f82012-11-21 00:36:55 +00005173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005174s390_irgen_XY(UChar r1, IRTemp op2addr)
5175{
5176 IRTemp op1 = newTemp(Ity_I32);
5177 IRTemp op2 = newTemp(Ity_I32);
5178 IRTemp result = newTemp(Ity_I32);
5179
5180 assign(op1, get_gpr_w1(r1));
5181 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5182 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5183 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5184 put_gpr_w1(r1, mkexpr(result));
5185
5186 return "xy";
5187}
5188
florian55085f82012-11-21 00:36:55 +00005189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005190s390_irgen_XG(UChar r1, IRTemp op2addr)
5191{
5192 IRTemp op1 = newTemp(Ity_I64);
5193 IRTemp op2 = newTemp(Ity_I64);
5194 IRTemp result = newTemp(Ity_I64);
5195
5196 assign(op1, get_gpr_dw0(r1));
5197 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5198 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5199 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5200 put_gpr_dw0(r1, mkexpr(result));
5201
5202 return "xg";
5203}
5204
florian55085f82012-11-21 00:36:55 +00005205static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005206s390_irgen_XI(UChar i2, IRTemp op1addr)
5207{
5208 IRTemp op1 = newTemp(Ity_I8);
5209 UChar op2;
5210 IRTemp result = newTemp(Ity_I8);
5211
5212 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5213 op2 = i2;
5214 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5215 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5216 store(mkexpr(op1addr), mkexpr(result));
5217
5218 return "xi";
5219}
5220
florian55085f82012-11-21 00:36:55 +00005221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005222s390_irgen_XIY(UChar i2, IRTemp op1addr)
5223{
5224 IRTemp op1 = newTemp(Ity_I8);
5225 UChar op2;
5226 IRTemp result = newTemp(Ity_I8);
5227
5228 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5229 op2 = i2;
5230 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5231 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5232 store(mkexpr(op1addr), mkexpr(result));
5233
5234 return "xiy";
5235}
5236
florian55085f82012-11-21 00:36:55 +00005237static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005238s390_irgen_XIHF(UChar r1, UInt i2)
5239{
5240 IRTemp op1 = newTemp(Ity_I32);
5241 UInt op2;
5242 IRTemp result = newTemp(Ity_I32);
5243
5244 assign(op1, get_gpr_w0(r1));
5245 op2 = i2;
5246 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5247 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5248 put_gpr_w0(r1, mkexpr(result));
5249
5250 return "xihf";
5251}
5252
florian55085f82012-11-21 00:36:55 +00005253static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005254s390_irgen_XILF(UChar r1, UInt i2)
5255{
5256 IRTemp op1 = newTemp(Ity_I32);
5257 UInt op2;
5258 IRTemp result = newTemp(Ity_I32);
5259
5260 assign(op1, get_gpr_w1(r1));
5261 op2 = i2;
5262 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5263 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5264 put_gpr_w1(r1, mkexpr(result));
5265
5266 return "xilf";
5267}
5268
florian55085f82012-11-21 00:36:55 +00005269static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005270s390_irgen_EAR(UChar r1, UChar r2)
5271{
5272 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005273 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005274 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5275
5276 return "ear";
5277}
5278
florian55085f82012-11-21 00:36:55 +00005279static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005280s390_irgen_IC(UChar r1, IRTemp op2addr)
5281{
5282 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5283
5284 return "ic";
5285}
5286
florian55085f82012-11-21 00:36:55 +00005287static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005288s390_irgen_ICY(UChar r1, IRTemp op2addr)
5289{
5290 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5291
5292 return "icy";
5293}
5294
florian55085f82012-11-21 00:36:55 +00005295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005296s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5297{
5298 UChar n;
5299 IRTemp result = newTemp(Ity_I32);
5300 UInt mask;
5301
5302 n = 0;
5303 mask = (UInt)r3;
5304 if ((mask & 8) != 0) {
5305 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5306 n = n + 1;
5307 }
5308 if ((mask & 4) != 0) {
5309 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5310
5311 n = n + 1;
5312 }
5313 if ((mask & 2) != 0) {
5314 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5315
5316 n = n + 1;
5317 }
5318 if ((mask & 1) != 0) {
5319 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5320
5321 n = n + 1;
5322 }
5323 assign(result, get_gpr_w1(r1));
5324 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5325 mkU32(mask)));
5326
5327 return "icm";
5328}
5329
florian55085f82012-11-21 00:36:55 +00005330static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005331s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5332{
5333 UChar n;
5334 IRTemp result = newTemp(Ity_I32);
5335 UInt mask;
5336
5337 n = 0;
5338 mask = (UInt)r3;
5339 if ((mask & 8) != 0) {
5340 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5341 n = n + 1;
5342 }
5343 if ((mask & 4) != 0) {
5344 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5345
5346 n = n + 1;
5347 }
5348 if ((mask & 2) != 0) {
5349 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5350
5351 n = n + 1;
5352 }
5353 if ((mask & 1) != 0) {
5354 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5355
5356 n = n + 1;
5357 }
5358 assign(result, get_gpr_w1(r1));
5359 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5360 mkU32(mask)));
5361
5362 return "icmy";
5363}
5364
florian55085f82012-11-21 00:36:55 +00005365static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005366s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5367{
5368 UChar n;
5369 IRTemp result = newTemp(Ity_I32);
5370 UInt mask;
5371
5372 n = 0;
5373 mask = (UInt)r3;
5374 if ((mask & 8) != 0) {
5375 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5376 n = n + 1;
5377 }
5378 if ((mask & 4) != 0) {
5379 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5380
5381 n = n + 1;
5382 }
5383 if ((mask & 2) != 0) {
5384 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5385
5386 n = n + 1;
5387 }
5388 if ((mask & 1) != 0) {
5389 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5390
5391 n = n + 1;
5392 }
5393 assign(result, get_gpr_w0(r1));
5394 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5395 mkU32(mask)));
5396
5397 return "icmh";
5398}
5399
florian55085f82012-11-21 00:36:55 +00005400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005401s390_irgen_IIHF(UChar r1, UInt i2)
5402{
5403 put_gpr_w0(r1, mkU32(i2));
5404
5405 return "iihf";
5406}
5407
florian55085f82012-11-21 00:36:55 +00005408static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005409s390_irgen_IIHH(UChar r1, UShort i2)
5410{
5411 put_gpr_hw0(r1, mkU16(i2));
5412
5413 return "iihh";
5414}
5415
florian55085f82012-11-21 00:36:55 +00005416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005417s390_irgen_IIHL(UChar r1, UShort i2)
5418{
5419 put_gpr_hw1(r1, mkU16(i2));
5420
5421 return "iihl";
5422}
5423
florian55085f82012-11-21 00:36:55 +00005424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005425s390_irgen_IILF(UChar r1, UInt i2)
5426{
5427 put_gpr_w1(r1, mkU32(i2));
5428
5429 return "iilf";
5430}
5431
florian55085f82012-11-21 00:36:55 +00005432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005433s390_irgen_IILH(UChar r1, UShort i2)
5434{
5435 put_gpr_hw2(r1, mkU16(i2));
5436
5437 return "iilh";
5438}
5439
florian55085f82012-11-21 00:36:55 +00005440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005441s390_irgen_IILL(UChar r1, UShort i2)
5442{
5443 put_gpr_hw3(r1, mkU16(i2));
5444
5445 return "iill";
5446}
5447
florian55085f82012-11-21 00:36:55 +00005448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005449s390_irgen_LR(UChar r1, UChar r2)
5450{
5451 put_gpr_w1(r1, get_gpr_w1(r2));
5452
5453 return "lr";
5454}
5455
florian55085f82012-11-21 00:36:55 +00005456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005457s390_irgen_LGR(UChar r1, UChar r2)
5458{
5459 put_gpr_dw0(r1, get_gpr_dw0(r2));
5460
5461 return "lgr";
5462}
5463
florian55085f82012-11-21 00:36:55 +00005464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005465s390_irgen_LGFR(UChar r1, UChar r2)
5466{
5467 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5468
5469 return "lgfr";
5470}
5471
florian55085f82012-11-21 00:36:55 +00005472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005473s390_irgen_L(UChar r1, IRTemp op2addr)
5474{
5475 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5476
5477 return "l";
5478}
5479
florian55085f82012-11-21 00:36:55 +00005480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005481s390_irgen_LY(UChar r1, IRTemp op2addr)
5482{
5483 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5484
5485 return "ly";
5486}
5487
florian55085f82012-11-21 00:36:55 +00005488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005489s390_irgen_LG(UChar r1, IRTemp op2addr)
5490{
5491 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5492
5493 return "lg";
5494}
5495
florian55085f82012-11-21 00:36:55 +00005496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005497s390_irgen_LGF(UChar r1, IRTemp op2addr)
5498{
5499 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5500
5501 return "lgf";
5502}
5503
florian55085f82012-11-21 00:36:55 +00005504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005505s390_irgen_LGFI(UChar r1, UInt i2)
5506{
5507 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5508
5509 return "lgfi";
5510}
5511
florian55085f82012-11-21 00:36:55 +00005512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005513s390_irgen_LRL(UChar r1, UInt i2)
5514{
5515 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5516 i2 << 1))));
5517
5518 return "lrl";
5519}
5520
florian55085f82012-11-21 00:36:55 +00005521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005522s390_irgen_LGRL(UChar r1, UInt i2)
5523{
5524 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5525 i2 << 1))));
5526
5527 return "lgrl";
5528}
5529
florian55085f82012-11-21 00:36:55 +00005530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005531s390_irgen_LGFRL(UChar r1, UInt i2)
5532{
5533 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5534 ((ULong)(Long)(Int)i2 << 1)))));
5535
5536 return "lgfrl";
5537}
5538
florian55085f82012-11-21 00:36:55 +00005539static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005540s390_irgen_LA(UChar r1, IRTemp op2addr)
5541{
5542 put_gpr_dw0(r1, mkexpr(op2addr));
5543
5544 return "la";
5545}
5546
florian55085f82012-11-21 00:36:55 +00005547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005548s390_irgen_LAY(UChar r1, IRTemp op2addr)
5549{
5550 put_gpr_dw0(r1, mkexpr(op2addr));
5551
5552 return "lay";
5553}
5554
florian55085f82012-11-21 00:36:55 +00005555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005556s390_irgen_LAE(UChar r1, IRTemp op2addr)
5557{
5558 put_gpr_dw0(r1, mkexpr(op2addr));
5559
5560 return "lae";
5561}
5562
florian55085f82012-11-21 00:36:55 +00005563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005564s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5565{
5566 put_gpr_dw0(r1, mkexpr(op2addr));
5567
5568 return "laey";
5569}
5570
florian55085f82012-11-21 00:36:55 +00005571static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005572s390_irgen_LARL(UChar r1, UInt i2)
5573{
5574 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5575
5576 return "larl";
5577}
5578
floriana265ee72012-12-02 20:58:17 +00005579/* The IR representation of LAA and friends is an approximation of what
5580 happens natively. Essentially a loop containing a compare-and-swap is
5581 constructed which will iterate until the CAS succeeds. As a consequence,
5582 instrumenters may see more memory accesses than happen natively. See also
5583 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005584static void
5585s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005586{
floriana265ee72012-12-02 20:58:17 +00005587 IRCAS *cas;
5588 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005589 IRTemp op2 = newTemp(Ity_I32);
5590 IRTemp op3 = newTemp(Ity_I32);
5591 IRTemp result = newTemp(Ity_I32);
5592
5593 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5594 assign(op3, get_gpr_w1(r3));
5595 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005596
5597 /* Place the addition of second operand and third operand at the
5598 second-operand location everytime */
5599 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5600 Iend_BE, mkexpr(op2addr),
5601 NULL, mkexpr(op2), /* expected value */
5602 NULL, mkexpr(result) /* new value */);
5603 stmt(IRStmt_CAS(cas));
5604
florianffc94012012-12-02 21:31:15 +00005605 /* Set CC according to 32-bit addition */
5606 if (is_signed) {
5607 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5608 } else {
5609 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5610 }
floriana265ee72012-12-02 20:58:17 +00005611
5612 /* If old_mem contains the expected value, then the CAS succeeded.
5613 Otherwise, it did not */
5614 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5615 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005616}
5617
5618static void
5619s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5620{
5621 IRCAS *cas;
5622 IRTemp old_mem = newTemp(Ity_I64);
5623 IRTemp op2 = newTemp(Ity_I64);
5624 IRTemp op3 = newTemp(Ity_I64);
5625 IRTemp result = newTemp(Ity_I64);
5626
5627 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5628 assign(op3, get_gpr_dw0(r3));
5629 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5630
5631 /* Place the addition of second operand and third operand at the
5632 second-operand location everytime */
5633 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5634 Iend_BE, mkexpr(op2addr),
5635 NULL, mkexpr(op2), /* expected value */
5636 NULL, mkexpr(result) /* new value */);
5637 stmt(IRStmt_CAS(cas));
5638
5639 /* Set CC according to 64-bit addition */
5640 if (is_signed) {
5641 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5642 } else {
5643 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5644 }
5645
5646 /* If old_mem contains the expected value, then the CAS succeeded.
5647 Otherwise, it did not */
5648 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5649 put_gpr_dw0(r1, mkexpr(old_mem));
5650}
5651
5652static void
5653s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5654{
5655 IRCAS *cas;
5656 IRTemp old_mem = newTemp(Ity_I32);
5657 IRTemp op2 = newTemp(Ity_I32);
5658 IRTemp op3 = newTemp(Ity_I32);
5659 IRTemp result = newTemp(Ity_I32);
5660
5661 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5662 assign(op3, get_gpr_w1(r3));
5663 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5664
5665 /* Place the addition of second operand and third operand at the
5666 second-operand location everytime */
5667 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5668 Iend_BE, mkexpr(op2addr),
5669 NULL, mkexpr(op2), /* expected value */
5670 NULL, mkexpr(result) /* new value */);
5671 stmt(IRStmt_CAS(cas));
5672
5673 /* Set CC according to bitwise operation */
5674 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5675
5676 /* If old_mem contains the expected value, then the CAS succeeded.
5677 Otherwise, it did not */
5678 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5679 put_gpr_w1(r1, mkexpr(old_mem));
5680}
5681
5682static void
5683s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5684{
5685 IRCAS *cas;
5686 IRTemp old_mem = newTemp(Ity_I64);
5687 IRTemp op2 = newTemp(Ity_I64);
5688 IRTemp op3 = newTemp(Ity_I64);
5689 IRTemp result = newTemp(Ity_I64);
5690
5691 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5692 assign(op3, get_gpr_dw0(r3));
5693 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5694
5695 /* Place the addition of second operand and third operand at the
5696 second-operand location everytime */
5697 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5698 Iend_BE, mkexpr(op2addr),
5699 NULL, mkexpr(op2), /* expected value */
5700 NULL, mkexpr(result) /* new value */);
5701 stmt(IRStmt_CAS(cas));
5702
5703 /* Set CC according to bitwise operation */
5704 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5705
5706 /* If old_mem contains the expected value, then the CAS succeeded.
5707 Otherwise, it did not */
5708 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5709 put_gpr_dw0(r1, mkexpr(old_mem));
5710}
5711
5712static const HChar *
5713s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5714{
5715 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005716
5717 return "laa";
5718}
5719
florian55085f82012-11-21 00:36:55 +00005720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005721s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5722{
florianffc94012012-12-02 21:31:15 +00005723 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005724
5725 return "laag";
5726}
5727
florian55085f82012-11-21 00:36:55 +00005728static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005729s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5730{
florianffc94012012-12-02 21:31:15 +00005731 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005732
5733 return "laal";
5734}
5735
florian55085f82012-11-21 00:36:55 +00005736static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005737s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5738{
florianffc94012012-12-02 21:31:15 +00005739 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005740
5741 return "laalg";
5742}
5743
florian55085f82012-11-21 00:36:55 +00005744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005745s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5746{
florianffc94012012-12-02 21:31:15 +00005747 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005748
5749 return "lan";
5750}
5751
florian55085f82012-11-21 00:36:55 +00005752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005753s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5754{
florianffc94012012-12-02 21:31:15 +00005755 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005756
5757 return "lang";
5758}
5759
florian55085f82012-11-21 00:36:55 +00005760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005761s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5762{
florianffc94012012-12-02 21:31:15 +00005763 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005764
5765 return "lax";
5766}
5767
florian55085f82012-11-21 00:36:55 +00005768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005769s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5770{
florianffc94012012-12-02 21:31:15 +00005771 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005772
5773 return "laxg";
5774}
5775
florian55085f82012-11-21 00:36:55 +00005776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005777s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5778{
florianffc94012012-12-02 21:31:15 +00005779 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005780
5781 return "lao";
5782}
5783
florian55085f82012-11-21 00:36:55 +00005784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005785s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5786{
florianffc94012012-12-02 21:31:15 +00005787 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005788
5789 return "laog";
5790}
5791
florian55085f82012-11-21 00:36:55 +00005792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005793s390_irgen_LTR(UChar r1, UChar r2)
5794{
5795 IRTemp op2 = newTemp(Ity_I32);
5796
5797 assign(op2, get_gpr_w1(r2));
5798 put_gpr_w1(r1, mkexpr(op2));
5799 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5800
5801 return "ltr";
5802}
5803
florian55085f82012-11-21 00:36:55 +00005804static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005805s390_irgen_LTGR(UChar r1, UChar r2)
5806{
5807 IRTemp op2 = newTemp(Ity_I64);
5808
5809 assign(op2, get_gpr_dw0(r2));
5810 put_gpr_dw0(r1, mkexpr(op2));
5811 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5812
5813 return "ltgr";
5814}
5815
florian55085f82012-11-21 00:36:55 +00005816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005817s390_irgen_LTGFR(UChar r1, UChar r2)
5818{
5819 IRTemp op2 = newTemp(Ity_I64);
5820
5821 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5822 put_gpr_dw0(r1, mkexpr(op2));
5823 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5824
5825 return "ltgfr";
5826}
5827
florian55085f82012-11-21 00:36:55 +00005828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005829s390_irgen_LT(UChar r1, IRTemp op2addr)
5830{
5831 IRTemp op2 = newTemp(Ity_I32);
5832
5833 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5834 put_gpr_w1(r1, mkexpr(op2));
5835 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5836
5837 return "lt";
5838}
5839
florian55085f82012-11-21 00:36:55 +00005840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005841s390_irgen_LTG(UChar r1, IRTemp op2addr)
5842{
5843 IRTemp op2 = newTemp(Ity_I64);
5844
5845 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5846 put_gpr_dw0(r1, mkexpr(op2));
5847 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5848
5849 return "ltg";
5850}
5851
florian55085f82012-11-21 00:36:55 +00005852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005853s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5854{
5855 IRTemp op2 = newTemp(Ity_I64);
5856
5857 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5858 put_gpr_dw0(r1, mkexpr(op2));
5859 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5860
5861 return "ltgf";
5862}
5863
florian55085f82012-11-21 00:36:55 +00005864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005865s390_irgen_LBR(UChar r1, UChar r2)
5866{
5867 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5868
5869 return "lbr";
5870}
5871
florian55085f82012-11-21 00:36:55 +00005872static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005873s390_irgen_LGBR(UChar r1, UChar r2)
5874{
5875 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5876
5877 return "lgbr";
5878}
5879
florian55085f82012-11-21 00:36:55 +00005880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005881s390_irgen_LB(UChar r1, IRTemp op2addr)
5882{
5883 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5884
5885 return "lb";
5886}
5887
florian55085f82012-11-21 00:36:55 +00005888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005889s390_irgen_LGB(UChar r1, IRTemp op2addr)
5890{
5891 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5892
5893 return "lgb";
5894}
5895
florian55085f82012-11-21 00:36:55 +00005896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005897s390_irgen_LBH(UChar r1, IRTemp op2addr)
5898{
5899 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5900
5901 return "lbh";
5902}
5903
florian55085f82012-11-21 00:36:55 +00005904static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005905s390_irgen_LCR(UChar r1, UChar r2)
5906{
5907 Int op1;
5908 IRTemp op2 = newTemp(Ity_I32);
5909 IRTemp result = newTemp(Ity_I32);
5910
5911 op1 = 0;
5912 assign(op2, get_gpr_w1(r2));
5913 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5914 put_gpr_w1(r1, mkexpr(result));
5915 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5916 op1)), op2);
5917
5918 return "lcr";
5919}
5920
florian55085f82012-11-21 00:36:55 +00005921static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005922s390_irgen_LCGR(UChar r1, UChar r2)
5923{
5924 Long op1;
5925 IRTemp op2 = newTemp(Ity_I64);
5926 IRTemp result = newTemp(Ity_I64);
5927
5928 op1 = 0ULL;
5929 assign(op2, get_gpr_dw0(r2));
5930 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5931 put_gpr_dw0(r1, mkexpr(result));
5932 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5933 op1)), op2);
5934
5935 return "lcgr";
5936}
5937
florian55085f82012-11-21 00:36:55 +00005938static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005939s390_irgen_LCGFR(UChar r1, UChar r2)
5940{
5941 Long op1;
5942 IRTemp op2 = newTemp(Ity_I64);
5943 IRTemp result = newTemp(Ity_I64);
5944
5945 op1 = 0ULL;
5946 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5947 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5948 put_gpr_dw0(r1, mkexpr(result));
5949 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5950 op1)), op2);
5951
5952 return "lcgfr";
5953}
5954
florian55085f82012-11-21 00:36:55 +00005955static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005956s390_irgen_LHR(UChar r1, UChar r2)
5957{
5958 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5959
5960 return "lhr";
5961}
5962
florian55085f82012-11-21 00:36:55 +00005963static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005964s390_irgen_LGHR(UChar r1, UChar r2)
5965{
5966 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5967
5968 return "lghr";
5969}
5970
florian55085f82012-11-21 00:36:55 +00005971static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005972s390_irgen_LH(UChar r1, IRTemp op2addr)
5973{
5974 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5975
5976 return "lh";
5977}
5978
florian55085f82012-11-21 00:36:55 +00005979static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005980s390_irgen_LHY(UChar r1, IRTemp op2addr)
5981{
5982 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5983
5984 return "lhy";
5985}
5986
florian55085f82012-11-21 00:36:55 +00005987static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005988s390_irgen_LGH(UChar r1, IRTemp op2addr)
5989{
5990 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5991
5992 return "lgh";
5993}
5994
florian55085f82012-11-21 00:36:55 +00005995static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005996s390_irgen_LHI(UChar r1, UShort i2)
5997{
5998 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5999
6000 return "lhi";
6001}
6002
florian55085f82012-11-21 00:36:55 +00006003static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006004s390_irgen_LGHI(UChar r1, UShort i2)
6005{
6006 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6007
6008 return "lghi";
6009}
6010
florian55085f82012-11-21 00:36:55 +00006011static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006012s390_irgen_LHRL(UChar r1, UInt i2)
6013{
6014 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6015 ((ULong)(Long)(Int)i2 << 1)))));
6016
6017 return "lhrl";
6018}
6019
florian55085f82012-11-21 00:36:55 +00006020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006021s390_irgen_LGHRL(UChar r1, UInt i2)
6022{
6023 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6024 ((ULong)(Long)(Int)i2 << 1)))));
6025
6026 return "lghrl";
6027}
6028
florian55085f82012-11-21 00:36:55 +00006029static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006030s390_irgen_LHH(UChar r1, IRTemp op2addr)
6031{
6032 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6033
6034 return "lhh";
6035}
6036
florian55085f82012-11-21 00:36:55 +00006037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006038s390_irgen_LFH(UChar r1, IRTemp op2addr)
6039{
6040 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6041
6042 return "lfh";
6043}
6044
florian55085f82012-11-21 00:36:55 +00006045static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006046s390_irgen_LLGFR(UChar r1, UChar r2)
6047{
6048 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6049
6050 return "llgfr";
6051}
6052
florian55085f82012-11-21 00:36:55 +00006053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006054s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6055{
6056 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6057
6058 return "llgf";
6059}
6060
florian55085f82012-11-21 00:36:55 +00006061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006062s390_irgen_LLGFRL(UChar r1, UInt i2)
6063{
6064 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6065 ((ULong)(Long)(Int)i2 << 1)))));
6066
6067 return "llgfrl";
6068}
6069
florian55085f82012-11-21 00:36:55 +00006070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006071s390_irgen_LLCR(UChar r1, UChar r2)
6072{
6073 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6074
6075 return "llcr";
6076}
6077
florian55085f82012-11-21 00:36:55 +00006078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006079s390_irgen_LLGCR(UChar r1, UChar r2)
6080{
6081 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6082
6083 return "llgcr";
6084}
6085
florian55085f82012-11-21 00:36:55 +00006086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006087s390_irgen_LLC(UChar r1, IRTemp op2addr)
6088{
6089 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6090
6091 return "llc";
6092}
6093
florian55085f82012-11-21 00:36:55 +00006094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006095s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6096{
6097 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6098
6099 return "llgc";
6100}
6101
florian55085f82012-11-21 00:36:55 +00006102static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006103s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6104{
6105 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6106
6107 return "llch";
6108}
6109
florian55085f82012-11-21 00:36:55 +00006110static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006111s390_irgen_LLHR(UChar r1, UChar r2)
6112{
6113 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6114
6115 return "llhr";
6116}
6117
florian55085f82012-11-21 00:36:55 +00006118static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006119s390_irgen_LLGHR(UChar r1, UChar r2)
6120{
6121 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6122
6123 return "llghr";
6124}
6125
florian55085f82012-11-21 00:36:55 +00006126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006127s390_irgen_LLH(UChar r1, IRTemp op2addr)
6128{
6129 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6130
6131 return "llh";
6132}
6133
florian55085f82012-11-21 00:36:55 +00006134static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006135s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6136{
6137 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6138
6139 return "llgh";
6140}
6141
florian55085f82012-11-21 00:36:55 +00006142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006143s390_irgen_LLHRL(UChar r1, UInt i2)
6144{
6145 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6146 ((ULong)(Long)(Int)i2 << 1)))));
6147
6148 return "llhrl";
6149}
6150
florian55085f82012-11-21 00:36:55 +00006151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006152s390_irgen_LLGHRL(UChar r1, UInt i2)
6153{
6154 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6155 ((ULong)(Long)(Int)i2 << 1)))));
6156
6157 return "llghrl";
6158}
6159
florian55085f82012-11-21 00:36:55 +00006160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006161s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6162{
6163 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6164
6165 return "llhh";
6166}
6167
florian55085f82012-11-21 00:36:55 +00006168static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006169s390_irgen_LLIHF(UChar r1, UInt i2)
6170{
6171 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6172
6173 return "llihf";
6174}
6175
florian55085f82012-11-21 00:36:55 +00006176static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006177s390_irgen_LLIHH(UChar r1, UShort i2)
6178{
6179 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6180
6181 return "llihh";
6182}
6183
florian55085f82012-11-21 00:36:55 +00006184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006185s390_irgen_LLIHL(UChar r1, UShort i2)
6186{
6187 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6188
6189 return "llihl";
6190}
6191
florian55085f82012-11-21 00:36:55 +00006192static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006193s390_irgen_LLILF(UChar r1, UInt i2)
6194{
6195 put_gpr_dw0(r1, mkU64(i2));
6196
6197 return "llilf";
6198}
6199
florian55085f82012-11-21 00:36:55 +00006200static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006201s390_irgen_LLILH(UChar r1, UShort i2)
6202{
6203 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6204
6205 return "llilh";
6206}
6207
florian55085f82012-11-21 00:36:55 +00006208static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006209s390_irgen_LLILL(UChar r1, UShort i2)
6210{
6211 put_gpr_dw0(r1, mkU64(i2));
6212
6213 return "llill";
6214}
6215
florian55085f82012-11-21 00:36:55 +00006216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006217s390_irgen_LLGTR(UChar r1, UChar r2)
6218{
6219 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6220 mkU32(2147483647))));
6221
6222 return "llgtr";
6223}
6224
florian55085f82012-11-21 00:36:55 +00006225static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006226s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6227{
6228 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6229 mkexpr(op2addr)), mkU32(2147483647))));
6230
6231 return "llgt";
6232}
6233
florian55085f82012-11-21 00:36:55 +00006234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006235s390_irgen_LNR(UChar r1, UChar r2)
6236{
6237 IRTemp op2 = newTemp(Ity_I32);
6238 IRTemp result = newTemp(Ity_I32);
6239
6240 assign(op2, get_gpr_w1(r2));
6241 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6242 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6243 put_gpr_w1(r1, mkexpr(result));
6244 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6245
6246 return "lnr";
6247}
6248
florian55085f82012-11-21 00:36:55 +00006249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006250s390_irgen_LNGR(UChar r1, UChar r2)
6251{
6252 IRTemp op2 = newTemp(Ity_I64);
6253 IRTemp result = newTemp(Ity_I64);
6254
6255 assign(op2, get_gpr_dw0(r2));
6256 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6257 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6258 put_gpr_dw0(r1, mkexpr(result));
6259 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6260
6261 return "lngr";
6262}
6263
florian55085f82012-11-21 00:36:55 +00006264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006265s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6266{
6267 IRTemp op2 = newTemp(Ity_I64);
6268 IRTemp result = newTemp(Ity_I64);
6269
6270 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6271 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6272 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6273 put_gpr_dw0(r1, mkexpr(result));
6274 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6275
6276 return "lngfr";
6277}
6278
florian55085f82012-11-21 00:36:55 +00006279static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006280s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6281{
florian6820ba52012-07-26 02:01:50 +00006282 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006283 put_gpr_w1(r1, get_gpr_w1(r2));
6284
6285 return "locr";
6286}
6287
florian55085f82012-11-21 00:36:55 +00006288static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006289s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6290{
florian6820ba52012-07-26 02:01:50 +00006291 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006292 put_gpr_dw0(r1, get_gpr_dw0(r2));
6293
6294 return "locgr";
6295}
6296
florian55085f82012-11-21 00:36:55 +00006297static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006298s390_irgen_LOC(UChar r1, IRTemp op2addr)
6299{
6300 /* condition is checked in format handler */
6301 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6302
6303 return "loc";
6304}
6305
florian55085f82012-11-21 00:36:55 +00006306static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006307s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6308{
6309 /* condition is checked in format handler */
6310 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6311
6312 return "locg";
6313}
6314
florian55085f82012-11-21 00:36:55 +00006315static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006316s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6317{
6318 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6319 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6320 ));
6321
6322 return "lpq";
6323}
6324
florian55085f82012-11-21 00:36:55 +00006325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006326s390_irgen_LPR(UChar r1, UChar r2)
6327{
6328 IRTemp op2 = newTemp(Ity_I32);
6329 IRTemp result = newTemp(Ity_I32);
6330
6331 assign(op2, get_gpr_w1(r2));
6332 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6333 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6334 put_gpr_w1(r1, mkexpr(result));
6335 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6336
6337 return "lpr";
6338}
6339
florian55085f82012-11-21 00:36:55 +00006340static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006341s390_irgen_LPGR(UChar r1, UChar r2)
6342{
6343 IRTemp op2 = newTemp(Ity_I64);
6344 IRTemp result = newTemp(Ity_I64);
6345
6346 assign(op2, get_gpr_dw0(r2));
6347 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6348 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6349 put_gpr_dw0(r1, mkexpr(result));
6350 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6351
6352 return "lpgr";
6353}
6354
florian55085f82012-11-21 00:36:55 +00006355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006356s390_irgen_LPGFR(UChar r1, UChar r2)
6357{
6358 IRTemp op2 = newTemp(Ity_I64);
6359 IRTemp result = newTemp(Ity_I64);
6360
6361 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6362 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6363 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6364 put_gpr_dw0(r1, mkexpr(result));
6365 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6366
6367 return "lpgfr";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006371s390_irgen_LRVR(UChar r1, UChar r2)
6372{
6373 IRTemp b0 = newTemp(Ity_I8);
6374 IRTemp b1 = newTemp(Ity_I8);
6375 IRTemp b2 = newTemp(Ity_I8);
6376 IRTemp b3 = newTemp(Ity_I8);
6377
6378 assign(b3, get_gpr_b7(r2));
6379 assign(b2, get_gpr_b6(r2));
6380 assign(b1, get_gpr_b5(r2));
6381 assign(b0, get_gpr_b4(r2));
6382 put_gpr_b4(r1, mkexpr(b3));
6383 put_gpr_b5(r1, mkexpr(b2));
6384 put_gpr_b6(r1, mkexpr(b1));
6385 put_gpr_b7(r1, mkexpr(b0));
6386
6387 return "lrvr";
6388}
6389
florian55085f82012-11-21 00:36:55 +00006390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006391s390_irgen_LRVGR(UChar r1, UChar r2)
6392{
6393 IRTemp b0 = newTemp(Ity_I8);
6394 IRTemp b1 = newTemp(Ity_I8);
6395 IRTemp b2 = newTemp(Ity_I8);
6396 IRTemp b3 = newTemp(Ity_I8);
6397 IRTemp b4 = newTemp(Ity_I8);
6398 IRTemp b5 = newTemp(Ity_I8);
6399 IRTemp b6 = newTemp(Ity_I8);
6400 IRTemp b7 = newTemp(Ity_I8);
6401
6402 assign(b7, get_gpr_b7(r2));
6403 assign(b6, get_gpr_b6(r2));
6404 assign(b5, get_gpr_b5(r2));
6405 assign(b4, get_gpr_b4(r2));
6406 assign(b3, get_gpr_b3(r2));
6407 assign(b2, get_gpr_b2(r2));
6408 assign(b1, get_gpr_b1(r2));
6409 assign(b0, get_gpr_b0(r2));
6410 put_gpr_b0(r1, mkexpr(b7));
6411 put_gpr_b1(r1, mkexpr(b6));
6412 put_gpr_b2(r1, mkexpr(b5));
6413 put_gpr_b3(r1, mkexpr(b4));
6414 put_gpr_b4(r1, mkexpr(b3));
6415 put_gpr_b5(r1, mkexpr(b2));
6416 put_gpr_b6(r1, mkexpr(b1));
6417 put_gpr_b7(r1, mkexpr(b0));
6418
6419 return "lrvgr";
6420}
6421
florian55085f82012-11-21 00:36:55 +00006422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006423s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6424{
6425 IRTemp op2 = newTemp(Ity_I16);
6426
6427 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6428 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6429 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6430
6431 return "lrvh";
6432}
6433
florian55085f82012-11-21 00:36:55 +00006434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006435s390_irgen_LRV(UChar r1, IRTemp op2addr)
6436{
6437 IRTemp op2 = newTemp(Ity_I32);
6438
6439 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6440 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6441 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6442 mkU8(8)), mkU32(255))));
6443 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6444 mkU8(16)), mkU32(255))));
6445 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6446 mkU8(24)), mkU32(255))));
6447
6448 return "lrv";
6449}
6450
florian55085f82012-11-21 00:36:55 +00006451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006452s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6453{
6454 IRTemp op2 = newTemp(Ity_I64);
6455
6456 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6457 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6458 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6459 mkU8(8)), mkU64(255))));
6460 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6461 mkU8(16)), mkU64(255))));
6462 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6463 mkU8(24)), mkU64(255))));
6464 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6465 mkU8(32)), mkU64(255))));
6466 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6467 mkU8(40)), mkU64(255))));
6468 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6469 mkU8(48)), mkU64(255))));
6470 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6471 mkU8(56)), mkU64(255))));
6472
6473 return "lrvg";
6474}
6475
florian55085f82012-11-21 00:36:55 +00006476static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006477s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6478{
6479 store(mkexpr(op1addr), mkU16(i2));
6480
6481 return "mvhhi";
6482}
6483
florian55085f82012-11-21 00:36:55 +00006484static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006485s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6486{
6487 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6488
6489 return "mvhi";
6490}
6491
florian55085f82012-11-21 00:36:55 +00006492static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006493s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6494{
6495 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6496
6497 return "mvghi";
6498}
6499
florian55085f82012-11-21 00:36:55 +00006500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006501s390_irgen_MVI(UChar i2, IRTemp op1addr)
6502{
6503 store(mkexpr(op1addr), mkU8(i2));
6504
6505 return "mvi";
6506}
6507
florian55085f82012-11-21 00:36:55 +00006508static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006509s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6510{
6511 store(mkexpr(op1addr), mkU8(i2));
6512
6513 return "mviy";
6514}
6515
florian55085f82012-11-21 00:36:55 +00006516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006517s390_irgen_MR(UChar r1, UChar r2)
6518{
6519 IRTemp op1 = newTemp(Ity_I32);
6520 IRTemp op2 = newTemp(Ity_I32);
6521 IRTemp result = newTemp(Ity_I64);
6522
6523 assign(op1, get_gpr_w1(r1 + 1));
6524 assign(op2, get_gpr_w1(r2));
6525 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6526 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6527 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6528
6529 return "mr";
6530}
6531
florian55085f82012-11-21 00:36:55 +00006532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006533s390_irgen_M(UChar r1, IRTemp op2addr)
6534{
6535 IRTemp op1 = newTemp(Ity_I32);
6536 IRTemp op2 = newTemp(Ity_I32);
6537 IRTemp result = newTemp(Ity_I64);
6538
6539 assign(op1, get_gpr_w1(r1 + 1));
6540 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6541 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6542 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6543 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6544
6545 return "m";
6546}
6547
florian55085f82012-11-21 00:36:55 +00006548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006549s390_irgen_MFY(UChar r1, IRTemp op2addr)
6550{
6551 IRTemp op1 = newTemp(Ity_I32);
6552 IRTemp op2 = newTemp(Ity_I32);
6553 IRTemp result = newTemp(Ity_I64);
6554
6555 assign(op1, get_gpr_w1(r1 + 1));
6556 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6557 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6558 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6559 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6560
6561 return "mfy";
6562}
6563
florian55085f82012-11-21 00:36:55 +00006564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006565s390_irgen_MH(UChar r1, IRTemp op2addr)
6566{
6567 IRTemp op1 = newTemp(Ity_I32);
6568 IRTemp op2 = newTemp(Ity_I16);
6569 IRTemp result = newTemp(Ity_I64);
6570
6571 assign(op1, get_gpr_w1(r1));
6572 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6573 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6574 ));
6575 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6576
6577 return "mh";
6578}
6579
florian55085f82012-11-21 00:36:55 +00006580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006581s390_irgen_MHY(UChar r1, IRTemp op2addr)
6582{
6583 IRTemp op1 = newTemp(Ity_I32);
6584 IRTemp op2 = newTemp(Ity_I16);
6585 IRTemp result = newTemp(Ity_I64);
6586
6587 assign(op1, get_gpr_w1(r1));
6588 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6589 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6590 ));
6591 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6592
6593 return "mhy";
6594}
6595
florian55085f82012-11-21 00:36:55 +00006596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006597s390_irgen_MHI(UChar r1, UShort i2)
6598{
6599 IRTemp op1 = newTemp(Ity_I32);
6600 Short op2;
6601 IRTemp result = newTemp(Ity_I64);
6602
6603 assign(op1, get_gpr_w1(r1));
6604 op2 = (Short)i2;
6605 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6606 mkU16((UShort)op2))));
6607 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6608
6609 return "mhi";
6610}
6611
florian55085f82012-11-21 00:36:55 +00006612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006613s390_irgen_MGHI(UChar r1, UShort i2)
6614{
6615 IRTemp op1 = newTemp(Ity_I64);
6616 Short op2;
6617 IRTemp result = newTemp(Ity_I128);
6618
6619 assign(op1, get_gpr_dw0(r1));
6620 op2 = (Short)i2;
6621 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6622 mkU16((UShort)op2))));
6623 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6624
6625 return "mghi";
6626}
6627
florian55085f82012-11-21 00:36:55 +00006628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006629s390_irgen_MLR(UChar r1, UChar r2)
6630{
6631 IRTemp op1 = newTemp(Ity_I32);
6632 IRTemp op2 = newTemp(Ity_I32);
6633 IRTemp result = newTemp(Ity_I64);
6634
6635 assign(op1, get_gpr_w1(r1 + 1));
6636 assign(op2, get_gpr_w1(r2));
6637 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6638 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6639 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6640
6641 return "mlr";
6642}
6643
florian55085f82012-11-21 00:36:55 +00006644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006645s390_irgen_MLGR(UChar r1, UChar r2)
6646{
6647 IRTemp op1 = newTemp(Ity_I64);
6648 IRTemp op2 = newTemp(Ity_I64);
6649 IRTemp result = newTemp(Ity_I128);
6650
6651 assign(op1, get_gpr_dw0(r1 + 1));
6652 assign(op2, get_gpr_dw0(r2));
6653 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6654 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6655 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6656
6657 return "mlgr";
6658}
6659
florian55085f82012-11-21 00:36:55 +00006660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006661s390_irgen_ML(UChar r1, IRTemp op2addr)
6662{
6663 IRTemp op1 = newTemp(Ity_I32);
6664 IRTemp op2 = newTemp(Ity_I32);
6665 IRTemp result = newTemp(Ity_I64);
6666
6667 assign(op1, get_gpr_w1(r1 + 1));
6668 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6669 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6670 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6671 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6672
6673 return "ml";
6674}
6675
florian55085f82012-11-21 00:36:55 +00006676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006677s390_irgen_MLG(UChar r1, IRTemp op2addr)
6678{
6679 IRTemp op1 = newTemp(Ity_I64);
6680 IRTemp op2 = newTemp(Ity_I64);
6681 IRTemp result = newTemp(Ity_I128);
6682
6683 assign(op1, get_gpr_dw0(r1 + 1));
6684 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6685 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6686 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6687 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6688
6689 return "mlg";
6690}
6691
florian55085f82012-11-21 00:36:55 +00006692static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006693s390_irgen_MSR(UChar r1, UChar r2)
6694{
6695 IRTemp op1 = newTemp(Ity_I32);
6696 IRTemp op2 = newTemp(Ity_I32);
6697 IRTemp result = newTemp(Ity_I64);
6698
6699 assign(op1, get_gpr_w1(r1));
6700 assign(op2, get_gpr_w1(r2));
6701 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6702 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6703
6704 return "msr";
6705}
6706
florian55085f82012-11-21 00:36:55 +00006707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006708s390_irgen_MSGR(UChar r1, UChar r2)
6709{
6710 IRTemp op1 = newTemp(Ity_I64);
6711 IRTemp op2 = newTemp(Ity_I64);
6712 IRTemp result = newTemp(Ity_I128);
6713
6714 assign(op1, get_gpr_dw0(r1));
6715 assign(op2, get_gpr_dw0(r2));
6716 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6717 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6718
6719 return "msgr";
6720}
6721
florian55085f82012-11-21 00:36:55 +00006722static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006723s390_irgen_MSGFR(UChar r1, UChar r2)
6724{
6725 IRTemp op1 = newTemp(Ity_I64);
6726 IRTemp op2 = newTemp(Ity_I32);
6727 IRTemp result = newTemp(Ity_I128);
6728
6729 assign(op1, get_gpr_dw0(r1));
6730 assign(op2, get_gpr_w1(r2));
6731 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6732 ));
6733 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6734
6735 return "msgfr";
6736}
6737
florian55085f82012-11-21 00:36:55 +00006738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006739s390_irgen_MS(UChar r1, IRTemp op2addr)
6740{
6741 IRTemp op1 = newTemp(Ity_I32);
6742 IRTemp op2 = newTemp(Ity_I32);
6743 IRTemp result = newTemp(Ity_I64);
6744
6745 assign(op1, get_gpr_w1(r1));
6746 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6747 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6748 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6749
6750 return "ms";
6751}
6752
florian55085f82012-11-21 00:36:55 +00006753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006754s390_irgen_MSY(UChar r1, IRTemp op2addr)
6755{
6756 IRTemp op1 = newTemp(Ity_I32);
6757 IRTemp op2 = newTemp(Ity_I32);
6758 IRTemp result = newTemp(Ity_I64);
6759
6760 assign(op1, get_gpr_w1(r1));
6761 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6762 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6763 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6764
6765 return "msy";
6766}
6767
florian55085f82012-11-21 00:36:55 +00006768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006769s390_irgen_MSG(UChar r1, IRTemp op2addr)
6770{
6771 IRTemp op1 = newTemp(Ity_I64);
6772 IRTemp op2 = newTemp(Ity_I64);
6773 IRTemp result = newTemp(Ity_I128);
6774
6775 assign(op1, get_gpr_dw0(r1));
6776 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6777 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6778 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6779
6780 return "msg";
6781}
6782
florian55085f82012-11-21 00:36:55 +00006783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006784s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6785{
6786 IRTemp op1 = newTemp(Ity_I64);
6787 IRTemp op2 = newTemp(Ity_I32);
6788 IRTemp result = newTemp(Ity_I128);
6789
6790 assign(op1, get_gpr_dw0(r1));
6791 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6792 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6793 ));
6794 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6795
6796 return "msgf";
6797}
6798
florian55085f82012-11-21 00:36:55 +00006799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006800s390_irgen_MSFI(UChar r1, UInt i2)
6801{
6802 IRTemp op1 = newTemp(Ity_I32);
6803 Int op2;
6804 IRTemp result = newTemp(Ity_I64);
6805
6806 assign(op1, get_gpr_w1(r1));
6807 op2 = (Int)i2;
6808 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6809 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6810
6811 return "msfi";
6812}
6813
florian55085f82012-11-21 00:36:55 +00006814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006815s390_irgen_MSGFI(UChar r1, UInt i2)
6816{
6817 IRTemp op1 = newTemp(Ity_I64);
6818 Int op2;
6819 IRTemp result = newTemp(Ity_I128);
6820
6821 assign(op1, get_gpr_dw0(r1));
6822 op2 = (Int)i2;
6823 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6824 op2))));
6825 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6826
6827 return "msgfi";
6828}
6829
florian55085f82012-11-21 00:36:55 +00006830static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006831s390_irgen_OR(UChar r1, UChar r2)
6832{
6833 IRTemp op1 = newTemp(Ity_I32);
6834 IRTemp op2 = newTemp(Ity_I32);
6835 IRTemp result = newTemp(Ity_I32);
6836
6837 assign(op1, get_gpr_w1(r1));
6838 assign(op2, get_gpr_w1(r2));
6839 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6840 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6841 put_gpr_w1(r1, mkexpr(result));
6842
6843 return "or";
6844}
6845
florian55085f82012-11-21 00:36:55 +00006846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006847s390_irgen_OGR(UChar r1, UChar r2)
6848{
6849 IRTemp op1 = newTemp(Ity_I64);
6850 IRTemp op2 = newTemp(Ity_I64);
6851 IRTemp result = newTemp(Ity_I64);
6852
6853 assign(op1, get_gpr_dw0(r1));
6854 assign(op2, get_gpr_dw0(r2));
6855 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6856 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6857 put_gpr_dw0(r1, mkexpr(result));
6858
6859 return "ogr";
6860}
6861
florian55085f82012-11-21 00:36:55 +00006862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006863s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6864{
6865 IRTemp op2 = newTemp(Ity_I32);
6866 IRTemp op3 = newTemp(Ity_I32);
6867 IRTemp result = newTemp(Ity_I32);
6868
6869 assign(op2, get_gpr_w1(r2));
6870 assign(op3, get_gpr_w1(r3));
6871 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6872 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6873 put_gpr_w1(r1, mkexpr(result));
6874
6875 return "ork";
6876}
6877
florian55085f82012-11-21 00:36:55 +00006878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006879s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6880{
6881 IRTemp op2 = newTemp(Ity_I64);
6882 IRTemp op3 = newTemp(Ity_I64);
6883 IRTemp result = newTemp(Ity_I64);
6884
6885 assign(op2, get_gpr_dw0(r2));
6886 assign(op3, get_gpr_dw0(r3));
6887 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6888 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6889 put_gpr_dw0(r1, mkexpr(result));
6890
6891 return "ogrk";
6892}
6893
florian55085f82012-11-21 00:36:55 +00006894static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006895s390_irgen_O(UChar r1, IRTemp op2addr)
6896{
6897 IRTemp op1 = newTemp(Ity_I32);
6898 IRTemp op2 = newTemp(Ity_I32);
6899 IRTemp result = newTemp(Ity_I32);
6900
6901 assign(op1, get_gpr_w1(r1));
6902 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6903 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6904 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6905 put_gpr_w1(r1, mkexpr(result));
6906
6907 return "o";
6908}
6909
florian55085f82012-11-21 00:36:55 +00006910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006911s390_irgen_OY(UChar r1, IRTemp op2addr)
6912{
6913 IRTemp op1 = newTemp(Ity_I32);
6914 IRTemp op2 = newTemp(Ity_I32);
6915 IRTemp result = newTemp(Ity_I32);
6916
6917 assign(op1, get_gpr_w1(r1));
6918 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6919 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6920 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6921 put_gpr_w1(r1, mkexpr(result));
6922
6923 return "oy";
6924}
6925
florian55085f82012-11-21 00:36:55 +00006926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006927s390_irgen_OG(UChar r1, IRTemp op2addr)
6928{
6929 IRTemp op1 = newTemp(Ity_I64);
6930 IRTemp op2 = newTemp(Ity_I64);
6931 IRTemp result = newTemp(Ity_I64);
6932
6933 assign(op1, get_gpr_dw0(r1));
6934 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6935 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6936 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6937 put_gpr_dw0(r1, mkexpr(result));
6938
6939 return "og";
6940}
6941
florian55085f82012-11-21 00:36:55 +00006942static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006943s390_irgen_OI(UChar i2, IRTemp op1addr)
6944{
6945 IRTemp op1 = newTemp(Ity_I8);
6946 UChar op2;
6947 IRTemp result = newTemp(Ity_I8);
6948
6949 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6950 op2 = i2;
6951 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6952 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6953 store(mkexpr(op1addr), mkexpr(result));
6954
6955 return "oi";
6956}
6957
florian55085f82012-11-21 00:36:55 +00006958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006959s390_irgen_OIY(UChar i2, IRTemp op1addr)
6960{
6961 IRTemp op1 = newTemp(Ity_I8);
6962 UChar op2;
6963 IRTemp result = newTemp(Ity_I8);
6964
6965 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6966 op2 = i2;
6967 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6968 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6969 store(mkexpr(op1addr), mkexpr(result));
6970
6971 return "oiy";
6972}
6973
florian55085f82012-11-21 00:36:55 +00006974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006975s390_irgen_OIHF(UChar r1, UInt i2)
6976{
6977 IRTemp op1 = newTemp(Ity_I32);
6978 UInt op2;
6979 IRTemp result = newTemp(Ity_I32);
6980
6981 assign(op1, get_gpr_w0(r1));
6982 op2 = i2;
6983 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6984 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6985 put_gpr_w0(r1, mkexpr(result));
6986
6987 return "oihf";
6988}
6989
florian55085f82012-11-21 00:36:55 +00006990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006991s390_irgen_OIHH(UChar r1, UShort i2)
6992{
6993 IRTemp op1 = newTemp(Ity_I16);
6994 UShort op2;
6995 IRTemp result = newTemp(Ity_I16);
6996
6997 assign(op1, get_gpr_hw0(r1));
6998 op2 = i2;
6999 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7000 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7001 put_gpr_hw0(r1, mkexpr(result));
7002
7003 return "oihh";
7004}
7005
florian55085f82012-11-21 00:36:55 +00007006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007007s390_irgen_OIHL(UChar r1, UShort i2)
7008{
7009 IRTemp op1 = newTemp(Ity_I16);
7010 UShort op2;
7011 IRTemp result = newTemp(Ity_I16);
7012
7013 assign(op1, get_gpr_hw1(r1));
7014 op2 = i2;
7015 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7016 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7017 put_gpr_hw1(r1, mkexpr(result));
7018
7019 return "oihl";
7020}
7021
florian55085f82012-11-21 00:36:55 +00007022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007023s390_irgen_OILF(UChar r1, UInt i2)
7024{
7025 IRTemp op1 = newTemp(Ity_I32);
7026 UInt op2;
7027 IRTemp result = newTemp(Ity_I32);
7028
7029 assign(op1, get_gpr_w1(r1));
7030 op2 = i2;
7031 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7032 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7033 put_gpr_w1(r1, mkexpr(result));
7034
7035 return "oilf";
7036}
7037
florian55085f82012-11-21 00:36:55 +00007038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007039s390_irgen_OILH(UChar r1, UShort i2)
7040{
7041 IRTemp op1 = newTemp(Ity_I16);
7042 UShort op2;
7043 IRTemp result = newTemp(Ity_I16);
7044
7045 assign(op1, get_gpr_hw2(r1));
7046 op2 = i2;
7047 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7048 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7049 put_gpr_hw2(r1, mkexpr(result));
7050
7051 return "oilh";
7052}
7053
florian55085f82012-11-21 00:36:55 +00007054static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007055s390_irgen_OILL(UChar r1, UShort i2)
7056{
7057 IRTemp op1 = newTemp(Ity_I16);
7058 UShort op2;
7059 IRTemp result = newTemp(Ity_I16);
7060
7061 assign(op1, get_gpr_hw3(r1));
7062 op2 = i2;
7063 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7064 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7065 put_gpr_hw3(r1, mkexpr(result));
7066
7067 return "oill";
7068}
7069
florian55085f82012-11-21 00:36:55 +00007070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007071s390_irgen_PFD(void)
7072{
7073
7074 return "pfd";
7075}
7076
florian55085f82012-11-21 00:36:55 +00007077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007078s390_irgen_PFDRL(void)
7079{
7080
7081 return "pfdrl";
7082}
7083
florian55085f82012-11-21 00:36:55 +00007084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007085s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7086{
7087 IRTemp amount = newTemp(Ity_I64);
7088 IRTemp op = newTemp(Ity_I32);
7089
7090 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7091 assign(op, get_gpr_w1(r3));
7092 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7093 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7094 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7095
7096 return "rll";
7097}
7098
florian55085f82012-11-21 00:36:55 +00007099static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007100s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7101{
7102 IRTemp amount = newTemp(Ity_I64);
7103 IRTemp op = newTemp(Ity_I64);
7104
7105 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7106 assign(op, get_gpr_dw0(r3));
7107 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7108 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7109 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7110
7111 return "rllg";
7112}
7113
florian55085f82012-11-21 00:36:55 +00007114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007115s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7116{
7117 UChar from;
7118 UChar to;
7119 UChar rot;
7120 UChar t_bit;
7121 ULong mask;
7122 ULong maskc;
7123 IRTemp result = newTemp(Ity_I64);
7124 IRTemp op2 = newTemp(Ity_I64);
7125
7126 from = i3 & 63;
7127 to = i4 & 63;
7128 rot = i5 & 63;
7129 t_bit = i3 & 128;
7130 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7131 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7132 mkU8(64 - rot))));
7133 if (from <= to) {
7134 mask = ~0ULL;
7135 mask = (mask >> from) & (mask << (63 - to));
7136 maskc = ~mask;
7137 } else {
7138 maskc = ~0ULL;
7139 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7140 mask = ~maskc;
7141 }
7142 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7143 ), mkU64(mask)));
7144 if (t_bit == 0) {
7145 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7146 mkU64(maskc)), mkexpr(result)));
7147 }
7148 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7149
7150 return "rnsbg";
7151}
7152
florian55085f82012-11-21 00:36:55 +00007153static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007154s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7155{
7156 UChar from;
7157 UChar to;
7158 UChar rot;
7159 UChar t_bit;
7160 ULong mask;
7161 ULong maskc;
7162 IRTemp result = newTemp(Ity_I64);
7163 IRTemp op2 = newTemp(Ity_I64);
7164
7165 from = i3 & 63;
7166 to = i4 & 63;
7167 rot = i5 & 63;
7168 t_bit = i3 & 128;
7169 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7170 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7171 mkU8(64 - rot))));
7172 if (from <= to) {
7173 mask = ~0ULL;
7174 mask = (mask >> from) & (mask << (63 - to));
7175 maskc = ~mask;
7176 } else {
7177 maskc = ~0ULL;
7178 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7179 mask = ~maskc;
7180 }
7181 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7182 ), mkU64(mask)));
7183 if (t_bit == 0) {
7184 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7185 mkU64(maskc)), mkexpr(result)));
7186 }
7187 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7188
7189 return "rxsbg";
7190}
7191
florian55085f82012-11-21 00:36:55 +00007192static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007193s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7194{
7195 UChar from;
7196 UChar to;
7197 UChar rot;
7198 UChar t_bit;
7199 ULong mask;
7200 ULong maskc;
7201 IRTemp result = newTemp(Ity_I64);
7202 IRTemp op2 = newTemp(Ity_I64);
7203
7204 from = i3 & 63;
7205 to = i4 & 63;
7206 rot = i5 & 63;
7207 t_bit = i3 & 128;
7208 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7209 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7210 mkU8(64 - rot))));
7211 if (from <= to) {
7212 mask = ~0ULL;
7213 mask = (mask >> from) & (mask << (63 - to));
7214 maskc = ~mask;
7215 } else {
7216 maskc = ~0ULL;
7217 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7218 mask = ~maskc;
7219 }
7220 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7221 ), mkU64(mask)));
7222 if (t_bit == 0) {
7223 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7224 mkU64(maskc)), mkexpr(result)));
7225 }
7226 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7227
7228 return "rosbg";
7229}
7230
florian55085f82012-11-21 00:36:55 +00007231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007232s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7233{
7234 UChar from;
7235 UChar to;
7236 UChar rot;
7237 UChar z_bit;
7238 ULong mask;
7239 ULong maskc;
7240 IRTemp op2 = newTemp(Ity_I64);
7241 IRTemp result = newTemp(Ity_I64);
7242
7243 from = i3 & 63;
7244 to = i4 & 63;
7245 rot = i5 & 63;
7246 z_bit = i4 & 128;
7247 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7248 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7249 mkU8(64 - rot))));
7250 if (from <= to) {
7251 mask = ~0ULL;
7252 mask = (mask >> from) & (mask << (63 - to));
7253 maskc = ~mask;
7254 } else {
7255 maskc = ~0ULL;
7256 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7257 mask = ~maskc;
7258 }
7259 if (z_bit == 0) {
7260 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7261 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7262 } else {
7263 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7264 }
7265 assign(result, get_gpr_dw0(r1));
7266 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7267
7268 return "risbg";
7269}
7270
florian55085f82012-11-21 00:36:55 +00007271static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007272s390_irgen_SAR(UChar r1, UChar r2)
7273{
7274 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007275 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007276 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7277
7278 return "sar";
7279}
7280
florian55085f82012-11-21 00:36:55 +00007281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007282s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7283{
7284 IRTemp p1 = newTemp(Ity_I64);
7285 IRTemp p2 = newTemp(Ity_I64);
7286 IRTemp op = newTemp(Ity_I64);
7287 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007288 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007289 IRTemp shift_amount = newTemp(Ity_I64);
7290
7291 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7292 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7293 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7294 ));
7295 sign_mask = 1ULL << 63;
7296 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7297 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007298 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7299 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007300 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7301 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7302 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7303
7304 return "slda";
7305}
7306
florian55085f82012-11-21 00:36:55 +00007307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007308s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7309{
7310 IRTemp p1 = newTemp(Ity_I64);
7311 IRTemp p2 = newTemp(Ity_I64);
7312 IRTemp result = newTemp(Ity_I64);
7313
7314 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7315 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7316 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7317 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7318 mkexpr(op2addr), mkU64(63)))));
7319 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7320 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7321
7322 return "sldl";
7323}
7324
florian55085f82012-11-21 00:36:55 +00007325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007326s390_irgen_SLA(UChar r1, IRTemp op2addr)
7327{
7328 IRTemp uop = newTemp(Ity_I32);
7329 IRTemp result = newTemp(Ity_I32);
7330 UInt sign_mask;
7331 IRTemp shift_amount = newTemp(Ity_I64);
7332 IRTemp op = newTemp(Ity_I32);
7333
7334 assign(op, get_gpr_w1(r1));
7335 assign(uop, get_gpr_w1(r1));
7336 sign_mask = 2147483648U;
7337 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7338 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7339 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7340 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7341 put_gpr_w1(r1, mkexpr(result));
7342 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7343
7344 return "sla";
7345}
7346
florian55085f82012-11-21 00:36:55 +00007347static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007348s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7349{
7350 IRTemp uop = newTemp(Ity_I32);
7351 IRTemp result = newTemp(Ity_I32);
7352 UInt sign_mask;
7353 IRTemp shift_amount = newTemp(Ity_I64);
7354 IRTemp op = newTemp(Ity_I32);
7355
7356 assign(op, get_gpr_w1(r3));
7357 assign(uop, get_gpr_w1(r3));
7358 sign_mask = 2147483648U;
7359 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7360 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7361 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7362 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7363 put_gpr_w1(r1, mkexpr(result));
7364 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7365
7366 return "slak";
7367}
7368
florian55085f82012-11-21 00:36:55 +00007369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007370s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7371{
7372 IRTemp uop = newTemp(Ity_I64);
7373 IRTemp result = newTemp(Ity_I64);
7374 ULong sign_mask;
7375 IRTemp shift_amount = newTemp(Ity_I64);
7376 IRTemp op = newTemp(Ity_I64);
7377
7378 assign(op, get_gpr_dw0(r3));
7379 assign(uop, get_gpr_dw0(r3));
7380 sign_mask = 9223372036854775808ULL;
7381 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7382 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7383 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7384 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7385 put_gpr_dw0(r1, mkexpr(result));
7386 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7387
7388 return "slag";
7389}
7390
florian55085f82012-11-21 00:36:55 +00007391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007392s390_irgen_SLL(UChar r1, IRTemp op2addr)
7393{
7394 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7395 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7396
7397 return "sll";
7398}
7399
florian55085f82012-11-21 00:36:55 +00007400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007401s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7402{
7403 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7404 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7405
7406 return "sllk";
7407}
7408
florian55085f82012-11-21 00:36:55 +00007409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007410s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7411{
7412 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7413 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7414
7415 return "sllg";
7416}
7417
florian55085f82012-11-21 00:36:55 +00007418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007419s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7420{
7421 IRTemp p1 = newTemp(Ity_I64);
7422 IRTemp p2 = newTemp(Ity_I64);
7423 IRTemp result = newTemp(Ity_I64);
7424
7425 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7426 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7427 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7428 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7429 mkexpr(op2addr), mkU64(63)))));
7430 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7431 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7432 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7433
7434 return "srda";
7435}
7436
florian55085f82012-11-21 00:36:55 +00007437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007438s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7439{
7440 IRTemp p1 = newTemp(Ity_I64);
7441 IRTemp p2 = newTemp(Ity_I64);
7442 IRTemp result = newTemp(Ity_I64);
7443
7444 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7445 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7446 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7447 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7448 mkexpr(op2addr), mkU64(63)))));
7449 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7450 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7451
7452 return "srdl";
7453}
7454
florian55085f82012-11-21 00:36:55 +00007455static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007456s390_irgen_SRA(UChar r1, IRTemp op2addr)
7457{
7458 IRTemp result = newTemp(Ity_I32);
7459 IRTemp op = newTemp(Ity_I32);
7460
7461 assign(op, get_gpr_w1(r1));
7462 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7463 mkexpr(op2addr), mkU64(63)))));
7464 put_gpr_w1(r1, mkexpr(result));
7465 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7466
7467 return "sra";
7468}
7469
florian55085f82012-11-21 00:36:55 +00007470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007471s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7472{
7473 IRTemp result = newTemp(Ity_I32);
7474 IRTemp op = newTemp(Ity_I32);
7475
7476 assign(op, get_gpr_w1(r3));
7477 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7478 mkexpr(op2addr), mkU64(63)))));
7479 put_gpr_w1(r1, mkexpr(result));
7480 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7481
7482 return "srak";
7483}
7484
florian55085f82012-11-21 00:36:55 +00007485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007486s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7487{
7488 IRTemp result = newTemp(Ity_I64);
7489 IRTemp op = newTemp(Ity_I64);
7490
7491 assign(op, get_gpr_dw0(r3));
7492 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7493 mkexpr(op2addr), mkU64(63)))));
7494 put_gpr_dw0(r1, mkexpr(result));
7495 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7496
7497 return "srag";
7498}
7499
florian55085f82012-11-21 00:36:55 +00007500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007501s390_irgen_SRL(UChar r1, IRTemp op2addr)
7502{
7503 IRTemp op = newTemp(Ity_I32);
7504
7505 assign(op, get_gpr_w1(r1));
7506 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7507 mkexpr(op2addr), mkU64(63)))));
7508
7509 return "srl";
7510}
7511
florian55085f82012-11-21 00:36:55 +00007512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007513s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7514{
7515 IRTemp op = newTemp(Ity_I32);
7516
7517 assign(op, get_gpr_w1(r3));
7518 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7519 mkexpr(op2addr), mkU64(63)))));
7520
7521 return "srlk";
7522}
7523
florian55085f82012-11-21 00:36:55 +00007524static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007525s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7526{
7527 IRTemp op = newTemp(Ity_I64);
7528
7529 assign(op, get_gpr_dw0(r3));
7530 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7531 mkexpr(op2addr), mkU64(63)))));
7532
7533 return "srlg";
7534}
7535
florian55085f82012-11-21 00:36:55 +00007536static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007537s390_irgen_ST(UChar r1, IRTemp op2addr)
7538{
7539 store(mkexpr(op2addr), get_gpr_w1(r1));
7540
7541 return "st";
7542}
7543
florian55085f82012-11-21 00:36:55 +00007544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007545s390_irgen_STY(UChar r1, IRTemp op2addr)
7546{
7547 store(mkexpr(op2addr), get_gpr_w1(r1));
7548
7549 return "sty";
7550}
7551
florian55085f82012-11-21 00:36:55 +00007552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007553s390_irgen_STG(UChar r1, IRTemp op2addr)
7554{
7555 store(mkexpr(op2addr), get_gpr_dw0(r1));
7556
7557 return "stg";
7558}
7559
florian55085f82012-11-21 00:36:55 +00007560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007561s390_irgen_STRL(UChar r1, UInt i2)
7562{
7563 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7564 get_gpr_w1(r1));
7565
7566 return "strl";
7567}
7568
florian55085f82012-11-21 00:36:55 +00007569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007570s390_irgen_STGRL(UChar r1, UInt i2)
7571{
7572 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7573 get_gpr_dw0(r1));
7574
7575 return "stgrl";
7576}
7577
florian55085f82012-11-21 00:36:55 +00007578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007579s390_irgen_STC(UChar r1, IRTemp op2addr)
7580{
7581 store(mkexpr(op2addr), get_gpr_b7(r1));
7582
7583 return "stc";
7584}
7585
florian55085f82012-11-21 00:36:55 +00007586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007587s390_irgen_STCY(UChar r1, IRTemp op2addr)
7588{
7589 store(mkexpr(op2addr), get_gpr_b7(r1));
7590
7591 return "stcy";
7592}
7593
florian55085f82012-11-21 00:36:55 +00007594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007595s390_irgen_STCH(UChar r1, IRTemp op2addr)
7596{
7597 store(mkexpr(op2addr), get_gpr_b3(r1));
7598
7599 return "stch";
7600}
7601
florian55085f82012-11-21 00:36:55 +00007602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007603s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7604{
7605 UChar mask;
7606 UChar n;
7607
7608 mask = (UChar)r3;
7609 n = 0;
7610 if ((mask & 8) != 0) {
7611 store(mkexpr(op2addr), get_gpr_b4(r1));
7612 n = n + 1;
7613 }
7614 if ((mask & 4) != 0) {
7615 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7616 n = n + 1;
7617 }
7618 if ((mask & 2) != 0) {
7619 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7620 n = n + 1;
7621 }
7622 if ((mask & 1) != 0) {
7623 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7624 }
7625
7626 return "stcm";
7627}
7628
florian55085f82012-11-21 00:36:55 +00007629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007630s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7631{
7632 UChar mask;
7633 UChar n;
7634
7635 mask = (UChar)r3;
7636 n = 0;
7637 if ((mask & 8) != 0) {
7638 store(mkexpr(op2addr), get_gpr_b4(r1));
7639 n = n + 1;
7640 }
7641 if ((mask & 4) != 0) {
7642 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7643 n = n + 1;
7644 }
7645 if ((mask & 2) != 0) {
7646 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7647 n = n + 1;
7648 }
7649 if ((mask & 1) != 0) {
7650 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7651 }
7652
7653 return "stcmy";
7654}
7655
florian55085f82012-11-21 00:36:55 +00007656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007657s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7658{
7659 UChar mask;
7660 UChar n;
7661
7662 mask = (UChar)r3;
7663 n = 0;
7664 if ((mask & 8) != 0) {
7665 store(mkexpr(op2addr), get_gpr_b0(r1));
7666 n = n + 1;
7667 }
7668 if ((mask & 4) != 0) {
7669 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7670 n = n + 1;
7671 }
7672 if ((mask & 2) != 0) {
7673 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7674 n = n + 1;
7675 }
7676 if ((mask & 1) != 0) {
7677 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7678 }
7679
7680 return "stcmh";
7681}
7682
florian55085f82012-11-21 00:36:55 +00007683static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007684s390_irgen_STH(UChar r1, IRTemp op2addr)
7685{
7686 store(mkexpr(op2addr), get_gpr_hw3(r1));
7687
7688 return "sth";
7689}
7690
florian55085f82012-11-21 00:36:55 +00007691static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007692s390_irgen_STHY(UChar r1, IRTemp op2addr)
7693{
7694 store(mkexpr(op2addr), get_gpr_hw3(r1));
7695
7696 return "sthy";
7697}
7698
florian55085f82012-11-21 00:36:55 +00007699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007700s390_irgen_STHRL(UChar r1, UInt i2)
7701{
7702 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7703 get_gpr_hw3(r1));
7704
7705 return "sthrl";
7706}
7707
florian55085f82012-11-21 00:36:55 +00007708static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007709s390_irgen_STHH(UChar r1, IRTemp op2addr)
7710{
7711 store(mkexpr(op2addr), get_gpr_hw1(r1));
7712
7713 return "sthh";
7714}
7715
florian55085f82012-11-21 00:36:55 +00007716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007717s390_irgen_STFH(UChar r1, IRTemp op2addr)
7718{
7719 store(mkexpr(op2addr), get_gpr_w0(r1));
7720
7721 return "stfh";
7722}
7723
florian55085f82012-11-21 00:36:55 +00007724static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007725s390_irgen_STOC(UChar r1, IRTemp op2addr)
7726{
7727 /* condition is checked in format handler */
7728 store(mkexpr(op2addr), get_gpr_w1(r1));
7729
7730 return "stoc";
7731}
7732
florian55085f82012-11-21 00:36:55 +00007733static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007734s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7735{
7736 /* condition is checked in format handler */
7737 store(mkexpr(op2addr), get_gpr_dw0(r1));
7738
7739 return "stocg";
7740}
7741
florian55085f82012-11-21 00:36:55 +00007742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007743s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7744{
7745 store(mkexpr(op2addr), get_gpr_dw0(r1));
7746 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7747
7748 return "stpq";
7749}
7750
florian55085f82012-11-21 00:36:55 +00007751static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007752s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7753{
7754 store(mkexpr(op2addr), get_gpr_b7(r1));
7755 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7756
7757 return "strvh";
7758}
7759
florian55085f82012-11-21 00:36:55 +00007760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007761s390_irgen_STRV(UChar r1, IRTemp op2addr)
7762{
7763 store(mkexpr(op2addr), get_gpr_b7(r1));
7764 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7765 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7766 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7767
7768 return "strv";
7769}
7770
florian55085f82012-11-21 00:36:55 +00007771static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007772s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7773{
7774 store(mkexpr(op2addr), get_gpr_b7(r1));
7775 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7776 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7777 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7778 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7779 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7780 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7781 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7782
7783 return "strvg";
7784}
7785
florian55085f82012-11-21 00:36:55 +00007786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007787s390_irgen_SR(UChar r1, UChar r2)
7788{
7789 IRTemp op1 = newTemp(Ity_I32);
7790 IRTemp op2 = newTemp(Ity_I32);
7791 IRTemp result = newTemp(Ity_I32);
7792
7793 assign(op1, get_gpr_w1(r1));
7794 assign(op2, get_gpr_w1(r2));
7795 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7796 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7797 put_gpr_w1(r1, mkexpr(result));
7798
7799 return "sr";
7800}
7801
florian55085f82012-11-21 00:36:55 +00007802static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007803s390_irgen_SGR(UChar r1, UChar r2)
7804{
7805 IRTemp op1 = newTemp(Ity_I64);
7806 IRTemp op2 = newTemp(Ity_I64);
7807 IRTemp result = newTemp(Ity_I64);
7808
7809 assign(op1, get_gpr_dw0(r1));
7810 assign(op2, get_gpr_dw0(r2));
7811 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7812 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7813 put_gpr_dw0(r1, mkexpr(result));
7814
7815 return "sgr";
7816}
7817
florian55085f82012-11-21 00:36:55 +00007818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007819s390_irgen_SGFR(UChar r1, UChar r2)
7820{
7821 IRTemp op1 = newTemp(Ity_I64);
7822 IRTemp op2 = newTemp(Ity_I64);
7823 IRTemp result = newTemp(Ity_I64);
7824
7825 assign(op1, get_gpr_dw0(r1));
7826 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7827 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7828 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7829 put_gpr_dw0(r1, mkexpr(result));
7830
7831 return "sgfr";
7832}
7833
florian55085f82012-11-21 00:36:55 +00007834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007835s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7836{
7837 IRTemp op2 = newTemp(Ity_I32);
7838 IRTemp op3 = newTemp(Ity_I32);
7839 IRTemp result = newTemp(Ity_I32);
7840
7841 assign(op2, get_gpr_w1(r2));
7842 assign(op3, get_gpr_w1(r3));
7843 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7844 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7845 put_gpr_w1(r1, mkexpr(result));
7846
7847 return "srk";
7848}
7849
florian55085f82012-11-21 00:36:55 +00007850static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007851s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7852{
7853 IRTemp op2 = newTemp(Ity_I64);
7854 IRTemp op3 = newTemp(Ity_I64);
7855 IRTemp result = newTemp(Ity_I64);
7856
7857 assign(op2, get_gpr_dw0(r2));
7858 assign(op3, get_gpr_dw0(r3));
7859 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7860 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7861 put_gpr_dw0(r1, mkexpr(result));
7862
7863 return "sgrk";
7864}
7865
florian55085f82012-11-21 00:36:55 +00007866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007867s390_irgen_S(UChar r1, IRTemp op2addr)
7868{
7869 IRTemp op1 = newTemp(Ity_I32);
7870 IRTemp op2 = newTemp(Ity_I32);
7871 IRTemp result = newTemp(Ity_I32);
7872
7873 assign(op1, get_gpr_w1(r1));
7874 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7875 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7876 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7877 put_gpr_w1(r1, mkexpr(result));
7878
7879 return "s";
7880}
7881
florian55085f82012-11-21 00:36:55 +00007882static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007883s390_irgen_SY(UChar r1, IRTemp op2addr)
7884{
7885 IRTemp op1 = newTemp(Ity_I32);
7886 IRTemp op2 = newTemp(Ity_I32);
7887 IRTemp result = newTemp(Ity_I32);
7888
7889 assign(op1, get_gpr_w1(r1));
7890 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7891 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7892 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7893 put_gpr_w1(r1, mkexpr(result));
7894
7895 return "sy";
7896}
7897
florian55085f82012-11-21 00:36:55 +00007898static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007899s390_irgen_SG(UChar r1, IRTemp op2addr)
7900{
7901 IRTemp op1 = newTemp(Ity_I64);
7902 IRTemp op2 = newTemp(Ity_I64);
7903 IRTemp result = newTemp(Ity_I64);
7904
7905 assign(op1, get_gpr_dw0(r1));
7906 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7907 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7908 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7909 put_gpr_dw0(r1, mkexpr(result));
7910
7911 return "sg";
7912}
7913
florian55085f82012-11-21 00:36:55 +00007914static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007915s390_irgen_SGF(UChar r1, IRTemp op2addr)
7916{
7917 IRTemp op1 = newTemp(Ity_I64);
7918 IRTemp op2 = newTemp(Ity_I64);
7919 IRTemp result = newTemp(Ity_I64);
7920
7921 assign(op1, get_gpr_dw0(r1));
7922 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7923 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7924 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7925 put_gpr_dw0(r1, mkexpr(result));
7926
7927 return "sgf";
7928}
7929
florian55085f82012-11-21 00:36:55 +00007930static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007931s390_irgen_SH(UChar r1, IRTemp op2addr)
7932{
7933 IRTemp op1 = newTemp(Ity_I32);
7934 IRTemp op2 = newTemp(Ity_I32);
7935 IRTemp result = newTemp(Ity_I32);
7936
7937 assign(op1, get_gpr_w1(r1));
7938 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7939 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7940 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7941 put_gpr_w1(r1, mkexpr(result));
7942
7943 return "sh";
7944}
7945
florian55085f82012-11-21 00:36:55 +00007946static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007947s390_irgen_SHY(UChar r1, IRTemp op2addr)
7948{
7949 IRTemp op1 = newTemp(Ity_I32);
7950 IRTemp op2 = newTemp(Ity_I32);
7951 IRTemp result = newTemp(Ity_I32);
7952
7953 assign(op1, get_gpr_w1(r1));
7954 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7955 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7956 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7957 put_gpr_w1(r1, mkexpr(result));
7958
7959 return "shy";
7960}
7961
florian55085f82012-11-21 00:36:55 +00007962static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007963s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7964{
7965 IRTemp op2 = newTemp(Ity_I32);
7966 IRTemp op3 = newTemp(Ity_I32);
7967 IRTemp result = newTemp(Ity_I32);
7968
7969 assign(op2, get_gpr_w0(r1));
7970 assign(op3, get_gpr_w0(r2));
7971 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7972 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7973 put_gpr_w0(r1, mkexpr(result));
7974
7975 return "shhhr";
7976}
7977
florian55085f82012-11-21 00:36:55 +00007978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007979s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7980{
7981 IRTemp op2 = newTemp(Ity_I32);
7982 IRTemp op3 = newTemp(Ity_I32);
7983 IRTemp result = newTemp(Ity_I32);
7984
7985 assign(op2, get_gpr_w0(r1));
7986 assign(op3, get_gpr_w1(r2));
7987 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7989 put_gpr_w0(r1, mkexpr(result));
7990
7991 return "shhlr";
7992}
7993
florian55085f82012-11-21 00:36:55 +00007994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007995s390_irgen_SLR(UChar r1, UChar r2)
7996{
7997 IRTemp op1 = newTemp(Ity_I32);
7998 IRTemp op2 = newTemp(Ity_I32);
7999 IRTemp result = newTemp(Ity_I32);
8000
8001 assign(op1, get_gpr_w1(r1));
8002 assign(op2, get_gpr_w1(r2));
8003 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8004 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8005 put_gpr_w1(r1, mkexpr(result));
8006
8007 return "slr";
8008}
8009
florian55085f82012-11-21 00:36:55 +00008010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008011s390_irgen_SLGR(UChar r1, UChar r2)
8012{
8013 IRTemp op1 = newTemp(Ity_I64);
8014 IRTemp op2 = newTemp(Ity_I64);
8015 IRTemp result = newTemp(Ity_I64);
8016
8017 assign(op1, get_gpr_dw0(r1));
8018 assign(op2, get_gpr_dw0(r2));
8019 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8020 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8021 put_gpr_dw0(r1, mkexpr(result));
8022
8023 return "slgr";
8024}
8025
florian55085f82012-11-21 00:36:55 +00008026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008027s390_irgen_SLGFR(UChar r1, UChar r2)
8028{
8029 IRTemp op1 = newTemp(Ity_I64);
8030 IRTemp op2 = newTemp(Ity_I64);
8031 IRTemp result = newTemp(Ity_I64);
8032
8033 assign(op1, get_gpr_dw0(r1));
8034 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8035 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8036 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8037 put_gpr_dw0(r1, mkexpr(result));
8038
8039 return "slgfr";
8040}
8041
florian55085f82012-11-21 00:36:55 +00008042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008043s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8044{
8045 IRTemp op2 = newTemp(Ity_I32);
8046 IRTemp op3 = newTemp(Ity_I32);
8047 IRTemp result = newTemp(Ity_I32);
8048
8049 assign(op2, get_gpr_w1(r2));
8050 assign(op3, get_gpr_w1(r3));
8051 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8052 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8053 put_gpr_w1(r1, mkexpr(result));
8054
8055 return "slrk";
8056}
8057
florian55085f82012-11-21 00:36:55 +00008058static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008059s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8060{
8061 IRTemp op2 = newTemp(Ity_I64);
8062 IRTemp op3 = newTemp(Ity_I64);
8063 IRTemp result = newTemp(Ity_I64);
8064
8065 assign(op2, get_gpr_dw0(r2));
8066 assign(op3, get_gpr_dw0(r3));
8067 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8068 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8069 put_gpr_dw0(r1, mkexpr(result));
8070
8071 return "slgrk";
8072}
8073
florian55085f82012-11-21 00:36:55 +00008074static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008075s390_irgen_SL(UChar r1, IRTemp op2addr)
8076{
8077 IRTemp op1 = newTemp(Ity_I32);
8078 IRTemp op2 = newTemp(Ity_I32);
8079 IRTemp result = newTemp(Ity_I32);
8080
8081 assign(op1, get_gpr_w1(r1));
8082 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8083 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8084 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8085 put_gpr_w1(r1, mkexpr(result));
8086
8087 return "sl";
8088}
8089
florian55085f82012-11-21 00:36:55 +00008090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008091s390_irgen_SLY(UChar r1, IRTemp op2addr)
8092{
8093 IRTemp op1 = newTemp(Ity_I32);
8094 IRTemp op2 = newTemp(Ity_I32);
8095 IRTemp result = newTemp(Ity_I32);
8096
8097 assign(op1, get_gpr_w1(r1));
8098 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8099 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8100 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8101 put_gpr_w1(r1, mkexpr(result));
8102
8103 return "sly";
8104}
8105
florian55085f82012-11-21 00:36:55 +00008106static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008107s390_irgen_SLG(UChar r1, IRTemp op2addr)
8108{
8109 IRTemp op1 = newTemp(Ity_I64);
8110 IRTemp op2 = newTemp(Ity_I64);
8111 IRTemp result = newTemp(Ity_I64);
8112
8113 assign(op1, get_gpr_dw0(r1));
8114 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8115 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8116 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8117 put_gpr_dw0(r1, mkexpr(result));
8118
8119 return "slg";
8120}
8121
florian55085f82012-11-21 00:36:55 +00008122static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008123s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8124{
8125 IRTemp op1 = newTemp(Ity_I64);
8126 IRTemp op2 = newTemp(Ity_I64);
8127 IRTemp result = newTemp(Ity_I64);
8128
8129 assign(op1, get_gpr_dw0(r1));
8130 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8131 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8132 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8133 put_gpr_dw0(r1, mkexpr(result));
8134
8135 return "slgf";
8136}
8137
florian55085f82012-11-21 00:36:55 +00008138static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008139s390_irgen_SLFI(UChar r1, UInt i2)
8140{
8141 IRTemp op1 = newTemp(Ity_I32);
8142 UInt op2;
8143 IRTemp result = newTemp(Ity_I32);
8144
8145 assign(op1, get_gpr_w1(r1));
8146 op2 = i2;
8147 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8148 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8149 mkU32(op2)));
8150 put_gpr_w1(r1, mkexpr(result));
8151
8152 return "slfi";
8153}
8154
florian55085f82012-11-21 00:36:55 +00008155static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008156s390_irgen_SLGFI(UChar r1, UInt i2)
8157{
8158 IRTemp op1 = newTemp(Ity_I64);
8159 ULong op2;
8160 IRTemp result = newTemp(Ity_I64);
8161
8162 assign(op1, get_gpr_dw0(r1));
8163 op2 = (ULong)i2;
8164 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8165 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8166 mkU64(op2)));
8167 put_gpr_dw0(r1, mkexpr(result));
8168
8169 return "slgfi";
8170}
8171
florian55085f82012-11-21 00:36:55 +00008172static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008173s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8174{
8175 IRTemp op2 = newTemp(Ity_I32);
8176 IRTemp op3 = newTemp(Ity_I32);
8177 IRTemp result = newTemp(Ity_I32);
8178
8179 assign(op2, get_gpr_w0(r1));
8180 assign(op3, get_gpr_w0(r2));
8181 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8182 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8183 put_gpr_w0(r1, mkexpr(result));
8184
8185 return "slhhhr";
8186}
8187
florian55085f82012-11-21 00:36:55 +00008188static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008189s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8190{
8191 IRTemp op2 = newTemp(Ity_I32);
8192 IRTemp op3 = newTemp(Ity_I32);
8193 IRTemp result = newTemp(Ity_I32);
8194
8195 assign(op2, get_gpr_w0(r1));
8196 assign(op3, get_gpr_w1(r2));
8197 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8198 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8199 put_gpr_w0(r1, mkexpr(result));
8200
8201 return "slhhlr";
8202}
8203
florian55085f82012-11-21 00:36:55 +00008204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008205s390_irgen_SLBR(UChar r1, UChar r2)
8206{
8207 IRTemp op1 = newTemp(Ity_I32);
8208 IRTemp op2 = newTemp(Ity_I32);
8209 IRTemp result = newTemp(Ity_I32);
8210 IRTemp borrow_in = newTemp(Ity_I32);
8211
8212 assign(op1, get_gpr_w1(r1));
8213 assign(op2, get_gpr_w1(r2));
8214 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8215 s390_call_calculate_cc(), mkU8(1))));
8216 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8217 mkexpr(borrow_in)));
8218 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8219 put_gpr_w1(r1, mkexpr(result));
8220
8221 return "slbr";
8222}
8223
florian55085f82012-11-21 00:36:55 +00008224static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008225s390_irgen_SLBGR(UChar r1, UChar r2)
8226{
8227 IRTemp op1 = newTemp(Ity_I64);
8228 IRTemp op2 = newTemp(Ity_I64);
8229 IRTemp result = newTemp(Ity_I64);
8230 IRTemp borrow_in = newTemp(Ity_I64);
8231
8232 assign(op1, get_gpr_dw0(r1));
8233 assign(op2, get_gpr_dw0(r2));
8234 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8235 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8236 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8237 mkexpr(borrow_in)));
8238 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8239 put_gpr_dw0(r1, mkexpr(result));
8240
8241 return "slbgr";
8242}
8243
florian55085f82012-11-21 00:36:55 +00008244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008245s390_irgen_SLB(UChar r1, IRTemp op2addr)
8246{
8247 IRTemp op1 = newTemp(Ity_I32);
8248 IRTemp op2 = newTemp(Ity_I32);
8249 IRTemp result = newTemp(Ity_I32);
8250 IRTemp borrow_in = newTemp(Ity_I32);
8251
8252 assign(op1, get_gpr_w1(r1));
8253 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8254 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8255 s390_call_calculate_cc(), mkU8(1))));
8256 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8257 mkexpr(borrow_in)));
8258 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8259 put_gpr_w1(r1, mkexpr(result));
8260
8261 return "slb";
8262}
8263
florian55085f82012-11-21 00:36:55 +00008264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008265s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8266{
8267 IRTemp op1 = newTemp(Ity_I64);
8268 IRTemp op2 = newTemp(Ity_I64);
8269 IRTemp result = newTemp(Ity_I64);
8270 IRTemp borrow_in = newTemp(Ity_I64);
8271
8272 assign(op1, get_gpr_dw0(r1));
8273 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8274 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8275 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8276 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8277 mkexpr(borrow_in)));
8278 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8279 put_gpr_dw0(r1, mkexpr(result));
8280
8281 return "slbg";
8282}
8283
florian55085f82012-11-21 00:36:55 +00008284static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008285s390_irgen_SVC(UChar i)
8286{
8287 IRTemp sysno = newTemp(Ity_I64);
8288
8289 if (i != 0) {
8290 assign(sysno, mkU64(i));
8291 } else {
8292 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8293 }
8294 system_call(mkexpr(sysno));
8295
8296 return "svc";
8297}
8298
florian55085f82012-11-21 00:36:55 +00008299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008300s390_irgen_TM(UChar i2, IRTemp op1addr)
8301{
8302 UChar mask;
8303 IRTemp value = newTemp(Ity_I8);
8304
8305 mask = i2;
8306 assign(value, load(Ity_I8, mkexpr(op1addr)));
8307 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8308 mkU8(mask)));
8309
8310 return "tm";
8311}
8312
florian55085f82012-11-21 00:36:55 +00008313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008314s390_irgen_TMY(UChar i2, IRTemp op1addr)
8315{
8316 UChar mask;
8317 IRTemp value = newTemp(Ity_I8);
8318
8319 mask = i2;
8320 assign(value, load(Ity_I8, mkexpr(op1addr)));
8321 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8322 mkU8(mask)));
8323
8324 return "tmy";
8325}
8326
florian55085f82012-11-21 00:36:55 +00008327static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008328s390_irgen_TMHH(UChar r1, UShort i2)
8329{
8330 UShort mask;
8331 IRTemp value = newTemp(Ity_I16);
8332
8333 mask = i2;
8334 assign(value, get_gpr_hw0(r1));
8335 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8336 mkU16(mask)));
8337
8338 return "tmhh";
8339}
8340
florian55085f82012-11-21 00:36:55 +00008341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008342s390_irgen_TMHL(UChar r1, UShort i2)
8343{
8344 UShort mask;
8345 IRTemp value = newTemp(Ity_I16);
8346
8347 mask = i2;
8348 assign(value, get_gpr_hw1(r1));
8349 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8350 mkU16(mask)));
8351
8352 return "tmhl";
8353}
8354
florian55085f82012-11-21 00:36:55 +00008355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008356s390_irgen_TMLH(UChar r1, UShort i2)
8357{
8358 UShort mask;
8359 IRTemp value = newTemp(Ity_I16);
8360
8361 mask = i2;
8362 assign(value, get_gpr_hw2(r1));
8363 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8364 mkU16(mask)));
8365
8366 return "tmlh";
8367}
8368
florian55085f82012-11-21 00:36:55 +00008369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008370s390_irgen_TMLL(UChar r1, UShort i2)
8371{
8372 UShort mask;
8373 IRTemp value = newTemp(Ity_I16);
8374
8375 mask = i2;
8376 assign(value, get_gpr_hw3(r1));
8377 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8378 mkU16(mask)));
8379
8380 return "tmll";
8381}
8382
florian55085f82012-11-21 00:36:55 +00008383static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008384s390_irgen_EFPC(UChar r1)
8385{
8386 put_gpr_w1(r1, get_fpc_w0());
8387
8388 return "efpc";
8389}
8390
florian55085f82012-11-21 00:36:55 +00008391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008392s390_irgen_LER(UChar r1, UChar r2)
8393{
8394 put_fpr_w0(r1, get_fpr_w0(r2));
8395
8396 return "ler";
8397}
8398
florian55085f82012-11-21 00:36:55 +00008399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008400s390_irgen_LDR(UChar r1, UChar r2)
8401{
8402 put_fpr_dw0(r1, get_fpr_dw0(r2));
8403
8404 return "ldr";
8405}
8406
florian55085f82012-11-21 00:36:55 +00008407static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008408s390_irgen_LXR(UChar r1, UChar r2)
8409{
8410 put_fpr_dw0(r1, get_fpr_dw0(r2));
8411 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8412
8413 return "lxr";
8414}
8415
florian55085f82012-11-21 00:36:55 +00008416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008417s390_irgen_LE(UChar r1, IRTemp op2addr)
8418{
8419 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8420
8421 return "le";
8422}
8423
florian55085f82012-11-21 00:36:55 +00008424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008425s390_irgen_LD(UChar r1, IRTemp op2addr)
8426{
8427 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8428
8429 return "ld";
8430}
8431
florian55085f82012-11-21 00:36:55 +00008432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008433s390_irgen_LEY(UChar r1, IRTemp op2addr)
8434{
8435 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8436
8437 return "ley";
8438}
8439
florian55085f82012-11-21 00:36:55 +00008440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008441s390_irgen_LDY(UChar r1, IRTemp op2addr)
8442{
8443 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8444
8445 return "ldy";
8446}
8447
florian55085f82012-11-21 00:36:55 +00008448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008449s390_irgen_LFPC(IRTemp op2addr)
8450{
8451 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8452
8453 return "lfpc";
8454}
8455
florian55085f82012-11-21 00:36:55 +00008456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008457s390_irgen_LZER(UChar r1)
8458{
8459 put_fpr_w0(r1, mkF32i(0x0));
8460
8461 return "lzer";
8462}
8463
florian55085f82012-11-21 00:36:55 +00008464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008465s390_irgen_LZDR(UChar r1)
8466{
8467 put_fpr_dw0(r1, mkF64i(0x0));
8468
8469 return "lzdr";
8470}
8471
florian55085f82012-11-21 00:36:55 +00008472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008473s390_irgen_LZXR(UChar r1)
8474{
8475 put_fpr_dw0(r1, mkF64i(0x0));
8476 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8477
8478 return "lzxr";
8479}
8480
florian55085f82012-11-21 00:36:55 +00008481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008482s390_irgen_SRNM(IRTemp op2addr)
8483{
florianf0fa1be2012-09-18 20:24:38 +00008484 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008485
florianf0fa1be2012-09-18 20:24:38 +00008486 input_mask = 3;
8487 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008488
florianf0fa1be2012-09-18 20:24:38 +00008489 put_fpc_w0(binop(Iop_Or32,
8490 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8491 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8492 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008493 return "srnm";
8494}
8495
florian55085f82012-11-21 00:36:55 +00008496static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008497s390_irgen_SRNMB(IRTemp op2addr)
8498{
8499 UInt input_mask, fpc_mask;
8500
8501 input_mask = 7;
8502 fpc_mask = 7;
8503
8504 put_fpc_w0(binop(Iop_Or32,
8505 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8506 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8507 mkU32(input_mask))));
8508 return "srnmb";
8509}
8510
florian81a4bfe2012-09-20 01:25:28 +00008511static void
florianf0fa1be2012-09-18 20:24:38 +00008512s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8513{
8514 if (b2 == 0) { /* This is the typical case */
8515 if (d2 > 3) {
8516 if (s390_host_has_fpext && d2 == 7) {
8517 /* ok */
8518 } else {
8519 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008520 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008521 }
8522 }
8523 }
8524
8525 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8526}
8527
8528
florian55085f82012-11-21 00:36:55 +00008529static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008530s390_irgen_SFPC(UChar r1)
8531{
8532 put_fpc_w0(get_gpr_w1(r1));
8533
8534 return "sfpc";
8535}
8536
florian55085f82012-11-21 00:36:55 +00008537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008538s390_irgen_STE(UChar r1, IRTemp op2addr)
8539{
8540 store(mkexpr(op2addr), get_fpr_w0(r1));
8541
8542 return "ste";
8543}
8544
florian55085f82012-11-21 00:36:55 +00008545static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008546s390_irgen_STD(UChar r1, IRTemp op2addr)
8547{
8548 store(mkexpr(op2addr), get_fpr_dw0(r1));
8549
8550 return "std";
8551}
8552
florian55085f82012-11-21 00:36:55 +00008553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008554s390_irgen_STEY(UChar r1, IRTemp op2addr)
8555{
8556 store(mkexpr(op2addr), get_fpr_w0(r1));
8557
8558 return "stey";
8559}
8560
florian55085f82012-11-21 00:36:55 +00008561static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008562s390_irgen_STDY(UChar r1, IRTemp op2addr)
8563{
8564 store(mkexpr(op2addr), get_fpr_dw0(r1));
8565
8566 return "stdy";
8567}
8568
florian55085f82012-11-21 00:36:55 +00008569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008570s390_irgen_STFPC(IRTemp op2addr)
8571{
8572 store(mkexpr(op2addr), get_fpc_w0());
8573
8574 return "stfpc";
8575}
8576
florian55085f82012-11-21 00:36:55 +00008577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008578s390_irgen_AEBR(UChar r1, UChar r2)
8579{
8580 IRTemp op1 = newTemp(Ity_F32);
8581 IRTemp op2 = newTemp(Ity_F32);
8582 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008583 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008584
8585 assign(op1, get_fpr_w0(r1));
8586 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008587 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008588 mkexpr(op2)));
8589 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8590 put_fpr_w0(r1, mkexpr(result));
8591
8592 return "aebr";
8593}
8594
florian55085f82012-11-21 00:36:55 +00008595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008596s390_irgen_ADBR(UChar r1, UChar r2)
8597{
8598 IRTemp op1 = newTemp(Ity_F64);
8599 IRTemp op2 = newTemp(Ity_F64);
8600 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008601 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008602
8603 assign(op1, get_fpr_dw0(r1));
8604 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008605 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008606 mkexpr(op2)));
8607 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8608 put_fpr_dw0(r1, mkexpr(result));
8609
8610 return "adbr";
8611}
8612
florian55085f82012-11-21 00:36:55 +00008613static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008614s390_irgen_AEB(UChar r1, IRTemp op2addr)
8615{
8616 IRTemp op1 = newTemp(Ity_F32);
8617 IRTemp op2 = newTemp(Ity_F32);
8618 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008619 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008620
8621 assign(op1, get_fpr_w0(r1));
8622 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008623 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008624 mkexpr(op2)));
8625 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8626 put_fpr_w0(r1, mkexpr(result));
8627
8628 return "aeb";
8629}
8630
florian55085f82012-11-21 00:36:55 +00008631static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008632s390_irgen_ADB(UChar r1, IRTemp op2addr)
8633{
8634 IRTemp op1 = newTemp(Ity_F64);
8635 IRTemp op2 = newTemp(Ity_F64);
8636 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008637 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008638
8639 assign(op1, get_fpr_dw0(r1));
8640 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008641 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008642 mkexpr(op2)));
8643 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8644 put_fpr_dw0(r1, mkexpr(result));
8645
8646 return "adb";
8647}
8648
florian55085f82012-11-21 00:36:55 +00008649static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008650s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8651 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008652{
florian125e20d2012-10-07 15:42:37 +00008653 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008654 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008655 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008656 }
sewardj2019a972011-03-07 16:04:07 +00008657 IRTemp op2 = newTemp(Ity_I32);
8658
8659 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008660 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008661 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008662
8663 return "cefbr";
8664}
8665
florian55085f82012-11-21 00:36:55 +00008666static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008667s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8668 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008669{
8670 IRTemp op2 = newTemp(Ity_I32);
8671
8672 assign(op2, get_gpr_w1(r2));
8673 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8674
8675 return "cdfbr";
8676}
8677
florian55085f82012-11-21 00:36:55 +00008678static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008679s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8680 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008681{
florian125e20d2012-10-07 15:42:37 +00008682 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008683 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008684 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008685 }
sewardj2019a972011-03-07 16:04:07 +00008686 IRTemp op2 = newTemp(Ity_I64);
8687
8688 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008689 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008690 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008691
8692 return "cegbr";
8693}
8694
florian55085f82012-11-21 00:36:55 +00008695static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008696s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8697 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008698{
florian125e20d2012-10-07 15:42:37 +00008699 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008700 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008701 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008702 }
sewardj2019a972011-03-07 16:04:07 +00008703 IRTemp op2 = newTemp(Ity_I64);
8704
8705 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008706 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008707 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008708
8709 return "cdgbr";
8710}
8711
florian55085f82012-11-21 00:36:55 +00008712static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008713s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8714 UChar r1, UChar r2)
8715{
floriane75dafa2012-09-01 17:54:09 +00008716 if (! s390_host_has_fpext) {
8717 emulation_failure(EmFail_S390X_fpext);
8718 } else {
8719 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008720
floriane75dafa2012-09-01 17:54:09 +00008721 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008722 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008723 mkexpr(op2)));
8724 }
florian1c8f7ff2012-09-01 00:12:11 +00008725 return "celfbr";
8726}
8727
florian55085f82012-11-21 00:36:55 +00008728static const HChar *
floriand2129202012-09-01 20:01:39 +00008729s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8730 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008731{
floriane75dafa2012-09-01 17:54:09 +00008732 if (! s390_host_has_fpext) {
8733 emulation_failure(EmFail_S390X_fpext);
8734 } else {
8735 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008736
floriane75dafa2012-09-01 17:54:09 +00008737 assign(op2, get_gpr_w1(r2));
8738 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8739 }
florian1c8f7ff2012-09-01 00:12:11 +00008740 return "cdlfbr";
8741}
8742
florian55085f82012-11-21 00:36:55 +00008743static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008744s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8745 UChar r1, UChar r2)
8746{
floriane75dafa2012-09-01 17:54:09 +00008747 if (! s390_host_has_fpext) {
8748 emulation_failure(EmFail_S390X_fpext);
8749 } else {
8750 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008751
floriane75dafa2012-09-01 17:54:09 +00008752 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008753 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008754 mkexpr(op2)));
8755 }
florian1c8f7ff2012-09-01 00:12:11 +00008756 return "celgbr";
8757}
8758
florian55085f82012-11-21 00:36:55 +00008759static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008760s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8761 UChar r1, UChar r2)
8762{
floriane75dafa2012-09-01 17:54:09 +00008763 if (! s390_host_has_fpext) {
8764 emulation_failure(EmFail_S390X_fpext);
8765 } else {
8766 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008767
floriane75dafa2012-09-01 17:54:09 +00008768 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008769 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8770 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008771 mkexpr(op2)));
8772 }
florian1c8f7ff2012-09-01 00:12:11 +00008773 return "cdlgbr";
8774}
8775
florian55085f82012-11-21 00:36:55 +00008776static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008777s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8778 UChar r1, UChar r2)
8779{
floriane75dafa2012-09-01 17:54:09 +00008780 if (! s390_host_has_fpext) {
8781 emulation_failure(EmFail_S390X_fpext);
8782 } else {
8783 IRTemp op = newTemp(Ity_F32);
8784 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008785 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008786
floriane75dafa2012-09-01 17:54:09 +00008787 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008788 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008789 mkexpr(op)));
8790 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008791 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008792 }
florian1c8f7ff2012-09-01 00:12:11 +00008793 return "clfebr";
8794}
8795
florian55085f82012-11-21 00:36:55 +00008796static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008797s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8798 UChar r1, UChar r2)
8799{
floriane75dafa2012-09-01 17:54:09 +00008800 if (! s390_host_has_fpext) {
8801 emulation_failure(EmFail_S390X_fpext);
8802 } else {
8803 IRTemp op = newTemp(Ity_F64);
8804 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008805 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008806
floriane75dafa2012-09-01 17:54:09 +00008807 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008808 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008809 mkexpr(op)));
8810 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008811 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008812 }
florian1c8f7ff2012-09-01 00:12:11 +00008813 return "clfdbr";
8814}
8815
florian55085f82012-11-21 00:36:55 +00008816static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008817s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8818 UChar r1, UChar r2)
8819{
floriane75dafa2012-09-01 17:54:09 +00008820 if (! s390_host_has_fpext) {
8821 emulation_failure(EmFail_S390X_fpext);
8822 } else {
8823 IRTemp op = newTemp(Ity_F32);
8824 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008825 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008826
floriane75dafa2012-09-01 17:54:09 +00008827 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008828 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008829 mkexpr(op)));
8830 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008831 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008832 }
florian1c8f7ff2012-09-01 00:12:11 +00008833 return "clgebr";
8834}
8835
florian55085f82012-11-21 00:36:55 +00008836static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008837s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8838 UChar r1, UChar r2)
8839{
floriane75dafa2012-09-01 17:54:09 +00008840 if (! s390_host_has_fpext) {
8841 emulation_failure(EmFail_S390X_fpext);
8842 } else {
8843 IRTemp op = newTemp(Ity_F64);
8844 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008845 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008846
floriane75dafa2012-09-01 17:54:09 +00008847 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008848 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008849 mkexpr(op)));
8850 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008851 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008852 }
florian1c8f7ff2012-09-01 00:12:11 +00008853 return "clgdbr";
8854}
8855
florian55085f82012-11-21 00:36:55 +00008856static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008857s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8858 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008859{
8860 IRTemp op = newTemp(Ity_F32);
8861 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008862 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008863
8864 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008865 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008866 mkexpr(op)));
8867 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008868 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008869
8870 return "cfebr";
8871}
8872
florian55085f82012-11-21 00:36:55 +00008873static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008874s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8875 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008876{
8877 IRTemp op = newTemp(Ity_F64);
8878 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008879 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008880
8881 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008882 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008883 mkexpr(op)));
8884 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008885 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008886
8887 return "cfdbr";
8888}
8889
florian55085f82012-11-21 00:36:55 +00008890static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008891s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8892 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008893{
8894 IRTemp op = newTemp(Ity_F32);
8895 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008896 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008897
8898 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008899 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008900 mkexpr(op)));
8901 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008902 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008903
8904 return "cgebr";
8905}
8906
florian55085f82012-11-21 00:36:55 +00008907static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008908s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8909 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008910{
8911 IRTemp op = newTemp(Ity_F64);
8912 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008913 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008914
8915 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008916 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008917 mkexpr(op)));
8918 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008919 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008920
8921 return "cgdbr";
8922}
8923
florian55085f82012-11-21 00:36:55 +00008924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008925s390_irgen_DEBR(UChar r1, UChar r2)
8926{
8927 IRTemp op1 = newTemp(Ity_F32);
8928 IRTemp op2 = newTemp(Ity_F32);
8929 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008930 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008931
8932 assign(op1, get_fpr_w0(r1));
8933 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008934 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008935 mkexpr(op2)));
8936 put_fpr_w0(r1, mkexpr(result));
8937
8938 return "debr";
8939}
8940
florian55085f82012-11-21 00:36:55 +00008941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008942s390_irgen_DDBR(UChar r1, UChar r2)
8943{
8944 IRTemp op1 = newTemp(Ity_F64);
8945 IRTemp op2 = newTemp(Ity_F64);
8946 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008947 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008948
8949 assign(op1, get_fpr_dw0(r1));
8950 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008951 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008952 mkexpr(op2)));
8953 put_fpr_dw0(r1, mkexpr(result));
8954
8955 return "ddbr";
8956}
8957
florian55085f82012-11-21 00:36:55 +00008958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008959s390_irgen_DEB(UChar r1, IRTemp op2addr)
8960{
8961 IRTemp op1 = newTemp(Ity_F32);
8962 IRTemp op2 = newTemp(Ity_F32);
8963 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008964 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008965
8966 assign(op1, get_fpr_w0(r1));
8967 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008968 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008969 mkexpr(op2)));
8970 put_fpr_w0(r1, mkexpr(result));
8971
8972 return "deb";
8973}
8974
florian55085f82012-11-21 00:36:55 +00008975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008976s390_irgen_DDB(UChar r1, IRTemp op2addr)
8977{
8978 IRTemp op1 = newTemp(Ity_F64);
8979 IRTemp op2 = newTemp(Ity_F64);
8980 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008981 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008982
8983 assign(op1, get_fpr_dw0(r1));
8984 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008985 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008986 mkexpr(op2)));
8987 put_fpr_dw0(r1, mkexpr(result));
8988
8989 return "ddb";
8990}
8991
florian55085f82012-11-21 00:36:55 +00008992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008993s390_irgen_LTEBR(UChar r1, UChar r2)
8994{
8995 IRTemp result = newTemp(Ity_F32);
8996
8997 assign(result, get_fpr_w0(r2));
8998 put_fpr_w0(r1, mkexpr(result));
8999 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9000
9001 return "ltebr";
9002}
9003
florian55085f82012-11-21 00:36:55 +00009004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009005s390_irgen_LTDBR(UChar r1, UChar r2)
9006{
9007 IRTemp result = newTemp(Ity_F64);
9008
9009 assign(result, get_fpr_dw0(r2));
9010 put_fpr_dw0(r1, mkexpr(result));
9011 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9012
9013 return "ltdbr";
9014}
9015
florian55085f82012-11-21 00:36:55 +00009016static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009017s390_irgen_LCEBR(UChar r1, UChar r2)
9018{
9019 IRTemp result = newTemp(Ity_F32);
9020
9021 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9022 put_fpr_w0(r1, mkexpr(result));
9023 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9024
9025 return "lcebr";
9026}
9027
florian55085f82012-11-21 00:36:55 +00009028static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009029s390_irgen_LCDBR(UChar r1, UChar r2)
9030{
9031 IRTemp result = newTemp(Ity_F64);
9032
9033 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9034 put_fpr_dw0(r1, mkexpr(result));
9035 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9036
9037 return "lcdbr";
9038}
9039
florian55085f82012-11-21 00:36:55 +00009040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009041s390_irgen_LDEBR(UChar r1, UChar r2)
9042{
9043 IRTemp op = newTemp(Ity_F32);
9044
9045 assign(op, get_fpr_w0(r2));
9046 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9047
9048 return "ldebr";
9049}
9050
florian55085f82012-11-21 00:36:55 +00009051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009052s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9053{
9054 IRTemp op = newTemp(Ity_F32);
9055
9056 assign(op, load(Ity_F32, mkexpr(op2addr)));
9057 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9058
9059 return "ldeb";
9060}
9061
florian55085f82012-11-21 00:36:55 +00009062static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009063s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9064 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009065{
florian125e20d2012-10-07 15:42:37 +00009066 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009067 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009068 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009069 }
sewardj2019a972011-03-07 16:04:07 +00009070 IRTemp op = newTemp(Ity_F64);
9071
9072 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009073 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009074 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009075
9076 return "ledbr";
9077}
9078
florian55085f82012-11-21 00:36:55 +00009079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009080s390_irgen_MEEBR(UChar r1, UChar r2)
9081{
9082 IRTemp op1 = newTemp(Ity_F32);
9083 IRTemp op2 = newTemp(Ity_F32);
9084 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009085 IRRoundingMode rounding_mode =
9086 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009087
9088 assign(op1, get_fpr_w0(r1));
9089 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009090 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009091 mkexpr(op2)));
9092 put_fpr_w0(r1, mkexpr(result));
9093
9094 return "meebr";
9095}
9096
florian55085f82012-11-21 00:36:55 +00009097static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009098s390_irgen_MDBR(UChar r1, UChar r2)
9099{
9100 IRTemp op1 = newTemp(Ity_F64);
9101 IRTemp op2 = newTemp(Ity_F64);
9102 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009103 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009104
9105 assign(op1, get_fpr_dw0(r1));
9106 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009107 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009108 mkexpr(op2)));
9109 put_fpr_dw0(r1, mkexpr(result));
9110
9111 return "mdbr";
9112}
9113
florian55085f82012-11-21 00:36:55 +00009114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009115s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9116{
9117 IRTemp op1 = newTemp(Ity_F32);
9118 IRTemp op2 = newTemp(Ity_F32);
9119 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009120 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009121
9122 assign(op1, get_fpr_w0(r1));
9123 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009124 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009125 mkexpr(op2)));
9126 put_fpr_w0(r1, mkexpr(result));
9127
9128 return "meeb";
9129}
9130
florian55085f82012-11-21 00:36:55 +00009131static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009132s390_irgen_MDB(UChar r1, IRTemp op2addr)
9133{
9134 IRTemp op1 = newTemp(Ity_F64);
9135 IRTemp op2 = newTemp(Ity_F64);
9136 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009137 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009138
9139 assign(op1, get_fpr_dw0(r1));
9140 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009141 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009142 mkexpr(op2)));
9143 put_fpr_dw0(r1, mkexpr(result));
9144
9145 return "mdb";
9146}
9147
florian55085f82012-11-21 00:36:55 +00009148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009149s390_irgen_SEBR(UChar r1, UChar r2)
9150{
9151 IRTemp op1 = newTemp(Ity_F32);
9152 IRTemp op2 = newTemp(Ity_F32);
9153 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009154 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009155
9156 assign(op1, get_fpr_w0(r1));
9157 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009158 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009159 mkexpr(op2)));
9160 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9161 put_fpr_w0(r1, mkexpr(result));
9162
9163 return "sebr";
9164}
9165
florian55085f82012-11-21 00:36:55 +00009166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009167s390_irgen_SDBR(UChar r1, UChar r2)
9168{
9169 IRTemp op1 = newTemp(Ity_F64);
9170 IRTemp op2 = newTemp(Ity_F64);
9171 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009172 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009173
9174 assign(op1, get_fpr_dw0(r1));
9175 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009176 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009177 mkexpr(op2)));
9178 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9179 put_fpr_dw0(r1, mkexpr(result));
9180
9181 return "sdbr";
9182}
9183
florian55085f82012-11-21 00:36:55 +00009184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009185s390_irgen_SEB(UChar r1, IRTemp op2addr)
9186{
9187 IRTemp op1 = newTemp(Ity_F32);
9188 IRTemp op2 = newTemp(Ity_F32);
9189 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009190 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009191
9192 assign(op1, get_fpr_w0(r1));
9193 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009194 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009195 mkexpr(op2)));
9196 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9197 put_fpr_w0(r1, mkexpr(result));
9198
9199 return "seb";
9200}
9201
florian55085f82012-11-21 00:36:55 +00009202static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009203s390_irgen_SDB(UChar r1, IRTemp op2addr)
9204{
9205 IRTemp op1 = newTemp(Ity_F64);
9206 IRTemp op2 = newTemp(Ity_F64);
9207 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009208 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009209
9210 assign(op1, get_fpr_dw0(r1));
9211 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009212 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009213 mkexpr(op2)));
9214 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9215 put_fpr_dw0(r1, mkexpr(result));
9216
9217 return "sdb";
9218}
9219
florian55085f82012-11-21 00:36:55 +00009220static const HChar *
florian12390202012-11-10 22:34:14 +00009221s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9222{
9223 IRTemp op1 = newTemp(Ity_D64);
9224 IRTemp op2 = newTemp(Ity_D64);
9225 IRTemp result = newTemp(Ity_D64);
9226 IRTemp rounding_mode;
9227
9228 vassert(s390_host_has_dfp);
9229 vassert(m4 == 0 || s390_host_has_fpext);
9230 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9231 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9232 rounding_mode = encode_dfp_rounding_mode(m4);
9233 assign(op1, get_dpr_dw0(r2));
9234 assign(op2, get_dpr_dw0(r3));
9235 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9236 mkexpr(op2)));
9237 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9238 put_dpr_dw0(r1, mkexpr(result));
9239
9240 return (m4 == 0) ? "adtr" : "adtra";
9241}
9242
florian55085f82012-11-21 00:36:55 +00009243static const HChar *
floriane38f6412012-12-21 17:32:12 +00009244s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9245{
9246 IRTemp op1 = newTemp(Ity_D128);
9247 IRTemp op2 = newTemp(Ity_D128);
9248 IRTemp result = newTemp(Ity_D128);
9249 IRTemp rounding_mode;
9250
9251 vassert(s390_host_has_dfp);
9252 vassert(m4 == 0 || s390_host_has_fpext);
9253 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9254 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9255 rounding_mode = encode_dfp_rounding_mode(m4);
9256 assign(op1, get_dpr_pair(r2));
9257 assign(op2, get_dpr_pair(r3));
9258 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9259 mkexpr(op2)));
9260 put_dpr_pair(r1, mkexpr(result));
9261
9262 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9263
9264 return (m4 == 0) ? "axtr" : "axtra";
9265}
9266
9267static const HChar *
9268s390_irgen_CDTR(UChar r1, UChar r2)
9269{
9270 IRTemp op1 = newTemp(Ity_D64);
9271 IRTemp op2 = newTemp(Ity_D64);
9272 IRTemp cc_vex = newTemp(Ity_I32);
9273 IRTemp cc_s390 = newTemp(Ity_I32);
9274
9275 assign(op1, get_dpr_dw0(r1));
9276 assign(op2, get_dpr_dw0(r2));
9277 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9278
florian2d3d87f2012-12-21 21:05:17 +00009279 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009280 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9281
9282 return "cdtr";
9283}
9284
9285static const HChar *
9286s390_irgen_CXTR(UChar r1, UChar r2)
9287{
9288 IRTemp op1 = newTemp(Ity_D128);
9289 IRTemp op2 = newTemp(Ity_D128);
9290 IRTemp cc_vex = newTemp(Ity_I32);
9291 IRTemp cc_s390 = newTemp(Ity_I32);
9292
9293 assign(op1, get_dpr_pair(r1));
9294 assign(op2, get_dpr_pair(r2));
9295 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9296
florian2d3d87f2012-12-21 21:05:17 +00009297 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009298 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9299
9300 return "cxtr";
9301}
9302
9303static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009304s390_irgen_CEDTR(UChar r1, UChar r2)
9305{
9306 IRTemp op1 = newTemp(Ity_D64);
9307 IRTemp op2 = newTemp(Ity_D64);
9308 IRTemp cc_vex = newTemp(Ity_I32);
9309 IRTemp cc_s390 = newTemp(Ity_I32);
9310
9311 vassert(s390_host_has_dfp);
9312 assign(op1, get_dpr_dw0(r1));
9313 assign(op2, get_dpr_dw0(r2));
9314 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9315
9316 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9317 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9318
9319 return "cedtr";
9320}
9321
9322static const HChar *
9323s390_irgen_CEXTR(UChar r1, UChar r2)
9324{
9325 IRTemp op1 = newTemp(Ity_D128);
9326 IRTemp op2 = newTemp(Ity_D128);
9327 IRTemp cc_vex = newTemp(Ity_I32);
9328 IRTemp cc_s390 = newTemp(Ity_I32);
9329
9330 vassert(s390_host_has_dfp);
9331 assign(op1, get_dpr_pair(r1));
9332 assign(op2, get_dpr_pair(r2));
9333 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9334
9335 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9336 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9337
9338 return "cextr";
9339}
9340
9341static const HChar *
florian12390202012-11-10 22:34:14 +00009342s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9343{
9344 IRTemp op1 = newTemp(Ity_D64);
9345 IRTemp op2 = newTemp(Ity_D64);
9346 IRTemp result = newTemp(Ity_D64);
9347 IRTemp rounding_mode;
9348
9349 vassert(s390_host_has_dfp);
9350 vassert(m4 == 0 || s390_host_has_fpext);
9351 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9352 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9353 rounding_mode = encode_dfp_rounding_mode(m4);
9354 assign(op1, get_dpr_dw0(r2));
9355 assign(op2, get_dpr_dw0(r3));
9356 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9357 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009358 put_dpr_dw0(r1, mkexpr(result));
9359
9360 return (m4 == 0) ? "ddtr" : "ddtra";
9361}
9362
florian55085f82012-11-21 00:36:55 +00009363static const HChar *
floriane38f6412012-12-21 17:32:12 +00009364s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9365{
9366 IRTemp op1 = newTemp(Ity_D128);
9367 IRTemp op2 = newTemp(Ity_D128);
9368 IRTemp result = newTemp(Ity_D128);
9369 IRTemp rounding_mode;
9370
9371 vassert(s390_host_has_dfp);
9372 vassert(m4 == 0 || s390_host_has_fpext);
9373 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9374 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9375 rounding_mode = encode_dfp_rounding_mode(m4);
9376 assign(op1, get_dpr_pair(r2));
9377 assign(op2, get_dpr_pair(r3));
9378 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9379 mkexpr(op2)));
9380 put_dpr_pair(r1, mkexpr(result));
9381
9382 return (m4 == 0) ? "dxtr" : "dxtra";
9383}
9384
9385static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009386s390_irgen_ESDTR(UChar r1, UChar r2)
9387{
9388 vassert(s390_host_has_dfp);
9389 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
9390 return "esdtr";
9391}
9392
9393static const HChar *
9394s390_irgen_ESXTR(UChar r1, UChar r2)
9395{
9396 vassert(s390_host_has_dfp);
9397 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
9398 return "esxtr";
9399}
9400
9401static const HChar *
floriane38f6412012-12-21 17:32:12 +00009402s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9403{
9404 IRTemp op = newTemp(Ity_D32);
9405
9406 vassert(s390_host_has_dfp);
9407
9408 assign(op, get_dpr_w0(r2));
9409 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
9410
9411 return "ldetr";
9412}
9413
9414static const HChar *
9415s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9416{
9417 IRTemp op = newTemp(Ity_D64);
9418
9419 assign(op, get_dpr_dw0(r2));
9420 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
9421
9422 return "lxdtr";
9423}
9424
9425static const HChar *
9426s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
9427 UChar r1, UChar r2)
9428{
9429 vassert(s390_host_has_dfp);
9430 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9431 emulation_warning(EmWarn_S390X_fpext_rounding);
9432 m3 = S390_DFP_ROUND_PER_FPC_0;
9433 }
9434 IRTemp result = newTemp(Ity_D64);
9435
9436 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
9437 get_dpr_pair(r2)));
9438 put_dpr_dw0(r1, mkexpr(result));
9439
9440 return "ldxtr";
9441}
9442
9443static const HChar *
9444s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
9445 UChar r1, UChar r2)
9446{
9447 vassert(s390_host_has_dfp);
9448 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9449 emulation_warning(EmWarn_S390X_fpext_rounding);
9450 m3 = S390_DFP_ROUND_PER_FPC_0;
9451 }
9452 IRTemp op = newTemp(Ity_D64);
9453
9454 assign(op, get_dpr_dw0(r2));
9455 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
9456 mkexpr(op)));
9457
9458 return "ledtr";
9459}
9460
9461static const HChar *
9462s390_irgen_LTDTR(UChar r1, UChar r2)
9463{
9464 IRTemp result = newTemp(Ity_D64);
9465
9466 assign(result, get_dpr_dw0(r2));
9467 put_dpr_dw0(r1, mkexpr(result));
9468 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9469
9470 return "ltdtr";
9471}
9472
9473static const HChar *
9474s390_irgen_LTXTR(UChar r1, UChar r2)
9475{
9476 IRTemp result = newTemp(Ity_D128);
9477
9478 assign(result, get_dpr_pair(r2));
9479 put_dpr_pair(r1, mkexpr(result));
9480 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9481
9482 return "ltxtr";
9483}
9484
9485static const HChar *
florian12390202012-11-10 22:34:14 +00009486s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9487{
9488 IRTemp op1 = newTemp(Ity_D64);
9489 IRTemp op2 = newTemp(Ity_D64);
9490 IRTemp result = newTemp(Ity_D64);
9491 IRTemp rounding_mode;
9492
9493 vassert(s390_host_has_dfp);
9494 vassert(m4 == 0 || s390_host_has_fpext);
9495 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9496 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9497 rounding_mode = encode_dfp_rounding_mode(m4);
9498 assign(op1, get_dpr_dw0(r2));
9499 assign(op2, get_dpr_dw0(r3));
9500 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9501 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009502 put_dpr_dw0(r1, mkexpr(result));
9503
9504 return (m4 == 0) ? "mdtr" : "mdtra";
9505}
9506
florian55085f82012-11-21 00:36:55 +00009507static const HChar *
floriane38f6412012-12-21 17:32:12 +00009508s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9509{
9510 IRTemp op1 = newTemp(Ity_D128);
9511 IRTemp op2 = newTemp(Ity_D128);
9512 IRTemp result = newTemp(Ity_D128);
9513 IRTemp rounding_mode;
9514
9515 vassert(s390_host_has_dfp);
9516 vassert(m4 == 0 || s390_host_has_fpext);
9517 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9518 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9519 rounding_mode = encode_dfp_rounding_mode(m4);
9520 assign(op1, get_dpr_pair(r2));
9521 assign(op2, get_dpr_pair(r3));
9522 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
9523 mkexpr(op2)));
9524 put_dpr_pair(r1, mkexpr(result));
9525
9526 return (m4 == 0) ? "mxtr" : "mxtra";
9527}
9528
9529static const HChar *
florian12390202012-11-10 22:34:14 +00009530s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9531{
9532 IRTemp op1 = newTemp(Ity_D64);
9533 IRTemp op2 = newTemp(Ity_D64);
9534 IRTemp result = newTemp(Ity_D64);
9535 IRTemp rounding_mode;
9536
9537 vassert(s390_host_has_dfp);
9538 vassert(m4 == 0 || s390_host_has_fpext);
9539 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9540 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9541 rounding_mode = encode_dfp_rounding_mode(m4);
9542 assign(op1, get_dpr_dw0(r2));
9543 assign(op2, get_dpr_dw0(r3));
9544 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9545 mkexpr(op2)));
9546 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9547 put_dpr_dw0(r1, mkexpr(result));
9548
9549 return (m4 == 0) ? "sdtr" : "sdtra";
9550}
9551
floriane38f6412012-12-21 17:32:12 +00009552static const HChar *
9553s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9554{
9555 IRTemp op1 = newTemp(Ity_D128);
9556 IRTemp op2 = newTemp(Ity_D128);
9557 IRTemp result = newTemp(Ity_D128);
9558 IRTemp rounding_mode;
9559
9560 vassert(s390_host_has_dfp);
9561 vassert(m4 == 0 || s390_host_has_fpext);
9562 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9563 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9564 rounding_mode = encode_dfp_rounding_mode(m4);
9565 assign(op1, get_dpr_pair(r2));
9566 assign(op2, get_dpr_pair(r3));
9567 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
9568 mkexpr(op2)));
9569 put_dpr_pair(r1, mkexpr(result));
9570
9571 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9572
9573 return (m4 == 0) ? "sxtr" : "sxtra";
9574}
sewardj2019a972011-03-07 16:04:07 +00009575
florian55085f82012-11-21 00:36:55 +00009576static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009577s390_irgen_TDCET(UChar r1, IRTemp op2addr)
9578{
9579 IRTemp value = newTemp(Ity_D32);
9580
9581 vassert(s390_host_has_dfp);
9582 assign(value, get_dpr_w0(r1));
9583
9584 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
9585
9586 return "tdcet";
9587}
9588
9589static const HChar *
9590s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
9591{
9592 IRTemp value = newTemp(Ity_D64);
9593
9594 vassert(s390_host_has_dfp);
9595 assign(value, get_dpr_dw0(r1));
9596
9597 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
9598
9599 return "tdcdt";
9600}
9601
9602static const HChar *
9603s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
9604{
9605 IRTemp value = newTemp(Ity_D128);
9606
9607 vassert(s390_host_has_dfp);
9608 assign(value, get_dpr_pair(r1));
9609
9610 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
9611
9612 return "tdcxt";
9613}
9614
9615static const HChar *
9616s390_irgen_TDGET(UChar r1, IRTemp op2addr)
9617{
9618 IRTemp value = newTemp(Ity_D32);
9619
9620 vassert(s390_host_has_dfp);
9621 assign(value, get_dpr_w0(r1));
9622
9623 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
9624
9625 return "tdget";
9626}
9627
9628static const HChar *
9629s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
9630{
9631 IRTemp value = newTemp(Ity_D64);
9632
9633 vassert(s390_host_has_dfp);
9634 assign(value, get_dpr_dw0(r1));
9635
9636 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
9637
9638 return "tdgdt";
9639}
9640
9641static const HChar *
9642s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
9643{
9644 IRTemp value = newTemp(Ity_D128);
9645
9646 vassert(s390_host_has_dfp);
9647 assign(value, get_dpr_pair(r1));
9648
9649 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
9650
9651 return "tdgxt";
9652}
9653
9654static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009655s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9656{
florian79e839e2012-05-05 02:20:30 +00009657 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009658
florian79e839e2012-05-05 02:20:30 +00009659 assign(len, mkU64(length));
9660 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009661
9662 return "clc";
9663}
9664
florian55085f82012-11-21 00:36:55 +00009665static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009666s390_irgen_CLCL(UChar r1, UChar r2)
9667{
9668 IRTemp addr1 = newTemp(Ity_I64);
9669 IRTemp addr2 = newTemp(Ity_I64);
9670 IRTemp addr1_load = newTemp(Ity_I64);
9671 IRTemp addr2_load = newTemp(Ity_I64);
9672 IRTemp len1 = newTemp(Ity_I32);
9673 IRTemp len2 = newTemp(Ity_I32);
9674 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9675 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9676 IRTemp single1 = newTemp(Ity_I8);
9677 IRTemp single2 = newTemp(Ity_I8);
9678 IRTemp pad = newTemp(Ity_I8);
9679
9680 assign(addr1, get_gpr_dw0(r1));
9681 assign(r1p1, get_gpr_w1(r1 + 1));
9682 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9683 assign(addr2, get_gpr_dw0(r2));
9684 assign(r2p1, get_gpr_w1(r2 + 1));
9685 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9686 assign(pad, get_gpr_b4(r2 + 1));
9687
9688 /* len1 == 0 and len2 == 0? Exit */
9689 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009690 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9691 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009692
9693 /* Because mkite evaluates both the then-clause and the else-clause
9694 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9695 may be NULL and loading from there would segfault. So we provide a
9696 valid dummy address in that case. Loading from there does no harm and
9697 the value will be discarded at runtime. */
9698 assign(addr1_load,
9699 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9700 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9701 assign(single1,
9702 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9703 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9704
9705 assign(addr2_load,
9706 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9707 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9708 assign(single2,
9709 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9710 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9711
9712 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9713 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009714 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009715
9716 /* Update len1 and addr1, unless len1 == 0. */
9717 put_gpr_dw0(r1,
9718 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9719 mkexpr(addr1),
9720 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9721
9722 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9723 put_gpr_w1(r1 + 1,
9724 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9725 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9726 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9727
9728 /* Update len2 and addr2, unless len2 == 0. */
9729 put_gpr_dw0(r2,
9730 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9731 mkexpr(addr2),
9732 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9733
9734 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9735 put_gpr_w1(r2 + 1,
9736 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9737 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9738 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9739
florian6820ba52012-07-26 02:01:50 +00009740 iterate();
florianb0c9a132011-09-08 15:37:39 +00009741
9742 return "clcl";
9743}
9744
florian55085f82012-11-21 00:36:55 +00009745static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009746s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9747{
9748 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9749
9750 addr1 = newTemp(Ity_I64);
9751 addr3 = newTemp(Ity_I64);
9752 addr1_load = newTemp(Ity_I64);
9753 addr3_load = newTemp(Ity_I64);
9754 len1 = newTemp(Ity_I64);
9755 len3 = newTemp(Ity_I64);
9756 single1 = newTemp(Ity_I8);
9757 single3 = newTemp(Ity_I8);
9758
9759 assign(addr1, get_gpr_dw0(r1));
9760 assign(len1, get_gpr_dw0(r1 + 1));
9761 assign(addr3, get_gpr_dw0(r3));
9762 assign(len3, get_gpr_dw0(r3 + 1));
9763
9764 /* len1 == 0 and len3 == 0? Exit */
9765 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009766 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9767 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009768
9769 /* A mux requires both ways to be possible. This is a way to prevent clcle
9770 from reading from addr1 if it should read from the pad. Since the pad
9771 has no address, just read from the instruction, we discard that anyway */
9772 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009773 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9774 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009775
9776 /* same for addr3 */
9777 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009778 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9779 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009780
9781 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009782 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9783 unop(Iop_64to8, mkexpr(pad2)),
9784 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009785
9786 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009787 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9788 unop(Iop_64to8, mkexpr(pad2)),
9789 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009790
9791 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9792 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009793 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009794
9795 /* If a length in 0 we must not change this length and the address */
9796 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009797 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9798 mkexpr(addr1),
9799 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009800
9801 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009802 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9803 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009804
9805 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009806 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9807 mkexpr(addr3),
9808 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009809
9810 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009811 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9812 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009813
florian6820ba52012-07-26 02:01:50 +00009814 iterate();
sewardj2019a972011-03-07 16:04:07 +00009815
9816 return "clcle";
9817}
floriana64c2432011-07-16 02:11:50 +00009818
florianb0bf6602012-05-05 00:01:16 +00009819
sewardj2019a972011-03-07 16:04:07 +00009820static void
9821s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9822{
florianb0bf6602012-05-05 00:01:16 +00009823 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9824}
sewardj2019a972011-03-07 16:04:07 +00009825
sewardj2019a972011-03-07 16:04:07 +00009826
florianb0bf6602012-05-05 00:01:16 +00009827static void
9828s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9829{
9830 s390_irgen_xonc(Iop_And8, length, start1, start2);
9831}
sewardj2019a972011-03-07 16:04:07 +00009832
sewardj2019a972011-03-07 16:04:07 +00009833
florianb0bf6602012-05-05 00:01:16 +00009834static void
9835s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9836{
9837 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009838}
9839
9840
9841static void
9842s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9843{
9844 IRTemp current1 = newTemp(Ity_I8);
9845 IRTemp current2 = newTemp(Ity_I8);
9846 IRTemp counter = newTemp(Ity_I64);
9847
9848 assign(counter, get_counter_dw0());
9849 put_counter_dw0(mkU64(0));
9850
9851 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9852 mkexpr(counter))));
9853 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9854 mkexpr(counter))));
9855 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9856 False);
9857
9858 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009859 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009860
9861 /* Check for end of field */
9862 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009863 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009864 put_counter_dw0(mkU64(0));
9865}
9866
9867static void
9868s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9869{
9870 IRTemp counter = newTemp(Ity_I64);
9871
9872 assign(counter, get_counter_dw0());
9873
9874 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9875 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9876
9877 /* Check for end of field */
9878 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009879 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009880 put_counter_dw0(mkU64(0));
9881}
9882
florianf87d4fb2012-05-05 02:55:24 +00009883static void
9884s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9885{
9886 IRTemp op = newTemp(Ity_I8);
9887 IRTemp op1 = newTemp(Ity_I8);
9888 IRTemp result = newTemp(Ity_I64);
9889 IRTemp counter = newTemp(Ity_I64);
9890
9891 assign(counter, get_counter_dw0());
9892
9893 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9894
9895 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9896
9897 assign(op1, load(Ity_I8, mkexpr(result)));
9898 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9899
9900 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009901 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009902 put_counter_dw0(mkU64(0));
9903}
sewardj2019a972011-03-07 16:04:07 +00009904
9905
9906static void
9907s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009908 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +00009909 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +00009910{
9911 struct SS {
9912 unsigned int op : 8;
9913 unsigned int l : 8;
9914 unsigned int b1 : 4;
9915 unsigned int d1 : 12;
9916 unsigned int b2 : 4;
9917 unsigned int d2 : 12;
9918 };
9919 union {
9920 struct SS dec;
9921 unsigned long bytes;
9922 } ss;
9923 IRTemp cond;
9924 IRDirty *d;
9925 IRTemp torun;
9926
9927 IRTemp start1 = newTemp(Ity_I64);
9928 IRTemp start2 = newTemp(Ity_I64);
9929 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9930 cond = newTemp(Ity_I1);
9931 torun = newTemp(Ity_I64);
9932
9933 assign(torun, load(Ity_I64, mkexpr(addr2)));
9934 /* Start with a check that the saved code is still correct */
9935 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9936 /* If not, save the new value */
9937 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9938 mkIRExprVec_1(mkexpr(torun)));
9939 d->guard = mkexpr(cond);
9940 stmt(IRStmt_Dirty(d));
9941
9942 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009943 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9944 mkU64(guest_IA_curr_instr)));
9945 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009946 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009947
9948 ss.bytes = last_execute_target;
9949 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9950 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9951 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9952 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9953 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9954 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9955 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009956
sewardj2019a972011-03-07 16:04:07 +00009957 last_execute_target = 0;
9958}
9959
florian55085f82012-11-21 00:36:55 +00009960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009961s390_irgen_EX(UChar r1, IRTemp addr2)
9962{
9963 switch(last_execute_target & 0xff00000000000000ULL) {
9964 case 0:
9965 {
9966 /* no code information yet */
9967 IRDirty *d;
9968
9969 /* so safe the code... */
9970 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9971 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9972 stmt(IRStmt_Dirty(d));
9973 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009974 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9975 mkU64(guest_IA_curr_instr)));
9976 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009977 restart_if(IRExpr_Const(IRConst_U1(True)));
9978
sewardj2019a972011-03-07 16:04:07 +00009979 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009980 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009981 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009982 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009983 break;
9984 }
9985
9986 case 0xd200000000000000ULL:
9987 /* special case MVC */
9988 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +00009989 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +00009990
9991 case 0xd500000000000000ULL:
9992 /* special case CLC */
9993 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +00009994 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +00009995
9996 case 0xd700000000000000ULL:
9997 /* special case XC */
9998 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +00009999 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010000
florianb0bf6602012-05-05 00:01:16 +000010001 case 0xd600000000000000ULL:
10002 /* special case OC */
10003 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010004 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010005
10006 case 0xd400000000000000ULL:
10007 /* special case NC */
10008 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010009 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010010
florianf87d4fb2012-05-05 02:55:24 +000010011 case 0xdc00000000000000ULL:
10012 /* special case TR */
10013 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010014 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010015
sewardj2019a972011-03-07 16:04:07 +000010016 default:
10017 {
10018 /* everything else will get a self checking prefix that also checks the
10019 register content */
10020 IRDirty *d;
10021 UChar *bytes;
10022 IRTemp cond;
10023 IRTemp orperand;
10024 IRTemp torun;
10025
10026 cond = newTemp(Ity_I1);
10027 orperand = newTemp(Ity_I64);
10028 torun = newTemp(Ity_I64);
10029
10030 if (r1 == 0)
10031 assign(orperand, mkU64(0));
10032 else
10033 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10034 /* This code is going to be translated */
10035 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10036 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10037
10038 /* Start with a check that saved code is still correct */
10039 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10040 mkU64(last_execute_target)));
10041 /* If not, save the new value */
10042 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10043 mkIRExprVec_1(mkexpr(torun)));
10044 d->guard = mkexpr(cond);
10045 stmt(IRStmt_Dirty(d));
10046
10047 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010048 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10049 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010050 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010051
10052 /* Now comes the actual translation */
10053 bytes = (UChar *) &last_execute_target;
10054 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10055 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010056 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010057 vex_printf(" which was executed by\n");
10058 /* dont make useless translations in the next execute */
10059 last_execute_target = 0;
10060 }
10061 }
10062 return "ex";
10063}
10064
florian55085f82012-11-21 00:36:55 +000010065static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010066s390_irgen_EXRL(UChar r1, UInt offset)
10067{
10068 IRTemp addr = newTemp(Ity_I64);
10069 /* we might save one round trip because we know the target */
10070 if (!last_execute_target)
10071 last_execute_target = *(ULong *)(HWord)
10072 (guest_IA_curr_instr + offset * 2UL);
10073 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10074 s390_irgen_EX(r1, addr);
10075 return "exrl";
10076}
10077
florian55085f82012-11-21 00:36:55 +000010078static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010079s390_irgen_IPM(UChar r1)
10080{
10081 // As long as we dont support SPM, lets just assume 0 as program mask
10082 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
10083 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
10084
10085 return "ipm";
10086}
10087
10088
florian55085f82012-11-21 00:36:55 +000010089static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010090s390_irgen_SRST(UChar r1, UChar r2)
10091{
10092 IRTemp address = newTemp(Ity_I64);
10093 IRTemp next = newTemp(Ity_I64);
10094 IRTemp delim = newTemp(Ity_I8);
10095 IRTemp counter = newTemp(Ity_I64);
10096 IRTemp byte = newTemp(Ity_I8);
10097
10098 assign(address, get_gpr_dw0(r2));
10099 assign(next, get_gpr_dw0(r1));
10100
10101 assign(counter, get_counter_dw0());
10102 put_counter_dw0(mkU64(0));
10103
10104 // start = next? CC=2 and out r1 and r2 unchanged
10105 s390_cc_set(2);
10106 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010107 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000010108
10109 assign(byte, load(Ity_I8, mkexpr(address)));
10110 assign(delim, get_gpr_b7(0));
10111
10112 // byte = delim? CC=1, R1=address
10113 s390_cc_set(1);
10114 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000010115 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010116
10117 // else: all equal, no end yet, loop
10118 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10119 put_gpr_dw0(r1, mkexpr(next));
10120 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010121
florian6820ba52012-07-26 02:01:50 +000010122 iterate();
sewardj2019a972011-03-07 16:04:07 +000010123
10124 return "srst";
10125}
10126
florian55085f82012-11-21 00:36:55 +000010127static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010128s390_irgen_CLST(UChar r1, UChar r2)
10129{
10130 IRTemp address1 = newTemp(Ity_I64);
10131 IRTemp address2 = newTemp(Ity_I64);
10132 IRTemp end = newTemp(Ity_I8);
10133 IRTemp counter = newTemp(Ity_I64);
10134 IRTemp byte1 = newTemp(Ity_I8);
10135 IRTemp byte2 = newTemp(Ity_I8);
10136
10137 assign(address1, get_gpr_dw0(r1));
10138 assign(address2, get_gpr_dw0(r2));
10139 assign(end, get_gpr_b7(0));
10140 assign(counter, get_counter_dw0());
10141 put_counter_dw0(mkU64(0));
10142 assign(byte1, load(Ity_I8, mkexpr(address1)));
10143 assign(byte2, load(Ity_I8, mkexpr(address2)));
10144
10145 // end in both? all equal, reset r1 and r2 to start values
10146 s390_cc_set(0);
10147 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
10148 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010149 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10150 binop(Iop_Or8,
10151 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10152 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010153
10154 put_gpr_dw0(r1, mkexpr(address1));
10155 put_gpr_dw0(r2, mkexpr(address2));
10156
10157 // End found in string1
10158 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010159 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010160
10161 // End found in string2
10162 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010163 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010164
10165 // string1 < string2
10166 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010167 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10168 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010169
10170 // string2 < string1
10171 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010172 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10173 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010174
10175 // else: all equal, no end yet, loop
10176 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10177 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10178 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010179
florian6820ba52012-07-26 02:01:50 +000010180 iterate();
sewardj2019a972011-03-07 16:04:07 +000010181
10182 return "clst";
10183}
10184
10185static void
10186s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10187{
10188 UChar reg;
10189 IRTemp addr = newTemp(Ity_I64);
10190
10191 assign(addr, mkexpr(op2addr));
10192 reg = r1;
10193 do {
10194 IRTemp old = addr;
10195
10196 reg %= 16;
10197 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10198 addr = newTemp(Ity_I64);
10199 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10200 reg++;
10201 } while (reg != (r3 + 1));
10202}
10203
florian55085f82012-11-21 00:36:55 +000010204static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010205s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10206{
10207 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10208
10209 return "lm";
10210}
10211
florian55085f82012-11-21 00:36:55 +000010212static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010213s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
10214{
10215 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10216
10217 return "lmy";
10218}
10219
florian55085f82012-11-21 00:36:55 +000010220static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010221s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
10222{
10223 UChar reg;
10224 IRTemp addr = newTemp(Ity_I64);
10225
10226 assign(addr, mkexpr(op2addr));
10227 reg = r1;
10228 do {
10229 IRTemp old = addr;
10230
10231 reg %= 16;
10232 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
10233 addr = newTemp(Ity_I64);
10234 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10235 reg++;
10236 } while (reg != (r3 + 1));
10237
10238 return "lmh";
10239}
10240
florian55085f82012-11-21 00:36:55 +000010241static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010242s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
10243{
10244 UChar reg;
10245 IRTemp addr = newTemp(Ity_I64);
10246
10247 assign(addr, mkexpr(op2addr));
10248 reg = r1;
10249 do {
10250 IRTemp old = addr;
10251
10252 reg %= 16;
10253 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
10254 addr = newTemp(Ity_I64);
10255 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10256 reg++;
10257 } while (reg != (r3 + 1));
10258
10259 return "lmg";
10260}
10261
10262static void
10263s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10264{
10265 UChar reg;
10266 IRTemp addr = newTemp(Ity_I64);
10267
10268 assign(addr, mkexpr(op2addr));
10269 reg = r1;
10270 do {
10271 IRTemp old = addr;
10272
10273 reg %= 16;
10274 store(mkexpr(addr), get_gpr_w1(reg));
10275 addr = newTemp(Ity_I64);
10276 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10277 reg++;
10278 } while( reg != (r3 + 1));
10279}
10280
florian55085f82012-11-21 00:36:55 +000010281static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010282s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
10283{
10284 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10285
10286 return "stm";
10287}
10288
florian55085f82012-11-21 00:36:55 +000010289static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010290s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
10291{
10292 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10293
10294 return "stmy";
10295}
10296
florian55085f82012-11-21 00:36:55 +000010297static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010298s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
10299{
10300 UChar reg;
10301 IRTemp addr = newTemp(Ity_I64);
10302
10303 assign(addr, mkexpr(op2addr));
10304 reg = r1;
10305 do {
10306 IRTemp old = addr;
10307
10308 reg %= 16;
10309 store(mkexpr(addr), get_gpr_w0(reg));
10310 addr = newTemp(Ity_I64);
10311 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10312 reg++;
10313 } while( reg != (r3 + 1));
10314
10315 return "stmh";
10316}
10317
florian55085f82012-11-21 00:36:55 +000010318static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010319s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
10320{
10321 UChar reg;
10322 IRTemp addr = newTemp(Ity_I64);
10323
10324 assign(addr, mkexpr(op2addr));
10325 reg = r1;
10326 do {
10327 IRTemp old = addr;
10328
10329 reg %= 16;
10330 store(mkexpr(addr), get_gpr_dw0(reg));
10331 addr = newTemp(Ity_I64);
10332 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10333 reg++;
10334 } while( reg != (r3 + 1));
10335
10336 return "stmg";
10337}
10338
10339static void
florianb0bf6602012-05-05 00:01:16 +000010340s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000010341{
10342 IRTemp old1 = newTemp(Ity_I8);
10343 IRTemp old2 = newTemp(Ity_I8);
10344 IRTemp new1 = newTemp(Ity_I8);
10345 IRTemp counter = newTemp(Ity_I32);
10346 IRTemp addr1 = newTemp(Ity_I64);
10347
10348 assign(counter, get_counter_w0());
10349
10350 assign(addr1, binop(Iop_Add64, mkexpr(start1),
10351 unop(Iop_32Uto64, mkexpr(counter))));
10352
10353 assign(old1, load(Ity_I8, mkexpr(addr1)));
10354 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10355 unop(Iop_32Uto64,mkexpr(counter)))));
10356 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
10357
10358 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000010359 if (op == Iop_Xor8) {
10360 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000010361 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
10362 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000010363 } else
10364 store(mkexpr(addr1), mkexpr(new1));
10365 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
10366 get_counter_w1()));
10367
10368 /* Check for end of field */
10369 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010370 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010371 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
10372 False);
10373 put_counter_dw0(mkU64(0));
10374}
10375
florian55085f82012-11-21 00:36:55 +000010376static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010377s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
10378{
florianb0bf6602012-05-05 00:01:16 +000010379 IRTemp len = newTemp(Ity_I32);
10380
10381 assign(len, mkU32(length));
10382 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010383
10384 return "xc";
10385}
10386
sewardjb63967e2011-03-24 08:50:04 +000010387static void
10388s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
10389{
10390 IRTemp counter = newTemp(Ity_I32);
10391 IRTemp start = newTemp(Ity_I64);
10392 IRTemp addr = newTemp(Ity_I64);
10393
10394 assign(start,
10395 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
10396
10397 if (length < 8) {
10398 UInt i;
10399
10400 for (i = 0; i <= length; ++i) {
10401 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
10402 }
10403 } else {
10404 assign(counter, get_counter_w0());
10405
10406 assign(addr, binop(Iop_Add64, mkexpr(start),
10407 unop(Iop_32Uto64, mkexpr(counter))));
10408
10409 store(mkexpr(addr), mkU8(0));
10410
10411 /* Check for end of field */
10412 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010413 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000010414
10415 /* Reset counter */
10416 put_counter_dw0(mkU64(0));
10417 }
10418
10419 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
10420
sewardj7ee97522011-05-09 21:45:04 +000010421 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000010422 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
10423}
10424
florian55085f82012-11-21 00:36:55 +000010425static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010426s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
10427{
florianb0bf6602012-05-05 00:01:16 +000010428 IRTemp len = newTemp(Ity_I32);
10429
10430 assign(len, mkU32(length));
10431 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010432
10433 return "nc";
10434}
10435
florian55085f82012-11-21 00:36:55 +000010436static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010437s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
10438{
florianb0bf6602012-05-05 00:01:16 +000010439 IRTemp len = newTemp(Ity_I32);
10440
10441 assign(len, mkU32(length));
10442 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010443
10444 return "oc";
10445}
10446
10447
florian55085f82012-11-21 00:36:55 +000010448static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010449s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
10450{
florian79e839e2012-05-05 02:20:30 +000010451 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010452
florian79e839e2012-05-05 02:20:30 +000010453 assign(len, mkU64(length));
10454 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010455
10456 return "mvc";
10457}
10458
florian55085f82012-11-21 00:36:55 +000010459static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010460s390_irgen_MVCL(UChar r1, UChar r2)
10461{
10462 IRTemp addr1 = newTemp(Ity_I64);
10463 IRTemp addr2 = newTemp(Ity_I64);
10464 IRTemp addr2_load = newTemp(Ity_I64);
10465 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10466 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10467 IRTemp len1 = newTemp(Ity_I32);
10468 IRTemp len2 = newTemp(Ity_I32);
10469 IRTemp pad = newTemp(Ity_I8);
10470 IRTemp single = newTemp(Ity_I8);
10471
10472 assign(addr1, get_gpr_dw0(r1));
10473 assign(r1p1, get_gpr_w1(r1 + 1));
10474 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10475 assign(addr2, get_gpr_dw0(r2));
10476 assign(r2p1, get_gpr_w1(r2 + 1));
10477 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10478 assign(pad, get_gpr_b4(r2 + 1));
10479
10480 /* len1 == 0 ? */
10481 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010482 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010483
10484 /* Check for destructive overlap:
10485 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
10486 s390_cc_set(3);
10487 IRTemp cond1 = newTemp(Ity_I32);
10488 assign(cond1, unop(Iop_1Uto32,
10489 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
10490 IRTemp cond2 = newTemp(Ity_I32);
10491 assign(cond2, unop(Iop_1Uto32,
10492 binop(Iop_CmpLT64U, mkexpr(addr1),
10493 binop(Iop_Add64, mkexpr(addr2),
10494 unop(Iop_32Uto64, mkexpr(len1))))));
10495 IRTemp cond3 = newTemp(Ity_I32);
10496 assign(cond3, unop(Iop_1Uto32,
10497 binop(Iop_CmpLT64U,
10498 mkexpr(addr1),
10499 binop(Iop_Add64, mkexpr(addr2),
10500 unop(Iop_32Uto64, mkexpr(len2))))));
10501
florian6820ba52012-07-26 02:01:50 +000010502 next_insn_if(binop(Iop_CmpEQ32,
10503 binop(Iop_And32,
10504 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10505 mkexpr(cond3)),
10506 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010507
10508 /* See s390_irgen_CLCL for explanation why we cannot load directly
10509 and need two steps. */
10510 assign(addr2_load,
10511 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10512 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10513 assign(single,
10514 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10515 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10516
10517 store(mkexpr(addr1), mkexpr(single));
10518
10519 /* Update addr1 and len1 */
10520 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10521 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10522
10523 /* Update addr2 and len2 */
10524 put_gpr_dw0(r2,
10525 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10526 mkexpr(addr2),
10527 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10528
10529 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10530 put_gpr_w1(r2 + 1,
10531 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10532 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10533 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10534
10535 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010536 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010537
10538 return "mvcl";
10539}
10540
10541
florian55085f82012-11-21 00:36:55 +000010542static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010543s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10544{
10545 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10546
10547 addr1 = newTemp(Ity_I64);
10548 addr3 = newTemp(Ity_I64);
10549 addr3_load = newTemp(Ity_I64);
10550 len1 = newTemp(Ity_I64);
10551 len3 = newTemp(Ity_I64);
10552 single = newTemp(Ity_I8);
10553
10554 assign(addr1, get_gpr_dw0(r1));
10555 assign(len1, get_gpr_dw0(r1 + 1));
10556 assign(addr3, get_gpr_dw0(r3));
10557 assign(len3, get_gpr_dw0(r3 + 1));
10558
10559 // len1 == 0 ?
10560 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010561 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010562
10563 /* This is a hack to prevent mvcle from reading from addr3 if it
10564 should read from the pad. Since the pad has no address, just
10565 read from the instruction, we discard that anyway */
10566 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010567 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10568 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010569
10570 assign(single,
florian6ad49522011-09-09 02:38:55 +000010571 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10572 unop(Iop_64to8, mkexpr(pad2)),
10573 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010574 store(mkexpr(addr1), mkexpr(single));
10575
10576 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10577
10578 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10579
10580 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010581 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10582 mkexpr(addr3),
10583 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010584
10585 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010586 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10587 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010588
sewardj2019a972011-03-07 16:04:07 +000010589 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010590 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010591
10592 return "mvcle";
10593}
10594
florian55085f82012-11-21 00:36:55 +000010595static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010596s390_irgen_MVST(UChar r1, UChar r2)
10597{
10598 IRTemp addr1 = newTemp(Ity_I64);
10599 IRTemp addr2 = newTemp(Ity_I64);
10600 IRTemp end = newTemp(Ity_I8);
10601 IRTemp byte = newTemp(Ity_I8);
10602 IRTemp counter = newTemp(Ity_I64);
10603
10604 assign(addr1, get_gpr_dw0(r1));
10605 assign(addr2, get_gpr_dw0(r2));
10606 assign(counter, get_counter_dw0());
10607 assign(end, get_gpr_b7(0));
10608 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10609 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10610
10611 // We use unlimited as cpu-determined number
10612 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010613 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010614
10615 // and always set cc=1 at the end + update r1
10616 s390_cc_set(1);
10617 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10618 put_counter_dw0(mkU64(0));
10619
10620 return "mvst";
10621}
10622
10623static void
10624s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10625{
10626 IRTemp op1 = newTemp(Ity_I64);
10627 IRTemp result = newTemp(Ity_I64);
10628
10629 assign(op1, binop(Iop_32HLto64,
10630 get_gpr_w1(r1), // high 32 bits
10631 get_gpr_w1(r1 + 1))); // low 32 bits
10632 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10633 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10634 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10635}
10636
10637static void
10638s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10639{
10640 IRTemp op1 = newTemp(Ity_I128);
10641 IRTemp result = newTemp(Ity_I128);
10642
10643 assign(op1, binop(Iop_64HLto128,
10644 get_gpr_dw0(r1), // high 64 bits
10645 get_gpr_dw0(r1 + 1))); // low 64 bits
10646 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10647 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10648 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10649}
10650
10651static void
10652s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10653{
10654 IRTemp op1 = newTemp(Ity_I64);
10655 IRTemp result = newTemp(Ity_I128);
10656
10657 assign(op1, get_gpr_dw0(r1 + 1));
10658 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10659 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10660 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10661}
10662
florian55085f82012-11-21 00:36:55 +000010663static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010664s390_irgen_DR(UChar r1, UChar r2)
10665{
10666 IRTemp op2 = newTemp(Ity_I32);
10667
10668 assign(op2, get_gpr_w1(r2));
10669
10670 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10671
10672 return "dr";
10673}
10674
florian55085f82012-11-21 00:36:55 +000010675static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010676s390_irgen_D(UChar r1, IRTemp op2addr)
10677{
10678 IRTemp op2 = newTemp(Ity_I32);
10679
10680 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10681
10682 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10683
10684 return "d";
10685}
10686
florian55085f82012-11-21 00:36:55 +000010687static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010688s390_irgen_DLR(UChar r1, UChar r2)
10689{
10690 IRTemp op2 = newTemp(Ity_I32);
10691
10692 assign(op2, get_gpr_w1(r2));
10693
10694 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10695
florian7cd1cde2012-08-16 23:57:43 +000010696 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010697}
10698
florian55085f82012-11-21 00:36:55 +000010699static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010700s390_irgen_DL(UChar r1, IRTemp op2addr)
10701{
10702 IRTemp op2 = newTemp(Ity_I32);
10703
10704 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10705
10706 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10707
10708 return "dl";
10709}
10710
florian55085f82012-11-21 00:36:55 +000010711static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010712s390_irgen_DLG(UChar r1, IRTemp op2addr)
10713{
10714 IRTemp op2 = newTemp(Ity_I64);
10715
10716 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10717
10718 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10719
10720 return "dlg";
10721}
10722
florian55085f82012-11-21 00:36:55 +000010723static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010724s390_irgen_DLGR(UChar r1, UChar r2)
10725{
10726 IRTemp op2 = newTemp(Ity_I64);
10727
10728 assign(op2, get_gpr_dw0(r2));
10729
10730 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10731
10732 return "dlgr";
10733}
10734
florian55085f82012-11-21 00:36:55 +000010735static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010736s390_irgen_DSGR(UChar r1, UChar r2)
10737{
10738 IRTemp op2 = newTemp(Ity_I64);
10739
10740 assign(op2, get_gpr_dw0(r2));
10741
10742 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10743
10744 return "dsgr";
10745}
10746
florian55085f82012-11-21 00:36:55 +000010747static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010748s390_irgen_DSG(UChar r1, IRTemp op2addr)
10749{
10750 IRTemp op2 = newTemp(Ity_I64);
10751
10752 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10753
10754 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10755
10756 return "dsg";
10757}
10758
florian55085f82012-11-21 00:36:55 +000010759static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010760s390_irgen_DSGFR(UChar r1, UChar r2)
10761{
10762 IRTemp op2 = newTemp(Ity_I64);
10763
10764 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10765
10766 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10767
10768 return "dsgfr";
10769}
10770
florian55085f82012-11-21 00:36:55 +000010771static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010772s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10773{
10774 IRTemp op2 = newTemp(Ity_I64);
10775
10776 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10777
10778 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10779
10780 return "dsgf";
10781}
10782
10783static void
10784s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10785{
10786 UChar reg;
10787 IRTemp addr = newTemp(Ity_I64);
10788
10789 assign(addr, mkexpr(op2addr));
10790 reg = r1;
10791 do {
10792 IRTemp old = addr;
10793
10794 reg %= 16;
10795 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10796 addr = newTemp(Ity_I64);
10797 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10798 reg++;
10799 } while (reg != (r3 + 1));
10800}
10801
florian55085f82012-11-21 00:36:55 +000010802static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010803s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10804{
10805 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10806
10807 return "lam";
10808}
10809
florian55085f82012-11-21 00:36:55 +000010810static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010811s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10812{
10813 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10814
10815 return "lamy";
10816}
10817
10818static void
10819s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10820{
10821 UChar reg;
10822 IRTemp addr = newTemp(Ity_I64);
10823
10824 assign(addr, mkexpr(op2addr));
10825 reg = r1;
10826 do {
10827 IRTemp old = addr;
10828
10829 reg %= 16;
10830 store(mkexpr(addr), get_ar_w0(reg));
10831 addr = newTemp(Ity_I64);
10832 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10833 reg++;
10834 } while (reg != (r3 + 1));
10835}
10836
florian55085f82012-11-21 00:36:55 +000010837static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010838s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10839{
10840 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10841
10842 return "stam";
10843}
10844
florian55085f82012-11-21 00:36:55 +000010845static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010846s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10847{
10848 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10849
10850 return "stamy";
10851}
10852
10853
10854/* Implementation for 32-bit compare-and-swap */
10855static void
10856s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10857{
10858 IRCAS *cas;
10859 IRTemp op1 = newTemp(Ity_I32);
10860 IRTemp old_mem = newTemp(Ity_I32);
10861 IRTemp op3 = newTemp(Ity_I32);
10862 IRTemp result = newTemp(Ity_I32);
10863 IRTemp nequal = newTemp(Ity_I1);
10864
10865 assign(op1, get_gpr_w1(r1));
10866 assign(op3, get_gpr_w1(r3));
10867
10868 /* The first and second operands are compared. If they are equal,
10869 the third operand is stored at the second- operand location. */
10870 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10871 Iend_BE, mkexpr(op2addr),
10872 NULL, mkexpr(op1), /* expected value */
10873 NULL, mkexpr(op3) /* new value */);
10874 stmt(IRStmt_CAS(cas));
10875
10876 /* Set CC. Operands compared equal -> 0, else 1. */
10877 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10878 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10879
10880 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10881 Otherwise, store the old_value from memory in r1 and yield. */
10882 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10883 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010884 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010885}
10886
florian55085f82012-11-21 00:36:55 +000010887static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010888s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10889{
10890 s390_irgen_cas_32(r1, r3, op2addr);
10891
10892 return "cs";
10893}
10894
florian55085f82012-11-21 00:36:55 +000010895static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010896s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10897{
10898 s390_irgen_cas_32(r1, r3, op2addr);
10899
10900 return "csy";
10901}
10902
florian55085f82012-11-21 00:36:55 +000010903static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010904s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10905{
10906 IRCAS *cas;
10907 IRTemp op1 = newTemp(Ity_I64);
10908 IRTemp old_mem = newTemp(Ity_I64);
10909 IRTemp op3 = newTemp(Ity_I64);
10910 IRTemp result = newTemp(Ity_I64);
10911 IRTemp nequal = newTemp(Ity_I1);
10912
10913 assign(op1, get_gpr_dw0(r1));
10914 assign(op3, get_gpr_dw0(r3));
10915
10916 /* The first and second operands are compared. If they are equal,
10917 the third operand is stored at the second- operand location. */
10918 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10919 Iend_BE, mkexpr(op2addr),
10920 NULL, mkexpr(op1), /* expected value */
10921 NULL, mkexpr(op3) /* new value */);
10922 stmt(IRStmt_CAS(cas));
10923
10924 /* Set CC. Operands compared equal -> 0, else 1. */
10925 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10926 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10927
10928 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10929 Otherwise, store the old_value from memory in r1 and yield. */
10930 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10931 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010932 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010933
10934 return "csg";
10935}
10936
florian448cbba2012-06-06 02:26:01 +000010937/* Implementation for 32-bit compare-double-and-swap */
10938static void
10939s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10940{
10941 IRCAS *cas;
10942 IRTemp op1_high = newTemp(Ity_I32);
10943 IRTemp op1_low = newTemp(Ity_I32);
10944 IRTemp old_mem_high = newTemp(Ity_I32);
10945 IRTemp old_mem_low = newTemp(Ity_I32);
10946 IRTemp op3_high = newTemp(Ity_I32);
10947 IRTemp op3_low = newTemp(Ity_I32);
10948 IRTemp result = newTemp(Ity_I32);
10949 IRTemp nequal = newTemp(Ity_I1);
10950
10951 assign(op1_high, get_gpr_w1(r1));
10952 assign(op1_low, get_gpr_w1(r1+1));
10953 assign(op3_high, get_gpr_w1(r3));
10954 assign(op3_low, get_gpr_w1(r3+1));
10955
10956 /* The first and second operands are compared. If they are equal,
10957 the third operand is stored at the second-operand location. */
10958 cas = mkIRCAS(old_mem_high, old_mem_low,
10959 Iend_BE, mkexpr(op2addr),
10960 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10961 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10962 stmt(IRStmt_CAS(cas));
10963
10964 /* Set CC. Operands compared equal -> 0, else 1. */
10965 assign(result, unop(Iop_1Uto32,
10966 binop(Iop_CmpNE32,
10967 binop(Iop_Or32,
10968 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10969 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10970 mkU32(0))));
10971
10972 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10973
10974 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10975 Otherwise, store the old_value from memory in r1 and yield. */
10976 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10977 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10978 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010979 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010980}
10981
florian55085f82012-11-21 00:36:55 +000010982static const HChar *
florian448cbba2012-06-06 02:26:01 +000010983s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10984{
10985 s390_irgen_cdas_32(r1, r3, op2addr);
10986
10987 return "cds";
10988}
10989
florian55085f82012-11-21 00:36:55 +000010990static const HChar *
florian448cbba2012-06-06 02:26:01 +000010991s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10992{
10993 s390_irgen_cdas_32(r1, r3, op2addr);
10994
10995 return "cdsy";
10996}
10997
florian55085f82012-11-21 00:36:55 +000010998static const HChar *
florian448cbba2012-06-06 02:26:01 +000010999s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11000{
11001 IRCAS *cas;
11002 IRTemp op1_high = newTemp(Ity_I64);
11003 IRTemp op1_low = newTemp(Ity_I64);
11004 IRTemp old_mem_high = newTemp(Ity_I64);
11005 IRTemp old_mem_low = newTemp(Ity_I64);
11006 IRTemp op3_high = newTemp(Ity_I64);
11007 IRTemp op3_low = newTemp(Ity_I64);
11008 IRTemp result = newTemp(Ity_I64);
11009 IRTemp nequal = newTemp(Ity_I1);
11010
11011 assign(op1_high, get_gpr_dw0(r1));
11012 assign(op1_low, get_gpr_dw0(r1+1));
11013 assign(op3_high, get_gpr_dw0(r3));
11014 assign(op3_low, get_gpr_dw0(r3+1));
11015
11016 /* The first and second operands are compared. If they are equal,
11017 the third operand is stored at the second-operand location. */
11018 cas = mkIRCAS(old_mem_high, old_mem_low,
11019 Iend_BE, mkexpr(op2addr),
11020 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11021 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11022 stmt(IRStmt_CAS(cas));
11023
11024 /* Set CC. Operands compared equal -> 0, else 1. */
11025 assign(result, unop(Iop_1Uto64,
11026 binop(Iop_CmpNE64,
11027 binop(Iop_Or64,
11028 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11029 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11030 mkU64(0))));
11031
11032 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11033
11034 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11035 Otherwise, store the old_value from memory in r1 and yield. */
11036 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11037 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11038 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011039 yield_if(mkexpr(nequal));
11040
florian448cbba2012-06-06 02:26:01 +000011041 return "cdsg";
11042}
11043
sewardj2019a972011-03-07 16:04:07 +000011044
11045/* Binary floating point */
11046
florian55085f82012-11-21 00:36:55 +000011047static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011048s390_irgen_AXBR(UChar r1, UChar r2)
11049{
11050 IRTemp op1 = newTemp(Ity_F128);
11051 IRTemp op2 = newTemp(Ity_F128);
11052 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011053 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011054
11055 assign(op1, get_fpr_pair(r1));
11056 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011057 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011058 mkexpr(op2)));
11059 put_fpr_pair(r1, mkexpr(result));
11060
11061 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11062
11063 return "axbr";
11064}
11065
florian55085f82012-11-21 00:36:55 +000011066static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011067s390_irgen_CEBR(UChar r1, UChar r2)
11068{
11069 IRTemp op1 = newTemp(Ity_F32);
11070 IRTemp op2 = newTemp(Ity_F32);
11071 IRTemp cc_vex = newTemp(Ity_I32);
11072 IRTemp cc_s390 = newTemp(Ity_I32);
11073
11074 assign(op1, get_fpr_w0(r1));
11075 assign(op2, get_fpr_w0(r2));
11076 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11077
florian2d3d87f2012-12-21 21:05:17 +000011078 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011079 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11080
11081 return "cebr";
11082}
11083
florian55085f82012-11-21 00:36:55 +000011084static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011085s390_irgen_CDBR(UChar r1, UChar r2)
11086{
11087 IRTemp op1 = newTemp(Ity_F64);
11088 IRTemp op2 = newTemp(Ity_F64);
11089 IRTemp cc_vex = newTemp(Ity_I32);
11090 IRTemp cc_s390 = newTemp(Ity_I32);
11091
11092 assign(op1, get_fpr_dw0(r1));
11093 assign(op2, get_fpr_dw0(r2));
11094 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11095
florian2d3d87f2012-12-21 21:05:17 +000011096 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011097 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11098
11099 return "cdbr";
11100}
11101
florian55085f82012-11-21 00:36:55 +000011102static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011103s390_irgen_CXBR(UChar r1, UChar r2)
11104{
11105 IRTemp op1 = newTemp(Ity_F128);
11106 IRTemp op2 = newTemp(Ity_F128);
11107 IRTemp cc_vex = newTemp(Ity_I32);
11108 IRTemp cc_s390 = newTemp(Ity_I32);
11109
11110 assign(op1, get_fpr_pair(r1));
11111 assign(op2, get_fpr_pair(r2));
11112 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
11113
florian2d3d87f2012-12-21 21:05:17 +000011114 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011115 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11116
11117 return "cxbr";
11118}
11119
florian55085f82012-11-21 00:36:55 +000011120static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011121s390_irgen_CEB(UChar r1, IRTemp op2addr)
11122{
11123 IRTemp op1 = newTemp(Ity_F32);
11124 IRTemp op2 = newTemp(Ity_F32);
11125 IRTemp cc_vex = newTemp(Ity_I32);
11126 IRTemp cc_s390 = newTemp(Ity_I32);
11127
11128 assign(op1, get_fpr_w0(r1));
11129 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11130 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11131
florian2d3d87f2012-12-21 21:05:17 +000011132 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011133 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11134
11135 return "ceb";
11136}
11137
florian55085f82012-11-21 00:36:55 +000011138static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011139s390_irgen_CDB(UChar r1, IRTemp op2addr)
11140{
11141 IRTemp op1 = newTemp(Ity_F64);
11142 IRTemp op2 = newTemp(Ity_F64);
11143 IRTemp cc_vex = newTemp(Ity_I32);
11144 IRTemp cc_s390 = newTemp(Ity_I32);
11145
11146 assign(op1, get_fpr_dw0(r1));
11147 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11148 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11149
florian2d3d87f2012-12-21 21:05:17 +000011150 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011151 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11152
11153 return "cdb";
11154}
11155
florian55085f82012-11-21 00:36:55 +000011156static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011157s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11158 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011159{
11160 IRTemp op2 = newTemp(Ity_I32);
11161
11162 assign(op2, get_gpr_w1(r2));
11163 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11164
11165 return "cxfbr";
11166}
11167
florian55085f82012-11-21 00:36:55 +000011168static const HChar *
floriand2129202012-09-01 20:01:39 +000011169s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11170 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011171{
floriane75dafa2012-09-01 17:54:09 +000011172 if (! s390_host_has_fpext) {
11173 emulation_failure(EmFail_S390X_fpext);
11174 } else {
11175 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011176
floriane75dafa2012-09-01 17:54:09 +000011177 assign(op2, get_gpr_w1(r2));
11178 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11179 }
florian1c8f7ff2012-09-01 00:12:11 +000011180 return "cxlfbr";
11181}
11182
11183
florian55085f82012-11-21 00:36:55 +000011184static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011185s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11186 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011187{
11188 IRTemp op2 = newTemp(Ity_I64);
11189
11190 assign(op2, get_gpr_dw0(r2));
11191 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11192
11193 return "cxgbr";
11194}
11195
florian55085f82012-11-21 00:36:55 +000011196static const HChar *
floriand2129202012-09-01 20:01:39 +000011197s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11198 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011199{
floriane75dafa2012-09-01 17:54:09 +000011200 if (! s390_host_has_fpext) {
11201 emulation_failure(EmFail_S390X_fpext);
11202 } else {
11203 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011204
floriane75dafa2012-09-01 17:54:09 +000011205 assign(op2, get_gpr_dw0(r2));
11206 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11207 }
florian1c8f7ff2012-09-01 00:12:11 +000011208 return "cxlgbr";
11209}
11210
florian55085f82012-11-21 00:36:55 +000011211static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011212s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11213 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011214{
11215 IRTemp op = newTemp(Ity_F128);
11216 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011217 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011218
11219 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011220 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011221 mkexpr(op)));
11222 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011223 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011224
11225 return "cfxbr";
11226}
11227
florian55085f82012-11-21 00:36:55 +000011228static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011229s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
11230 UChar r1, UChar r2)
11231{
floriane75dafa2012-09-01 17:54:09 +000011232 if (! s390_host_has_fpext) {
11233 emulation_failure(EmFail_S390X_fpext);
11234 } else {
11235 IRTemp op = newTemp(Ity_F128);
11236 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011237 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011238
floriane75dafa2012-09-01 17:54:09 +000011239 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011240 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011241 mkexpr(op)));
11242 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011243 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011244 }
florian1c8f7ff2012-09-01 00:12:11 +000011245 return "clfxbr";
11246}
11247
11248
florian55085f82012-11-21 00:36:55 +000011249static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011250s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
11251 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011252{
11253 IRTemp op = newTemp(Ity_F128);
11254 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011255 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011256
11257 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011258 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011259 mkexpr(op)));
11260 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011261 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011262
11263 return "cgxbr";
11264}
11265
florian55085f82012-11-21 00:36:55 +000011266static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011267s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
11268 UChar r1, UChar r2)
11269{
floriane75dafa2012-09-01 17:54:09 +000011270 if (! s390_host_has_fpext) {
11271 emulation_failure(EmFail_S390X_fpext);
11272 } else {
11273 IRTemp op = newTemp(Ity_F128);
11274 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011275 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011276
floriane75dafa2012-09-01 17:54:09 +000011277 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011278 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011279 mkexpr(op)));
11280 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011281 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
11282 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011283 }
florian1c8f7ff2012-09-01 00:12:11 +000011284 return "clgxbr";
11285}
11286
florian55085f82012-11-21 00:36:55 +000011287static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011288s390_irgen_DXBR(UChar r1, UChar r2)
11289{
11290 IRTemp op1 = newTemp(Ity_F128);
11291 IRTemp op2 = newTemp(Ity_F128);
11292 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011293 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011294
11295 assign(op1, get_fpr_pair(r1));
11296 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011297 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011298 mkexpr(op2)));
11299 put_fpr_pair(r1, mkexpr(result));
11300
11301 return "dxbr";
11302}
11303
florian55085f82012-11-21 00:36:55 +000011304static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011305s390_irgen_LTXBR(UChar r1, UChar r2)
11306{
11307 IRTemp result = newTemp(Ity_F128);
11308
11309 assign(result, get_fpr_pair(r2));
11310 put_fpr_pair(r1, mkexpr(result));
11311 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11312
11313 return "ltxbr";
11314}
11315
florian55085f82012-11-21 00:36:55 +000011316static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011317s390_irgen_LCXBR(UChar r1, UChar r2)
11318{
11319 IRTemp result = newTemp(Ity_F128);
11320
11321 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
11322 put_fpr_pair(r1, mkexpr(result));
11323 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11324
11325 return "lcxbr";
11326}
11327
florian55085f82012-11-21 00:36:55 +000011328static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011329s390_irgen_LXDBR(UChar r1, UChar r2)
11330{
11331 IRTemp op = newTemp(Ity_F64);
11332
11333 assign(op, get_fpr_dw0(r2));
11334 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11335
11336 return "lxdbr";
11337}
11338
florian55085f82012-11-21 00:36:55 +000011339static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011340s390_irgen_LXEBR(UChar r1, UChar r2)
11341{
11342 IRTemp op = newTemp(Ity_F32);
11343
11344 assign(op, get_fpr_w0(r2));
11345 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11346
11347 return "lxebr";
11348}
11349
florian55085f82012-11-21 00:36:55 +000011350static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011351s390_irgen_LXDB(UChar r1, IRTemp op2addr)
11352{
11353 IRTemp op = newTemp(Ity_F64);
11354
11355 assign(op, load(Ity_F64, mkexpr(op2addr)));
11356 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11357
11358 return "lxdb";
11359}
11360
florian55085f82012-11-21 00:36:55 +000011361static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011362s390_irgen_LXEB(UChar r1, IRTemp op2addr)
11363{
11364 IRTemp op = newTemp(Ity_F32);
11365
11366 assign(op, load(Ity_F32, mkexpr(op2addr)));
11367 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11368
11369 return "lxeb";
11370}
11371
florian55085f82012-11-21 00:36:55 +000011372static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011373s390_irgen_LNEBR(UChar r1, UChar r2)
11374{
11375 IRTemp result = newTemp(Ity_F32);
11376
11377 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
11378 put_fpr_w0(r1, mkexpr(result));
11379 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11380
11381 return "lnebr";
11382}
11383
florian55085f82012-11-21 00:36:55 +000011384static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011385s390_irgen_LNDBR(UChar r1, UChar r2)
11386{
11387 IRTemp result = newTemp(Ity_F64);
11388
11389 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11390 put_fpr_dw0(r1, mkexpr(result));
11391 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11392
11393 return "lndbr";
11394}
11395
florian55085f82012-11-21 00:36:55 +000011396static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011397s390_irgen_LNXBR(UChar r1, UChar r2)
11398{
11399 IRTemp result = newTemp(Ity_F128);
11400
11401 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
11402 put_fpr_pair(r1, mkexpr(result));
11403 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11404
11405 return "lnxbr";
11406}
11407
florian55085f82012-11-21 00:36:55 +000011408static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011409s390_irgen_LPEBR(UChar r1, UChar r2)
11410{
11411 IRTemp result = newTemp(Ity_F32);
11412
11413 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
11414 put_fpr_w0(r1, mkexpr(result));
11415 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11416
11417 return "lpebr";
11418}
11419
florian55085f82012-11-21 00:36:55 +000011420static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011421s390_irgen_LPDBR(UChar r1, UChar r2)
11422{
11423 IRTemp result = newTemp(Ity_F64);
11424
11425 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11426 put_fpr_dw0(r1, mkexpr(result));
11427 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11428
11429 return "lpdbr";
11430}
11431
florian55085f82012-11-21 00:36:55 +000011432static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011433s390_irgen_LPXBR(UChar r1, UChar r2)
11434{
11435 IRTemp result = newTemp(Ity_F128);
11436
11437 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
11438 put_fpr_pair(r1, mkexpr(result));
11439 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11440
11441 return "lpxbr";
11442}
11443
florian55085f82012-11-21 00:36:55 +000011444static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011445s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
11446 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011447{
florian125e20d2012-10-07 15:42:37 +000011448 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011449 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011450 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011451 }
sewardj2019a972011-03-07 16:04:07 +000011452 IRTemp result = newTemp(Ity_F64);
11453
floriandb4fcaa2012-09-05 19:54:08 +000011454 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011455 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011456 put_fpr_dw0(r1, mkexpr(result));
11457
11458 return "ldxbr";
11459}
11460
florian55085f82012-11-21 00:36:55 +000011461static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011462s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11463 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011464{
florian125e20d2012-10-07 15:42:37 +000011465 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011466 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011467 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011468 }
sewardj2019a972011-03-07 16:04:07 +000011469 IRTemp result = newTemp(Ity_F32);
11470
floriandb4fcaa2012-09-05 19:54:08 +000011471 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011472 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011473 put_fpr_w0(r1, mkexpr(result));
11474
11475 return "lexbr";
11476}
11477
florian55085f82012-11-21 00:36:55 +000011478static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011479s390_irgen_MXBR(UChar r1, UChar r2)
11480{
11481 IRTemp op1 = newTemp(Ity_F128);
11482 IRTemp op2 = newTemp(Ity_F128);
11483 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011484 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011485
11486 assign(op1, get_fpr_pair(r1));
11487 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011488 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011489 mkexpr(op2)));
11490 put_fpr_pair(r1, mkexpr(result));
11491
11492 return "mxbr";
11493}
11494
florian55085f82012-11-21 00:36:55 +000011495static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011496s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11497{
florian125e20d2012-10-07 15:42:37 +000011498 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011499
floriandb4fcaa2012-09-05 19:54:08 +000011500 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011501 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011502
11503 return "maebr";
11504}
11505
florian55085f82012-11-21 00:36:55 +000011506static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011507s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11508{
florian125e20d2012-10-07 15:42:37 +000011509 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011510
floriandb4fcaa2012-09-05 19:54:08 +000011511 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011512 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011513
11514 return "madbr";
11515}
11516
florian55085f82012-11-21 00:36:55 +000011517static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011518s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11519{
11520 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011521 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011522
floriandb4fcaa2012-09-05 19:54:08 +000011523 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011524 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011525
11526 return "maeb";
11527}
11528
florian55085f82012-11-21 00:36:55 +000011529static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011530s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11531{
11532 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011533 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011534
floriandb4fcaa2012-09-05 19:54:08 +000011535 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011536 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011537
11538 return "madb";
11539}
11540
florian55085f82012-11-21 00:36:55 +000011541static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011542s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11543{
florian125e20d2012-10-07 15:42:37 +000011544 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011545
floriandb4fcaa2012-09-05 19:54:08 +000011546 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011547 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011548
11549 return "msebr";
11550}
11551
florian55085f82012-11-21 00:36:55 +000011552static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011553s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11554{
florian125e20d2012-10-07 15:42:37 +000011555 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011556
floriandb4fcaa2012-09-05 19:54:08 +000011557 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011558 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011559
11560 return "msdbr";
11561}
11562
florian55085f82012-11-21 00:36:55 +000011563static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011564s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11565{
11566 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011567 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011568
floriandb4fcaa2012-09-05 19:54:08 +000011569 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011570 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011571
11572 return "mseb";
11573}
11574
florian55085f82012-11-21 00:36:55 +000011575static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011576s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11577{
11578 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011579 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011580
floriandb4fcaa2012-09-05 19:54:08 +000011581 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011582 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011583
11584 return "msdb";
11585}
11586
florian55085f82012-11-21 00:36:55 +000011587static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011588s390_irgen_SQEBR(UChar r1, UChar r2)
11589{
11590 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011591 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011592
floriandb4fcaa2012-09-05 19:54:08 +000011593 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011594 put_fpr_w0(r1, mkexpr(result));
11595
11596 return "sqebr";
11597}
11598
florian55085f82012-11-21 00:36:55 +000011599static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011600s390_irgen_SQDBR(UChar r1, UChar r2)
11601{
11602 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011603 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011604
floriandb4fcaa2012-09-05 19:54:08 +000011605 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011606 put_fpr_dw0(r1, mkexpr(result));
11607
11608 return "sqdbr";
11609}
11610
florian55085f82012-11-21 00:36:55 +000011611static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011612s390_irgen_SQXBR(UChar r1, UChar r2)
11613{
11614 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011615 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011616
floriandb4fcaa2012-09-05 19:54:08 +000011617 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11618 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011619 put_fpr_pair(r1, mkexpr(result));
11620
11621 return "sqxbr";
11622}
11623
florian55085f82012-11-21 00:36:55 +000011624static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011625s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11626{
11627 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011628 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011629
11630 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011631 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011632
11633 return "sqeb";
11634}
11635
florian55085f82012-11-21 00:36:55 +000011636static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011637s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11638{
11639 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011640 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011641
11642 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011643 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011644
11645 return "sqdb";
11646}
11647
florian55085f82012-11-21 00:36:55 +000011648static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011649s390_irgen_SXBR(UChar r1, UChar r2)
11650{
11651 IRTemp op1 = newTemp(Ity_F128);
11652 IRTemp op2 = newTemp(Ity_F128);
11653 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011654 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011655
11656 assign(op1, get_fpr_pair(r1));
11657 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011658 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011659 mkexpr(op2)));
11660 put_fpr_pair(r1, mkexpr(result));
11661 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11662
11663 return "sxbr";
11664}
11665
florian55085f82012-11-21 00:36:55 +000011666static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011667s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11668{
11669 IRTemp value = newTemp(Ity_F32);
11670
11671 assign(value, get_fpr_w0(r1));
11672
11673 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11674
11675 return "tceb";
11676}
11677
florian55085f82012-11-21 00:36:55 +000011678static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011679s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11680{
11681 IRTemp value = newTemp(Ity_F64);
11682
11683 assign(value, get_fpr_dw0(r1));
11684
11685 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11686
11687 return "tcdb";
11688}
11689
florian55085f82012-11-21 00:36:55 +000011690static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011691s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11692{
11693 IRTemp value = newTemp(Ity_F128);
11694
11695 assign(value, get_fpr_pair(r1));
11696
11697 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11698
11699 return "tcxb";
11700}
11701
florian55085f82012-11-21 00:36:55 +000011702static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011703s390_irgen_LCDFR(UChar r1, UChar r2)
11704{
11705 IRTemp result = newTemp(Ity_F64);
11706
11707 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11708 put_fpr_dw0(r1, mkexpr(result));
11709
11710 return "lcdfr";
11711}
11712
florian55085f82012-11-21 00:36:55 +000011713static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011714s390_irgen_LNDFR(UChar r1, UChar r2)
11715{
11716 IRTemp result = newTemp(Ity_F64);
11717
11718 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11719 put_fpr_dw0(r1, mkexpr(result));
11720
11721 return "lndfr";
11722}
11723
florian55085f82012-11-21 00:36:55 +000011724static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011725s390_irgen_LPDFR(UChar r1, UChar r2)
11726{
11727 IRTemp result = newTemp(Ity_F64);
11728
11729 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11730 put_fpr_dw0(r1, mkexpr(result));
11731
11732 return "lpdfr";
11733}
11734
florian55085f82012-11-21 00:36:55 +000011735static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011736s390_irgen_LDGR(UChar r1, UChar r2)
11737{
11738 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11739
11740 return "ldgr";
11741}
11742
florian55085f82012-11-21 00:36:55 +000011743static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011744s390_irgen_LGDR(UChar r1, UChar r2)
11745{
11746 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11747
11748 return "lgdr";
11749}
11750
11751
florian55085f82012-11-21 00:36:55 +000011752static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011753s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11754{
11755 IRTemp sign = newTemp(Ity_I64);
11756 IRTemp value = newTemp(Ity_I64);
11757
11758 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11759 mkU64(1ULL << 63)));
11760 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11761 mkU64((1ULL << 63) - 1)));
11762 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11763 mkexpr(sign))));
11764
11765 return "cpsdr";
11766}
11767
11768
sewardj2019a972011-03-07 16:04:07 +000011769static IRExpr *
11770s390_call_cvb(IRExpr *in)
11771{
11772 IRExpr **args, *call;
11773
11774 args = mkIRExprVec_1(in);
11775 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11776 "s390_do_cvb", &s390_do_cvb, args);
11777
11778 /* Nothing is excluded from definedness checking. */
11779 call->Iex.CCall.cee->mcx_mask = 0;
11780
11781 return call;
11782}
11783
florian55085f82012-11-21 00:36:55 +000011784static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011785s390_irgen_CVB(UChar r1, IRTemp op2addr)
11786{
11787 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11788
11789 return "cvb";
11790}
11791
florian55085f82012-11-21 00:36:55 +000011792static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011793s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11794{
11795 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11796
11797 return "cvby";
11798}
11799
11800
sewardj2019a972011-03-07 16:04:07 +000011801static IRExpr *
11802s390_call_cvd(IRExpr *in)
11803{
11804 IRExpr **args, *call;
11805
11806 args = mkIRExprVec_1(in);
11807 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11808 "s390_do_cvd", &s390_do_cvd, args);
11809
11810 /* Nothing is excluded from definedness checking. */
11811 call->Iex.CCall.cee->mcx_mask = 0;
11812
11813 return call;
11814}
11815
florian55085f82012-11-21 00:36:55 +000011816static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011817s390_irgen_CVD(UChar r1, IRTemp op2addr)
11818{
florian11b8ee82012-08-06 13:35:33 +000011819 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011820
11821 return "cvd";
11822}
11823
florian55085f82012-11-21 00:36:55 +000011824static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011825s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11826{
11827 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11828
11829 return "cvdy";
11830}
11831
florian55085f82012-11-21 00:36:55 +000011832static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011833s390_irgen_FLOGR(UChar r1, UChar r2)
11834{
11835 IRTemp input = newTemp(Ity_I64);
11836 IRTemp not_zero = newTemp(Ity_I64);
11837 IRTemp tmpnum = newTemp(Ity_I64);
11838 IRTemp num = newTemp(Ity_I64);
11839 IRTemp shift_amount = newTemp(Ity_I8);
11840
11841 /* We use the "count leading zeroes" operator because the number of
11842 leading zeroes is identical with the bit position of the first '1' bit.
11843 However, that operator does not work when the input value is zero.
11844 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11845 the modified value. If input == 0, then the result is 64. Otherwise,
11846 the result of Clz64 is what we want. */
11847
11848 assign(input, get_gpr_dw0(r2));
11849 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11850 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11851
11852 /* num = (input == 0) ? 64 : tmpnum */
11853 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11854 /* == 0 */ mkU64(64),
11855 /* != 0 */ mkexpr(tmpnum)));
11856
11857 put_gpr_dw0(r1, mkexpr(num));
11858
11859 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11860 is to first shift the input value by NUM + 1 bits to the left which
11861 causes the leftmost '1' bit to disappear. Then we shift logically to
11862 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11863 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11864 the width of the value-to-be-shifted, we need to special case
11865 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11866 For both such INPUT values the result will be 0. */
11867
11868 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11869 mkU64(1))));
11870
11871 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011872 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11873 /* == 0 || == 1*/ mkU64(0),
11874 /* otherwise */
11875 binop(Iop_Shr64,
11876 binop(Iop_Shl64, mkexpr(input),
11877 mkexpr(shift_amount)),
11878 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011879
11880 /* Compare the original value as an unsigned integer with 0. */
11881 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11882 mktemp(Ity_I64, mkU64(0)), False);
11883
11884 return "flogr";
11885}
11886
florian55085f82012-11-21 00:36:55 +000011887static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011888s390_irgen_STCK(IRTemp op2addr)
11889{
11890 IRDirty *d;
11891 IRTemp cc = newTemp(Ity_I64);
11892
11893 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11894 &s390x_dirtyhelper_STCK,
11895 mkIRExprVec_1(mkexpr(op2addr)));
11896 d->mFx = Ifx_Write;
11897 d->mAddr = mkexpr(op2addr);
11898 d->mSize = 8;
11899 stmt(IRStmt_Dirty(d));
11900 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11901 mkexpr(cc), mkU64(0), mkU64(0));
11902 return "stck";
11903}
11904
florian55085f82012-11-21 00:36:55 +000011905static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011906s390_irgen_STCKF(IRTemp op2addr)
11907{
florianc5c669b2012-08-26 14:32:28 +000011908 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011909 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011910 } else {
11911 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011912
florianc5c669b2012-08-26 14:32:28 +000011913 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11914 &s390x_dirtyhelper_STCKF,
11915 mkIRExprVec_1(mkexpr(op2addr)));
11916 d->mFx = Ifx_Write;
11917 d->mAddr = mkexpr(op2addr);
11918 d->mSize = 8;
11919 stmt(IRStmt_Dirty(d));
11920 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11921 mkexpr(cc), mkU64(0), mkU64(0));
11922 }
sewardj1e5fea62011-05-17 16:18:36 +000011923 return "stckf";
11924}
11925
florian55085f82012-11-21 00:36:55 +000011926static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011927s390_irgen_STCKE(IRTemp op2addr)
11928{
11929 IRDirty *d;
11930 IRTemp cc = newTemp(Ity_I64);
11931
11932 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11933 &s390x_dirtyhelper_STCKE,
11934 mkIRExprVec_1(mkexpr(op2addr)));
11935 d->mFx = Ifx_Write;
11936 d->mAddr = mkexpr(op2addr);
11937 d->mSize = 16;
11938 stmt(IRStmt_Dirty(d));
11939 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11940 mkexpr(cc), mkU64(0), mkU64(0));
11941 return "stcke";
11942}
11943
florian55085f82012-11-21 00:36:55 +000011944static const HChar *
florian933065d2011-07-11 01:48:02 +000011945s390_irgen_STFLE(IRTemp op2addr)
11946{
florian4e0083e2012-08-26 03:41:56 +000011947 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011948 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011949 return "stfle";
11950 }
11951
florian933065d2011-07-11 01:48:02 +000011952 IRDirty *d;
11953 IRTemp cc = newTemp(Ity_I64);
11954
11955 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11956 &s390x_dirtyhelper_STFLE,
11957 mkIRExprVec_1(mkexpr(op2addr)));
11958
11959 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11960
sewardjc9069f22012-06-01 16:09:50 +000011961 d->nFxState = 1;
11962 vex_bzero(&d->fxState, sizeof(d->fxState));
11963
florian933065d2011-07-11 01:48:02 +000011964 d->fxState[0].fx = Ifx_Modify; /* read then write */
11965 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11966 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011967
11968 d->mAddr = mkexpr(op2addr);
11969 /* Pretend all double words are written */
11970 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11971 d->mFx = Ifx_Write;
11972
11973 stmt(IRStmt_Dirty(d));
11974
11975 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11976
11977 return "stfle";
11978}
11979
florian55085f82012-11-21 00:36:55 +000011980static const HChar *
floriana4384a32011-08-11 16:58:45 +000011981s390_irgen_CKSM(UChar r1,UChar r2)
11982{
11983 IRTemp addr = newTemp(Ity_I64);
11984 IRTemp op = newTemp(Ity_I32);
11985 IRTemp len = newTemp(Ity_I64);
11986 IRTemp oldval = newTemp(Ity_I32);
11987 IRTemp mask = newTemp(Ity_I32);
11988 IRTemp newop = newTemp(Ity_I32);
11989 IRTemp result = newTemp(Ity_I32);
11990 IRTemp result1 = newTemp(Ity_I32);
11991 IRTemp inc = newTemp(Ity_I64);
11992
11993 assign(oldval, get_gpr_w1(r1));
11994 assign(addr, get_gpr_dw0(r2));
11995 assign(len, get_gpr_dw0(r2+1));
11996
11997 /* Condition code is always zero. */
11998 s390_cc_set(0);
11999
12000 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012001 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012002
12003 /* Assiging the increment variable to adjust address and length
12004 later on. */
12005 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12006 mkexpr(len), mkU64(4)));
12007
12008 /* If length < 4 the final 4-byte 2nd operand value is computed by
12009 appending the remaining bytes to the right with 0. This is done
12010 by AND'ing the 4 bytes loaded from memory with an appropriate
12011 mask. If length >= 4, that mask is simply 0xffffffff. */
12012
12013 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12014 /* Mask computation when len < 4:
12015 0xffffffff << (32 - (len % 4)*8) */
12016 binop(Iop_Shl32, mkU32(0xffffffff),
12017 unop(Iop_32to8,
12018 binop(Iop_Sub32, mkU32(32),
12019 binop(Iop_Shl32,
12020 unop(Iop_64to32,
12021 binop(Iop_And64,
12022 mkexpr(len), mkU64(3))),
12023 mkU8(3))))),
12024 mkU32(0xffffffff)));
12025
12026 assign(op, load(Ity_I32, mkexpr(addr)));
12027 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12028 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12029
12030 /* Checking for carry */
12031 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12032 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12033 mkexpr(result)));
12034
12035 put_gpr_w1(r1, mkexpr(result1));
12036 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12037 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12038
florian6820ba52012-07-26 02:01:50 +000012039 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012040
12041 return "cksm";
12042}
12043
florian55085f82012-11-21 00:36:55 +000012044static const HChar *
florian9af37692012-01-15 21:01:16 +000012045s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12046{
12047 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12048 src_addr = newTemp(Ity_I64);
12049 des_addr = newTemp(Ity_I64);
12050 tab_addr = newTemp(Ity_I64);
12051 test_byte = newTemp(Ity_I8);
12052 src_len = newTemp(Ity_I64);
12053
12054 assign(src_addr, get_gpr_dw0(r2));
12055 assign(des_addr, get_gpr_dw0(r1));
12056 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012057 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012058 assign(test_byte, get_gpr_b7(0));
12059
12060 IRTemp op = newTemp(Ity_I8);
12061 IRTemp op1 = newTemp(Ity_I8);
12062 IRTemp result = newTemp(Ity_I64);
12063
12064 /* End of source string? We're done; proceed to next insn */
12065 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012066 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012067
12068 /* Load character from source string, index translation table and
12069 store translated character in op1. */
12070 assign(op, load(Ity_I8, mkexpr(src_addr)));
12071
12072 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12073 mkexpr(tab_addr)));
12074 assign(op1, load(Ity_I8, mkexpr(result)));
12075
12076 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12077 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012078 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000012079 }
12080 store(get_gpr_dw0(r1), mkexpr(op1));
12081
12082 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12083 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12084 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12085
florian6820ba52012-07-26 02:01:50 +000012086 iterate();
florian9af37692012-01-15 21:01:16 +000012087
12088 return "troo";
12089}
12090
florian55085f82012-11-21 00:36:55 +000012091static const HChar *
florian730448f2012-02-04 17:07:07 +000012092s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
12093{
12094 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12095 src_addr = newTemp(Ity_I64);
12096 des_addr = newTemp(Ity_I64);
12097 tab_addr = newTemp(Ity_I64);
12098 test_byte = newTemp(Ity_I8);
12099 src_len = newTemp(Ity_I64);
12100
12101 assign(src_addr, get_gpr_dw0(r2));
12102 assign(des_addr, get_gpr_dw0(r1));
12103 assign(tab_addr, get_gpr_dw0(1));
12104 assign(src_len, get_gpr_dw0(r1+1));
12105 assign(test_byte, get_gpr_b7(0));
12106
12107 IRTemp op = newTemp(Ity_I16);
12108 IRTemp op1 = newTemp(Ity_I8);
12109 IRTemp result = newTemp(Ity_I64);
12110
12111 /* End of source string? We're done; proceed to next insn */
12112 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012113 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012114
12115 /* Load character from source string, index translation table and
12116 store translated character in op1. */
12117 assign(op, load(Ity_I16, mkexpr(src_addr)));
12118
12119 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12120 mkexpr(tab_addr)));
12121
12122 assign(op1, load(Ity_I8, mkexpr(result)));
12123
12124 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12125 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012126 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012127 }
12128 store(get_gpr_dw0(r1), mkexpr(op1));
12129
12130 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12131 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12132 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12133
florian6820ba52012-07-26 02:01:50 +000012134 iterate();
florian730448f2012-02-04 17:07:07 +000012135
12136 return "trto";
12137}
12138
florian55085f82012-11-21 00:36:55 +000012139static const HChar *
florian730448f2012-02-04 17:07:07 +000012140s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
12141{
12142 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12143 src_addr = newTemp(Ity_I64);
12144 des_addr = newTemp(Ity_I64);
12145 tab_addr = newTemp(Ity_I64);
12146 test_byte = newTemp(Ity_I16);
12147 src_len = newTemp(Ity_I64);
12148
12149 assign(src_addr, get_gpr_dw0(r2));
12150 assign(des_addr, get_gpr_dw0(r1));
12151 assign(tab_addr, get_gpr_dw0(1));
12152 assign(src_len, get_gpr_dw0(r1+1));
12153 assign(test_byte, get_gpr_hw3(0));
12154
12155 IRTemp op = newTemp(Ity_I8);
12156 IRTemp op1 = newTemp(Ity_I16);
12157 IRTemp result = newTemp(Ity_I64);
12158
12159 /* End of source string? We're done; proceed to next insn */
12160 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012161 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012162
12163 /* Load character from source string, index translation table and
12164 store translated character in op1. */
12165 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12166
12167 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12168 mkexpr(tab_addr)));
12169 assign(op1, load(Ity_I16, mkexpr(result)));
12170
12171 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12172 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012173 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012174 }
12175 store(get_gpr_dw0(r1), mkexpr(op1));
12176
12177 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12178 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12179 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12180
florian6820ba52012-07-26 02:01:50 +000012181 iterate();
florian730448f2012-02-04 17:07:07 +000012182
12183 return "trot";
12184}
12185
florian55085f82012-11-21 00:36:55 +000012186static const HChar *
florian730448f2012-02-04 17:07:07 +000012187s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12188{
12189 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12190 src_addr = newTemp(Ity_I64);
12191 des_addr = newTemp(Ity_I64);
12192 tab_addr = newTemp(Ity_I64);
12193 test_byte = newTemp(Ity_I16);
12194 src_len = newTemp(Ity_I64);
12195
12196 assign(src_addr, get_gpr_dw0(r2));
12197 assign(des_addr, get_gpr_dw0(r1));
12198 assign(tab_addr, get_gpr_dw0(1));
12199 assign(src_len, get_gpr_dw0(r1+1));
12200 assign(test_byte, get_gpr_hw3(0));
12201
12202 IRTemp op = newTemp(Ity_I16);
12203 IRTemp op1 = newTemp(Ity_I16);
12204 IRTemp result = newTemp(Ity_I64);
12205
12206 /* End of source string? We're done; proceed to next insn */
12207 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012208 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012209
12210 /* Load character from source string, index translation table and
12211 store translated character in op1. */
12212 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12213
12214 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12215 mkexpr(tab_addr)));
12216 assign(op1, load(Ity_I16, mkexpr(result)));
12217
12218 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12219 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012220 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012221 }
12222
12223 store(get_gpr_dw0(r1), mkexpr(op1));
12224
12225 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12226 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12227 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12228
florian6820ba52012-07-26 02:01:50 +000012229 iterate();
florian730448f2012-02-04 17:07:07 +000012230
12231 return "trtt";
12232}
12233
florian55085f82012-11-21 00:36:55 +000012234static const HChar *
florian730448f2012-02-04 17:07:07 +000012235s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
12236{
florianf87d4fb2012-05-05 02:55:24 +000012237 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000012238
florianf87d4fb2012-05-05 02:55:24 +000012239 assign(len, mkU64(length));
12240 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000012241
12242 return "tr";
12243}
12244
florian55085f82012-11-21 00:36:55 +000012245static const HChar *
florian730448f2012-02-04 17:07:07 +000012246s390_irgen_TRE(UChar r1,UChar r2)
12247{
12248 IRTemp src_addr, tab_addr, src_len, test_byte;
12249 src_addr = newTemp(Ity_I64);
12250 tab_addr = newTemp(Ity_I64);
12251 src_len = newTemp(Ity_I64);
12252 test_byte = newTemp(Ity_I8);
12253
12254 assign(src_addr, get_gpr_dw0(r1));
12255 assign(src_len, get_gpr_dw0(r1+1));
12256 assign(tab_addr, get_gpr_dw0(r2));
12257 assign(test_byte, get_gpr_b7(0));
12258
12259 IRTemp op = newTemp(Ity_I8);
12260 IRTemp op1 = newTemp(Ity_I8);
12261 IRTemp result = newTemp(Ity_I64);
12262
12263 /* End of source string? We're done; proceed to next insn */
12264 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012265 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012266
12267 /* Load character from source string and compare with test byte */
12268 assign(op, load(Ity_I8, mkexpr(src_addr)));
12269
12270 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012271 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012272
12273 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12274 mkexpr(tab_addr)));
12275
12276 assign(op1, load(Ity_I8, mkexpr(result)));
12277
12278 store(get_gpr_dw0(r1), mkexpr(op1));
12279 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12280 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12281
florian6820ba52012-07-26 02:01:50 +000012282 iterate();
florian730448f2012-02-04 17:07:07 +000012283
12284 return "tre";
12285}
12286
floriana0100c92012-07-20 00:06:35 +000012287static IRExpr *
12288s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
12289{
12290 IRExpr **args, *call;
12291 args = mkIRExprVec_2(srcval, low_surrogate);
12292 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12293 "s390_do_cu21", &s390_do_cu21, args);
12294
12295 /* Nothing is excluded from definedness checking. */
12296 call->Iex.CCall.cee->mcx_mask = 0;
12297
12298 return call;
12299}
12300
florian55085f82012-11-21 00:36:55 +000012301static const HChar *
floriana0100c92012-07-20 00:06:35 +000012302s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
12303{
12304 IRTemp addr1 = newTemp(Ity_I64);
12305 IRTemp addr2 = newTemp(Ity_I64);
12306 IRTemp len1 = newTemp(Ity_I64);
12307 IRTemp len2 = newTemp(Ity_I64);
12308
12309 assign(addr1, get_gpr_dw0(r1));
12310 assign(addr2, get_gpr_dw0(r2));
12311 assign(len1, get_gpr_dw0(r1 + 1));
12312 assign(len2, get_gpr_dw0(r2 + 1));
12313
12314 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12315 there are less than 2 bytes left, then the 2nd operand is exhausted
12316 and we're done here. cc = 0 */
12317 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012318 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000012319
12320 /* There are at least two bytes there. Read them. */
12321 IRTemp srcval = newTemp(Ity_I32);
12322 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12323
12324 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12325 inside the interval [0xd800 - 0xdbff] */
12326 IRTemp is_high_surrogate = newTemp(Ity_I32);
12327 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12328 mkU32(1), mkU32(0));
12329 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12330 mkU32(1), mkU32(0));
12331 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12332
12333 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12334 then the 2nd operand is exhausted and we're done here. cc = 0 */
12335 IRExpr *not_enough_bytes =
12336 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12337
florian6820ba52012-07-26 02:01:50 +000012338 next_insn_if(binop(Iop_CmpEQ32,
12339 binop(Iop_And32, mkexpr(is_high_surrogate),
12340 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000012341
12342 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12343 surrogate, read the next two bytes (low surrogate). */
12344 IRTemp low_surrogate = newTemp(Ity_I32);
12345 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12346
12347 assign(low_surrogate,
12348 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12349 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12350 mkU32(0))); // any value is fine; it will not be used
12351
12352 /* Call the helper */
12353 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012354 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
12355 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000012356
12357 /* Before we can test whether the 1st operand is exhausted we need to
12358 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12359 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12360 IRExpr *invalid_low_surrogate =
12361 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12362
12363 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012364 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000012365 }
12366
12367 /* Now test whether the 1st operand is exhausted */
12368 IRTemp num_bytes = newTemp(Ity_I64);
12369 assign(num_bytes, binop(Iop_And64,
12370 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12371 mkU64(0xff)));
12372 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012373 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000012374
12375 /* Extract the bytes to be stored at addr1 */
12376 IRTemp data = newTemp(Ity_I64);
12377 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12378
12379 /* To store the bytes construct 4 dirty helper calls. The helper calls
12380 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12381 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012382 UInt i;
floriana0100c92012-07-20 00:06:35 +000012383 for (i = 1; i <= 4; ++i) {
12384 IRDirty *d;
12385
12386 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12387 &s390x_dirtyhelper_CUxy,
12388 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12389 mkexpr(num_bytes)));
12390 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12391 d->mFx = Ifx_Write;
12392 d->mAddr = mkexpr(addr1);
12393 d->mSize = i;
12394 stmt(IRStmt_Dirty(d));
12395 }
12396
12397 /* Update source address and length */
12398 IRTemp num_src_bytes = newTemp(Ity_I64);
12399 assign(num_src_bytes,
12400 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12401 mkU64(4), mkU64(2)));
12402 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12403 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12404
12405 /* Update destination address and length */
12406 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12407 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12408
florian6820ba52012-07-26 02:01:50 +000012409 iterate();
floriana0100c92012-07-20 00:06:35 +000012410
12411 return "cu21";
12412}
12413
florian2a415a12012-07-21 17:41:36 +000012414static IRExpr *
12415s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
12416{
12417 IRExpr **args, *call;
12418 args = mkIRExprVec_2(srcval, low_surrogate);
12419 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12420 "s390_do_cu24", &s390_do_cu24, args);
12421
12422 /* Nothing is excluded from definedness checking. */
12423 call->Iex.CCall.cee->mcx_mask = 0;
12424
12425 return call;
12426}
12427
florian55085f82012-11-21 00:36:55 +000012428static const HChar *
florian2a415a12012-07-21 17:41:36 +000012429s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
12430{
12431 IRTemp addr1 = newTemp(Ity_I64);
12432 IRTemp addr2 = newTemp(Ity_I64);
12433 IRTemp len1 = newTemp(Ity_I64);
12434 IRTemp len2 = newTemp(Ity_I64);
12435
12436 assign(addr1, get_gpr_dw0(r1));
12437 assign(addr2, get_gpr_dw0(r2));
12438 assign(len1, get_gpr_dw0(r1 + 1));
12439 assign(len2, get_gpr_dw0(r2 + 1));
12440
12441 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12442 there are less than 2 bytes left, then the 2nd operand is exhausted
12443 and we're done here. cc = 0 */
12444 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012445 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000012446
12447 /* There are at least two bytes there. Read them. */
12448 IRTemp srcval = newTemp(Ity_I32);
12449 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12450
12451 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12452 inside the interval [0xd800 - 0xdbff] */
12453 IRTemp is_high_surrogate = newTemp(Ity_I32);
12454 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12455 mkU32(1), mkU32(0));
12456 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12457 mkU32(1), mkU32(0));
12458 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12459
12460 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12461 then the 2nd operand is exhausted and we're done here. cc = 0 */
12462 IRExpr *not_enough_bytes =
12463 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12464
florian6820ba52012-07-26 02:01:50 +000012465 next_insn_if(binop(Iop_CmpEQ32,
12466 binop(Iop_And32, mkexpr(is_high_surrogate),
12467 not_enough_bytes),
12468 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012469
12470 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12471 surrogate, read the next two bytes (low surrogate). */
12472 IRTemp low_surrogate = newTemp(Ity_I32);
12473 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12474
12475 assign(low_surrogate,
12476 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12477 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12478 mkU32(0))); // any value is fine; it will not be used
12479
12480 /* Call the helper */
12481 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012482 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12483 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012484
12485 /* Before we can test whether the 1st operand is exhausted we need to
12486 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12487 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12488 IRExpr *invalid_low_surrogate =
12489 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12490
12491 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012492 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012493 }
12494
12495 /* Now test whether the 1st operand is exhausted */
12496 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012497 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012498
12499 /* Extract the bytes to be stored at addr1 */
12500 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12501
12502 store(mkexpr(addr1), data);
12503
12504 /* Update source address and length */
12505 IRTemp num_src_bytes = newTemp(Ity_I64);
12506 assign(num_src_bytes,
12507 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12508 mkU64(4), mkU64(2)));
12509 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12510 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12511
12512 /* Update destination address and length */
12513 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12514 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12515
florian6820ba52012-07-26 02:01:50 +000012516 iterate();
florian2a415a12012-07-21 17:41:36 +000012517
12518 return "cu24";
12519}
floriana4384a32011-08-11 16:58:45 +000012520
florian956194b2012-07-28 22:18:32 +000012521static IRExpr *
12522s390_call_cu42(IRExpr *srcval)
12523{
12524 IRExpr **args, *call;
12525 args = mkIRExprVec_1(srcval);
12526 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12527 "s390_do_cu42", &s390_do_cu42, args);
12528
12529 /* Nothing is excluded from definedness checking. */
12530 call->Iex.CCall.cee->mcx_mask = 0;
12531
12532 return call;
12533}
12534
florian55085f82012-11-21 00:36:55 +000012535static const HChar *
florian956194b2012-07-28 22:18:32 +000012536s390_irgen_CU42(UChar r1, UChar r2)
12537{
12538 IRTemp addr1 = newTemp(Ity_I64);
12539 IRTemp addr2 = newTemp(Ity_I64);
12540 IRTemp len1 = newTemp(Ity_I64);
12541 IRTemp len2 = newTemp(Ity_I64);
12542
12543 assign(addr1, get_gpr_dw0(r1));
12544 assign(addr2, get_gpr_dw0(r2));
12545 assign(len1, get_gpr_dw0(r1 + 1));
12546 assign(len2, get_gpr_dw0(r2 + 1));
12547
12548 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12549 there are less than 4 bytes left, then the 2nd operand is exhausted
12550 and we're done here. cc = 0 */
12551 s390_cc_set(0);
12552 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12553
12554 /* Read the 2nd operand. */
12555 IRTemp srcval = newTemp(Ity_I32);
12556 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12557
12558 /* Call the helper */
12559 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012560 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012561
12562 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12563 cc=2 outranks cc=1 (1st operand exhausted) */
12564 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12565
12566 s390_cc_set(2);
12567 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12568
12569 /* Now test whether the 1st operand is exhausted */
12570 IRTemp num_bytes = newTemp(Ity_I64);
12571 assign(num_bytes, binop(Iop_And64,
12572 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12573 mkU64(0xff)));
12574 s390_cc_set(1);
12575 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12576
12577 /* Extract the bytes to be stored at addr1 */
12578 IRTemp data = newTemp(Ity_I64);
12579 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12580
12581 /* To store the bytes construct 2 dirty helper calls. The helper calls
12582 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12583 that only one of them will be called at runtime. */
12584
12585 Int i;
12586 for (i = 2; i <= 4; ++i) {
12587 IRDirty *d;
12588
12589 if (i == 3) continue; // skip this one
12590
12591 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12592 &s390x_dirtyhelper_CUxy,
12593 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12594 mkexpr(num_bytes)));
12595 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12596 d->mFx = Ifx_Write;
12597 d->mAddr = mkexpr(addr1);
12598 d->mSize = i;
12599 stmt(IRStmt_Dirty(d));
12600 }
12601
12602 /* Update source address and length */
12603 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12604 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12605
12606 /* Update destination address and length */
12607 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12608 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12609
12610 iterate();
12611
12612 return "cu42";
12613}
12614
florian6d9b9b22012-08-03 18:35:39 +000012615static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012616s390_call_cu41(IRExpr *srcval)
12617{
12618 IRExpr **args, *call;
12619 args = mkIRExprVec_1(srcval);
12620 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12621 "s390_do_cu41", &s390_do_cu41, args);
12622
12623 /* Nothing is excluded from definedness checking. */
12624 call->Iex.CCall.cee->mcx_mask = 0;
12625
12626 return call;
12627}
12628
florian55085f82012-11-21 00:36:55 +000012629static const HChar *
florianaf2194f2012-08-06 00:07:54 +000012630s390_irgen_CU41(UChar r1, UChar r2)
12631{
12632 IRTemp addr1 = newTemp(Ity_I64);
12633 IRTemp addr2 = newTemp(Ity_I64);
12634 IRTemp len1 = newTemp(Ity_I64);
12635 IRTemp len2 = newTemp(Ity_I64);
12636
12637 assign(addr1, get_gpr_dw0(r1));
12638 assign(addr2, get_gpr_dw0(r2));
12639 assign(len1, get_gpr_dw0(r1 + 1));
12640 assign(len2, get_gpr_dw0(r2 + 1));
12641
12642 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12643 there are less than 4 bytes left, then the 2nd operand is exhausted
12644 and we're done here. cc = 0 */
12645 s390_cc_set(0);
12646 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12647
12648 /* Read the 2nd operand. */
12649 IRTemp srcval = newTemp(Ity_I32);
12650 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12651
12652 /* Call the helper */
12653 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012654 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012655
12656 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12657 cc=2 outranks cc=1 (1st operand exhausted) */
12658 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12659
12660 s390_cc_set(2);
12661 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12662
12663 /* Now test whether the 1st operand is exhausted */
12664 IRTemp num_bytes = newTemp(Ity_I64);
12665 assign(num_bytes, binop(Iop_And64,
12666 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12667 mkU64(0xff)));
12668 s390_cc_set(1);
12669 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12670
12671 /* Extract the bytes to be stored at addr1 */
12672 IRTemp data = newTemp(Ity_I64);
12673 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12674
12675 /* To store the bytes construct 4 dirty helper calls. The helper calls
12676 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12677 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012678 UInt i;
florianaf2194f2012-08-06 00:07:54 +000012679 for (i = 1; i <= 4; ++i) {
12680 IRDirty *d;
12681
12682 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12683 &s390x_dirtyhelper_CUxy,
12684 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12685 mkexpr(num_bytes)));
12686 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12687 d->mFx = Ifx_Write;
12688 d->mAddr = mkexpr(addr1);
12689 d->mSize = i;
12690 stmt(IRStmt_Dirty(d));
12691 }
12692
12693 /* Update source address and length */
12694 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12695 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12696
12697 /* Update destination address and length */
12698 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12699 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12700
12701 iterate();
12702
12703 return "cu41";
12704}
12705
12706static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012707s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012708{
12709 IRExpr **args, *call;
12710 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012711 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12712 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012713
12714 /* Nothing is excluded from definedness checking. */
12715 call->Iex.CCall.cee->mcx_mask = 0;
12716
12717 return call;
12718}
12719
12720static IRExpr *
12721s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12722 IRExpr *byte4, IRExpr *stuff)
12723{
12724 IRExpr **args, *call;
12725 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12726 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12727 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12728
12729 /* Nothing is excluded from definedness checking. */
12730 call->Iex.CCall.cee->mcx_mask = 0;
12731
12732 return call;
12733}
12734
florian3f8a96a2012-08-05 02:59:55 +000012735static IRExpr *
12736s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12737 IRExpr *byte4, IRExpr *stuff)
12738{
12739 IRExpr **args, *call;
12740 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12741 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12742 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12743
12744 /* Nothing is excluded from definedness checking. */
12745 call->Iex.CCall.cee->mcx_mask = 0;
12746
12747 return call;
12748}
12749
12750static void
12751s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012752{
12753 IRTemp addr1 = newTemp(Ity_I64);
12754 IRTemp addr2 = newTemp(Ity_I64);
12755 IRTemp len1 = newTemp(Ity_I64);
12756 IRTemp len2 = newTemp(Ity_I64);
12757
12758 assign(addr1, get_gpr_dw0(r1));
12759 assign(addr2, get_gpr_dw0(r2));
12760 assign(len1, get_gpr_dw0(r1 + 1));
12761 assign(len2, get_gpr_dw0(r2 + 1));
12762
12763 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12764
12765 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12766 there is less than 1 byte left, then the 2nd operand is exhausted
12767 and we're done here. cc = 0 */
12768 s390_cc_set(0);
12769 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12770
12771 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012772 IRTemp byte1 = newTemp(Ity_I64);
12773 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012774
12775 /* Call the helper to get number of bytes and invalid byte indicator */
12776 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012777 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012778 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012779
12780 /* Check for invalid 1st byte */
12781 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12782 s390_cc_set(2);
12783 next_insn_if(is_invalid);
12784
12785 /* How many bytes do we have to read? */
12786 IRTemp num_src_bytes = newTemp(Ity_I64);
12787 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12788
12789 /* Now test whether the 2nd operand is exhausted */
12790 s390_cc_set(0);
12791 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12792
12793 /* Read the remaining bytes */
12794 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12795
12796 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12797 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012798 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012799 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12800 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012801 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012802 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12803 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012804 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012805
12806 /* Call the helper to get the converted value and invalid byte indicator.
12807 We can pass at most 5 arguments; therefore some encoding is needed
12808 here */
12809 IRExpr *stuff = binop(Iop_Or64,
12810 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12811 mkU64(extended_checking));
12812 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012813
12814 if (is_cu12) {
12815 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12816 byte4, stuff));
12817 } else {
12818 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12819 byte4, stuff));
12820 }
florian6d9b9b22012-08-03 18:35:39 +000012821
12822 /* Check for invalid character */
12823 s390_cc_set(2);
12824 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12825 next_insn_if(is_invalid);
12826
12827 /* Now test whether the 1st operand is exhausted */
12828 IRTemp num_bytes = newTemp(Ity_I64);
12829 assign(num_bytes, binop(Iop_And64,
12830 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12831 mkU64(0xff)));
12832 s390_cc_set(1);
12833 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12834
12835 /* Extract the bytes to be stored at addr1 */
12836 IRTemp data = newTemp(Ity_I64);
12837 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12838
florian3f8a96a2012-08-05 02:59:55 +000012839 if (is_cu12) {
12840 /* To store the bytes construct 2 dirty helper calls. The helper calls
12841 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12842 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012843
florian3f8a96a2012-08-05 02:59:55 +000012844 Int i;
12845 for (i = 2; i <= 4; ++i) {
12846 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012847
florian3f8a96a2012-08-05 02:59:55 +000012848 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012849
florian3f8a96a2012-08-05 02:59:55 +000012850 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12851 &s390x_dirtyhelper_CUxy,
12852 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12853 mkexpr(num_bytes)));
12854 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12855 d->mFx = Ifx_Write;
12856 d->mAddr = mkexpr(addr1);
12857 d->mSize = i;
12858 stmt(IRStmt_Dirty(d));
12859 }
12860 } else {
12861 // cu14
12862 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012863 }
12864
12865 /* Update source address and length */
12866 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12867 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12868
12869 /* Update destination address and length */
12870 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12871 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12872
12873 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012874}
12875
florian55085f82012-11-21 00:36:55 +000012876static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012877s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12878{
12879 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012880
12881 return "cu12";
12882}
12883
florian55085f82012-11-21 00:36:55 +000012884static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012885s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12886{
12887 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12888
12889 return "cu14";
12890}
12891
florian8c88cb62012-08-26 18:58:13 +000012892static IRExpr *
12893s390_call_ecag(IRExpr *op2addr)
12894{
12895 IRExpr **args, *call;
12896
12897 args = mkIRExprVec_1(op2addr);
12898 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12899 "s390_do_ecag", &s390_do_ecag, args);
12900
12901 /* Nothing is excluded from definedness checking. */
12902 call->Iex.CCall.cee->mcx_mask = 0;
12903
12904 return call;
12905}
12906
florian55085f82012-11-21 00:36:55 +000012907static const HChar *
floriand2129202012-09-01 20:01:39 +000012908s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012909{
12910 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012911 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012912 } else {
12913 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12914 }
12915
12916 return "ecag";
12917}
12918
12919
florianb7def222012-12-04 04:45:32 +000012920/* New insns are added here.
12921 If an insn is contingent on a facility being installed also
12922 check whether the list of supported facilities in function
12923 s390x_dirtyhelper_STFLE needs updating */
12924
sewardj2019a972011-03-07 16:04:07 +000012925/*------------------------------------------------------------*/
12926/*--- Build IR for special instructions ---*/
12927/*------------------------------------------------------------*/
12928
florianb4df7682011-07-05 02:09:01 +000012929static void
sewardj2019a972011-03-07 16:04:07 +000012930s390_irgen_client_request(void)
12931{
12932 if (0)
12933 vex_printf("%%R3 = client_request ( %%R2 )\n");
12934
florianf9e1ed72012-04-17 02:41:56 +000012935 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12936 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012937
florianf9e1ed72012-04-17 02:41:56 +000012938 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012939 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012940
12941 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012942}
12943
florianb4df7682011-07-05 02:09:01 +000012944static void
sewardj2019a972011-03-07 16:04:07 +000012945s390_irgen_guest_NRADDR(void)
12946{
12947 if (0)
12948 vex_printf("%%R3 = guest_NRADDR\n");
12949
floriane88b3c92011-07-05 02:48:39 +000012950 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012951}
12952
florianb4df7682011-07-05 02:09:01 +000012953static void
sewardj2019a972011-03-07 16:04:07 +000012954s390_irgen_call_noredir(void)
12955{
florianf9e1ed72012-04-17 02:41:56 +000012956 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12957 + S390_SPECIAL_OP_SIZE;
12958
sewardj2019a972011-03-07 16:04:07 +000012959 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012960 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012961
12962 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012963 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012964
12965 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012966 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012967}
12968
12969/* Force proper alignment for the structures below. */
12970#pragma pack(1)
12971
12972
12973static s390_decode_t
12974s390_decode_2byte_and_irgen(UChar *bytes)
12975{
12976 typedef union {
12977 struct {
12978 unsigned int op : 16;
12979 } E;
12980 struct {
12981 unsigned int op : 8;
12982 unsigned int i : 8;
12983 } I;
12984 struct {
12985 unsigned int op : 8;
12986 unsigned int r1 : 4;
12987 unsigned int r2 : 4;
12988 } RR;
12989 } formats;
12990 union {
12991 formats fmt;
12992 UShort value;
12993 } ovl;
12994
12995 vassert(sizeof(formats) == 2);
12996
florianffbd84d2012-12-09 02:06:29 +000012997 ((UChar *)(&ovl.value))[0] = bytes[0];
12998 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000012999
13000 switch (ovl.value & 0xffff) {
13001 case 0x0101: /* PR */ goto unimplemented;
13002 case 0x0102: /* UPT */ goto unimplemented;
13003 case 0x0104: /* PTFF */ goto unimplemented;
13004 case 0x0107: /* SCKPF */ goto unimplemented;
13005 case 0x010a: /* PFPO */ goto unimplemented;
13006 case 0x010b: /* TAM */ goto unimplemented;
13007 case 0x010c: /* SAM24 */ goto unimplemented;
13008 case 0x010d: /* SAM31 */ goto unimplemented;
13009 case 0x010e: /* SAM64 */ goto unimplemented;
13010 case 0x01ff: /* TRAP2 */ goto unimplemented;
13011 }
13012
13013 switch ((ovl.value & 0xff00) >> 8) {
13014 case 0x04: /* SPM */ goto unimplemented;
13015 case 0x05: /* BALR */ goto unimplemented;
13016 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13017 goto ok;
13018 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13019 goto ok;
13020 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13021 case 0x0b: /* BSM */ goto unimplemented;
13022 case 0x0c: /* BASSM */ goto unimplemented;
13023 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13024 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013025 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13026 goto ok;
13027 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13028 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013029 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13030 goto ok;
13031 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13032 goto ok;
13033 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13034 goto ok;
13035 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13036 goto ok;
13037 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13038 goto ok;
13039 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13040 goto ok;
13041 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13042 goto ok;
13043 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13044 goto ok;
13045 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13046 goto ok;
13047 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13048 goto ok;
13049 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13050 goto ok;
13051 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13052 goto ok;
13053 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13054 goto ok;
13055 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13056 goto ok;
13057 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13058 goto ok;
13059 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13060 goto ok;
13061 case 0x20: /* LPDR */ goto unimplemented;
13062 case 0x21: /* LNDR */ goto unimplemented;
13063 case 0x22: /* LTDR */ goto unimplemented;
13064 case 0x23: /* LCDR */ goto unimplemented;
13065 case 0x24: /* HDR */ goto unimplemented;
13066 case 0x25: /* LDXR */ goto unimplemented;
13067 case 0x26: /* MXR */ goto unimplemented;
13068 case 0x27: /* MXDR */ goto unimplemented;
13069 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13070 goto ok;
13071 case 0x29: /* CDR */ goto unimplemented;
13072 case 0x2a: /* ADR */ goto unimplemented;
13073 case 0x2b: /* SDR */ goto unimplemented;
13074 case 0x2c: /* MDR */ goto unimplemented;
13075 case 0x2d: /* DDR */ goto unimplemented;
13076 case 0x2e: /* AWR */ goto unimplemented;
13077 case 0x2f: /* SWR */ goto unimplemented;
13078 case 0x30: /* LPER */ goto unimplemented;
13079 case 0x31: /* LNER */ goto unimplemented;
13080 case 0x32: /* LTER */ goto unimplemented;
13081 case 0x33: /* LCER */ goto unimplemented;
13082 case 0x34: /* HER */ goto unimplemented;
13083 case 0x35: /* LEDR */ goto unimplemented;
13084 case 0x36: /* AXR */ goto unimplemented;
13085 case 0x37: /* SXR */ goto unimplemented;
13086 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13087 goto ok;
13088 case 0x39: /* CER */ goto unimplemented;
13089 case 0x3a: /* AER */ goto unimplemented;
13090 case 0x3b: /* SER */ goto unimplemented;
13091 case 0x3c: /* MDER */ goto unimplemented;
13092 case 0x3d: /* DER */ goto unimplemented;
13093 case 0x3e: /* AUR */ goto unimplemented;
13094 case 0x3f: /* SUR */ goto unimplemented;
13095 }
13096
13097 return S390_DECODE_UNKNOWN_INSN;
13098
13099ok:
13100 return S390_DECODE_OK;
13101
13102unimplemented:
13103 return S390_DECODE_UNIMPLEMENTED_INSN;
13104}
13105
13106static s390_decode_t
13107s390_decode_4byte_and_irgen(UChar *bytes)
13108{
13109 typedef union {
13110 struct {
13111 unsigned int op1 : 8;
13112 unsigned int r1 : 4;
13113 unsigned int op2 : 4;
13114 unsigned int i2 : 16;
13115 } RI;
13116 struct {
13117 unsigned int op : 16;
13118 unsigned int : 8;
13119 unsigned int r1 : 4;
13120 unsigned int r2 : 4;
13121 } RRE;
13122 struct {
13123 unsigned int op : 16;
13124 unsigned int r1 : 4;
13125 unsigned int : 4;
13126 unsigned int r3 : 4;
13127 unsigned int r2 : 4;
13128 } RRF;
13129 struct {
13130 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000013131 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000013132 unsigned int m4 : 4;
13133 unsigned int r1 : 4;
13134 unsigned int r2 : 4;
13135 } RRF2;
13136 struct {
13137 unsigned int op : 16;
13138 unsigned int r3 : 4;
13139 unsigned int : 4;
13140 unsigned int r1 : 4;
13141 unsigned int r2 : 4;
13142 } RRF3;
13143 struct {
13144 unsigned int op : 16;
13145 unsigned int r3 : 4;
13146 unsigned int : 4;
13147 unsigned int r1 : 4;
13148 unsigned int r2 : 4;
13149 } RRR;
13150 struct {
13151 unsigned int op : 16;
13152 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013153 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013154 unsigned int r1 : 4;
13155 unsigned int r2 : 4;
13156 } RRF4;
13157 struct {
floriane38f6412012-12-21 17:32:12 +000013158 unsigned int op : 16;
13159 unsigned int : 4;
13160 unsigned int m4 : 4;
13161 unsigned int r1 : 4;
13162 unsigned int r2 : 4;
13163 } RRF5;
13164 struct {
sewardj2019a972011-03-07 16:04:07 +000013165 unsigned int op : 8;
13166 unsigned int r1 : 4;
13167 unsigned int r3 : 4;
13168 unsigned int b2 : 4;
13169 unsigned int d2 : 12;
13170 } RS;
13171 struct {
13172 unsigned int op : 8;
13173 unsigned int r1 : 4;
13174 unsigned int r3 : 4;
13175 unsigned int i2 : 16;
13176 } RSI;
13177 struct {
13178 unsigned int op : 8;
13179 unsigned int r1 : 4;
13180 unsigned int x2 : 4;
13181 unsigned int b2 : 4;
13182 unsigned int d2 : 12;
13183 } RX;
13184 struct {
13185 unsigned int op : 16;
13186 unsigned int b2 : 4;
13187 unsigned int d2 : 12;
13188 } S;
13189 struct {
13190 unsigned int op : 8;
13191 unsigned int i2 : 8;
13192 unsigned int b1 : 4;
13193 unsigned int d1 : 12;
13194 } SI;
13195 } formats;
13196 union {
13197 formats fmt;
13198 UInt value;
13199 } ovl;
13200
13201 vassert(sizeof(formats) == 4);
13202
florianffbd84d2012-12-09 02:06:29 +000013203 ((UChar *)(&ovl.value))[0] = bytes[0];
13204 ((UChar *)(&ovl.value))[1] = bytes[1];
13205 ((UChar *)(&ovl.value))[2] = bytes[2];
13206 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013207
13208 switch ((ovl.value & 0xff0f0000) >> 16) {
13209 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13210 ovl.fmt.RI.i2); goto ok;
13211 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13212 ovl.fmt.RI.i2); goto ok;
13213 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
13214 ovl.fmt.RI.i2); goto ok;
13215 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
13216 ovl.fmt.RI.i2); goto ok;
13217 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
13218 ovl.fmt.RI.i2); goto ok;
13219 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
13220 ovl.fmt.RI.i2); goto ok;
13221 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
13222 ovl.fmt.RI.i2); goto ok;
13223 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
13224 ovl.fmt.RI.i2); goto ok;
13225 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
13226 ovl.fmt.RI.i2); goto ok;
13227 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
13228 ovl.fmt.RI.i2); goto ok;
13229 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
13230 ovl.fmt.RI.i2); goto ok;
13231 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
13232 ovl.fmt.RI.i2); goto ok;
13233 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
13234 ovl.fmt.RI.i2); goto ok;
13235 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
13236 ovl.fmt.RI.i2); goto ok;
13237 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
13238 ovl.fmt.RI.i2); goto ok;
13239 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
13240 ovl.fmt.RI.i2); goto ok;
13241 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
13242 ovl.fmt.RI.i2); goto ok;
13243 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
13244 ovl.fmt.RI.i2); goto ok;
13245 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
13246 ovl.fmt.RI.i2); goto ok;
13247 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
13248 ovl.fmt.RI.i2); goto ok;
13249 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13250 goto ok;
13251 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
13252 ovl.fmt.RI.i2); goto ok;
13253 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
13254 ovl.fmt.RI.i2); goto ok;
13255 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
13256 ovl.fmt.RI.i2); goto ok;
13257 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13258 goto ok;
13259 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
13260 ovl.fmt.RI.i2); goto ok;
13261 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13262 goto ok;
13263 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
13264 ovl.fmt.RI.i2); goto ok;
13265 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13266 goto ok;
13267 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
13268 ovl.fmt.RI.i2); goto ok;
13269 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13270 goto ok;
13271 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
13272 ovl.fmt.RI.i2); goto ok;
13273 }
13274
13275 switch ((ovl.value & 0xffff0000) >> 16) {
13276 case 0x8000: /* SSM */ goto unimplemented;
13277 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013278 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013279 case 0xb202: /* STIDP */ goto unimplemented;
13280 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013281 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
13282 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013283 case 0xb206: /* SCKC */ goto unimplemented;
13284 case 0xb207: /* STCKC */ goto unimplemented;
13285 case 0xb208: /* SPT */ goto unimplemented;
13286 case 0xb209: /* STPT */ goto unimplemented;
13287 case 0xb20a: /* SPKA */ goto unimplemented;
13288 case 0xb20b: /* IPK */ goto unimplemented;
13289 case 0xb20d: /* PTLB */ goto unimplemented;
13290 case 0xb210: /* SPX */ goto unimplemented;
13291 case 0xb211: /* STPX */ goto unimplemented;
13292 case 0xb212: /* STAP */ goto unimplemented;
13293 case 0xb214: /* SIE */ goto unimplemented;
13294 case 0xb218: /* PC */ goto unimplemented;
13295 case 0xb219: /* SAC */ goto unimplemented;
13296 case 0xb21a: /* CFC */ goto unimplemented;
13297 case 0xb221: /* IPTE */ goto unimplemented;
13298 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
13299 case 0xb223: /* IVSK */ goto unimplemented;
13300 case 0xb224: /* IAC */ goto unimplemented;
13301 case 0xb225: /* SSAR */ goto unimplemented;
13302 case 0xb226: /* EPAR */ goto unimplemented;
13303 case 0xb227: /* ESAR */ goto unimplemented;
13304 case 0xb228: /* PT */ goto unimplemented;
13305 case 0xb229: /* ISKE */ goto unimplemented;
13306 case 0xb22a: /* RRBE */ goto unimplemented;
13307 case 0xb22b: /* SSKE */ goto unimplemented;
13308 case 0xb22c: /* TB */ goto unimplemented;
13309 case 0xb22d: /* DXR */ goto unimplemented;
13310 case 0xb22e: /* PGIN */ goto unimplemented;
13311 case 0xb22f: /* PGOUT */ goto unimplemented;
13312 case 0xb230: /* CSCH */ goto unimplemented;
13313 case 0xb231: /* HSCH */ goto unimplemented;
13314 case 0xb232: /* MSCH */ goto unimplemented;
13315 case 0xb233: /* SSCH */ goto unimplemented;
13316 case 0xb234: /* STSCH */ goto unimplemented;
13317 case 0xb235: /* TSCH */ goto unimplemented;
13318 case 0xb236: /* TPI */ goto unimplemented;
13319 case 0xb237: /* SAL */ goto unimplemented;
13320 case 0xb238: /* RSCH */ goto unimplemented;
13321 case 0xb239: /* STCRW */ goto unimplemented;
13322 case 0xb23a: /* STCPS */ goto unimplemented;
13323 case 0xb23b: /* RCHP */ goto unimplemented;
13324 case 0xb23c: /* SCHM */ goto unimplemented;
13325 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000013326 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
13327 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013328 case 0xb244: /* SQDR */ goto unimplemented;
13329 case 0xb245: /* SQER */ goto unimplemented;
13330 case 0xb246: /* STURA */ goto unimplemented;
13331 case 0xb247: /* MSTA */ goto unimplemented;
13332 case 0xb248: /* PALB */ goto unimplemented;
13333 case 0xb249: /* EREG */ goto unimplemented;
13334 case 0xb24a: /* ESTA */ goto unimplemented;
13335 case 0xb24b: /* LURA */ goto unimplemented;
13336 case 0xb24c: /* TAR */ goto unimplemented;
13337 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
13338 ovl.fmt.RRE.r2); goto ok;
13339 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13340 goto ok;
13341 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13342 goto ok;
13343 case 0xb250: /* CSP */ goto unimplemented;
13344 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
13345 ovl.fmt.RRE.r2); goto ok;
13346 case 0xb254: /* MVPG */ goto unimplemented;
13347 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
13348 ovl.fmt.RRE.r2); goto ok;
13349 case 0xb257: /* CUSE */ goto unimplemented;
13350 case 0xb258: /* BSG */ goto unimplemented;
13351 case 0xb25a: /* BSA */ goto unimplemented;
13352 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
13353 ovl.fmt.RRE.r2); goto ok;
13354 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
13355 ovl.fmt.RRE.r2); goto ok;
13356 case 0xb263: /* CMPSC */ goto unimplemented;
13357 case 0xb274: /* SIGA */ goto unimplemented;
13358 case 0xb276: /* XSCH */ goto unimplemented;
13359 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013360 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 +000013361 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013362 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 +000013363 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013364 case 0xb280: /* LPP */ goto unimplemented;
13365 case 0xb284: /* LCCTL */ goto unimplemented;
13366 case 0xb285: /* LPCTL */ goto unimplemented;
13367 case 0xb286: /* QSI */ goto unimplemented;
13368 case 0xb287: /* LSCTL */ goto unimplemented;
13369 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013370 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
13371 goto ok;
13372 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13373 goto ok;
13374 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13375 goto ok;
florian730448f2012-02-04 17:07:07 +000013376 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 +000013377 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
13378 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13379 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000013380 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
13381 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13382 goto ok;
florian933065d2011-07-11 01:48:02 +000013383 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
13384 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013385 case 0xb2b1: /* STFL */ goto unimplemented;
13386 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000013387 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
13388 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013389 case 0xb2b9: /* SRNMT */ goto unimplemented;
13390 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013391 case 0xb2e0: /* SCCTR */ goto unimplemented;
13392 case 0xb2e1: /* SPCTR */ goto unimplemented;
13393 case 0xb2e4: /* ECCTR */ goto unimplemented;
13394 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013395 case 0xb2e8: /* PPA */ goto unimplemented;
13396 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013397 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013398 case 0xb2f8: /* TEND */ goto unimplemented;
13399 case 0xb2fa: /* NIAI */ goto unimplemented;
13400 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013401 case 0xb2ff: /* TRAP4 */ goto unimplemented;
13402 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
13403 ovl.fmt.RRE.r2); goto ok;
13404 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
13405 ovl.fmt.RRE.r2); goto ok;
13406 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
13407 ovl.fmt.RRE.r2); goto ok;
13408 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
13409 ovl.fmt.RRE.r2); goto ok;
13410 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
13411 ovl.fmt.RRE.r2); goto ok;
13412 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
13413 ovl.fmt.RRE.r2); goto ok;
13414 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
13415 ovl.fmt.RRE.r2); goto ok;
13416 case 0xb307: /* MXDBR */ goto unimplemented;
13417 case 0xb308: /* KEBR */ goto unimplemented;
13418 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
13419 ovl.fmt.RRE.r2); goto ok;
13420 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
13421 ovl.fmt.RRE.r2); goto ok;
13422 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
13423 ovl.fmt.RRE.r2); goto ok;
13424 case 0xb30c: /* MDEBR */ goto unimplemented;
13425 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
13426 ovl.fmt.RRE.r2); goto ok;
13427 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
13428 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13429 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
13430 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13431 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
13432 ovl.fmt.RRE.r2); goto ok;
13433 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
13434 ovl.fmt.RRE.r2); goto ok;
13435 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
13436 ovl.fmt.RRE.r2); goto ok;
13437 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
13438 ovl.fmt.RRE.r2); goto ok;
13439 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
13440 ovl.fmt.RRE.r2); goto ok;
13441 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
13442 ovl.fmt.RRE.r2); goto ok;
13443 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
13444 ovl.fmt.RRE.r2); goto ok;
13445 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
13446 ovl.fmt.RRE.r2); goto ok;
13447 case 0xb318: /* KDBR */ goto unimplemented;
13448 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
13449 ovl.fmt.RRE.r2); goto ok;
13450 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
13451 ovl.fmt.RRE.r2); goto ok;
13452 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
13453 ovl.fmt.RRE.r2); goto ok;
13454 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
13455 ovl.fmt.RRE.r2); goto ok;
13456 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
13457 ovl.fmt.RRE.r2); goto ok;
13458 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
13459 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13460 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
13461 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13462 case 0xb324: /* LDER */ goto unimplemented;
13463 case 0xb325: /* LXDR */ goto unimplemented;
13464 case 0xb326: /* LXER */ goto unimplemented;
13465 case 0xb32e: /* MAER */ goto unimplemented;
13466 case 0xb32f: /* MSER */ goto unimplemented;
13467 case 0xb336: /* SQXR */ goto unimplemented;
13468 case 0xb337: /* MEER */ goto unimplemented;
13469 case 0xb338: /* MAYLR */ goto unimplemented;
13470 case 0xb339: /* MYLR */ goto unimplemented;
13471 case 0xb33a: /* MAYR */ goto unimplemented;
13472 case 0xb33b: /* MYR */ goto unimplemented;
13473 case 0xb33c: /* MAYHR */ goto unimplemented;
13474 case 0xb33d: /* MYHR */ goto unimplemented;
13475 case 0xb33e: /* MADR */ goto unimplemented;
13476 case 0xb33f: /* MSDR */ goto unimplemented;
13477 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
13478 ovl.fmt.RRE.r2); goto ok;
13479 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
13480 ovl.fmt.RRE.r2); goto ok;
13481 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
13482 ovl.fmt.RRE.r2); goto ok;
13483 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
13484 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013485 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13486 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13487 ovl.fmt.RRF2.r2); goto ok;
13488 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13489 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13490 ovl.fmt.RRF2.r2); goto ok;
13491 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13492 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13493 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013494 case 0xb347: /* FIXBR */ goto unimplemented;
13495 case 0xb348: /* KXBR */ goto unimplemented;
13496 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13497 ovl.fmt.RRE.r2); goto ok;
13498 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13499 ovl.fmt.RRE.r2); goto ok;
13500 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13501 ovl.fmt.RRE.r2); goto ok;
13502 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13503 ovl.fmt.RRE.r2); goto ok;
13504 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13505 ovl.fmt.RRE.r2); goto ok;
13506 case 0xb350: /* TBEDR */ goto unimplemented;
13507 case 0xb351: /* TBDR */ goto unimplemented;
13508 case 0xb353: /* DIEBR */ goto unimplemented;
13509 case 0xb357: /* FIEBR */ goto unimplemented;
13510 case 0xb358: /* THDER */ goto unimplemented;
13511 case 0xb359: /* THDR */ goto unimplemented;
13512 case 0xb35b: /* DIDBR */ goto unimplemented;
13513 case 0xb35f: /* FIDBR */ goto unimplemented;
13514 case 0xb360: /* LPXR */ goto unimplemented;
13515 case 0xb361: /* LNXR */ goto unimplemented;
13516 case 0xb362: /* LTXR */ goto unimplemented;
13517 case 0xb363: /* LCXR */ goto unimplemented;
13518 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13519 ovl.fmt.RRE.r2); goto ok;
13520 case 0xb366: /* LEXR */ goto unimplemented;
13521 case 0xb367: /* FIXR */ goto unimplemented;
13522 case 0xb369: /* CXR */ goto unimplemented;
13523 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13524 ovl.fmt.RRE.r2); goto ok;
13525 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13526 ovl.fmt.RRE.r2); goto ok;
13527 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13528 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13529 goto ok;
13530 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13531 ovl.fmt.RRE.r2); goto ok;
13532 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13533 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13534 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13535 case 0xb377: /* FIER */ goto unimplemented;
13536 case 0xb37f: /* FIDR */ goto unimplemented;
13537 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13538 case 0xb385: /* SFASR */ goto unimplemented;
13539 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013540 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13541 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13542 ovl.fmt.RRF2.r2); goto ok;
13543 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13544 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13545 ovl.fmt.RRF2.r2); goto ok;
13546 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13547 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13548 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013549 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13550 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13551 ovl.fmt.RRF2.r2); goto ok;
13552 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13553 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13554 ovl.fmt.RRF2.r2); goto ok;
13555 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13556 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13557 ovl.fmt.RRF2.r2); goto ok;
13558 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13559 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13560 ovl.fmt.RRF2.r2); goto ok;
13561 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13562 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13563 ovl.fmt.RRF2.r2); goto ok;
13564 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13565 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13566 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013567 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13568 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13569 ovl.fmt.RRF2.r2); goto ok;
13570 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13571 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13572 ovl.fmt.RRF2.r2); goto ok;
13573 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13574 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13575 ovl.fmt.RRF2.r2); goto ok;
13576 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13577 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13578 ovl.fmt.RRF2.r2); goto ok;
13579 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13580 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13581 ovl.fmt.RRF2.r2); goto ok;
13582 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13583 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13584 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013585 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13586 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13587 ovl.fmt.RRF2.r2); goto ok;
13588 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13589 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13590 ovl.fmt.RRF2.r2); goto ok;
13591 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13592 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13593 ovl.fmt.RRF2.r2); goto ok;
13594 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13595 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13596 ovl.fmt.RRF2.r2); goto ok;
13597 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13598 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13599 ovl.fmt.RRF2.r2); goto ok;
13600 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13601 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13602 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013603 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13604 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13605 ovl.fmt.RRF2.r2); goto ok;
13606 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13607 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13608 ovl.fmt.RRF2.r2); goto ok;
13609 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13610 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13611 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013612 case 0xb3b4: /* CEFR */ goto unimplemented;
13613 case 0xb3b5: /* CDFR */ goto unimplemented;
13614 case 0xb3b6: /* CXFR */ goto unimplemented;
13615 case 0xb3b8: /* CFER */ goto unimplemented;
13616 case 0xb3b9: /* CFDR */ goto unimplemented;
13617 case 0xb3ba: /* CFXR */ goto unimplemented;
13618 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13619 ovl.fmt.RRE.r2); goto ok;
13620 case 0xb3c4: /* CEGR */ goto unimplemented;
13621 case 0xb3c5: /* CDGR */ goto unimplemented;
13622 case 0xb3c6: /* CXGR */ goto unimplemented;
13623 case 0xb3c8: /* CGER */ goto unimplemented;
13624 case 0xb3c9: /* CGDR */ goto unimplemented;
13625 case 0xb3ca: /* CGXR */ goto unimplemented;
13626 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13627 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013628 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13629 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13630 ovl.fmt.RRF4.r2); goto ok;
13631 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13632 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13633 ovl.fmt.RRF4.r2); goto ok;
13634 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13635 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13636 ovl.fmt.RRF4.r2); goto ok;
13637 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13638 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13639 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000013640 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
13641 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13642 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
13643 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13644 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013645 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13646 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013647 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013648 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
13649 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13650 ovl.fmt.RRF4.r2); goto ok;
13651 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
13652 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13653 ovl.fmt.RRF4.r2); goto ok;
13654 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
13655 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13656 ovl.fmt.RRF4.r2); goto ok;
13657 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
13658 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13659 ovl.fmt.RRF4.r2); goto ok;
13660 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
13661 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13662 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
13663 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13664 ovl.fmt.RRF2.r2); goto ok;
13665 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
13666 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013667 case 0xb3df: /* FIXTR */ goto unimplemented;
13668 case 0xb3e0: /* KDTR */ goto unimplemented;
13669 case 0xb3e1: /* CGDTR */ goto unimplemented;
13670 case 0xb3e2: /* CUDTR */ goto unimplemented;
13671 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013672 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
13673 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013674 case 0xb3e5: /* EEDTR */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000013675 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
13676 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013677 case 0xb3e8: /* KXTR */ goto unimplemented;
13678 case 0xb3e9: /* CGXTR */ goto unimplemented;
13679 case 0xb3ea: /* CUXTR */ goto unimplemented;
13680 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013681 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
13682 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013683 case 0xb3ed: /* EEXTR */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000013684 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
13685 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013686 case 0xb3f1: /* CDGTR */ goto unimplemented;
13687 case 0xb3f2: /* CDUTR */ goto unimplemented;
13688 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000013689 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
13690 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013691 case 0xb3f5: /* QADTR */ goto unimplemented;
13692 case 0xb3f6: /* IEDTR */ goto unimplemented;
13693 case 0xb3f7: /* RRDTR */ goto unimplemented;
13694 case 0xb3f9: /* CXGTR */ goto unimplemented;
13695 case 0xb3fa: /* CXUTR */ goto unimplemented;
13696 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000013697 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
13698 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013699 case 0xb3fd: /* QAXTR */ goto unimplemented;
13700 case 0xb3fe: /* IEXTR */ goto unimplemented;
13701 case 0xb3ff: /* RRXTR */ goto unimplemented;
13702 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13703 ovl.fmt.RRE.r2); goto ok;
13704 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13705 ovl.fmt.RRE.r2); goto ok;
13706 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13707 ovl.fmt.RRE.r2); goto ok;
13708 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13709 ovl.fmt.RRE.r2); goto ok;
13710 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13711 ovl.fmt.RRE.r2); goto ok;
13712 case 0xb905: /* LURAG */ goto unimplemented;
13713 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13714 ovl.fmt.RRE.r2); goto ok;
13715 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13716 ovl.fmt.RRE.r2); goto ok;
13717 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13718 ovl.fmt.RRE.r2); goto ok;
13719 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13720 ovl.fmt.RRE.r2); goto ok;
13721 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13722 ovl.fmt.RRE.r2); goto ok;
13723 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13724 ovl.fmt.RRE.r2); goto ok;
13725 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13726 ovl.fmt.RRE.r2); goto ok;
13727 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13728 ovl.fmt.RRE.r2); goto ok;
13729 case 0xb90e: /* EREGG */ goto unimplemented;
13730 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13731 ovl.fmt.RRE.r2); goto ok;
13732 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13733 ovl.fmt.RRE.r2); goto ok;
13734 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13735 ovl.fmt.RRE.r2); goto ok;
13736 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13737 ovl.fmt.RRE.r2); goto ok;
13738 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13739 ovl.fmt.RRE.r2); goto ok;
13740 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13741 ovl.fmt.RRE.r2); goto ok;
13742 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13743 ovl.fmt.RRE.r2); goto ok;
13744 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13745 ovl.fmt.RRE.r2); goto ok;
13746 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13747 ovl.fmt.RRE.r2); goto ok;
13748 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13749 ovl.fmt.RRE.r2); goto ok;
13750 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13751 ovl.fmt.RRE.r2); goto ok;
13752 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13753 ovl.fmt.RRE.r2); goto ok;
13754 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13755 ovl.fmt.RRE.r2); goto ok;
13756 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13757 ovl.fmt.RRE.r2); goto ok;
13758 case 0xb91e: /* KMAC */ goto unimplemented;
13759 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13760 ovl.fmt.RRE.r2); goto ok;
13761 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13762 ovl.fmt.RRE.r2); goto ok;
13763 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13764 ovl.fmt.RRE.r2); goto ok;
13765 case 0xb925: /* STURG */ goto unimplemented;
13766 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13767 ovl.fmt.RRE.r2); goto ok;
13768 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13769 ovl.fmt.RRE.r2); goto ok;
13770 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013771 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013772 case 0xb92b: /* KMO */ goto unimplemented;
13773 case 0xb92c: /* PCC */ goto unimplemented;
13774 case 0xb92d: /* KMCTR */ goto unimplemented;
13775 case 0xb92e: /* KM */ goto unimplemented;
13776 case 0xb92f: /* KMC */ goto unimplemented;
13777 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13778 ovl.fmt.RRE.r2); goto ok;
13779 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13780 ovl.fmt.RRE.r2); goto ok;
13781 case 0xb93e: /* KIMD */ goto unimplemented;
13782 case 0xb93f: /* KLMD */ goto unimplemented;
13783 case 0xb941: /* CFDTR */ goto unimplemented;
13784 case 0xb942: /* CLGDTR */ goto unimplemented;
13785 case 0xb943: /* CLFDTR */ goto unimplemented;
13786 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13787 ovl.fmt.RRE.r2); goto ok;
13788 case 0xb949: /* CFXTR */ goto unimplemented;
13789 case 0xb94a: /* CLGXTR */ goto unimplemented;
13790 case 0xb94b: /* CLFXTR */ goto unimplemented;
13791 case 0xb951: /* CDFTR */ goto unimplemented;
13792 case 0xb952: /* CDLGTR */ goto unimplemented;
13793 case 0xb953: /* CDLFTR */ goto unimplemented;
13794 case 0xb959: /* CXFTR */ goto unimplemented;
13795 case 0xb95a: /* CXLGTR */ goto unimplemented;
13796 case 0xb95b: /* CXLFTR */ goto unimplemented;
13797 case 0xb960: /* CGRT */ goto unimplemented;
13798 case 0xb961: /* CLGRT */ goto unimplemented;
13799 case 0xb972: /* CRT */ goto unimplemented;
13800 case 0xb973: /* CLRT */ goto unimplemented;
13801 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13802 ovl.fmt.RRE.r2); goto ok;
13803 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13804 ovl.fmt.RRE.r2); goto ok;
13805 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13806 ovl.fmt.RRE.r2); goto ok;
13807 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13808 ovl.fmt.RRE.r2); goto ok;
13809 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13810 ovl.fmt.RRE.r2); goto ok;
13811 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13812 ovl.fmt.RRE.r2); goto ok;
13813 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13814 ovl.fmt.RRE.r2); goto ok;
13815 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13816 ovl.fmt.RRE.r2); goto ok;
13817 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13818 ovl.fmt.RRE.r2); goto ok;
13819 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13820 ovl.fmt.RRE.r2); goto ok;
13821 case 0xb98a: /* CSPG */ goto unimplemented;
13822 case 0xb98d: /* EPSW */ goto unimplemented;
13823 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013824 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013825 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13826 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13827 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13828 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13829 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13830 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013831 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13832 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013833 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13834 ovl.fmt.RRE.r2); goto ok;
13835 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13836 ovl.fmt.RRE.r2); goto ok;
13837 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13838 ovl.fmt.RRE.r2); goto ok;
13839 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13840 ovl.fmt.RRE.r2); goto ok;
13841 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13842 ovl.fmt.RRE.r2); goto ok;
13843 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13844 ovl.fmt.RRE.r2); goto ok;
13845 case 0xb99a: /* EPAIR */ goto unimplemented;
13846 case 0xb99b: /* ESAIR */ goto unimplemented;
13847 case 0xb99d: /* ESEA */ goto unimplemented;
13848 case 0xb99e: /* PTI */ goto unimplemented;
13849 case 0xb99f: /* SSAIR */ goto unimplemented;
13850 case 0xb9a2: /* PTF */ goto unimplemented;
13851 case 0xb9aa: /* LPTEA */ goto unimplemented;
13852 case 0xb9ae: /* RRBM */ goto unimplemented;
13853 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013854 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13855 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13856 goto ok;
florian2a415a12012-07-21 17:41:36 +000013857 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13858 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13859 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013860 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13861 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013862 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13863 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013864 case 0xb9bd: /* TRTRE */ goto unimplemented;
13865 case 0xb9be: /* SRSTU */ goto unimplemented;
13866 case 0xb9bf: /* TRTE */ goto unimplemented;
13867 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13868 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13869 goto ok;
13870 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13871 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13872 goto ok;
13873 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13874 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13875 goto ok;
13876 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13877 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13878 goto ok;
13879 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13880 ovl.fmt.RRE.r2); goto ok;
13881 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13882 ovl.fmt.RRE.r2); goto ok;
13883 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13884 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13885 goto ok;
13886 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13887 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13888 goto ok;
13889 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13890 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13891 goto ok;
13892 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13893 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13894 goto ok;
13895 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13896 ovl.fmt.RRE.r2); goto ok;
13897 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13898 ovl.fmt.RRE.r2); goto ok;
13899 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013900 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13901 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13902 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013903 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13904 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13905 goto ok;
13906 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13907 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13908 goto ok;
13909 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13910 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13911 goto ok;
13912 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13913 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13914 goto ok;
13915 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13916 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13917 goto ok;
13918 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13919 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13920 goto ok;
13921 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13922 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13923 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013924 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13925 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13926 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013927 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13928 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13929 goto ok;
13930 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13931 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13932 goto ok;
13933 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13934 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13935 goto ok;
13936 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13937 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13938 goto ok;
13939 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13940 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13941 goto ok;
13942 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13943 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13944 goto ok;
13945 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13946 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13947 goto ok;
13948 }
13949
13950 switch ((ovl.value & 0xff000000) >> 24) {
13951 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13952 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13953 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13954 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13955 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13956 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13957 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13958 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13959 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13960 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13961 case 0x45: /* BAL */ goto unimplemented;
13962 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13963 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13964 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13965 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13966 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13967 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13968 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13969 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13970 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13971 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13972 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13973 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13974 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13975 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13976 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13977 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13978 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13979 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13980 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13981 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13982 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13983 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13984 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13985 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13986 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13987 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13988 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13989 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13990 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13991 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13992 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13993 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13994 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13995 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13996 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13997 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13998 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13999 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14000 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14001 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14002 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14003 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14004 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14005 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14006 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14007 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14008 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14009 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14010 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14011 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14012 case 0x67: /* MXD */ goto unimplemented;
14013 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14014 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14015 case 0x69: /* CD */ goto unimplemented;
14016 case 0x6a: /* AD */ goto unimplemented;
14017 case 0x6b: /* SD */ goto unimplemented;
14018 case 0x6c: /* MD */ goto unimplemented;
14019 case 0x6d: /* DD */ goto unimplemented;
14020 case 0x6e: /* AW */ goto unimplemented;
14021 case 0x6f: /* SW */ goto unimplemented;
14022 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14023 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14024 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14025 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14026 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14027 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14028 case 0x79: /* CE */ goto unimplemented;
14029 case 0x7a: /* AE */ goto unimplemented;
14030 case 0x7b: /* SE */ goto unimplemented;
14031 case 0x7c: /* MDE */ goto unimplemented;
14032 case 0x7d: /* DE */ goto unimplemented;
14033 case 0x7e: /* AU */ goto unimplemented;
14034 case 0x7f: /* SU */ goto unimplemented;
14035 case 0x83: /* DIAG */ goto unimplemented;
14036 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
14037 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14038 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
14039 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14040 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14041 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14042 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14043 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14044 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14045 ovl.fmt.RS.d2); goto ok;
14046 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14047 ovl.fmt.RS.d2); goto ok;
14048 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14049 ovl.fmt.RS.d2); goto ok;
14050 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14051 ovl.fmt.RS.d2); goto ok;
14052 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14053 ovl.fmt.RS.d2); goto ok;
14054 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14055 ovl.fmt.RS.d2); goto ok;
14056 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14057 ovl.fmt.RS.d2); goto ok;
14058 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14059 ovl.fmt.RS.d2); goto ok;
14060 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14061 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14062 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14063 ovl.fmt.SI.d1); goto ok;
14064 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14065 ovl.fmt.SI.d1); goto ok;
14066 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14067 ovl.fmt.SI.d1); goto ok;
14068 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14069 ovl.fmt.SI.d1); goto ok;
14070 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14071 ovl.fmt.SI.d1); goto ok;
14072 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14073 ovl.fmt.SI.d1); goto ok;
14074 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14075 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14076 case 0x99: /* TRACE */ goto unimplemented;
14077 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14078 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14079 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14080 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14081 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
14082 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14083 goto ok;
14084 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
14085 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14086 goto ok;
14087 case 0xac: /* STNSM */ goto unimplemented;
14088 case 0xad: /* STOSM */ goto unimplemented;
14089 case 0xae: /* SIGP */ goto unimplemented;
14090 case 0xaf: /* MC */ goto unimplemented;
14091 case 0xb1: /* LRA */ goto unimplemented;
14092 case 0xb6: /* STCTL */ goto unimplemented;
14093 case 0xb7: /* LCTL */ goto unimplemented;
14094 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14095 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014096 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14097 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014098 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14099 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14100 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14101 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14102 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14103 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14104 }
14105
14106 return S390_DECODE_UNKNOWN_INSN;
14107
14108ok:
14109 return S390_DECODE_OK;
14110
14111unimplemented:
14112 return S390_DECODE_UNIMPLEMENTED_INSN;
14113}
14114
14115static s390_decode_t
14116s390_decode_6byte_and_irgen(UChar *bytes)
14117{
14118 typedef union {
14119 struct {
14120 unsigned int op1 : 8;
14121 unsigned int r1 : 4;
14122 unsigned int r3 : 4;
14123 unsigned int i2 : 16;
14124 unsigned int : 8;
14125 unsigned int op2 : 8;
14126 } RIE;
14127 struct {
14128 unsigned int op1 : 8;
14129 unsigned int r1 : 4;
14130 unsigned int r2 : 4;
14131 unsigned int i3 : 8;
14132 unsigned int i4 : 8;
14133 unsigned int i5 : 8;
14134 unsigned int op2 : 8;
14135 } RIE_RRUUU;
14136 struct {
14137 unsigned int op1 : 8;
14138 unsigned int r1 : 4;
14139 unsigned int : 4;
14140 unsigned int i2 : 16;
14141 unsigned int m3 : 4;
14142 unsigned int : 4;
14143 unsigned int op2 : 8;
14144 } RIEv1;
14145 struct {
14146 unsigned int op1 : 8;
14147 unsigned int r1 : 4;
14148 unsigned int r2 : 4;
14149 unsigned int i4 : 16;
14150 unsigned int m3 : 4;
14151 unsigned int : 4;
14152 unsigned int op2 : 8;
14153 } RIE_RRPU;
14154 struct {
14155 unsigned int op1 : 8;
14156 unsigned int r1 : 4;
14157 unsigned int m3 : 4;
14158 unsigned int i4 : 16;
14159 unsigned int i2 : 8;
14160 unsigned int op2 : 8;
14161 } RIEv3;
14162 struct {
14163 unsigned int op1 : 8;
14164 unsigned int r1 : 4;
14165 unsigned int op2 : 4;
14166 unsigned int i2 : 32;
14167 } RIL;
14168 struct {
14169 unsigned int op1 : 8;
14170 unsigned int r1 : 4;
14171 unsigned int m3 : 4;
14172 unsigned int b4 : 4;
14173 unsigned int d4 : 12;
14174 unsigned int i2 : 8;
14175 unsigned int op2 : 8;
14176 } RIS;
14177 struct {
14178 unsigned int op1 : 8;
14179 unsigned int r1 : 4;
14180 unsigned int r2 : 4;
14181 unsigned int b4 : 4;
14182 unsigned int d4 : 12;
14183 unsigned int m3 : 4;
14184 unsigned int : 4;
14185 unsigned int op2 : 8;
14186 } RRS;
14187 struct {
14188 unsigned int op1 : 8;
14189 unsigned int l1 : 4;
14190 unsigned int : 4;
14191 unsigned int b1 : 4;
14192 unsigned int d1 : 12;
14193 unsigned int : 8;
14194 unsigned int op2 : 8;
14195 } RSL;
14196 struct {
14197 unsigned int op1 : 8;
14198 unsigned int r1 : 4;
14199 unsigned int r3 : 4;
14200 unsigned int b2 : 4;
14201 unsigned int dl2 : 12;
14202 unsigned int dh2 : 8;
14203 unsigned int op2 : 8;
14204 } RSY;
14205 struct {
14206 unsigned int op1 : 8;
14207 unsigned int r1 : 4;
14208 unsigned int x2 : 4;
14209 unsigned int b2 : 4;
14210 unsigned int d2 : 12;
14211 unsigned int : 8;
14212 unsigned int op2 : 8;
14213 } RXE;
14214 struct {
14215 unsigned int op1 : 8;
14216 unsigned int r3 : 4;
14217 unsigned int x2 : 4;
14218 unsigned int b2 : 4;
14219 unsigned int d2 : 12;
14220 unsigned int r1 : 4;
14221 unsigned int : 4;
14222 unsigned int op2 : 8;
14223 } RXF;
14224 struct {
14225 unsigned int op1 : 8;
14226 unsigned int r1 : 4;
14227 unsigned int x2 : 4;
14228 unsigned int b2 : 4;
14229 unsigned int dl2 : 12;
14230 unsigned int dh2 : 8;
14231 unsigned int op2 : 8;
14232 } RXY;
14233 struct {
14234 unsigned int op1 : 8;
14235 unsigned int i2 : 8;
14236 unsigned int b1 : 4;
14237 unsigned int dl1 : 12;
14238 unsigned int dh1 : 8;
14239 unsigned int op2 : 8;
14240 } SIY;
14241 struct {
14242 unsigned int op : 8;
14243 unsigned int l : 8;
14244 unsigned int b1 : 4;
14245 unsigned int d1 : 12;
14246 unsigned int b2 : 4;
14247 unsigned int d2 : 12;
14248 } SS;
14249 struct {
14250 unsigned int op : 8;
14251 unsigned int l1 : 4;
14252 unsigned int l2 : 4;
14253 unsigned int b1 : 4;
14254 unsigned int d1 : 12;
14255 unsigned int b2 : 4;
14256 unsigned int d2 : 12;
14257 } SS_LLRDRD;
14258 struct {
14259 unsigned int op : 8;
14260 unsigned int r1 : 4;
14261 unsigned int r3 : 4;
14262 unsigned int b2 : 4;
14263 unsigned int d2 : 12;
14264 unsigned int b4 : 4;
14265 unsigned int d4 : 12;
14266 } SS_RRRDRD2;
14267 struct {
14268 unsigned int op : 16;
14269 unsigned int b1 : 4;
14270 unsigned int d1 : 12;
14271 unsigned int b2 : 4;
14272 unsigned int d2 : 12;
14273 } SSE;
14274 struct {
14275 unsigned int op1 : 8;
14276 unsigned int r3 : 4;
14277 unsigned int op2 : 4;
14278 unsigned int b1 : 4;
14279 unsigned int d1 : 12;
14280 unsigned int b2 : 4;
14281 unsigned int d2 : 12;
14282 } SSF;
14283 struct {
14284 unsigned int op : 16;
14285 unsigned int b1 : 4;
14286 unsigned int d1 : 12;
14287 unsigned int i2 : 16;
14288 } SIL;
14289 } formats;
14290 union {
14291 formats fmt;
14292 ULong value;
14293 } ovl;
14294
14295 vassert(sizeof(formats) == 6);
14296
florianffbd84d2012-12-09 02:06:29 +000014297 ((UChar *)(&ovl.value))[0] = bytes[0];
14298 ((UChar *)(&ovl.value))[1] = bytes[1];
14299 ((UChar *)(&ovl.value))[2] = bytes[2];
14300 ((UChar *)(&ovl.value))[3] = bytes[3];
14301 ((UChar *)(&ovl.value))[4] = bytes[4];
14302 ((UChar *)(&ovl.value))[5] = bytes[5];
14303 ((UChar *)(&ovl.value))[6] = 0x0;
14304 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000014305
14306 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
14307 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
14308 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14309 ovl.fmt.RXY.dl2,
14310 ovl.fmt.RXY.dh2); goto ok;
14311 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
14312 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
14313 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14314 ovl.fmt.RXY.dl2,
14315 ovl.fmt.RXY.dh2); goto ok;
14316 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
14317 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14318 ovl.fmt.RXY.dl2,
14319 ovl.fmt.RXY.dh2); goto ok;
14320 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
14321 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14322 ovl.fmt.RXY.dl2,
14323 ovl.fmt.RXY.dh2); goto ok;
14324 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
14325 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14326 ovl.fmt.RXY.dl2,
14327 ovl.fmt.RXY.dh2); goto ok;
14328 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
14329 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14330 ovl.fmt.RXY.dl2,
14331 ovl.fmt.RXY.dh2); goto ok;
14332 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
14333 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14334 ovl.fmt.RXY.dl2,
14335 ovl.fmt.RXY.dh2); goto ok;
14336 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
14337 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14338 ovl.fmt.RXY.dl2,
14339 ovl.fmt.RXY.dh2); goto ok;
14340 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
14341 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14342 ovl.fmt.RXY.dl2,
14343 ovl.fmt.RXY.dh2); goto ok;
14344 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
14345 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
14346 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14347 ovl.fmt.RXY.dl2,
14348 ovl.fmt.RXY.dh2); goto ok;
14349 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
14350 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14351 ovl.fmt.RXY.dl2,
14352 ovl.fmt.RXY.dh2); goto ok;
14353 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
14354 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
14355 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14356 ovl.fmt.RXY.dl2,
14357 ovl.fmt.RXY.dh2); goto ok;
14358 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
14359 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14360 ovl.fmt.RXY.dl2,
14361 ovl.fmt.RXY.dh2); goto ok;
14362 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
14363 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14364 ovl.fmt.RXY.dl2,
14365 ovl.fmt.RXY.dh2); goto ok;
14366 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
14367 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14368 ovl.fmt.RXY.dl2,
14369 ovl.fmt.RXY.dh2); goto ok;
14370 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
14371 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14372 ovl.fmt.RXY.dl2,
14373 ovl.fmt.RXY.dh2); goto ok;
14374 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
14375 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14376 ovl.fmt.RXY.dl2,
14377 ovl.fmt.RXY.dh2); goto ok;
14378 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
14379 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14380 ovl.fmt.RXY.dl2,
14381 ovl.fmt.RXY.dh2); goto ok;
14382 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
14383 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14384 ovl.fmt.RXY.dl2,
14385 ovl.fmt.RXY.dh2); goto ok;
14386 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
14387 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14388 ovl.fmt.RXY.dl2,
14389 ovl.fmt.RXY.dh2); goto ok;
14390 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
14391 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14392 ovl.fmt.RXY.dl2,
14393 ovl.fmt.RXY.dh2); goto ok;
14394 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
14395 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14396 ovl.fmt.RXY.dl2,
14397 ovl.fmt.RXY.dh2); goto ok;
14398 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
14399 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14400 ovl.fmt.RXY.dl2,
14401 ovl.fmt.RXY.dh2); goto ok;
14402 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
14403 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14404 ovl.fmt.RXY.dl2,
14405 ovl.fmt.RXY.dh2); goto ok;
14406 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
14407 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14408 ovl.fmt.RXY.dl2,
14409 ovl.fmt.RXY.dh2); goto ok;
14410 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
14411 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14412 ovl.fmt.RXY.dl2,
14413 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014414 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014415 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
14416 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14417 ovl.fmt.RXY.dl2,
14418 ovl.fmt.RXY.dh2); goto ok;
14419 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
14420 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
14421 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14422 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14423 ovl.fmt.RXY.dh2); goto ok;
14424 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
14425 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14426 ovl.fmt.RXY.dl2,
14427 ovl.fmt.RXY.dh2); goto ok;
14428 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
14429 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14430 ovl.fmt.RXY.dl2,
14431 ovl.fmt.RXY.dh2); goto ok;
14432 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
14433 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14434 ovl.fmt.RXY.dl2,
14435 ovl.fmt.RXY.dh2); goto ok;
14436 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
14437 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14438 ovl.fmt.RXY.dl2,
14439 ovl.fmt.RXY.dh2); goto ok;
14440 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
14441 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14442 ovl.fmt.RXY.dl2,
14443 ovl.fmt.RXY.dh2); goto ok;
14444 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
14445 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14446 ovl.fmt.RXY.dl2,
14447 ovl.fmt.RXY.dh2); goto ok;
14448 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
14449 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14450 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14451 ovl.fmt.RXY.dh2); goto ok;
14452 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
14453 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14454 ovl.fmt.RXY.dl2,
14455 ovl.fmt.RXY.dh2); goto ok;
14456 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
14457 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14458 ovl.fmt.RXY.dl2,
14459 ovl.fmt.RXY.dh2); goto ok;
14460 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
14461 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14462 ovl.fmt.RXY.dl2,
14463 ovl.fmt.RXY.dh2); goto ok;
14464 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
14465 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14466 ovl.fmt.RXY.dl2,
14467 ovl.fmt.RXY.dh2); goto ok;
14468 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
14469 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14470 ovl.fmt.RXY.dl2,
14471 ovl.fmt.RXY.dh2); goto ok;
14472 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
14473 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14474 ovl.fmt.RXY.dl2,
14475 ovl.fmt.RXY.dh2); goto ok;
14476 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
14477 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14478 ovl.fmt.RXY.dl2,
14479 ovl.fmt.RXY.dh2); goto ok;
14480 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
14481 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14482 ovl.fmt.RXY.dl2,
14483 ovl.fmt.RXY.dh2); goto ok;
14484 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
14485 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14486 ovl.fmt.RXY.dl2,
14487 ovl.fmt.RXY.dh2); goto ok;
14488 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
14489 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14490 ovl.fmt.RXY.dl2,
14491 ovl.fmt.RXY.dh2); goto ok;
14492 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
14493 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14494 ovl.fmt.RXY.dl2,
14495 ovl.fmt.RXY.dh2); goto ok;
14496 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
14497 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14498 ovl.fmt.RXY.dl2,
14499 ovl.fmt.RXY.dh2); goto ok;
14500 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
14501 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14502 ovl.fmt.RXY.dl2,
14503 ovl.fmt.RXY.dh2); goto ok;
14504 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
14505 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14506 ovl.fmt.RXY.dl2,
14507 ovl.fmt.RXY.dh2); goto ok;
14508 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
14509 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14510 ovl.fmt.RXY.dl2,
14511 ovl.fmt.RXY.dh2); goto ok;
14512 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
14513 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14514 ovl.fmt.RXY.dl2,
14515 ovl.fmt.RXY.dh2); goto ok;
14516 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
14517 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14518 ovl.fmt.RXY.dl2,
14519 ovl.fmt.RXY.dh2); goto ok;
14520 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
14521 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14522 ovl.fmt.RXY.dl2,
14523 ovl.fmt.RXY.dh2); goto ok;
14524 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
14525 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14526 ovl.fmt.RXY.dl2,
14527 ovl.fmt.RXY.dh2); goto ok;
14528 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
14529 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14530 ovl.fmt.RXY.dl2,
14531 ovl.fmt.RXY.dh2); goto ok;
14532 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
14533 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14534 ovl.fmt.RXY.dl2,
14535 ovl.fmt.RXY.dh2); goto ok;
14536 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
14537 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14538 ovl.fmt.RXY.dl2,
14539 ovl.fmt.RXY.dh2); goto ok;
14540 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
14541 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14542 ovl.fmt.RXY.dl2,
14543 ovl.fmt.RXY.dh2); goto ok;
14544 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
14545 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14546 ovl.fmt.RXY.dl2,
14547 ovl.fmt.RXY.dh2); goto ok;
14548 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
14549 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14550 ovl.fmt.RXY.dl2,
14551 ovl.fmt.RXY.dh2); goto ok;
14552 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
14553 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14554 ovl.fmt.RXY.dl2,
14555 ovl.fmt.RXY.dh2); goto ok;
14556 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
14557 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14558 ovl.fmt.RXY.dl2,
14559 ovl.fmt.RXY.dh2); goto ok;
14560 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
14561 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14562 ovl.fmt.RXY.dl2,
14563 ovl.fmt.RXY.dh2); goto ok;
14564 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
14565 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14566 ovl.fmt.RXY.dl2,
14567 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014568 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014569 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
14570 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14571 ovl.fmt.RXY.dl2,
14572 ovl.fmt.RXY.dh2); goto ok;
14573 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14574 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14575 ovl.fmt.RXY.dl2,
14576 ovl.fmt.RXY.dh2); goto ok;
14577 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14578 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14579 ovl.fmt.RXY.dl2,
14580 ovl.fmt.RXY.dh2); goto ok;
14581 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14582 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14583 ovl.fmt.RXY.dl2,
14584 ovl.fmt.RXY.dh2); goto ok;
14585 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14586 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14587 ovl.fmt.RXY.dl2,
14588 ovl.fmt.RXY.dh2); goto ok;
14589 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14590 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14591 ovl.fmt.RXY.dl2,
14592 ovl.fmt.RXY.dh2); goto ok;
14593 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14594 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14595 ovl.fmt.RXY.dl2,
14596 ovl.fmt.RXY.dh2); goto ok;
14597 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
14598 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14599 ovl.fmt.RXY.dl2,
14600 ovl.fmt.RXY.dh2); goto ok;
14601 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
14602 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14603 ovl.fmt.RXY.dl2,
14604 ovl.fmt.RXY.dh2); goto ok;
14605 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
14606 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14607 ovl.fmt.RXY.dl2,
14608 ovl.fmt.RXY.dh2); goto ok;
14609 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
14610 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14611 ovl.fmt.RXY.dl2,
14612 ovl.fmt.RXY.dh2); goto ok;
14613 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
14614 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14615 ovl.fmt.RXY.dl2,
14616 ovl.fmt.RXY.dh2); goto ok;
14617 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
14618 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14619 ovl.fmt.RXY.dl2,
14620 ovl.fmt.RXY.dh2); goto ok;
14621 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
14622 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14623 ovl.fmt.RXY.dl2,
14624 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014625 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
14626 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
14627 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014628 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
14629 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14630 ovl.fmt.RXY.dl2,
14631 ovl.fmt.RXY.dh2); goto ok;
14632 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
14633 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14634 ovl.fmt.RXY.dl2,
14635 ovl.fmt.RXY.dh2); goto ok;
14636 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
14637 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14638 ovl.fmt.RXY.dl2,
14639 ovl.fmt.RXY.dh2); goto ok;
14640 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
14641 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14642 ovl.fmt.RXY.dl2,
14643 ovl.fmt.RXY.dh2); goto ok;
14644 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
14645 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14646 ovl.fmt.RXY.dl2,
14647 ovl.fmt.RXY.dh2); goto ok;
14648 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
14649 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14650 ovl.fmt.RXY.dl2,
14651 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014652 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014653 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
14654 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14655 ovl.fmt.RXY.dl2,
14656 ovl.fmt.RXY.dh2); goto ok;
14657 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
14658 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14659 ovl.fmt.RXY.dl2,
14660 ovl.fmt.RXY.dh2); goto ok;
14661 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
14662 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14663 ovl.fmt.RXY.dl2,
14664 ovl.fmt.RXY.dh2); goto ok;
14665 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
14666 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14667 ovl.fmt.RXY.dl2,
14668 ovl.fmt.RXY.dh2); goto ok;
14669 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14670 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14671 ovl.fmt.RSY.dl2,
14672 ovl.fmt.RSY.dh2); goto ok;
14673 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14674 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14675 ovl.fmt.RSY.dl2,
14676 ovl.fmt.RSY.dh2); goto ok;
14677 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14678 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14679 ovl.fmt.RSY.dl2,
14680 ovl.fmt.RSY.dh2); goto ok;
14681 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14682 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14683 ovl.fmt.RSY.dl2,
14684 ovl.fmt.RSY.dh2); goto ok;
14685 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14686 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14687 ovl.fmt.RSY.dl2,
14688 ovl.fmt.RSY.dh2); goto ok;
14689 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14690 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14691 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14692 ovl.fmt.RSY.dl2,
14693 ovl.fmt.RSY.dh2); goto ok;
14694 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14695 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14696 ovl.fmt.RSY.dl2,
14697 ovl.fmt.RSY.dh2); goto ok;
14698 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14699 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14700 ovl.fmt.RSY.dl2,
14701 ovl.fmt.RSY.dh2); goto ok;
14702 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14703 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14704 ovl.fmt.RSY.dl2,
14705 ovl.fmt.RSY.dh2); goto ok;
14706 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14707 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14708 ovl.fmt.RSY.dl2,
14709 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014710 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014711 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
14712 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14713 ovl.fmt.RSY.dl2,
14714 ovl.fmt.RSY.dh2); goto ok;
14715 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14716 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
14717 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14718 ovl.fmt.RSY.dl2,
14719 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014720 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014721 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14722 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14723 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14724 ovl.fmt.RSY.dh2); goto ok;
14725 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14726 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14727 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14728 ovl.fmt.RSY.dh2); goto ok;
14729 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14730 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14731 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14732 ovl.fmt.RSY.dl2,
14733 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014734 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
14735 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14736 ovl.fmt.RSY.dl2,
14737 ovl.fmt.RSY.dh2); goto ok;
14738 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
14739 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14740 ovl.fmt.RSY.dl2,
14741 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014742 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
14743 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14744 ovl.fmt.RSY.dl2,
14745 ovl.fmt.RSY.dh2); goto ok;
14746 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14747 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14748 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14749 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014750 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
14751 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14752 ovl.fmt.RSY.dl2,
14753 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014754 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14755 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14756 ovl.fmt.SIY.dh1); goto ok;
14757 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14758 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14759 ovl.fmt.SIY.dh1); goto ok;
14760 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14761 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14762 ovl.fmt.SIY.dh1); goto ok;
14763 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14764 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14765 ovl.fmt.SIY.dh1); goto ok;
14766 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14767 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14768 ovl.fmt.SIY.dh1); goto ok;
14769 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14770 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14771 ovl.fmt.SIY.dh1); goto ok;
14772 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14773 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14774 ovl.fmt.SIY.dh1); goto ok;
14775 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14776 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14777 ovl.fmt.SIY.dh1); goto ok;
14778 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14779 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14780 ovl.fmt.SIY.dh1); goto ok;
14781 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14782 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14783 ovl.fmt.SIY.dh1); goto ok;
14784 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14785 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14786 ovl.fmt.RSY.dl2,
14787 ovl.fmt.RSY.dh2); goto ok;
14788 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14789 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14790 ovl.fmt.RSY.dl2,
14791 ovl.fmt.RSY.dh2); goto ok;
14792 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14793 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14794 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14795 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14796 ovl.fmt.RSY.dl2,
14797 ovl.fmt.RSY.dh2); goto ok;
14798 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14799 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14800 ovl.fmt.RSY.dl2,
14801 ovl.fmt.RSY.dh2); goto ok;
14802 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14803 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14804 ovl.fmt.RSY.dl2,
14805 ovl.fmt.RSY.dh2); goto ok;
14806 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14807 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14808 ovl.fmt.RSY.dl2,
14809 ovl.fmt.RSY.dh2); goto ok;
14810 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14811 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14812 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14813 ovl.fmt.RSY.dh2); goto ok;
14814 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14815 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14816 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14817 ovl.fmt.RSY.dl2,
14818 ovl.fmt.RSY.dh2); goto ok;
14819 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14820 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14821 ovl.fmt.RSY.dl2,
14822 ovl.fmt.RSY.dh2); goto ok;
14823 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14824 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14825 ovl.fmt.RSY.dl2,
14826 ovl.fmt.RSY.dh2); goto ok;
14827 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14828 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14829 ovl.fmt.RSY.dl2,
14830 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014831 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14832 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14833 ovl.fmt.RSY.dl2,
14834 ovl.fmt.RSY.dh2,
14835 S390_XMNM_LOCG); goto ok;
14836 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14837 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14838 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14839 ovl.fmt.RSY.dh2,
14840 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014841 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14842 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14843 ovl.fmt.RSY.dl2,
14844 ovl.fmt.RSY.dh2); goto ok;
14845 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14846 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14847 ovl.fmt.RSY.dl2,
14848 ovl.fmt.RSY.dh2); goto ok;
14849 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14850 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14851 ovl.fmt.RSY.dl2,
14852 ovl.fmt.RSY.dh2); goto ok;
14853 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14854 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14855 ovl.fmt.RSY.dl2,
14856 ovl.fmt.RSY.dh2); goto ok;
14857 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14858 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14859 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14860 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014861 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14862 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14863 ovl.fmt.RSY.dl2,
14864 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14865 goto ok;
14866 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14867 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14868 ovl.fmt.RSY.dl2,
14869 ovl.fmt.RSY.dh2,
14870 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014871 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14872 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14873 ovl.fmt.RSY.dl2,
14874 ovl.fmt.RSY.dh2); goto ok;
14875 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14876 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14877 ovl.fmt.RSY.dl2,
14878 ovl.fmt.RSY.dh2); goto ok;
14879 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14880 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14881 ovl.fmt.RSY.dl2,
14882 ovl.fmt.RSY.dh2); goto ok;
14883 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14884 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14885 ovl.fmt.RSY.dl2,
14886 ovl.fmt.RSY.dh2); goto ok;
14887 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14888 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14889 ovl.fmt.RSY.dl2,
14890 ovl.fmt.RSY.dh2); goto ok;
14891 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14892 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14893 goto ok;
14894 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14895 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14896 goto ok;
14897 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14898 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14899 ovl.fmt.RIE_RRUUU.r1,
14900 ovl.fmt.RIE_RRUUU.r2,
14901 ovl.fmt.RIE_RRUUU.i3,
14902 ovl.fmt.RIE_RRUUU.i4,
14903 ovl.fmt.RIE_RRUUU.i5);
14904 goto ok;
14905 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14906 ovl.fmt.RIE_RRUUU.r1,
14907 ovl.fmt.RIE_RRUUU.r2,
14908 ovl.fmt.RIE_RRUUU.i3,
14909 ovl.fmt.RIE_RRUUU.i4,
14910 ovl.fmt.RIE_RRUUU.i5);
14911 goto ok;
14912 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14913 ovl.fmt.RIE_RRUUU.r1,
14914 ovl.fmt.RIE_RRUUU.r2,
14915 ovl.fmt.RIE_RRUUU.i3,
14916 ovl.fmt.RIE_RRUUU.i4,
14917 ovl.fmt.RIE_RRUUU.i5);
14918 goto ok;
14919 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14920 ovl.fmt.RIE_RRUUU.r1,
14921 ovl.fmt.RIE_RRUUU.r2,
14922 ovl.fmt.RIE_RRUUU.i3,
14923 ovl.fmt.RIE_RRUUU.i4,
14924 ovl.fmt.RIE_RRUUU.i5);
14925 goto ok;
florian2289cd42012-12-05 04:23:42 +000014926 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014927 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14928 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14929 ovl.fmt.RIE_RRPU.r1,
14930 ovl.fmt.RIE_RRPU.r2,
14931 ovl.fmt.RIE_RRPU.i4,
14932 ovl.fmt.RIE_RRPU.m3); goto ok;
14933 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14934 ovl.fmt.RIE_RRPU.r1,
14935 ovl.fmt.RIE_RRPU.r2,
14936 ovl.fmt.RIE_RRPU.i4,
14937 ovl.fmt.RIE_RRPU.m3); goto ok;
14938 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14939 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14940 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14941 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14942 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14943 ovl.fmt.RIE_RRPU.r1,
14944 ovl.fmt.RIE_RRPU.r2,
14945 ovl.fmt.RIE_RRPU.i4,
14946 ovl.fmt.RIE_RRPU.m3); goto ok;
14947 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14948 ovl.fmt.RIE_RRPU.r1,
14949 ovl.fmt.RIE_RRPU.r2,
14950 ovl.fmt.RIE_RRPU.i4,
14951 ovl.fmt.RIE_RRPU.m3); goto ok;
14952 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14953 ovl.fmt.RIEv3.r1,
14954 ovl.fmt.RIEv3.m3,
14955 ovl.fmt.RIEv3.i4,
14956 ovl.fmt.RIEv3.i2); goto ok;
14957 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14958 ovl.fmt.RIEv3.r1,
14959 ovl.fmt.RIEv3.m3,
14960 ovl.fmt.RIEv3.i4,
14961 ovl.fmt.RIEv3.i2); goto ok;
14962 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14963 ovl.fmt.RIEv3.r1,
14964 ovl.fmt.RIEv3.m3,
14965 ovl.fmt.RIEv3.i4,
14966 ovl.fmt.RIEv3.i2); goto ok;
14967 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14968 ovl.fmt.RIEv3.r1,
14969 ovl.fmt.RIEv3.m3,
14970 ovl.fmt.RIEv3.i4,
14971 ovl.fmt.RIEv3.i2); goto ok;
14972 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14973 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14974 goto ok;
14975 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14976 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14977 ovl.fmt.RIE.i2); goto ok;
14978 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14979 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14980 ovl.fmt.RIE.i2); goto ok;
14981 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14982 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14983 ovl.fmt.RIE.i2); goto ok;
14984 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14985 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14986 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14987 goto ok;
14988 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14989 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14990 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14991 goto ok;
14992 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14993 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14994 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14995 goto ok;
14996 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14997 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14998 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14999 goto ok;
15000 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15001 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15002 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15003 ovl.fmt.RIS.i2); goto ok;
15004 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15005 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15006 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15007 ovl.fmt.RIS.i2); goto ok;
15008 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15009 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15010 ovl.fmt.RIS.d4,
15011 ovl.fmt.RIS.i2); goto ok;
15012 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15013 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15014 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15015 ovl.fmt.RIS.i2); goto ok;
15016 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15017 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15018 ovl.fmt.RXE.d2); goto ok;
15019 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15020 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15021 ovl.fmt.RXE.d2); goto ok;
15022 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15023 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15024 ovl.fmt.RXE.d2); goto ok;
15025 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15026 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15027 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15028 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15029 ovl.fmt.RXE.d2); goto ok;
15030 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15031 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15032 ovl.fmt.RXE.d2); goto ok;
15033 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
15034 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15035 ovl.fmt.RXE.d2); goto ok;
15036 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
15037 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
15038 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15039 ovl.fmt.RXE.d2); goto ok;
15040 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
15041 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15042 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15043 ovl.fmt.RXF.r1); goto ok;
15044 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
15045 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15046 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15047 ovl.fmt.RXF.r1); goto ok;
15048 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
15049 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15050 ovl.fmt.RXE.d2); goto ok;
15051 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
15052 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15053 ovl.fmt.RXE.d2); goto ok;
15054 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
15055 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15056 ovl.fmt.RXE.d2); goto ok;
15057 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
15058 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15059 ovl.fmt.RXE.d2); goto ok;
15060 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
15061 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15062 ovl.fmt.RXE.d2); goto ok;
15063 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
15064 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15065 ovl.fmt.RXE.d2); goto ok;
15066 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
15067 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
15068 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15069 ovl.fmt.RXE.d2); goto ok;
15070 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
15071 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15072 ovl.fmt.RXE.d2); goto ok;
15073 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
15074 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15075 ovl.fmt.RXE.d2); goto ok;
15076 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
15077 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15078 ovl.fmt.RXE.d2); goto ok;
15079 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
15080 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15081 ovl.fmt.RXE.d2); goto ok;
15082 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
15083 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15084 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15085 ovl.fmt.RXF.r1); goto ok;
15086 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
15087 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15088 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15089 ovl.fmt.RXF.r1); goto ok;
15090 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
15091 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
15092 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
15093 case 0xed000000002eULL: /* MAE */ goto unimplemented;
15094 case 0xed000000002fULL: /* MSE */ goto unimplemented;
15095 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
15096 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
15097 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
15098 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
15099 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
15100 case 0xed000000003aULL: /* MAY */ goto unimplemented;
15101 case 0xed000000003bULL: /* MY */ goto unimplemented;
15102 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
15103 case 0xed000000003dULL: /* MYH */ goto unimplemented;
15104 case 0xed000000003eULL: /* MAD */ goto unimplemented;
15105 case 0xed000000003fULL: /* MSD */ goto unimplemented;
15106 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
15107 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
15108 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
15109 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000015110 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
15111 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15112 ovl.fmt.RXE.d2); goto ok;
15113 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
15114 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15115 ovl.fmt.RXE.d2); goto ok;
15116 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
15117 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15118 ovl.fmt.RXE.d2); goto ok;
15119 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
15120 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15121 ovl.fmt.RXE.d2); goto ok;
15122 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
15123 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15124 ovl.fmt.RXE.d2); goto ok;
15125 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
15126 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15127 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015128 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
15129 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15130 ovl.fmt.RXY.dl2,
15131 ovl.fmt.RXY.dh2); goto ok;
15132 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
15133 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15134 ovl.fmt.RXY.dl2,
15135 ovl.fmt.RXY.dh2); goto ok;
15136 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
15137 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15138 ovl.fmt.RXY.dl2,
15139 ovl.fmt.RXY.dh2); goto ok;
15140 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
15141 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15142 ovl.fmt.RXY.dl2,
15143 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015144 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
15145 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
15146 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
15147 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015148 }
15149
15150 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
15151 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
15152 ovl.fmt.RIL.i2); goto ok;
15153 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
15154 ovl.fmt.RIL.i2); goto ok;
15155 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
15156 ovl.fmt.RIL.i2); goto ok;
15157 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
15158 ovl.fmt.RIL.i2); goto ok;
15159 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
15160 ovl.fmt.RIL.i2); goto ok;
15161 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
15162 ovl.fmt.RIL.i2); goto ok;
15163 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
15164 ovl.fmt.RIL.i2); goto ok;
15165 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
15166 ovl.fmt.RIL.i2); goto ok;
15167 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
15168 ovl.fmt.RIL.i2); goto ok;
15169 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
15170 ovl.fmt.RIL.i2); goto ok;
15171 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
15172 ovl.fmt.RIL.i2); goto ok;
15173 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
15174 ovl.fmt.RIL.i2); goto ok;
15175 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
15176 ovl.fmt.RIL.i2); goto ok;
15177 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
15178 ovl.fmt.RIL.i2); goto ok;
15179 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
15180 ovl.fmt.RIL.i2); goto ok;
15181 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
15182 ovl.fmt.RIL.i2); goto ok;
15183 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
15184 ovl.fmt.RIL.i2); goto ok;
15185 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
15186 ovl.fmt.RIL.i2); goto ok;
15187 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
15188 ovl.fmt.RIL.i2); goto ok;
15189 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
15190 ovl.fmt.RIL.i2); goto ok;
15191 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
15192 ovl.fmt.RIL.i2); goto ok;
15193 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
15194 ovl.fmt.RIL.i2); goto ok;
15195 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
15196 ovl.fmt.RIL.i2); goto ok;
15197 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
15198 ovl.fmt.RIL.i2); goto ok;
15199 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
15200 ovl.fmt.RIL.i2); goto ok;
15201 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
15202 ovl.fmt.RIL.i2); goto ok;
15203 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
15204 ovl.fmt.RIL.i2); goto ok;
15205 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
15206 ovl.fmt.RIL.i2); goto ok;
15207 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
15208 ovl.fmt.RIL.i2); goto ok;
15209 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
15210 ovl.fmt.RIL.i2); goto ok;
15211 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
15212 ovl.fmt.RIL.i2); goto ok;
15213 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
15214 ovl.fmt.RIL.i2); goto ok;
15215 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
15216 ovl.fmt.RIL.i2); goto ok;
15217 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
15218 ovl.fmt.RIL.i2); goto ok;
15219 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
15220 ovl.fmt.RIL.i2); goto ok;
15221 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
15222 ovl.fmt.RIL.i2); goto ok;
15223 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
15224 ovl.fmt.RIL.i2); goto ok;
15225 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
15226 ovl.fmt.RIL.i2); goto ok;
15227 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
15228 ovl.fmt.RIL.i2); goto ok;
15229 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
15230 ovl.fmt.RIL.i2); goto ok;
15231 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
15232 ovl.fmt.RIL.i2); goto ok;
15233 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
15234 ovl.fmt.RIL.i2); goto ok;
15235 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
15236 ovl.fmt.RIL.i2); goto ok;
15237 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
15238 ovl.fmt.RIL.i2); goto ok;
15239 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
15240 ovl.fmt.RIL.i2); goto ok;
15241 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
15242 ovl.fmt.RIL.i2); goto ok;
15243 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
15244 ovl.fmt.RIL.i2); goto ok;
15245 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
15246 ovl.fmt.RIL.i2); goto ok;
15247 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
15248 ovl.fmt.RIL.i2); goto ok;
15249 case 0xc800ULL: /* MVCOS */ goto unimplemented;
15250 case 0xc801ULL: /* ECTG */ goto unimplemented;
15251 case 0xc802ULL: /* CSST */ goto unimplemented;
15252 case 0xc804ULL: /* LPD */ goto unimplemented;
15253 case 0xc805ULL: /* LPDG */ goto unimplemented;
15254 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
15255 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
15256 ovl.fmt.RIL.i2); goto ok;
15257 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
15258 ovl.fmt.RIL.i2); goto ok;
15259 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
15260 ovl.fmt.RIL.i2); goto ok;
15261 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
15262 ovl.fmt.RIL.i2); goto ok;
15263 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
15264 ovl.fmt.RIL.i2); goto ok;
15265 }
15266
15267 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000015268 case 0xc5ULL: /* BPRP */ goto unimplemented;
15269 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015270 case 0xd0ULL: /* TRTR */ goto unimplemented;
15271 case 0xd1ULL: /* MVN */ goto unimplemented;
15272 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
15273 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15274 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15275 case 0xd3ULL: /* MVZ */ goto unimplemented;
15276 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
15277 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15278 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15279 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
15280 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15281 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15282 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
15283 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15284 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000015285 case 0xd7ULL:
15286 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
15287 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
15288 else
15289 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
15290 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15291 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
15292 goto ok;
sewardj2019a972011-03-07 16:04:07 +000015293 case 0xd9ULL: /* MVCK */ goto unimplemented;
15294 case 0xdaULL: /* MVCP */ goto unimplemented;
15295 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015296 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
15297 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15298 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015299 case 0xddULL: /* TRT */ goto unimplemented;
15300 case 0xdeULL: /* ED */ goto unimplemented;
15301 case 0xdfULL: /* EDMK */ goto unimplemented;
15302 case 0xe1ULL: /* PKU */ goto unimplemented;
15303 case 0xe2ULL: /* UNPKU */ goto unimplemented;
15304 case 0xe8ULL: /* MVCIN */ goto unimplemented;
15305 case 0xe9ULL: /* PKA */ goto unimplemented;
15306 case 0xeaULL: /* UNPKA */ goto unimplemented;
15307 case 0xeeULL: /* PLO */ goto unimplemented;
15308 case 0xefULL: /* LMD */ goto unimplemented;
15309 case 0xf0ULL: /* SRP */ goto unimplemented;
15310 case 0xf1ULL: /* MVO */ goto unimplemented;
15311 case 0xf2ULL: /* PACK */ goto unimplemented;
15312 case 0xf3ULL: /* UNPK */ goto unimplemented;
15313 case 0xf8ULL: /* ZAP */ goto unimplemented;
15314 case 0xf9ULL: /* CP */ goto unimplemented;
15315 case 0xfaULL: /* AP */ goto unimplemented;
15316 case 0xfbULL: /* SP */ goto unimplemented;
15317 case 0xfcULL: /* MP */ goto unimplemented;
15318 case 0xfdULL: /* DP */ goto unimplemented;
15319 }
15320
15321 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
15322 case 0xe500ULL: /* LASP */ goto unimplemented;
15323 case 0xe501ULL: /* TPROT */ goto unimplemented;
15324 case 0xe502ULL: /* STRAG */ goto unimplemented;
15325 case 0xe50eULL: /* MVCSK */ goto unimplemented;
15326 case 0xe50fULL: /* MVCDK */ goto unimplemented;
15327 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
15328 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15329 goto ok;
15330 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
15331 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15332 goto ok;
15333 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
15334 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15335 goto ok;
15336 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
15337 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15338 goto ok;
15339 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
15340 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15341 goto ok;
15342 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
15343 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15344 goto ok;
15345 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
15346 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15347 goto ok;
15348 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
15349 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15350 goto ok;
15351 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
15352 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15353 goto ok;
florian2289cd42012-12-05 04:23:42 +000015354 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
15355 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015356 }
15357
15358 return S390_DECODE_UNKNOWN_INSN;
15359
15360ok:
15361 return S390_DECODE_OK;
15362
15363unimplemented:
15364 return S390_DECODE_UNIMPLEMENTED_INSN;
15365}
15366
15367/* Handle "special" instructions. */
15368static s390_decode_t
15369s390_decode_special_and_irgen(UChar *bytes)
15370{
15371 s390_decode_t status = S390_DECODE_OK;
15372
15373 /* Got a "Special" instruction preamble. Which one is it? */
15374 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
15375 s390_irgen_client_request();
15376 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
15377 s390_irgen_guest_NRADDR();
15378 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
15379 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000015380 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
15381 vex_inject_ir(irsb, Iend_BE);
15382
15383 /* Invalidate the current insn. The reason is that the IRop we're
15384 injecting here can change. In which case the translation has to
15385 be redone. For ease of handling, we simply invalidate all the
15386 time. */
15387 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
15388 mkU64(guest_IA_curr_instr)));
15389 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
15390 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
15391 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
15392 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
15393
15394 put_IA(mkaddr_expr(guest_IA_next_instr));
15395 dis_res->whatNext = Dis_StopHere;
15396 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000015397 } else {
15398 /* We don't know what it is. */
15399 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
15400 }
15401
15402 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15403
15404 return status;
15405}
15406
15407
15408/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000015409static UInt
sewardj2019a972011-03-07 16:04:07 +000015410s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
15411{
15412 s390_decode_t status;
15413
15414 dis_res = dres;
15415
15416 /* Spot the 8-byte preamble: 18ff lr r15,r15
15417 1811 lr r1,r1
15418 1822 lr r2,r2
15419 1833 lr r3,r3 */
15420 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
15421 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
15422 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
15423
15424 /* Handle special instruction that follows that preamble. */
15425 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000015426
15427 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15428 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15429
15430 status =
15431 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000015432 } else {
15433 /* Handle normal instructions. */
15434 switch (insn_length) {
15435 case 2:
15436 status = s390_decode_2byte_and_irgen(bytes);
15437 break;
15438
15439 case 4:
15440 status = s390_decode_4byte_and_irgen(bytes);
15441 break;
15442
15443 case 6:
15444 status = s390_decode_6byte_and_irgen(bytes);
15445 break;
15446
15447 default:
15448 status = S390_DECODE_ERROR;
15449 break;
15450 }
15451 }
florian5fcbba22011-07-27 20:40:22 +000015452 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000015453 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
15454 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000015455 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000015456 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000015457 }
15458
15459 if (status == S390_DECODE_OK) return insn_length; /* OK */
15460
15461 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000015462 if (sigill_diag) {
15463 vex_printf("vex s390->IR: ");
15464 switch (status) {
15465 case S390_DECODE_UNKNOWN_INSN:
15466 vex_printf("unknown insn: ");
15467 break;
sewardj2019a972011-03-07 16:04:07 +000015468
sewardj442e51a2012-12-06 18:08:04 +000015469 case S390_DECODE_UNIMPLEMENTED_INSN:
15470 vex_printf("unimplemented insn: ");
15471 break;
sewardj2019a972011-03-07 16:04:07 +000015472
sewardj442e51a2012-12-06 18:08:04 +000015473 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
15474 vex_printf("unimplemented special insn: ");
15475 break;
sewardj2019a972011-03-07 16:04:07 +000015476
sewardj442e51a2012-12-06 18:08:04 +000015477 default:
15478 case S390_DECODE_ERROR:
15479 vex_printf("decoding error: ");
15480 break;
15481 }
15482
15483 vex_printf("%02x%02x", bytes[0], bytes[1]);
15484 if (insn_length > 2) {
15485 vex_printf(" %02x%02x", bytes[2], bytes[3]);
15486 }
15487 if (insn_length > 4) {
15488 vex_printf(" %02x%02x", bytes[4], bytes[5]);
15489 }
15490 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000015491 }
15492
sewardj2019a972011-03-07 16:04:07 +000015493 return 0; /* Failed */
15494}
15495
15496
sewardj2019a972011-03-07 16:04:07 +000015497/* Disassemble a single instruction INSN into IR. */
15498static DisResult
florian420c5012011-07-22 02:12:28 +000015499disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000015500{
15501 UChar byte;
15502 UInt insn_length;
15503 DisResult dres;
15504
15505 /* ---------------------------------------------------- */
15506 /* --- Compute instruction length -- */
15507 /* ---------------------------------------------------- */
15508
15509 /* Get the first byte of the insn. */
15510 byte = insn[0];
15511
15512 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
15513 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
15514 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
15515
15516 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15517
15518 /* ---------------------------------------------------- */
15519 /* --- Initialise the DisResult data -- */
15520 /* ---------------------------------------------------- */
15521 dres.whatNext = Dis_Continue;
15522 dres.len = insn_length;
15523 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000015524 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000015525
floriana99f20e2011-07-17 14:16:41 +000015526 /* fixs390: consider chasing of conditional jumps */
15527
sewardj2019a972011-03-07 16:04:07 +000015528 /* Normal and special instruction handling starts here. */
15529 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
15530 /* All decode failures end up here. The decoder has already issued an
15531 error message.
15532 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000015533 not been executed, and (is currently) the next to be executed.
15534 The insn address in the guest state needs to be set to
15535 guest_IA_curr_instr, otherwise the complaint will report an
15536 incorrect address. */
15537 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000015538
florian8844a632012-04-13 04:04:06 +000015539 dres.whatNext = Dis_StopHere;
15540 dres.jk_StopHere = Ijk_NoDecode;
15541 dres.continueAt = 0;
15542 dres.len = 0;
15543 } else {
15544 /* Decode success */
15545 switch (dres.whatNext) {
15546 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015547 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015548 break;
15549 case Dis_ResteerU:
15550 case Dis_ResteerC:
15551 put_IA(mkaddr_expr(dres.continueAt));
15552 break;
15553 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000015554 if (dres.jk_StopHere == Ijk_EmWarn ||
15555 dres.jk_StopHere == Ijk_EmFail) {
15556 /* We assume here, that emulation warnings are not given for
15557 insns that transfer control. There is no good way to
15558 do that. */
15559 put_IA(mkaddr_expr(guest_IA_next_instr));
15560 }
florian8844a632012-04-13 04:04:06 +000015561 break;
15562 default:
15563 vassert(0);
15564 }
sewardj2019a972011-03-07 16:04:07 +000015565 }
15566
15567 return dres;
15568}
15569
15570
15571/*------------------------------------------------------------*/
15572/*--- Top-level fn ---*/
15573/*------------------------------------------------------------*/
15574
15575/* Disassemble a single instruction into IR. The instruction
15576 is located in host memory at &guest_code[delta]. */
15577
15578DisResult
15579disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015580 Bool (*resteerOkFn)(void *, Addr64),
15581 Bool resteerCisOk,
15582 void *callback_opaque,
15583 UChar *guest_code,
15584 Long delta,
15585 Addr64 guest_IP,
15586 VexArch guest_arch,
15587 VexArchInfo *archinfo,
15588 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000015589 Bool host_bigendian,
15590 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000015591{
15592 vassert(guest_arch == VexArchS390X);
15593
15594 /* The instruction decoder requires a big-endian machine. */
15595 vassert(host_bigendian == True);
15596
15597 /* Set globals (see top of this file) */
15598 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015599 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015600 resteer_fn = resteerOkFn;
15601 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000015602 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000015603
florian420c5012011-07-22 02:12:28 +000015604 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015605}
15606
15607/*---------------------------------------------------------------*/
15608/*--- end guest_s390_toIR.c ---*/
15609/*---------------------------------------------------------------*/