blob: ec475318db1d5cce4a93095994dda701b6206753 [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
243 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
635 op = mkU64(opc);
636 dep1 = mkexpr(d1);
637 dep2 = mkU64(0);
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, dep1, dep2, ndep);
641}
642
643
644/* Write a floating point value and an integer into the flags thunk. The
645 integer value is zero-extended first. */
646static void
647s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
648{
649 IRExpr *op, *dep1, *dep2, *ndep;
650
651 op = mkU64(opc);
652 dep1 = mkexpr(d1);
653 dep2 = s390_cc_widen(d2, False);
654 ndep = mkU64(0);
655
656 s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a 128-bit floating point value into the flags thunk. This is
661 done by splitting the value into two 64-bits values. */
662static void
663s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
664{
665 IRExpr *op, *hi, *lo, *ndep;
666
667 op = mkU64(opc);
668 hi = unop(Iop_F128HItoF64, mkexpr(d1));
669 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, hi, lo, ndep);
673}
674
675
676/* Write a 128-bit floating point value and an integer into the flags thunk.
677 The integer value is zero-extended first. */
678static void
679s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
680{
681 IRExpr *op, *hi, *lo, *lox, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
686 ndep = s390_cc_widen(nd, False);
687
688 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
689
690 s390_cc_thunk_fill(op, hi, lox, ndep);
691}
692
693
floriane38f6412012-12-21 17:32:12 +0000694/* Write a 128-bit decimal floating point value into the flags thunk.
695 This is done by splitting the value into two 64-bits values. */
696static void
697s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
698{
699 IRExpr *op, *hi, *lo, *ndep;
700
701 op = mkU64(opc);
702 hi = unop(Iop_D128HItoD64, mkexpr(d1));
703 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
704 ndep = mkU64(0);
705
706 s390_cc_thunk_fill(op, hi, lo, ndep);
707}
708
709
sewardj2019a972011-03-07 16:04:07 +0000710static void
711s390_cc_set(UInt val)
712{
713 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
714 mkU64(val), mkU64(0), mkU64(0));
715}
716
717/* Build IR to calculate the condition code from flags thunk.
718 Returns an expression of type Ity_I32 */
719static IRExpr *
720s390_call_calculate_cc(void)
721{
722 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
723
florian428dfdd2012-03-27 03:09:49 +0000724 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
725 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
726 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
727 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000728
729 args = mkIRExprVec_4(op, dep1, dep2, ndep);
730 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
731 "s390_calculate_cc", &s390_calculate_cc, args);
732
733 /* Exclude OP and NDEP from definedness checking. We're only
734 interested in DEP1 and DEP2. */
735 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
736
737 return call;
738}
739
740/* Build IR to calculate the internal condition code for a "compare and branch"
741 insn. Returns an expression of type Ity_I32 */
742static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000743s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000744{
florianff9613f2012-05-12 15:26:44 +0000745 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000746
florianff9613f2012-05-12 15:26:44 +0000747 switch (opc) {
748 case S390_CC_OP_SIGNED_COMPARE:
749 dep1 = s390_cc_widen(op1, True);
750 dep2 = s390_cc_widen(op2, True);
751 break;
752
753 case S390_CC_OP_UNSIGNED_COMPARE:
754 dep1 = s390_cc_widen(op1, False);
755 dep2 = s390_cc_widen(op2, False);
756 break;
757
758 default:
759 vpanic("s390_call_calculate_icc");
760 }
761
762 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000763 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000764
florianff9613f2012-05-12 15:26:44 +0000765 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000766 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000767 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000768
florianff9613f2012-05-12 15:26:44 +0000769 /* Exclude the requested condition, OP and NDEP from definedness
770 checking. We're only interested in DEP1 and DEP2. */
771 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000772
773 return call;
774}
775
776/* Build IR to calculate the condition code from flags thunk.
777 Returns an expression of type Ity_I32 */
778static IRExpr *
779s390_call_calculate_cond(UInt m)
780{
781 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
782
783 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000784 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
785 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
786 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
787 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000788
789 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
790 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
791 "s390_calculate_cond", &s390_calculate_cond, args);
792
793 /* Exclude the requested condition, OP and NDEP from definedness
794 checking. We're only interested in DEP1 and DEP2. */
795 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
796
797 return call;
798}
799
800#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
801#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
802#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
803#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
804#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
805#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
806#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
807 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
808#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
809 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000810
811
sewardj2019a972011-03-07 16:04:07 +0000812
813
814/*------------------------------------------------------------*/
815/*--- Guest register access ---*/
816/*------------------------------------------------------------*/
817
818
819/*------------------------------------------------------------*/
820/*--- ar registers ---*/
821/*------------------------------------------------------------*/
822
823/* Return the guest state offset of a ar register. */
824static UInt
825ar_offset(UInt archreg)
826{
827 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000828 S390X_GUEST_OFFSET(guest_a0),
829 S390X_GUEST_OFFSET(guest_a1),
830 S390X_GUEST_OFFSET(guest_a2),
831 S390X_GUEST_OFFSET(guest_a3),
832 S390X_GUEST_OFFSET(guest_a4),
833 S390X_GUEST_OFFSET(guest_a5),
834 S390X_GUEST_OFFSET(guest_a6),
835 S390X_GUEST_OFFSET(guest_a7),
836 S390X_GUEST_OFFSET(guest_a8),
837 S390X_GUEST_OFFSET(guest_a9),
838 S390X_GUEST_OFFSET(guest_a10),
839 S390X_GUEST_OFFSET(guest_a11),
840 S390X_GUEST_OFFSET(guest_a12),
841 S390X_GUEST_OFFSET(guest_a13),
842 S390X_GUEST_OFFSET(guest_a14),
843 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000844 };
845
846 vassert(archreg < 16);
847
848 return offset[archreg];
849}
850
851
852/* Return the guest state offset of word #0 of a ar register. */
853static __inline__ UInt
854ar_w0_offset(UInt archreg)
855{
856 return ar_offset(archreg) + 0;
857}
858
859/* Write word #0 of a ar to the guest state. */
860static __inline__ void
861put_ar_w0(UInt archreg, IRExpr *expr)
862{
863 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
864
865 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
866}
867
868/* Read word #0 of a ar register. */
869static __inline__ IRExpr *
870get_ar_w0(UInt archreg)
871{
872 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
873}
874
875
876/*------------------------------------------------------------*/
877/*--- fpr registers ---*/
878/*------------------------------------------------------------*/
879
880/* Return the guest state offset of a fpr register. */
881static UInt
882fpr_offset(UInt archreg)
883{
884 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000885 S390X_GUEST_OFFSET(guest_f0),
886 S390X_GUEST_OFFSET(guest_f1),
887 S390X_GUEST_OFFSET(guest_f2),
888 S390X_GUEST_OFFSET(guest_f3),
889 S390X_GUEST_OFFSET(guest_f4),
890 S390X_GUEST_OFFSET(guest_f5),
891 S390X_GUEST_OFFSET(guest_f6),
892 S390X_GUEST_OFFSET(guest_f7),
893 S390X_GUEST_OFFSET(guest_f8),
894 S390X_GUEST_OFFSET(guest_f9),
895 S390X_GUEST_OFFSET(guest_f10),
896 S390X_GUEST_OFFSET(guest_f11),
897 S390X_GUEST_OFFSET(guest_f12),
898 S390X_GUEST_OFFSET(guest_f13),
899 S390X_GUEST_OFFSET(guest_f14),
900 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000901 };
902
903 vassert(archreg < 16);
904
905 return offset[archreg];
906}
907
908
909/* Return the guest state offset of word #0 of a fpr register. */
910static __inline__ UInt
911fpr_w0_offset(UInt archreg)
912{
913 return fpr_offset(archreg) + 0;
914}
915
916/* Write word #0 of a fpr to the guest state. */
917static __inline__ void
918put_fpr_w0(UInt archreg, IRExpr *expr)
919{
920 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
921
922 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
923}
924
925/* Read word #0 of a fpr register. */
926static __inline__ IRExpr *
927get_fpr_w0(UInt archreg)
928{
929 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
930}
931
932/* Return the guest state offset of double word #0 of a fpr register. */
933static __inline__ UInt
934fpr_dw0_offset(UInt archreg)
935{
936 return fpr_offset(archreg) + 0;
937}
938
939/* Write double word #0 of a fpr to the guest state. */
940static __inline__ void
941put_fpr_dw0(UInt archreg, IRExpr *expr)
942{
943 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
944
945 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
946}
947
948/* Read double word #0 of a fpr register. */
949static __inline__ IRExpr *
950get_fpr_dw0(UInt archreg)
951{
952 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
953}
954
floriane38f6412012-12-21 17:32:12 +0000955/* Write word #0 of a dpr to the guest state. */
956static __inline__ void
957put_dpr_w0(UInt archreg, IRExpr *expr)
958{
959 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
960
961 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
962}
963
964/* Read word #0 of a dpr register. */
965static __inline__ IRExpr *
966get_dpr_w0(UInt archreg)
967{
968 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
969}
970
florian12390202012-11-10 22:34:14 +0000971/* Write double word #0 of a fpr containg DFP value to the guest state. */
972static __inline__ void
973put_dpr_dw0(UInt archreg, IRExpr *expr)
974{
975 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
976
977 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
978}
979
980/* Read double word #0 of a fpr register containing DFP value. */
981static __inline__ IRExpr *
982get_dpr_dw0(UInt archreg)
983{
984 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
985}
sewardj2019a972011-03-07 16:04:07 +0000986
987/*------------------------------------------------------------*/
988/*--- gpr registers ---*/
989/*------------------------------------------------------------*/
990
991/* Return the guest state offset of a gpr register. */
992static UInt
993gpr_offset(UInt archreg)
994{
995 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000996 S390X_GUEST_OFFSET(guest_r0),
997 S390X_GUEST_OFFSET(guest_r1),
998 S390X_GUEST_OFFSET(guest_r2),
999 S390X_GUEST_OFFSET(guest_r3),
1000 S390X_GUEST_OFFSET(guest_r4),
1001 S390X_GUEST_OFFSET(guest_r5),
1002 S390X_GUEST_OFFSET(guest_r6),
1003 S390X_GUEST_OFFSET(guest_r7),
1004 S390X_GUEST_OFFSET(guest_r8),
1005 S390X_GUEST_OFFSET(guest_r9),
1006 S390X_GUEST_OFFSET(guest_r10),
1007 S390X_GUEST_OFFSET(guest_r11),
1008 S390X_GUEST_OFFSET(guest_r12),
1009 S390X_GUEST_OFFSET(guest_r13),
1010 S390X_GUEST_OFFSET(guest_r14),
1011 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001012 };
1013
1014 vassert(archreg < 16);
1015
1016 return offset[archreg];
1017}
1018
1019
1020/* Return the guest state offset of word #0 of a gpr register. */
1021static __inline__ UInt
1022gpr_w0_offset(UInt archreg)
1023{
1024 return gpr_offset(archreg) + 0;
1025}
1026
1027/* Write word #0 of a gpr to the guest state. */
1028static __inline__ void
1029put_gpr_w0(UInt archreg, IRExpr *expr)
1030{
1031 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1032
1033 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1034}
1035
1036/* Read word #0 of a gpr register. */
1037static __inline__ IRExpr *
1038get_gpr_w0(UInt archreg)
1039{
1040 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1041}
1042
1043/* Return the guest state offset of double word #0 of a gpr register. */
1044static __inline__ UInt
1045gpr_dw0_offset(UInt archreg)
1046{
1047 return gpr_offset(archreg) + 0;
1048}
1049
1050/* Write double word #0 of a gpr to the guest state. */
1051static __inline__ void
1052put_gpr_dw0(UInt archreg, IRExpr *expr)
1053{
1054 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1055
1056 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1057}
1058
1059/* Read double word #0 of a gpr register. */
1060static __inline__ IRExpr *
1061get_gpr_dw0(UInt archreg)
1062{
1063 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1064}
1065
1066/* Return the guest state offset of half word #1 of a gpr register. */
1067static __inline__ UInt
1068gpr_hw1_offset(UInt archreg)
1069{
1070 return gpr_offset(archreg) + 2;
1071}
1072
1073/* Write half word #1 of a gpr to the guest state. */
1074static __inline__ void
1075put_gpr_hw1(UInt archreg, IRExpr *expr)
1076{
1077 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1078
1079 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1080}
1081
1082/* Read half word #1 of a gpr register. */
1083static __inline__ IRExpr *
1084get_gpr_hw1(UInt archreg)
1085{
1086 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1087}
1088
1089/* Return the guest state offset of byte #6 of a gpr register. */
1090static __inline__ UInt
1091gpr_b6_offset(UInt archreg)
1092{
1093 return gpr_offset(archreg) + 6;
1094}
1095
1096/* Write byte #6 of a gpr to the guest state. */
1097static __inline__ void
1098put_gpr_b6(UInt archreg, IRExpr *expr)
1099{
1100 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1101
1102 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1103}
1104
1105/* Read byte #6 of a gpr register. */
1106static __inline__ IRExpr *
1107get_gpr_b6(UInt archreg)
1108{
1109 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1110}
1111
1112/* Return the guest state offset of byte #3 of a gpr register. */
1113static __inline__ UInt
1114gpr_b3_offset(UInt archreg)
1115{
1116 return gpr_offset(archreg) + 3;
1117}
1118
1119/* Write byte #3 of a gpr to the guest state. */
1120static __inline__ void
1121put_gpr_b3(UInt archreg, IRExpr *expr)
1122{
1123 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1124
1125 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1126}
1127
1128/* Read byte #3 of a gpr register. */
1129static __inline__ IRExpr *
1130get_gpr_b3(UInt archreg)
1131{
1132 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1133}
1134
1135/* Return the guest state offset of byte #0 of a gpr register. */
1136static __inline__ UInt
1137gpr_b0_offset(UInt archreg)
1138{
1139 return gpr_offset(archreg) + 0;
1140}
1141
1142/* Write byte #0 of a gpr to the guest state. */
1143static __inline__ void
1144put_gpr_b0(UInt archreg, IRExpr *expr)
1145{
1146 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1147
1148 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1149}
1150
1151/* Read byte #0 of a gpr register. */
1152static __inline__ IRExpr *
1153get_gpr_b0(UInt archreg)
1154{
1155 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1156}
1157
1158/* Return the guest state offset of word #1 of a gpr register. */
1159static __inline__ UInt
1160gpr_w1_offset(UInt archreg)
1161{
1162 return gpr_offset(archreg) + 4;
1163}
1164
1165/* Write word #1 of a gpr to the guest state. */
1166static __inline__ void
1167put_gpr_w1(UInt archreg, IRExpr *expr)
1168{
1169 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1170
1171 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1172}
1173
1174/* Read word #1 of a gpr register. */
1175static __inline__ IRExpr *
1176get_gpr_w1(UInt archreg)
1177{
1178 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1179}
1180
1181/* Return the guest state offset of half word #3 of a gpr register. */
1182static __inline__ UInt
1183gpr_hw3_offset(UInt archreg)
1184{
1185 return gpr_offset(archreg) + 6;
1186}
1187
1188/* Write half word #3 of a gpr to the guest state. */
1189static __inline__ void
1190put_gpr_hw3(UInt archreg, IRExpr *expr)
1191{
1192 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1193
1194 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1195}
1196
1197/* Read half word #3 of a gpr register. */
1198static __inline__ IRExpr *
1199get_gpr_hw3(UInt archreg)
1200{
1201 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1202}
1203
1204/* Return the guest state offset of byte #7 of a gpr register. */
1205static __inline__ UInt
1206gpr_b7_offset(UInt archreg)
1207{
1208 return gpr_offset(archreg) + 7;
1209}
1210
1211/* Write byte #7 of a gpr to the guest state. */
1212static __inline__ void
1213put_gpr_b7(UInt archreg, IRExpr *expr)
1214{
1215 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1216
1217 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1218}
1219
1220/* Read byte #7 of a gpr register. */
1221static __inline__ IRExpr *
1222get_gpr_b7(UInt archreg)
1223{
1224 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1225}
1226
1227/* Return the guest state offset of half word #0 of a gpr register. */
1228static __inline__ UInt
1229gpr_hw0_offset(UInt archreg)
1230{
1231 return gpr_offset(archreg) + 0;
1232}
1233
1234/* Write half word #0 of a gpr to the guest state. */
1235static __inline__ void
1236put_gpr_hw0(UInt archreg, IRExpr *expr)
1237{
1238 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1239
1240 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1241}
1242
1243/* Read half word #0 of a gpr register. */
1244static __inline__ IRExpr *
1245get_gpr_hw0(UInt archreg)
1246{
1247 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1248}
1249
1250/* Return the guest state offset of byte #4 of a gpr register. */
1251static __inline__ UInt
1252gpr_b4_offset(UInt archreg)
1253{
1254 return gpr_offset(archreg) + 4;
1255}
1256
1257/* Write byte #4 of a gpr to the guest state. */
1258static __inline__ void
1259put_gpr_b4(UInt archreg, IRExpr *expr)
1260{
1261 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1262
1263 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1264}
1265
1266/* Read byte #4 of a gpr register. */
1267static __inline__ IRExpr *
1268get_gpr_b4(UInt archreg)
1269{
1270 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1271}
1272
1273/* Return the guest state offset of byte #1 of a gpr register. */
1274static __inline__ UInt
1275gpr_b1_offset(UInt archreg)
1276{
1277 return gpr_offset(archreg) + 1;
1278}
1279
1280/* Write byte #1 of a gpr to the guest state. */
1281static __inline__ void
1282put_gpr_b1(UInt archreg, IRExpr *expr)
1283{
1284 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1285
1286 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1287}
1288
1289/* Read byte #1 of a gpr register. */
1290static __inline__ IRExpr *
1291get_gpr_b1(UInt archreg)
1292{
1293 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1294}
1295
1296/* Return the guest state offset of half word #2 of a gpr register. */
1297static __inline__ UInt
1298gpr_hw2_offset(UInt archreg)
1299{
1300 return gpr_offset(archreg) + 4;
1301}
1302
1303/* Write half word #2 of a gpr to the guest state. */
1304static __inline__ void
1305put_gpr_hw2(UInt archreg, IRExpr *expr)
1306{
1307 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1308
1309 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1310}
1311
1312/* Read half word #2 of a gpr register. */
1313static __inline__ IRExpr *
1314get_gpr_hw2(UInt archreg)
1315{
1316 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1317}
1318
1319/* Return the guest state offset of byte #5 of a gpr register. */
1320static __inline__ UInt
1321gpr_b5_offset(UInt archreg)
1322{
1323 return gpr_offset(archreg) + 5;
1324}
1325
1326/* Write byte #5 of a gpr to the guest state. */
1327static __inline__ void
1328put_gpr_b5(UInt archreg, IRExpr *expr)
1329{
1330 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1331
1332 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1333}
1334
1335/* Read byte #5 of a gpr register. */
1336static __inline__ IRExpr *
1337get_gpr_b5(UInt archreg)
1338{
1339 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1340}
1341
1342/* Return the guest state offset of byte #2 of a gpr register. */
1343static __inline__ UInt
1344gpr_b2_offset(UInt archreg)
1345{
1346 return gpr_offset(archreg) + 2;
1347}
1348
1349/* Write byte #2 of a gpr to the guest state. */
1350static __inline__ void
1351put_gpr_b2(UInt archreg, IRExpr *expr)
1352{
1353 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1354
1355 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1356}
1357
1358/* Read byte #2 of a gpr register. */
1359static __inline__ IRExpr *
1360get_gpr_b2(UInt archreg)
1361{
1362 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1363}
1364
1365/* Return the guest state offset of the counter register. */
1366static UInt
1367counter_offset(void)
1368{
floriane88b3c92011-07-05 02:48:39 +00001369 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001370}
1371
1372/* Return the guest state offset of double word #0 of the counter register. */
1373static __inline__ UInt
1374counter_dw0_offset(void)
1375{
1376 return counter_offset() + 0;
1377}
1378
1379/* Write double word #0 of the counter to the guest state. */
1380static __inline__ void
1381put_counter_dw0(IRExpr *expr)
1382{
1383 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1384
1385 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1386}
1387
1388/* Read double word #0 of the counter register. */
1389static __inline__ IRExpr *
1390get_counter_dw0(void)
1391{
1392 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1393}
1394
1395/* Return the guest state offset of word #0 of the counter register. */
1396static __inline__ UInt
1397counter_w0_offset(void)
1398{
1399 return counter_offset() + 0;
1400}
1401
1402/* Return the guest state offset of word #1 of the counter register. */
1403static __inline__ UInt
1404counter_w1_offset(void)
1405{
1406 return counter_offset() + 4;
1407}
1408
1409/* Write word #0 of the counter to the guest state. */
1410static __inline__ void
1411put_counter_w0(IRExpr *expr)
1412{
1413 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1414
1415 stmt(IRStmt_Put(counter_w0_offset(), expr));
1416}
1417
1418/* Read word #0 of the counter register. */
1419static __inline__ IRExpr *
1420get_counter_w0(void)
1421{
1422 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1423}
1424
1425/* Write word #1 of the counter to the guest state. */
1426static __inline__ void
1427put_counter_w1(IRExpr *expr)
1428{
1429 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1430
1431 stmt(IRStmt_Put(counter_w1_offset(), expr));
1432}
1433
1434/* Read word #1 of the counter register. */
1435static __inline__ IRExpr *
1436get_counter_w1(void)
1437{
1438 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1439}
1440
1441/* Return the guest state offset of the fpc register. */
1442static UInt
1443fpc_offset(void)
1444{
floriane88b3c92011-07-05 02:48:39 +00001445 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001446}
1447
1448/* Return the guest state offset of word #0 of the fpc register. */
1449static __inline__ UInt
1450fpc_w0_offset(void)
1451{
1452 return fpc_offset() + 0;
1453}
1454
1455/* Write word #0 of the fpc to the guest state. */
1456static __inline__ void
1457put_fpc_w0(IRExpr *expr)
1458{
1459 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1460
1461 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1462}
1463
1464/* Read word #0 of the fpc register. */
1465static __inline__ IRExpr *
1466get_fpc_w0(void)
1467{
1468 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1469}
1470
1471
1472/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001473/*--- Rounding modes ---*/
1474/*------------------------------------------------------------*/
1475
florian125e20d2012-10-07 15:42:37 +00001476/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001477 IRRoundingMode:
1478
1479 rounding mode | s390 | IR
1480 -------------------------
1481 to nearest | 00 | 00
1482 to zero | 01 | 11
1483 to +infinity | 10 | 10
1484 to -infinity | 11 | 01
1485
1486 So: IR = (4 - s390) & 3
1487*/
1488static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001489get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001490{
1491 IRTemp fpc_bits = newTemp(Ity_I32);
1492
1493 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1494 Prior to that bits [30:31] contained the bfp rounding mode with
1495 bit 29 being unused and having a value of 0. So we can always
1496 extract the least significant 3 bits. */
1497 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1498
1499 /* fixs390:
1500
1501
1502 if (! s390_host_has_fpext && rounding_mode > 3) {
1503 emulation warning @ runtime and
1504 set fpc to round nearest
1505 }
1506 */
1507
1508 /* For now silently adjust an unsupported rounding mode to "nearest" */
1509 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1510 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001511 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001512
1513 // rm_IR = (4 - rm_s390) & 3;
1514 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1515}
1516
1517/* Encode the s390 rounding mode as it appears in the m3 field of certain
1518 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1519 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1520 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1521 considers the default rounding mode (4.3.3). */
1522static IRTemp
1523encode_bfp_rounding_mode(UChar mode)
1524{
1525 IRExpr *rm;
1526
1527 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001528 case S390_BFP_ROUND_PER_FPC:
1529 rm = get_bfp_rounding_mode_from_fpc();
1530 break;
1531 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1532 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1533 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1534 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1535 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1536 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001537 default:
1538 vpanic("encode_bfp_rounding_mode");
1539 }
1540
1541 return mktemp(Ity_I32, rm);
1542}
1543
florianc8e4f562012-10-27 16:19:31 +00001544/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1545 IRRoundingMode:
1546
1547 rounding mode | s390 | IR
1548 ------------------------------------------------
1549 to nearest, ties to even | 000 | 000
1550 to zero | 001 | 011
1551 to +infinity | 010 | 010
1552 to -infinity | 011 | 001
1553 to nearest, ties away from 0 | 100 | 100
1554 to nearest, ties toward 0 | 101 | 111
1555 to away from 0 | 110 | 110
1556 to prepare for shorter precision | 111 | 101
1557
1558 So: IR = (s390 ^ ((s390 << 1) & 2))
1559*/
florianc8e4f562012-10-27 16:19:31 +00001560static IRExpr *
1561get_dfp_rounding_mode_from_fpc(void)
1562{
1563 IRTemp fpc_bits = newTemp(Ity_I32);
1564
1565 /* The dfp rounding mode is stored in bits [25:27].
1566 extract the bits at 25:27 and right shift 4 times. */
1567 assign(fpc_bits, binop(Iop_Shr32,
1568 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1569 mkU8(4)));
1570
1571 IRExpr *rm_s390 = mkexpr(fpc_bits);
1572 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1573
1574 return binop(Iop_Xor32, rm_s390,
1575 binop( Iop_And32,
1576 binop(Iop_Shl32, rm_s390, mkU8(1)),
1577 mkU32(2)));
1578}
1579
1580/* Encode the s390 rounding mode as it appears in the m3 field of certain
1581 instructions to VEX's IRRoundingMode. */
1582static IRTemp
1583encode_dfp_rounding_mode(UChar mode)
1584{
1585 IRExpr *rm;
1586
1587 switch (mode) {
1588 case S390_DFP_ROUND_PER_FPC_0:
1589 case S390_DFP_ROUND_PER_FPC_2:
1590 rm = get_dfp_rounding_mode_from_fpc(); break;
1591 case S390_DFP_ROUND_NEAREST_EVEN_4:
1592 case S390_DFP_ROUND_NEAREST_EVEN_8:
1593 rm = mkU32(Irrm_DFP_NEAREST); break;
1594 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1595 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1596 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1597 case S390_DFP_ROUND_PREPARE_SHORT_3:
1598 case S390_DFP_ROUND_PREPARE_SHORT_15:
1599 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1600 case S390_DFP_ROUND_ZERO_5:
1601 case S390_DFP_ROUND_ZERO_9:
1602 rm = mkU32(Irrm_DFP_ZERO ); break;
1603 case S390_DFP_ROUND_POSINF_6:
1604 case S390_DFP_ROUND_POSINF_10:
1605 rm = mkU32(Irrm_DFP_PosINF); break;
1606 case S390_DFP_ROUND_NEGINF_7:
1607 case S390_DFP_ROUND_NEGINF_11:
1608 rm = mkU32(Irrm_DFP_NegINF); break;
1609 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1610 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1611 case S390_DFP_ROUND_AWAY_0:
1612 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1613 default:
1614 vpanic("encode_dfp_rounding_mode");
1615 }
1616
1617 return mktemp(Ity_I32, rm);
1618}
florian12390202012-11-10 22:34:14 +00001619
florianc8e4f562012-10-27 16:19:31 +00001620
florian2c74d242012-09-12 19:38:42 +00001621/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001622/*--- Condition code helpers ---*/
1623/*------------------------------------------------------------*/
1624
1625/* The result of a Iop_CmpFxx operation is a condition code. It is
1626 encoded using the values defined in type IRCmpFxxResult.
1627 Before we can store the condition code into the guest state (or do
1628 anything else with it for that matter) we need to convert it to
1629 the encoding that s390 uses. This is what this function does.
1630
1631 s390 VEX b6 b2 b0 cc.1 cc.0
1632 0 0x40 EQ 1 0 0 0 0
1633 1 0x01 LT 0 0 1 0 1
1634 2 0x00 GT 0 0 0 1 0
1635 3 0x45 Unordered 1 1 1 1 1
1636
1637 The following bits from the VEX encoding are interesting:
1638 b0, b2, b6 with b0 being the LSB. We observe:
1639
1640 cc.0 = b0;
1641 cc.1 = b2 | (~b0 & ~b6)
1642
1643 with cc being the s390 condition code.
1644*/
1645static IRExpr *
1646convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1647{
1648 IRTemp cc0 = newTemp(Ity_I32);
1649 IRTemp cc1 = newTemp(Ity_I32);
1650 IRTemp b0 = newTemp(Ity_I32);
1651 IRTemp b2 = newTemp(Ity_I32);
1652 IRTemp b6 = newTemp(Ity_I32);
1653
1654 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1655 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1656 mkU32(1)));
1657 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1658 mkU32(1)));
1659
1660 assign(cc0, mkexpr(b0));
1661 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1662 binop(Iop_And32,
1663 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1664 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1665 )));
1666
1667 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1668}
1669
1670
1671/* The result of a Iop_CmpDxx operation is a condition code. It is
1672 encoded using the values defined in type IRCmpDxxResult.
1673 Before we can store the condition code into the guest state (or do
1674 anything else with it for that matter) we need to convert it to
1675 the encoding that s390 uses. This is what this function does. */
1676static IRExpr *
1677convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1678{
1679 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1680 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001681 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001682}
1683
1684
1685/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001686/*--- Build IR for formats ---*/
1687/*------------------------------------------------------------*/
1688static void
florian55085f82012-11-21 00:36:55 +00001689s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001690 UChar i)
1691{
florian55085f82012-11-21 00:36:55 +00001692 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001693
sewardj7ee97522011-05-09 21:45:04 +00001694 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001695 s390_disasm(ENC2(MNM, UINT), mnm, i);
1696}
1697
1698static void
florian55085f82012-11-21 00:36:55 +00001699s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001700 UChar r1, UShort i2)
1701{
1702 irgen(r1, i2);
1703}
1704
1705static void
florian55085f82012-11-21 00:36:55 +00001706s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001707 UChar r1, UShort i2)
1708{
florian55085f82012-11-21 00:36:55 +00001709 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001710
sewardj7ee97522011-05-09 21:45:04 +00001711 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001712 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1713}
1714
1715static void
florian55085f82012-11-21 00:36:55 +00001716s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001717 UChar r1, UShort i2)
1718{
florian55085f82012-11-21 00:36:55 +00001719 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001720
sewardj7ee97522011-05-09 21:45:04 +00001721 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001722 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1723}
1724
1725static void
florian55085f82012-11-21 00:36:55 +00001726s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001727 UChar r1, UShort i2)
1728{
florian55085f82012-11-21 00:36:55 +00001729 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001730
sewardj7ee97522011-05-09 21:45:04 +00001731 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001732 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1733}
1734
1735static void
florian55085f82012-11-21 00:36:55 +00001736s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001737 UChar r1, UChar r3, UShort i2)
1738{
florian55085f82012-11-21 00:36:55 +00001739 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001740
sewardj7ee97522011-05-09 21:45:04 +00001741 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001742 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1743}
1744
1745static void
florian55085f82012-11-21 00:36:55 +00001746s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001747 UChar r1, UChar r3, UShort i2)
1748{
florian55085f82012-11-21 00:36:55 +00001749 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001750
sewardj7ee97522011-05-09 21:45:04 +00001751 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001752 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1753}
1754
1755static void
florian55085f82012-11-21 00:36:55 +00001756s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1757 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001758 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1759{
florian55085f82012-11-21 00:36:55 +00001760 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001761
sewardj7ee97522011-05-09 21:45:04 +00001762 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001763 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1764 i5);
1765}
1766
1767static void
florian55085f82012-11-21 00:36:55 +00001768s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1769 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001770 UChar r1, UChar r2, UShort i4, UChar m3)
1771{
florian55085f82012-11-21 00:36:55 +00001772 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001773
sewardj7ee97522011-05-09 21:45:04 +00001774 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001775 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1776 r2, m3, (Int)(Short)i4);
1777}
1778
1779static void
florian55085f82012-11-21 00:36:55 +00001780s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1781 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001782 UChar r1, UChar m3, UShort i4, UChar i2)
1783{
florian55085f82012-11-21 00:36:55 +00001784 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001785
sewardj7ee97522011-05-09 21:45:04 +00001786 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001787 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1788 r1, i2, m3, (Int)(Short)i4);
1789}
1790
1791static void
florian55085f82012-11-21 00:36:55 +00001792s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1793 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001794 UChar r1, UChar m3, UShort i4, UChar i2)
1795{
florian55085f82012-11-21 00:36:55 +00001796 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001797
sewardj7ee97522011-05-09 21:45:04 +00001798 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001799 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1800 (Int)(Char)i2, m3, (Int)(Short)i4);
1801}
1802
1803static void
florian55085f82012-11-21 00:36:55 +00001804s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001805 UChar r1, UInt i2)
1806{
1807 irgen(r1, i2);
1808}
1809
1810static void
florian55085f82012-11-21 00:36:55 +00001811s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001812 UChar r1, UInt i2)
1813{
florian55085f82012-11-21 00:36:55 +00001814 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001815
sewardj7ee97522011-05-09 21:45:04 +00001816 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001817 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1818}
1819
1820static void
florian55085f82012-11-21 00:36:55 +00001821s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001822 UChar r1, UInt i2)
1823{
florian55085f82012-11-21 00:36:55 +00001824 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001825
sewardj7ee97522011-05-09 21:45:04 +00001826 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001827 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1828}
1829
1830static void
florian55085f82012-11-21 00:36:55 +00001831s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001832 UChar r1, UInt i2)
1833{
florian55085f82012-11-21 00:36:55 +00001834 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001835
sewardj7ee97522011-05-09 21:45:04 +00001836 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001837 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1838}
1839
1840static void
florian55085f82012-11-21 00:36:55 +00001841s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001842 UChar r1, UInt i2)
1843{
florian55085f82012-11-21 00:36:55 +00001844 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001845
sewardj7ee97522011-05-09 21:45:04 +00001846 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001847 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1848}
1849
1850static void
florian55085f82012-11-21 00:36:55 +00001851s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001852 IRTemp op4addr),
1853 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1854{
florian55085f82012-11-21 00:36:55 +00001855 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001856 IRTemp op4addr = newTemp(Ity_I64);
1857
1858 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1859 mkU64(0)));
1860
1861 mnm = irgen(r1, m3, i2, op4addr);
1862
sewardj7ee97522011-05-09 21:45:04 +00001863 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001864 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1865 (Int)(Char)i2, m3, d4, 0, b4);
1866}
1867
1868static void
florian55085f82012-11-21 00:36:55 +00001869s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001870 IRTemp op4addr),
1871 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1872{
florian55085f82012-11-21 00:36:55 +00001873 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001874 IRTemp op4addr = newTemp(Ity_I64);
1875
1876 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1877 mkU64(0)));
1878
1879 mnm = irgen(r1, m3, i2, op4addr);
1880
sewardj7ee97522011-05-09 21:45:04 +00001881 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001882 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1883 i2, m3, d4, 0, b4);
1884}
1885
1886static void
florian55085f82012-11-21 00:36:55 +00001887s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001888 UChar r1, UChar r2)
1889{
1890 irgen(r1, r2);
1891}
1892
1893static void
florian55085f82012-11-21 00:36:55 +00001894s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001895 UChar r1, UChar r2)
1896{
florian55085f82012-11-21 00:36:55 +00001897 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001898
sewardj7ee97522011-05-09 21:45:04 +00001899 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001900 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1901}
1902
1903static void
florian55085f82012-11-21 00:36:55 +00001904s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001905 UChar r1, UChar r2)
1906{
florian55085f82012-11-21 00:36:55 +00001907 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001908
sewardj7ee97522011-05-09 21:45:04 +00001909 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001910 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1911}
1912
1913static void
florian55085f82012-11-21 00:36:55 +00001914s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001915 UChar r1, UChar r2)
1916{
1917 irgen(r1, r2);
1918}
1919
1920static void
florian55085f82012-11-21 00:36:55 +00001921s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001922 UChar r1, UChar r2)
1923{
florian55085f82012-11-21 00:36:55 +00001924 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001925
sewardj7ee97522011-05-09 21:45:04 +00001926 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001927 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1928}
1929
1930static void
florian55085f82012-11-21 00:36:55 +00001931s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001932 UChar r1, UChar r2)
1933{
florian55085f82012-11-21 00:36:55 +00001934 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001935
sewardj7ee97522011-05-09 21:45:04 +00001936 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001937 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1938}
1939
1940static void
florian55085f82012-11-21 00:36:55 +00001941s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001942 UChar r1, UChar r2)
1943{
florian55085f82012-11-21 00:36:55 +00001944 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001945
sewardj7ee97522011-05-09 21:45:04 +00001946 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001947 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1948}
1949
1950static void
florian55085f82012-11-21 00:36:55 +00001951s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001952 UChar r1, UChar r2)
1953{
florian55085f82012-11-21 00:36:55 +00001954 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001955
sewardj7ee97522011-05-09 21:45:04 +00001956 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001957 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1958}
1959
1960static void
florian55085f82012-11-21 00:36:55 +00001961s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001962 UChar r1)
1963{
florian55085f82012-11-21 00:36:55 +00001964 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001965
sewardj7ee97522011-05-09 21:45:04 +00001966 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001967 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1968}
1969
1970static void
florian55085f82012-11-21 00:36:55 +00001971s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001972 UChar r1)
1973{
florian55085f82012-11-21 00:36:55 +00001974 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001975
sewardj7ee97522011-05-09 21:45:04 +00001976 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001977 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1978}
1979
1980static void
florian55085f82012-11-21 00:36:55 +00001981s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00001982 UChar m3, UChar r1, UChar r2)
1983{
florian55085f82012-11-21 00:36:55 +00001984 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00001985
1986 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00001987 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00001988}
1989
1990static void
florian55085f82012-11-21 00:36:55 +00001991s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001992 UChar r1, UChar r3, UChar r2)
1993{
florian55085f82012-11-21 00:36:55 +00001994 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00001995
sewardj7ee97522011-05-09 21:45:04 +00001996 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001997 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
1998}
1999
2000static void
florian55085f82012-11-21 00:36:55 +00002001s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2002 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002003 UChar m3, UChar m4, UChar r1, UChar r2)
2004{
florian55085f82012-11-21 00:36:55 +00002005 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002006
2007 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2008 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2009}
2010
2011static void
floriane38f6412012-12-21 17:32:12 +00002012s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2013 UChar m4, UChar r1, UChar r2)
2014{
2015 const HChar *mnm = irgen(m4, r1, r2);
2016
2017 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2018 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2019}
2020
2021static void
florian55085f82012-11-21 00:36:55 +00002022s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2023 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002024 UChar m3, UChar m4, UChar r1, UChar r2)
2025{
florian55085f82012-11-21 00:36:55 +00002026 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002027
2028 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2029 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2030}
2031
2032static void
florian55085f82012-11-21 00:36:55 +00002033s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2034 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002035 UChar m3, UChar m4, UChar r1, UChar r2)
2036{
florian55085f82012-11-21 00:36:55 +00002037 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002038
2039 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2040 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2041}
2042
2043
2044static void
florian55085f82012-11-21 00:36:55 +00002045s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002046 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2047{
2048 irgen(m3, r1, r2);
2049
sewardj7ee97522011-05-09 21:45:04 +00002050 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002051 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2052}
2053
2054static void
florian55085f82012-11-21 00:36:55 +00002055s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002056 UChar r3, UChar r1, UChar r2)
2057{
florian55085f82012-11-21 00:36:55 +00002058 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002059
sewardj7ee97522011-05-09 21:45:04 +00002060 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002061 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2062}
2063
2064static void
florian55085f82012-11-21 00:36:55 +00002065s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002066 UChar r3, UChar m4, UChar r1, UChar r2)
2067{
florian55085f82012-11-21 00:36:55 +00002068 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002069
2070 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2071 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2072}
2073
2074static void
florian55085f82012-11-21 00:36:55 +00002075s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002076 UChar r3, UChar r1, UChar r2)
2077{
florian55085f82012-11-21 00:36:55 +00002078 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002079
sewardj7ee97522011-05-09 21:45:04 +00002080 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002081 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2082}
2083
2084static void
florian55085f82012-11-21 00:36:55 +00002085s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2086 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002087 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2088{
florian55085f82012-11-21 00:36:55 +00002089 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002090 IRTemp op4addr = newTemp(Ity_I64);
2091
2092 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2093 mkU64(0)));
2094
2095 mnm = irgen(r1, r2, m3, op4addr);
2096
sewardj7ee97522011-05-09 21:45:04 +00002097 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002098 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2099 r2, m3, d4, 0, b4);
2100}
2101
2102static void
florian55085f82012-11-21 00:36:55 +00002103s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002104 UChar r1, UChar b2, UShort d2)
2105{
florian55085f82012-11-21 00:36:55 +00002106 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002107 IRTemp op2addr = newTemp(Ity_I64);
2108
2109 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2110 mkU64(0)));
2111
2112 mnm = irgen(r1, op2addr);
2113
sewardj7ee97522011-05-09 21:45:04 +00002114 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002115 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2116}
2117
2118static void
florian55085f82012-11-21 00:36:55 +00002119s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002120 UChar r1, UChar r3, UChar b2, UShort d2)
2121{
florian55085f82012-11-21 00:36:55 +00002122 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002123 IRTemp op2addr = newTemp(Ity_I64);
2124
2125 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2126 mkU64(0)));
2127
2128 mnm = irgen(r1, r3, op2addr);
2129
sewardj7ee97522011-05-09 21:45:04 +00002130 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002131 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2132}
2133
2134static void
florian55085f82012-11-21 00:36:55 +00002135s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002136 UChar r1, UChar r3, UChar b2, UShort d2)
2137{
florian55085f82012-11-21 00:36:55 +00002138 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002139 IRTemp op2addr = newTemp(Ity_I64);
2140
2141 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2142 mkU64(0)));
2143
2144 mnm = irgen(r1, r3, op2addr);
2145
sewardj7ee97522011-05-09 21:45:04 +00002146 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002147 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2148}
2149
2150static void
florian55085f82012-11-21 00:36:55 +00002151s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002152 UChar r1, UChar r3, UChar b2, UShort d2)
2153{
florian55085f82012-11-21 00:36:55 +00002154 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002155 IRTemp op2addr = newTemp(Ity_I64);
2156
2157 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2158 mkU64(0)));
2159
2160 mnm = irgen(r1, r3, op2addr);
2161
sewardj7ee97522011-05-09 21:45:04 +00002162 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002163 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2164}
2165
2166static void
florian55085f82012-11-21 00:36:55 +00002167s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002168 UChar r1, UChar r3, UShort i2)
2169{
florian55085f82012-11-21 00:36:55 +00002170 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002171
sewardj7ee97522011-05-09 21:45:04 +00002172 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002173 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2174}
2175
2176static void
florian55085f82012-11-21 00:36:55 +00002177s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002178 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2179{
florian55085f82012-11-21 00:36:55 +00002180 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002181 IRTemp op2addr = newTemp(Ity_I64);
2182 IRTemp d2 = newTemp(Ity_I64);
2183
2184 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2185 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2186 mkU64(0)));
2187
2188 mnm = irgen(r1, r3, op2addr);
2189
sewardj7ee97522011-05-09 21:45:04 +00002190 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002191 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2192}
2193
2194static void
florian55085f82012-11-21 00:36:55 +00002195s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002196 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2197{
florian55085f82012-11-21 00:36:55 +00002198 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002199 IRTemp op2addr = newTemp(Ity_I64);
2200 IRTemp d2 = newTemp(Ity_I64);
2201
2202 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2203 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2204 mkU64(0)));
2205
2206 mnm = irgen(r1, r3, op2addr);
2207
sewardj7ee97522011-05-09 21:45:04 +00002208 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002209 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2210}
2211
2212static void
florian55085f82012-11-21 00:36:55 +00002213s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002214 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2215{
florian55085f82012-11-21 00:36:55 +00002216 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002217 IRTemp op2addr = newTemp(Ity_I64);
2218 IRTemp d2 = newTemp(Ity_I64);
2219
2220 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2221 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2222 mkU64(0)));
2223
2224 mnm = irgen(r1, r3, op2addr);
2225
sewardj7ee97522011-05-09 21:45:04 +00002226 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002227 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2228}
2229
2230static void
florian55085f82012-11-21 00:36:55 +00002231s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002232 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2233 Int xmnm_kind)
2234{
2235 IRTemp op2addr = newTemp(Ity_I64);
2236 IRTemp d2 = newTemp(Ity_I64);
2237
florian6820ba52012-07-26 02:01:50 +00002238 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2239
sewardjd7bde722011-04-05 13:19:33 +00002240 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2241 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2242 mkU64(0)));
2243
2244 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002245
2246 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002247
sewardj7ee97522011-05-09 21:45:04 +00002248 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002249 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2250}
2251
2252static void
florian55085f82012-11-21 00:36:55 +00002253s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002254 IRTemp op2addr),
2255 UChar r1, UChar x2, UChar b2, UShort d2)
2256{
2257 IRTemp op2addr = newTemp(Ity_I64);
2258
2259 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2260 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2261 mkU64(0)));
2262
2263 irgen(r1, x2, b2, d2, op2addr);
2264}
2265
2266static void
florian55085f82012-11-21 00:36:55 +00002267s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002268 UChar r1, UChar x2, UChar b2, UShort d2)
2269{
florian55085f82012-11-21 00:36:55 +00002270 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002271 IRTemp op2addr = newTemp(Ity_I64);
2272
2273 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2274 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2275 mkU64(0)));
2276
2277 mnm = irgen(r1, op2addr);
2278
sewardj7ee97522011-05-09 21:45:04 +00002279 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002280 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2281}
2282
2283static void
florian55085f82012-11-21 00:36:55 +00002284s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002285 UChar r1, UChar x2, UChar b2, UShort d2)
2286{
florian55085f82012-11-21 00:36:55 +00002287 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002288 IRTemp op2addr = newTemp(Ity_I64);
2289
2290 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2291 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2292 mkU64(0)));
2293
2294 mnm = irgen(r1, op2addr);
2295
sewardj7ee97522011-05-09 21:45:04 +00002296 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002297 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2298}
2299
2300static void
florian55085f82012-11-21 00:36:55 +00002301s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002302 UChar r1, UChar x2, UChar b2, UShort d2)
2303{
florian55085f82012-11-21 00:36:55 +00002304 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002305 IRTemp op2addr = newTemp(Ity_I64);
2306
2307 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2308 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2309 mkU64(0)));
2310
2311 mnm = irgen(r1, op2addr);
2312
sewardj7ee97522011-05-09 21:45:04 +00002313 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002314 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2315}
2316
2317static void
florian55085f82012-11-21 00:36:55 +00002318s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002319 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2320{
florian55085f82012-11-21 00:36:55 +00002321 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002322 IRTemp op2addr = newTemp(Ity_I64);
2323
2324 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2325 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2326 mkU64(0)));
2327
2328 mnm = irgen(r3, op2addr, r1);
2329
sewardj7ee97522011-05-09 21:45:04 +00002330 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002331 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2332}
2333
2334static void
florian55085f82012-11-21 00:36:55 +00002335s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002336 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2337{
florian55085f82012-11-21 00:36:55 +00002338 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002339 IRTemp op2addr = newTemp(Ity_I64);
2340 IRTemp d2 = newTemp(Ity_I64);
2341
2342 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2343 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2344 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2345 mkU64(0)));
2346
2347 mnm = irgen(r1, op2addr);
2348
sewardj7ee97522011-05-09 21:45:04 +00002349 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002350 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2351}
2352
2353static void
florian55085f82012-11-21 00:36:55 +00002354s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002355 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2356{
florian55085f82012-11-21 00:36:55 +00002357 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002358 IRTemp op2addr = newTemp(Ity_I64);
2359 IRTemp d2 = newTemp(Ity_I64);
2360
2361 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2362 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2363 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2364 mkU64(0)));
2365
2366 mnm = irgen(r1, op2addr);
2367
sewardj7ee97522011-05-09 21:45:04 +00002368 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002369 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2370}
2371
2372static void
florian55085f82012-11-21 00:36:55 +00002373s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002374 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2375{
florian55085f82012-11-21 00:36:55 +00002376 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002377 IRTemp op2addr = newTemp(Ity_I64);
2378 IRTemp d2 = newTemp(Ity_I64);
2379
2380 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2381 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2382 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2383 mkU64(0)));
2384
2385 mnm = irgen();
2386
sewardj7ee97522011-05-09 21:45:04 +00002387 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002388 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2389}
2390
2391static void
florian55085f82012-11-21 00:36:55 +00002392s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002393 UChar b2, UShort d2)
2394{
florian55085f82012-11-21 00:36:55 +00002395 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002396 IRTemp op2addr = newTemp(Ity_I64);
2397
2398 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2399 mkU64(0)));
2400
2401 mnm = irgen(op2addr);
2402
sewardj7ee97522011-05-09 21:45:04 +00002403 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002404 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2405}
2406
2407static void
florian55085f82012-11-21 00:36:55 +00002408s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002409 UChar i2, UChar b1, UShort d1)
2410{
florian55085f82012-11-21 00:36:55 +00002411 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002412 IRTemp op1addr = newTemp(Ity_I64);
2413
2414 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2415 mkU64(0)));
2416
2417 mnm = irgen(i2, op1addr);
2418
sewardj7ee97522011-05-09 21:45:04 +00002419 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002420 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2421}
2422
2423static void
florian55085f82012-11-21 00:36:55 +00002424s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002425 UChar i2, UChar b1, UShort dl1, UChar dh1)
2426{
florian55085f82012-11-21 00:36:55 +00002427 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002428 IRTemp op1addr = newTemp(Ity_I64);
2429 IRTemp d1 = newTemp(Ity_I64);
2430
2431 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2432 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2433 mkU64(0)));
2434
2435 mnm = irgen(i2, op1addr);
2436
sewardj7ee97522011-05-09 21:45:04 +00002437 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002438 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2439}
2440
2441static void
florian55085f82012-11-21 00:36:55 +00002442s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002443 UChar i2, UChar b1, UShort dl1, UChar dh1)
2444{
florian55085f82012-11-21 00:36:55 +00002445 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002446 IRTemp op1addr = newTemp(Ity_I64);
2447 IRTemp d1 = newTemp(Ity_I64);
2448
2449 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2450 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2451 mkU64(0)));
2452
2453 mnm = irgen(i2, op1addr);
2454
sewardj7ee97522011-05-09 21:45:04 +00002455 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002456 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2457}
2458
2459static void
florian55085f82012-11-21 00:36:55 +00002460s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002461 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2462{
florian55085f82012-11-21 00:36:55 +00002463 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002464 IRTemp op1addr = newTemp(Ity_I64);
2465 IRTemp op2addr = newTemp(Ity_I64);
2466
2467 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2468 mkU64(0)));
2469 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2470 mkU64(0)));
2471
2472 mnm = irgen(l, op1addr, op2addr);
2473
sewardj7ee97522011-05-09 21:45:04 +00002474 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002475 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2476}
2477
2478static void
florian55085f82012-11-21 00:36:55 +00002479s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002480 UChar b1, UShort d1, UShort i2)
2481{
florian55085f82012-11-21 00:36:55 +00002482 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002483 IRTemp op1addr = newTemp(Ity_I64);
2484
2485 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2486 mkU64(0)));
2487
2488 mnm = irgen(i2, op1addr);
2489
sewardj7ee97522011-05-09 21:45:04 +00002490 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002491 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2492}
2493
2494static void
florian55085f82012-11-21 00:36:55 +00002495s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002496 UChar b1, UShort d1, UShort i2)
2497{
florian55085f82012-11-21 00:36:55 +00002498 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002499 IRTemp op1addr = newTemp(Ity_I64);
2500
2501 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2502 mkU64(0)));
2503
2504 mnm = irgen(i2, op1addr);
2505
sewardj7ee97522011-05-09 21:45:04 +00002506 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002507 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2508}
2509
2510
2511
2512/*------------------------------------------------------------*/
2513/*--- Build IR for opcodes ---*/
2514/*------------------------------------------------------------*/
2515
florian55085f82012-11-21 00:36:55 +00002516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002517s390_irgen_AR(UChar r1, UChar r2)
2518{
2519 IRTemp op1 = newTemp(Ity_I32);
2520 IRTemp op2 = newTemp(Ity_I32);
2521 IRTemp result = newTemp(Ity_I32);
2522
2523 assign(op1, get_gpr_w1(r1));
2524 assign(op2, get_gpr_w1(r2));
2525 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2526 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2527 put_gpr_w1(r1, mkexpr(result));
2528
2529 return "ar";
2530}
2531
florian55085f82012-11-21 00:36:55 +00002532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002533s390_irgen_AGR(UChar r1, UChar r2)
2534{
2535 IRTemp op1 = newTemp(Ity_I64);
2536 IRTemp op2 = newTemp(Ity_I64);
2537 IRTemp result = newTemp(Ity_I64);
2538
2539 assign(op1, get_gpr_dw0(r1));
2540 assign(op2, get_gpr_dw0(r2));
2541 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2542 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2543 put_gpr_dw0(r1, mkexpr(result));
2544
2545 return "agr";
2546}
2547
florian55085f82012-11-21 00:36:55 +00002548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002549s390_irgen_AGFR(UChar r1, UChar r2)
2550{
2551 IRTemp op1 = newTemp(Ity_I64);
2552 IRTemp op2 = newTemp(Ity_I64);
2553 IRTemp result = newTemp(Ity_I64);
2554
2555 assign(op1, get_gpr_dw0(r1));
2556 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2557 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2558 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2559 put_gpr_dw0(r1, mkexpr(result));
2560
2561 return "agfr";
2562}
2563
florian55085f82012-11-21 00:36:55 +00002564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002565s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2566{
2567 IRTemp op2 = newTemp(Ity_I32);
2568 IRTemp op3 = newTemp(Ity_I32);
2569 IRTemp result = newTemp(Ity_I32);
2570
2571 assign(op2, get_gpr_w1(r2));
2572 assign(op3, get_gpr_w1(r3));
2573 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2574 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2575 put_gpr_w1(r1, mkexpr(result));
2576
2577 return "ark";
2578}
2579
florian55085f82012-11-21 00:36:55 +00002580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002581s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2582{
2583 IRTemp op2 = newTemp(Ity_I64);
2584 IRTemp op3 = newTemp(Ity_I64);
2585 IRTemp result = newTemp(Ity_I64);
2586
2587 assign(op2, get_gpr_dw0(r2));
2588 assign(op3, get_gpr_dw0(r3));
2589 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2590 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2591 put_gpr_dw0(r1, mkexpr(result));
2592
2593 return "agrk";
2594}
2595
florian55085f82012-11-21 00:36:55 +00002596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002597s390_irgen_A(UChar r1, IRTemp op2addr)
2598{
2599 IRTemp op1 = newTemp(Ity_I32);
2600 IRTemp op2 = newTemp(Ity_I32);
2601 IRTemp result = newTemp(Ity_I32);
2602
2603 assign(op1, get_gpr_w1(r1));
2604 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2605 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2606 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2607 put_gpr_w1(r1, mkexpr(result));
2608
2609 return "a";
2610}
2611
florian55085f82012-11-21 00:36:55 +00002612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002613s390_irgen_AY(UChar r1, IRTemp op2addr)
2614{
2615 IRTemp op1 = newTemp(Ity_I32);
2616 IRTemp op2 = newTemp(Ity_I32);
2617 IRTemp result = newTemp(Ity_I32);
2618
2619 assign(op1, get_gpr_w1(r1));
2620 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2621 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2622 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2623 put_gpr_w1(r1, mkexpr(result));
2624
2625 return "ay";
2626}
2627
florian55085f82012-11-21 00:36:55 +00002628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002629s390_irgen_AG(UChar r1, IRTemp op2addr)
2630{
2631 IRTemp op1 = newTemp(Ity_I64);
2632 IRTemp op2 = newTemp(Ity_I64);
2633 IRTemp result = newTemp(Ity_I64);
2634
2635 assign(op1, get_gpr_dw0(r1));
2636 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2637 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2638 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2639 put_gpr_dw0(r1, mkexpr(result));
2640
2641 return "ag";
2642}
2643
florian55085f82012-11-21 00:36:55 +00002644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002645s390_irgen_AGF(UChar r1, IRTemp op2addr)
2646{
2647 IRTemp op1 = newTemp(Ity_I64);
2648 IRTemp op2 = newTemp(Ity_I64);
2649 IRTemp result = newTemp(Ity_I64);
2650
2651 assign(op1, get_gpr_dw0(r1));
2652 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2653 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2654 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2655 put_gpr_dw0(r1, mkexpr(result));
2656
2657 return "agf";
2658}
2659
florian55085f82012-11-21 00:36:55 +00002660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002661s390_irgen_AFI(UChar r1, UInt i2)
2662{
2663 IRTemp op1 = newTemp(Ity_I32);
2664 Int op2;
2665 IRTemp result = newTemp(Ity_I32);
2666
2667 assign(op1, get_gpr_w1(r1));
2668 op2 = (Int)i2;
2669 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2670 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2671 mkU32((UInt)op2)));
2672 put_gpr_w1(r1, mkexpr(result));
2673
2674 return "afi";
2675}
2676
florian55085f82012-11-21 00:36:55 +00002677static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002678s390_irgen_AGFI(UChar r1, UInt i2)
2679{
2680 IRTemp op1 = newTemp(Ity_I64);
2681 Long op2;
2682 IRTemp result = newTemp(Ity_I64);
2683
2684 assign(op1, get_gpr_dw0(r1));
2685 op2 = (Long)(Int)i2;
2686 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2687 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2688 mkU64((ULong)op2)));
2689 put_gpr_dw0(r1, mkexpr(result));
2690
2691 return "agfi";
2692}
2693
florian55085f82012-11-21 00:36:55 +00002694static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002695s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2696{
2697 Int op2;
2698 IRTemp op3 = newTemp(Ity_I32);
2699 IRTemp result = newTemp(Ity_I32);
2700
2701 op2 = (Int)(Short)i2;
2702 assign(op3, get_gpr_w1(r3));
2703 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2704 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2705 op2)), op3);
2706 put_gpr_w1(r1, mkexpr(result));
2707
2708 return "ahik";
2709}
2710
florian55085f82012-11-21 00:36:55 +00002711static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002712s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2713{
2714 Long op2;
2715 IRTemp op3 = newTemp(Ity_I64);
2716 IRTemp result = newTemp(Ity_I64);
2717
2718 op2 = (Long)(Short)i2;
2719 assign(op3, get_gpr_dw0(r3));
2720 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2721 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2722 op2)), op3);
2723 put_gpr_dw0(r1, mkexpr(result));
2724
2725 return "aghik";
2726}
2727
florian55085f82012-11-21 00:36:55 +00002728static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002729s390_irgen_ASI(UChar i2, IRTemp op1addr)
2730{
2731 IRTemp op1 = newTemp(Ity_I32);
2732 Int op2;
2733 IRTemp result = newTemp(Ity_I32);
2734
2735 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2736 op2 = (Int)(Char)i2;
2737 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2738 store(mkexpr(op1addr), mkexpr(result));
2739 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2740 mkU32((UInt)op2)));
2741
2742 return "asi";
2743}
2744
florian55085f82012-11-21 00:36:55 +00002745static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002746s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2747{
2748 IRTemp op1 = newTemp(Ity_I64);
2749 Long op2;
2750 IRTemp result = newTemp(Ity_I64);
2751
2752 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2753 op2 = (Long)(Char)i2;
2754 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2755 store(mkexpr(op1addr), mkexpr(result));
2756 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2757 mkU64((ULong)op2)));
2758
2759 return "agsi";
2760}
2761
florian55085f82012-11-21 00:36:55 +00002762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002763s390_irgen_AH(UChar r1, IRTemp op2addr)
2764{
2765 IRTemp op1 = newTemp(Ity_I32);
2766 IRTemp op2 = newTemp(Ity_I32);
2767 IRTemp result = newTemp(Ity_I32);
2768
2769 assign(op1, get_gpr_w1(r1));
2770 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2771 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2772 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2773 put_gpr_w1(r1, mkexpr(result));
2774
2775 return "ah";
2776}
2777
florian55085f82012-11-21 00:36:55 +00002778static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002779s390_irgen_AHY(UChar r1, IRTemp op2addr)
2780{
2781 IRTemp op1 = newTemp(Ity_I32);
2782 IRTemp op2 = newTemp(Ity_I32);
2783 IRTemp result = newTemp(Ity_I32);
2784
2785 assign(op1, get_gpr_w1(r1));
2786 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2787 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2788 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2789 put_gpr_w1(r1, mkexpr(result));
2790
2791 return "ahy";
2792}
2793
florian55085f82012-11-21 00:36:55 +00002794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002795s390_irgen_AHI(UChar r1, UShort i2)
2796{
2797 IRTemp op1 = newTemp(Ity_I32);
2798 Int op2;
2799 IRTemp result = newTemp(Ity_I32);
2800
2801 assign(op1, get_gpr_w1(r1));
2802 op2 = (Int)(Short)i2;
2803 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2804 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2805 mkU32((UInt)op2)));
2806 put_gpr_w1(r1, mkexpr(result));
2807
2808 return "ahi";
2809}
2810
florian55085f82012-11-21 00:36:55 +00002811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002812s390_irgen_AGHI(UChar r1, UShort i2)
2813{
2814 IRTemp op1 = newTemp(Ity_I64);
2815 Long op2;
2816 IRTemp result = newTemp(Ity_I64);
2817
2818 assign(op1, get_gpr_dw0(r1));
2819 op2 = (Long)(Short)i2;
2820 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2821 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2822 mkU64((ULong)op2)));
2823 put_gpr_dw0(r1, mkexpr(result));
2824
2825 return "aghi";
2826}
2827
florian55085f82012-11-21 00:36:55 +00002828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002829s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2830{
2831 IRTemp op2 = newTemp(Ity_I32);
2832 IRTemp op3 = newTemp(Ity_I32);
2833 IRTemp result = newTemp(Ity_I32);
2834
2835 assign(op2, get_gpr_w0(r2));
2836 assign(op3, get_gpr_w0(r3));
2837 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2838 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2839 put_gpr_w0(r1, mkexpr(result));
2840
2841 return "ahhhr";
2842}
2843
florian55085f82012-11-21 00:36:55 +00002844static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002845s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2846{
2847 IRTemp op2 = newTemp(Ity_I32);
2848 IRTemp op3 = newTemp(Ity_I32);
2849 IRTemp result = newTemp(Ity_I32);
2850
2851 assign(op2, get_gpr_w0(r2));
2852 assign(op3, get_gpr_w1(r3));
2853 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2854 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2855 put_gpr_w0(r1, mkexpr(result));
2856
2857 return "ahhlr";
2858}
2859
florian55085f82012-11-21 00:36:55 +00002860static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002861s390_irgen_AIH(UChar r1, UInt i2)
2862{
2863 IRTemp op1 = newTemp(Ity_I32);
2864 Int op2;
2865 IRTemp result = newTemp(Ity_I32);
2866
2867 assign(op1, get_gpr_w0(r1));
2868 op2 = (Int)i2;
2869 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2870 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2871 mkU32((UInt)op2)));
2872 put_gpr_w0(r1, mkexpr(result));
2873
2874 return "aih";
2875}
2876
florian55085f82012-11-21 00:36:55 +00002877static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002878s390_irgen_ALR(UChar r1, UChar r2)
2879{
2880 IRTemp op1 = newTemp(Ity_I32);
2881 IRTemp op2 = newTemp(Ity_I32);
2882 IRTemp result = newTemp(Ity_I32);
2883
2884 assign(op1, get_gpr_w1(r1));
2885 assign(op2, get_gpr_w1(r2));
2886 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2887 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2888 put_gpr_w1(r1, mkexpr(result));
2889
2890 return "alr";
2891}
2892
florian55085f82012-11-21 00:36:55 +00002893static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002894s390_irgen_ALGR(UChar r1, UChar r2)
2895{
2896 IRTemp op1 = newTemp(Ity_I64);
2897 IRTemp op2 = newTemp(Ity_I64);
2898 IRTemp result = newTemp(Ity_I64);
2899
2900 assign(op1, get_gpr_dw0(r1));
2901 assign(op2, get_gpr_dw0(r2));
2902 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2903 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2904 put_gpr_dw0(r1, mkexpr(result));
2905
2906 return "algr";
2907}
2908
florian55085f82012-11-21 00:36:55 +00002909static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002910s390_irgen_ALGFR(UChar r1, UChar r2)
2911{
2912 IRTemp op1 = newTemp(Ity_I64);
2913 IRTemp op2 = newTemp(Ity_I64);
2914 IRTemp result = newTemp(Ity_I64);
2915
2916 assign(op1, get_gpr_dw0(r1));
2917 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2918 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2919 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2920 put_gpr_dw0(r1, mkexpr(result));
2921
2922 return "algfr";
2923}
2924
florian55085f82012-11-21 00:36:55 +00002925static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002926s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2927{
2928 IRTemp op2 = newTemp(Ity_I32);
2929 IRTemp op3 = newTemp(Ity_I32);
2930 IRTemp result = newTemp(Ity_I32);
2931
2932 assign(op2, get_gpr_w1(r2));
2933 assign(op3, get_gpr_w1(r3));
2934 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2935 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2936 put_gpr_w1(r1, mkexpr(result));
2937
2938 return "alrk";
2939}
2940
florian55085f82012-11-21 00:36:55 +00002941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002942s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2943{
2944 IRTemp op2 = newTemp(Ity_I64);
2945 IRTemp op3 = newTemp(Ity_I64);
2946 IRTemp result = newTemp(Ity_I64);
2947
2948 assign(op2, get_gpr_dw0(r2));
2949 assign(op3, get_gpr_dw0(r3));
2950 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2951 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2952 put_gpr_dw0(r1, mkexpr(result));
2953
2954 return "algrk";
2955}
2956
florian55085f82012-11-21 00:36:55 +00002957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002958s390_irgen_AL(UChar r1, IRTemp op2addr)
2959{
2960 IRTemp op1 = newTemp(Ity_I32);
2961 IRTemp op2 = newTemp(Ity_I32);
2962 IRTemp result = newTemp(Ity_I32);
2963
2964 assign(op1, get_gpr_w1(r1));
2965 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2966 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2967 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2968 put_gpr_w1(r1, mkexpr(result));
2969
2970 return "al";
2971}
2972
florian55085f82012-11-21 00:36:55 +00002973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002974s390_irgen_ALY(UChar r1, IRTemp op2addr)
2975{
2976 IRTemp op1 = newTemp(Ity_I32);
2977 IRTemp op2 = newTemp(Ity_I32);
2978 IRTemp result = newTemp(Ity_I32);
2979
2980 assign(op1, get_gpr_w1(r1));
2981 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2982 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2983 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2984 put_gpr_w1(r1, mkexpr(result));
2985
2986 return "aly";
2987}
2988
florian55085f82012-11-21 00:36:55 +00002989static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002990s390_irgen_ALG(UChar r1, IRTemp op2addr)
2991{
2992 IRTemp op1 = newTemp(Ity_I64);
2993 IRTemp op2 = newTemp(Ity_I64);
2994 IRTemp result = newTemp(Ity_I64);
2995
2996 assign(op1, get_gpr_dw0(r1));
2997 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2998 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2999 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3000 put_gpr_dw0(r1, mkexpr(result));
3001
3002 return "alg";
3003}
3004
florian55085f82012-11-21 00:36:55 +00003005static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003006s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3007{
3008 IRTemp op1 = newTemp(Ity_I64);
3009 IRTemp op2 = newTemp(Ity_I64);
3010 IRTemp result = newTemp(Ity_I64);
3011
3012 assign(op1, get_gpr_dw0(r1));
3013 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3014 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3015 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3016 put_gpr_dw0(r1, mkexpr(result));
3017
3018 return "algf";
3019}
3020
florian55085f82012-11-21 00:36:55 +00003021static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003022s390_irgen_ALFI(UChar r1, UInt i2)
3023{
3024 IRTemp op1 = newTemp(Ity_I32);
3025 UInt op2;
3026 IRTemp result = newTemp(Ity_I32);
3027
3028 assign(op1, get_gpr_w1(r1));
3029 op2 = i2;
3030 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3031 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3032 mkU32(op2)));
3033 put_gpr_w1(r1, mkexpr(result));
3034
3035 return "alfi";
3036}
3037
florian55085f82012-11-21 00:36:55 +00003038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003039s390_irgen_ALGFI(UChar r1, UInt i2)
3040{
3041 IRTemp op1 = newTemp(Ity_I64);
3042 ULong op2;
3043 IRTemp result = newTemp(Ity_I64);
3044
3045 assign(op1, get_gpr_dw0(r1));
3046 op2 = (ULong)i2;
3047 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3048 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3049 mkU64(op2)));
3050 put_gpr_dw0(r1, mkexpr(result));
3051
3052 return "algfi";
3053}
3054
florian55085f82012-11-21 00:36:55 +00003055static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003056s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3057{
3058 IRTemp op2 = newTemp(Ity_I32);
3059 IRTemp op3 = newTemp(Ity_I32);
3060 IRTemp result = newTemp(Ity_I32);
3061
3062 assign(op2, get_gpr_w0(r2));
3063 assign(op3, get_gpr_w0(r3));
3064 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3065 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3066 put_gpr_w0(r1, mkexpr(result));
3067
3068 return "alhhhr";
3069}
3070
florian55085f82012-11-21 00:36:55 +00003071static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003072s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3073{
3074 IRTemp op2 = newTemp(Ity_I32);
3075 IRTemp op3 = newTemp(Ity_I32);
3076 IRTemp result = newTemp(Ity_I32);
3077
3078 assign(op2, get_gpr_w0(r2));
3079 assign(op3, get_gpr_w1(r3));
3080 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3081 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3082 put_gpr_w0(r1, mkexpr(result));
3083
3084 return "alhhlr";
3085}
3086
florian55085f82012-11-21 00:36:55 +00003087static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003088s390_irgen_ALCR(UChar r1, UChar r2)
3089{
3090 IRTemp op1 = newTemp(Ity_I32);
3091 IRTemp op2 = newTemp(Ity_I32);
3092 IRTemp result = newTemp(Ity_I32);
3093 IRTemp carry_in = newTemp(Ity_I32);
3094
3095 assign(op1, get_gpr_w1(r1));
3096 assign(op2, get_gpr_w1(r2));
3097 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3098 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3099 mkexpr(carry_in)));
3100 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3101 put_gpr_w1(r1, mkexpr(result));
3102
3103 return "alcr";
3104}
3105
florian55085f82012-11-21 00:36:55 +00003106static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003107s390_irgen_ALCGR(UChar r1, UChar r2)
3108{
3109 IRTemp op1 = newTemp(Ity_I64);
3110 IRTemp op2 = newTemp(Ity_I64);
3111 IRTemp result = newTemp(Ity_I64);
3112 IRTemp carry_in = newTemp(Ity_I64);
3113
3114 assign(op1, get_gpr_dw0(r1));
3115 assign(op2, get_gpr_dw0(r2));
3116 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3117 mkU8(1))));
3118 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3119 mkexpr(carry_in)));
3120 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3121 put_gpr_dw0(r1, mkexpr(result));
3122
3123 return "alcgr";
3124}
3125
florian55085f82012-11-21 00:36:55 +00003126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003127s390_irgen_ALC(UChar r1, IRTemp op2addr)
3128{
3129 IRTemp op1 = newTemp(Ity_I32);
3130 IRTemp op2 = newTemp(Ity_I32);
3131 IRTemp result = newTemp(Ity_I32);
3132 IRTemp carry_in = newTemp(Ity_I32);
3133
3134 assign(op1, get_gpr_w1(r1));
3135 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3136 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3137 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3138 mkexpr(carry_in)));
3139 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3140 put_gpr_w1(r1, mkexpr(result));
3141
3142 return "alc";
3143}
3144
florian55085f82012-11-21 00:36:55 +00003145static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003146s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3147{
3148 IRTemp op1 = newTemp(Ity_I64);
3149 IRTemp op2 = newTemp(Ity_I64);
3150 IRTemp result = newTemp(Ity_I64);
3151 IRTemp carry_in = newTemp(Ity_I64);
3152
3153 assign(op1, get_gpr_dw0(r1));
3154 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3155 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3156 mkU8(1))));
3157 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3158 mkexpr(carry_in)));
3159 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3160 put_gpr_dw0(r1, mkexpr(result));
3161
3162 return "alcg";
3163}
3164
florian55085f82012-11-21 00:36:55 +00003165static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003166s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3167{
3168 IRTemp op1 = newTemp(Ity_I32);
3169 UInt op2;
3170 IRTemp result = newTemp(Ity_I32);
3171
3172 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3173 op2 = (UInt)(Int)(Char)i2;
3174 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3175 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3176 mkU32(op2)));
3177 store(mkexpr(op1addr), mkexpr(result));
3178
3179 return "alsi";
3180}
3181
florian55085f82012-11-21 00:36:55 +00003182static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003183s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3184{
3185 IRTemp op1 = newTemp(Ity_I64);
3186 ULong op2;
3187 IRTemp result = newTemp(Ity_I64);
3188
3189 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3190 op2 = (ULong)(Long)(Char)i2;
3191 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3192 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3193 mkU64(op2)));
3194 store(mkexpr(op1addr), mkexpr(result));
3195
3196 return "algsi";
3197}
3198
florian55085f82012-11-21 00:36:55 +00003199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003200s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3201{
3202 UInt op2;
3203 IRTemp op3 = newTemp(Ity_I32);
3204 IRTemp result = newTemp(Ity_I32);
3205
3206 op2 = (UInt)(Int)(Short)i2;
3207 assign(op3, get_gpr_w1(r3));
3208 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3209 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3210 op3);
3211 put_gpr_w1(r1, mkexpr(result));
3212
3213 return "alhsik";
3214}
3215
florian55085f82012-11-21 00:36:55 +00003216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003217s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3218{
3219 ULong op2;
3220 IRTemp op3 = newTemp(Ity_I64);
3221 IRTemp result = newTemp(Ity_I64);
3222
3223 op2 = (ULong)(Long)(Short)i2;
3224 assign(op3, get_gpr_dw0(r3));
3225 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3226 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3227 op3);
3228 put_gpr_dw0(r1, mkexpr(result));
3229
3230 return "alghsik";
3231}
3232
florian55085f82012-11-21 00:36:55 +00003233static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003234s390_irgen_ALSIH(UChar r1, UInt i2)
3235{
3236 IRTemp op1 = newTemp(Ity_I32);
3237 UInt op2;
3238 IRTemp result = newTemp(Ity_I32);
3239
3240 assign(op1, get_gpr_w0(r1));
3241 op2 = i2;
3242 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3243 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3244 mkU32(op2)));
3245 put_gpr_w0(r1, mkexpr(result));
3246
3247 return "alsih";
3248}
3249
florian55085f82012-11-21 00:36:55 +00003250static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003251s390_irgen_ALSIHN(UChar r1, UInt i2)
3252{
3253 IRTemp op1 = newTemp(Ity_I32);
3254 UInt op2;
3255 IRTemp result = newTemp(Ity_I32);
3256
3257 assign(op1, get_gpr_w0(r1));
3258 op2 = i2;
3259 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3260 put_gpr_w0(r1, mkexpr(result));
3261
3262 return "alsihn";
3263}
3264
florian55085f82012-11-21 00:36:55 +00003265static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003266s390_irgen_NR(UChar r1, UChar r2)
3267{
3268 IRTemp op1 = newTemp(Ity_I32);
3269 IRTemp op2 = newTemp(Ity_I32);
3270 IRTemp result = newTemp(Ity_I32);
3271
3272 assign(op1, get_gpr_w1(r1));
3273 assign(op2, get_gpr_w1(r2));
3274 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3275 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3276 put_gpr_w1(r1, mkexpr(result));
3277
3278 return "nr";
3279}
3280
florian55085f82012-11-21 00:36:55 +00003281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003282s390_irgen_NGR(UChar r1, UChar r2)
3283{
3284 IRTemp op1 = newTemp(Ity_I64);
3285 IRTemp op2 = newTemp(Ity_I64);
3286 IRTemp result = newTemp(Ity_I64);
3287
3288 assign(op1, get_gpr_dw0(r1));
3289 assign(op2, get_gpr_dw0(r2));
3290 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3291 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3292 put_gpr_dw0(r1, mkexpr(result));
3293
3294 return "ngr";
3295}
3296
florian55085f82012-11-21 00:36:55 +00003297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003298s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3299{
3300 IRTemp op2 = newTemp(Ity_I32);
3301 IRTemp op3 = newTemp(Ity_I32);
3302 IRTemp result = newTemp(Ity_I32);
3303
3304 assign(op2, get_gpr_w1(r2));
3305 assign(op3, get_gpr_w1(r3));
3306 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3307 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3308 put_gpr_w1(r1, mkexpr(result));
3309
3310 return "nrk";
3311}
3312
florian55085f82012-11-21 00:36:55 +00003313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003314s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3315{
3316 IRTemp op2 = newTemp(Ity_I64);
3317 IRTemp op3 = newTemp(Ity_I64);
3318 IRTemp result = newTemp(Ity_I64);
3319
3320 assign(op2, get_gpr_dw0(r2));
3321 assign(op3, get_gpr_dw0(r3));
3322 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3323 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3324 put_gpr_dw0(r1, mkexpr(result));
3325
3326 return "ngrk";
3327}
3328
florian55085f82012-11-21 00:36:55 +00003329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003330s390_irgen_N(UChar r1, IRTemp op2addr)
3331{
3332 IRTemp op1 = newTemp(Ity_I32);
3333 IRTemp op2 = newTemp(Ity_I32);
3334 IRTemp result = newTemp(Ity_I32);
3335
3336 assign(op1, get_gpr_w1(r1));
3337 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3338 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3339 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3340 put_gpr_w1(r1, mkexpr(result));
3341
3342 return "n";
3343}
3344
florian55085f82012-11-21 00:36:55 +00003345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003346s390_irgen_NY(UChar r1, IRTemp op2addr)
3347{
3348 IRTemp op1 = newTemp(Ity_I32);
3349 IRTemp op2 = newTemp(Ity_I32);
3350 IRTemp result = newTemp(Ity_I32);
3351
3352 assign(op1, get_gpr_w1(r1));
3353 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3354 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3355 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3356 put_gpr_w1(r1, mkexpr(result));
3357
3358 return "ny";
3359}
3360
florian55085f82012-11-21 00:36:55 +00003361static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003362s390_irgen_NG(UChar r1, IRTemp op2addr)
3363{
3364 IRTemp op1 = newTemp(Ity_I64);
3365 IRTemp op2 = newTemp(Ity_I64);
3366 IRTemp result = newTemp(Ity_I64);
3367
3368 assign(op1, get_gpr_dw0(r1));
3369 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3370 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3371 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3372 put_gpr_dw0(r1, mkexpr(result));
3373
3374 return "ng";
3375}
3376
florian55085f82012-11-21 00:36:55 +00003377static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003378s390_irgen_NI(UChar i2, IRTemp op1addr)
3379{
3380 IRTemp op1 = newTemp(Ity_I8);
3381 UChar op2;
3382 IRTemp result = newTemp(Ity_I8);
3383
3384 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3385 op2 = i2;
3386 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3387 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3388 store(mkexpr(op1addr), mkexpr(result));
3389
3390 return "ni";
3391}
3392
florian55085f82012-11-21 00:36:55 +00003393static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003394s390_irgen_NIY(UChar i2, IRTemp op1addr)
3395{
3396 IRTemp op1 = newTemp(Ity_I8);
3397 UChar op2;
3398 IRTemp result = newTemp(Ity_I8);
3399
3400 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3401 op2 = i2;
3402 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3403 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3404 store(mkexpr(op1addr), mkexpr(result));
3405
3406 return "niy";
3407}
3408
florian55085f82012-11-21 00:36:55 +00003409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003410s390_irgen_NIHF(UChar r1, UInt i2)
3411{
3412 IRTemp op1 = newTemp(Ity_I32);
3413 UInt op2;
3414 IRTemp result = newTemp(Ity_I32);
3415
3416 assign(op1, get_gpr_w0(r1));
3417 op2 = i2;
3418 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3419 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3420 put_gpr_w0(r1, mkexpr(result));
3421
3422 return "nihf";
3423}
3424
florian55085f82012-11-21 00:36:55 +00003425static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003426s390_irgen_NIHH(UChar r1, UShort i2)
3427{
3428 IRTemp op1 = newTemp(Ity_I16);
3429 UShort op2;
3430 IRTemp result = newTemp(Ity_I16);
3431
3432 assign(op1, get_gpr_hw0(r1));
3433 op2 = i2;
3434 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3435 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3436 put_gpr_hw0(r1, mkexpr(result));
3437
3438 return "nihh";
3439}
3440
florian55085f82012-11-21 00:36:55 +00003441static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003442s390_irgen_NIHL(UChar r1, UShort i2)
3443{
3444 IRTemp op1 = newTemp(Ity_I16);
3445 UShort op2;
3446 IRTemp result = newTemp(Ity_I16);
3447
3448 assign(op1, get_gpr_hw1(r1));
3449 op2 = i2;
3450 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3451 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3452 put_gpr_hw1(r1, mkexpr(result));
3453
3454 return "nihl";
3455}
3456
florian55085f82012-11-21 00:36:55 +00003457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003458s390_irgen_NILF(UChar r1, UInt i2)
3459{
3460 IRTemp op1 = newTemp(Ity_I32);
3461 UInt op2;
3462 IRTemp result = newTemp(Ity_I32);
3463
3464 assign(op1, get_gpr_w1(r1));
3465 op2 = i2;
3466 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3467 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3468 put_gpr_w1(r1, mkexpr(result));
3469
3470 return "nilf";
3471}
3472
florian55085f82012-11-21 00:36:55 +00003473static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003474s390_irgen_NILH(UChar r1, UShort i2)
3475{
3476 IRTemp op1 = newTemp(Ity_I16);
3477 UShort op2;
3478 IRTemp result = newTemp(Ity_I16);
3479
3480 assign(op1, get_gpr_hw2(r1));
3481 op2 = i2;
3482 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3483 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3484 put_gpr_hw2(r1, mkexpr(result));
3485
3486 return "nilh";
3487}
3488
florian55085f82012-11-21 00:36:55 +00003489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003490s390_irgen_NILL(UChar r1, UShort i2)
3491{
3492 IRTemp op1 = newTemp(Ity_I16);
3493 UShort op2;
3494 IRTemp result = newTemp(Ity_I16);
3495
3496 assign(op1, get_gpr_hw3(r1));
3497 op2 = i2;
3498 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3499 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3500 put_gpr_hw3(r1, mkexpr(result));
3501
3502 return "nill";
3503}
3504
florian55085f82012-11-21 00:36:55 +00003505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003506s390_irgen_BASR(UChar r1, UChar r2)
3507{
3508 IRTemp target = newTemp(Ity_I64);
3509
3510 if (r2 == 0) {
3511 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3512 } else {
3513 if (r1 != r2) {
3514 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3515 call_function(get_gpr_dw0(r2));
3516 } else {
3517 assign(target, get_gpr_dw0(r2));
3518 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3519 call_function(mkexpr(target));
3520 }
3521 }
3522
3523 return "basr";
3524}
3525
florian55085f82012-11-21 00:36:55 +00003526static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003527s390_irgen_BAS(UChar r1, IRTemp op2addr)
3528{
3529 IRTemp target = newTemp(Ity_I64);
3530
3531 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3532 assign(target, mkexpr(op2addr));
3533 call_function(mkexpr(target));
3534
3535 return "bas";
3536}
3537
florian55085f82012-11-21 00:36:55 +00003538static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003539s390_irgen_BCR(UChar r1, UChar r2)
3540{
3541 IRTemp cond = newTemp(Ity_I32);
3542
sewardja52e37e2011-04-28 18:48:06 +00003543 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3544 stmt(IRStmt_MBE(Imbe_Fence));
3545 }
3546
sewardj2019a972011-03-07 16:04:07 +00003547 if ((r2 == 0) || (r1 == 0)) {
3548 } else {
3549 if (r1 == 15) {
3550 return_from_function(get_gpr_dw0(r2));
3551 } else {
3552 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003553 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3554 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003555 }
3556 }
sewardj7ee97522011-05-09 21:45:04 +00003557 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003558 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3559
3560 return "bcr";
3561}
3562
florian55085f82012-11-21 00:36:55 +00003563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003564s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3565{
3566 IRTemp cond = newTemp(Ity_I32);
3567
3568 if (r1 == 0) {
3569 } else {
3570 if (r1 == 15) {
3571 always_goto(mkexpr(op2addr));
3572 } else {
3573 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003574 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3575 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003576 }
3577 }
sewardj7ee97522011-05-09 21:45:04 +00003578 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003579 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3580
3581 return "bc";
3582}
3583
florian55085f82012-11-21 00:36:55 +00003584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003585s390_irgen_BCTR(UChar r1, UChar r2)
3586{
3587 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3588 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003589 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3590 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003591 }
3592
3593 return "bctr";
3594}
3595
florian55085f82012-11-21 00:36:55 +00003596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003597s390_irgen_BCTGR(UChar r1, UChar r2)
3598{
3599 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3600 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003601 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3602 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003603 }
3604
3605 return "bctgr";
3606}
3607
florian55085f82012-11-21 00:36:55 +00003608static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003609s390_irgen_BCT(UChar r1, IRTemp op2addr)
3610{
3611 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003612 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3613 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003614
3615 return "bct";
3616}
3617
florian55085f82012-11-21 00:36:55 +00003618static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003619s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3620{
3621 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003622 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3623 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003624
3625 return "bctg";
3626}
3627
florian55085f82012-11-21 00:36:55 +00003628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003629s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3630{
3631 IRTemp value = newTemp(Ity_I32);
3632
3633 assign(value, get_gpr_w1(r3 | 1));
3634 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003635 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3636 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003637
3638 return "bxh";
3639}
3640
florian55085f82012-11-21 00:36:55 +00003641static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003642s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3643{
3644 IRTemp value = newTemp(Ity_I64);
3645
3646 assign(value, get_gpr_dw0(r3 | 1));
3647 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003648 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3649 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003650
3651 return "bxhg";
3652}
3653
florian55085f82012-11-21 00:36:55 +00003654static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003655s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3656{
3657 IRTemp value = newTemp(Ity_I32);
3658
3659 assign(value, get_gpr_w1(r3 | 1));
3660 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003661 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3662 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003663
3664 return "bxle";
3665}
3666
florian55085f82012-11-21 00:36:55 +00003667static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003668s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3669{
3670 IRTemp value = newTemp(Ity_I64);
3671
3672 assign(value, get_gpr_dw0(r3 | 1));
3673 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003674 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3675 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003676
3677 return "bxleg";
3678}
3679
florian55085f82012-11-21 00:36:55 +00003680static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003681s390_irgen_BRAS(UChar r1, UShort i2)
3682{
3683 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003684 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003685
3686 return "bras";
3687}
3688
florian55085f82012-11-21 00:36:55 +00003689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003690s390_irgen_BRASL(UChar r1, UInt i2)
3691{
3692 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003693 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003694
3695 return "brasl";
3696}
3697
florian55085f82012-11-21 00:36:55 +00003698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003699s390_irgen_BRC(UChar r1, UShort i2)
3700{
3701 IRTemp cond = newTemp(Ity_I32);
3702
3703 if (r1 == 0) {
3704 } else {
3705 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003706 always_goto_and_chase(
3707 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003708 } else {
3709 assign(cond, s390_call_calculate_cond(r1));
3710 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3711 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3712
3713 }
3714 }
sewardj7ee97522011-05-09 21:45:04 +00003715 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003716 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3717
3718 return "brc";
3719}
3720
florian55085f82012-11-21 00:36:55 +00003721static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003722s390_irgen_BRCL(UChar r1, UInt i2)
3723{
3724 IRTemp cond = newTemp(Ity_I32);
3725
3726 if (r1 == 0) {
3727 } else {
3728 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003729 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003730 } else {
3731 assign(cond, s390_call_calculate_cond(r1));
3732 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3733 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3734 }
3735 }
sewardj7ee97522011-05-09 21:45:04 +00003736 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003737 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3738
3739 return "brcl";
3740}
3741
florian55085f82012-11-21 00:36:55 +00003742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003743s390_irgen_BRCT(UChar r1, UShort i2)
3744{
3745 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3746 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3747 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3748
3749 return "brct";
3750}
3751
florian55085f82012-11-21 00:36:55 +00003752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003753s390_irgen_BRCTG(UChar r1, UShort i2)
3754{
3755 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3756 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3757 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3758
3759 return "brctg";
3760}
3761
florian55085f82012-11-21 00:36:55 +00003762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003763s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3764{
3765 IRTemp value = newTemp(Ity_I32);
3766
3767 assign(value, get_gpr_w1(r3 | 1));
3768 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3769 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3770 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3771
3772 return "brxh";
3773}
3774
florian55085f82012-11-21 00:36:55 +00003775static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003776s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3777{
3778 IRTemp value = newTemp(Ity_I64);
3779
3780 assign(value, get_gpr_dw0(r3 | 1));
3781 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3782 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3783 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3784
3785 return "brxhg";
3786}
3787
florian55085f82012-11-21 00:36:55 +00003788static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003789s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3790{
3791 IRTemp value = newTemp(Ity_I32);
3792
3793 assign(value, get_gpr_w1(r3 | 1));
3794 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3795 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3796 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3797
3798 return "brxle";
3799}
3800
florian55085f82012-11-21 00:36:55 +00003801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003802s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3803{
3804 IRTemp value = newTemp(Ity_I64);
3805
3806 assign(value, get_gpr_dw0(r3 | 1));
3807 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3808 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3809 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3810
3811 return "brxlg";
3812}
3813
florian55085f82012-11-21 00:36:55 +00003814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003815s390_irgen_CR(UChar r1, UChar r2)
3816{
3817 IRTemp op1 = newTemp(Ity_I32);
3818 IRTemp op2 = newTemp(Ity_I32);
3819
3820 assign(op1, get_gpr_w1(r1));
3821 assign(op2, get_gpr_w1(r2));
3822 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3823
3824 return "cr";
3825}
3826
florian55085f82012-11-21 00:36:55 +00003827static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003828s390_irgen_CGR(UChar r1, UChar r2)
3829{
3830 IRTemp op1 = newTemp(Ity_I64);
3831 IRTemp op2 = newTemp(Ity_I64);
3832
3833 assign(op1, get_gpr_dw0(r1));
3834 assign(op2, get_gpr_dw0(r2));
3835 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3836
3837 return "cgr";
3838}
3839
florian55085f82012-11-21 00:36:55 +00003840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003841s390_irgen_CGFR(UChar r1, UChar r2)
3842{
3843 IRTemp op1 = newTemp(Ity_I64);
3844 IRTemp op2 = newTemp(Ity_I64);
3845
3846 assign(op1, get_gpr_dw0(r1));
3847 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3848 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3849
3850 return "cgfr";
3851}
3852
florian55085f82012-11-21 00:36:55 +00003853static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003854s390_irgen_C(UChar r1, IRTemp op2addr)
3855{
3856 IRTemp op1 = newTemp(Ity_I32);
3857 IRTemp op2 = newTemp(Ity_I32);
3858
3859 assign(op1, get_gpr_w1(r1));
3860 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3861 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3862
3863 return "c";
3864}
3865
florian55085f82012-11-21 00:36:55 +00003866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003867s390_irgen_CY(UChar r1, IRTemp op2addr)
3868{
3869 IRTemp op1 = newTemp(Ity_I32);
3870 IRTemp op2 = newTemp(Ity_I32);
3871
3872 assign(op1, get_gpr_w1(r1));
3873 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3874 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3875
3876 return "cy";
3877}
3878
florian55085f82012-11-21 00:36:55 +00003879static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003880s390_irgen_CG(UChar r1, IRTemp op2addr)
3881{
3882 IRTemp op1 = newTemp(Ity_I64);
3883 IRTemp op2 = newTemp(Ity_I64);
3884
3885 assign(op1, get_gpr_dw0(r1));
3886 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3887 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3888
3889 return "cg";
3890}
3891
florian55085f82012-11-21 00:36:55 +00003892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003893s390_irgen_CGF(UChar r1, IRTemp op2addr)
3894{
3895 IRTemp op1 = newTemp(Ity_I64);
3896 IRTemp op2 = newTemp(Ity_I64);
3897
3898 assign(op1, get_gpr_dw0(r1));
3899 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3900 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3901
3902 return "cgf";
3903}
3904
florian55085f82012-11-21 00:36:55 +00003905static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003906s390_irgen_CFI(UChar r1, UInt i2)
3907{
3908 IRTemp op1 = newTemp(Ity_I32);
3909 Int op2;
3910
3911 assign(op1, get_gpr_w1(r1));
3912 op2 = (Int)i2;
3913 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3914 mkU32((UInt)op2)));
3915
3916 return "cfi";
3917}
3918
florian55085f82012-11-21 00:36:55 +00003919static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003920s390_irgen_CGFI(UChar r1, UInt i2)
3921{
3922 IRTemp op1 = newTemp(Ity_I64);
3923 Long op2;
3924
3925 assign(op1, get_gpr_dw0(r1));
3926 op2 = (Long)(Int)i2;
3927 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3928 mkU64((ULong)op2)));
3929
3930 return "cgfi";
3931}
3932
florian55085f82012-11-21 00:36:55 +00003933static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003934s390_irgen_CRL(UChar r1, UInt i2)
3935{
3936 IRTemp op1 = newTemp(Ity_I32);
3937 IRTemp op2 = newTemp(Ity_I32);
3938
3939 assign(op1, get_gpr_w1(r1));
3940 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3941 i2 << 1))));
3942 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3943
3944 return "crl";
3945}
3946
florian55085f82012-11-21 00:36:55 +00003947static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003948s390_irgen_CGRL(UChar r1, UInt i2)
3949{
3950 IRTemp op1 = newTemp(Ity_I64);
3951 IRTemp op2 = newTemp(Ity_I64);
3952
3953 assign(op1, get_gpr_dw0(r1));
3954 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3955 i2 << 1))));
3956 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3957
3958 return "cgrl";
3959}
3960
florian55085f82012-11-21 00:36:55 +00003961static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003962s390_irgen_CGFRL(UChar r1, UInt i2)
3963{
3964 IRTemp op1 = newTemp(Ity_I64);
3965 IRTemp op2 = newTemp(Ity_I64);
3966
3967 assign(op1, get_gpr_dw0(r1));
3968 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3969 ((ULong)(Long)(Int)i2 << 1)))));
3970 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3971
3972 return "cgfrl";
3973}
3974
florian55085f82012-11-21 00:36:55 +00003975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003976s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3977{
3978 IRTemp op1 = newTemp(Ity_I32);
3979 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003980 IRTemp cond = newTemp(Ity_I32);
3981
3982 if (m3 == 0) {
3983 } else {
3984 if (m3 == 14) {
3985 always_goto(mkexpr(op4addr));
3986 } else {
3987 assign(op1, get_gpr_w1(r1));
3988 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00003989 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
3990 op1, op2));
florianf321da72012-07-21 20:32:57 +00003991 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
3992 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00003993 }
3994 }
3995
3996 return "crb";
3997}
3998
florian55085f82012-11-21 00:36:55 +00003999static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004000s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4001{
4002 IRTemp op1 = newTemp(Ity_I64);
4003 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004004 IRTemp cond = newTemp(Ity_I32);
4005
4006 if (m3 == 0) {
4007 } else {
4008 if (m3 == 14) {
4009 always_goto(mkexpr(op4addr));
4010 } else {
4011 assign(op1, get_gpr_dw0(r1));
4012 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004013 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4014 op1, op2));
florianf321da72012-07-21 20:32:57 +00004015 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4016 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004017 }
4018 }
4019
4020 return "cgrb";
4021}
4022
florian55085f82012-11-21 00:36:55 +00004023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004024s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4025{
4026 IRTemp op1 = newTemp(Ity_I32);
4027 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004028 IRTemp cond = newTemp(Ity_I32);
4029
4030 if (m3 == 0) {
4031 } else {
4032 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004033 always_goto_and_chase(
4034 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004035 } else {
4036 assign(op1, get_gpr_w1(r1));
4037 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004038 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4039 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004040 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4041 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4042
4043 }
4044 }
4045
4046 return "crj";
4047}
4048
florian55085f82012-11-21 00:36:55 +00004049static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004050s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4051{
4052 IRTemp op1 = newTemp(Ity_I64);
4053 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004054 IRTemp cond = newTemp(Ity_I32);
4055
4056 if (m3 == 0) {
4057 } else {
4058 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004059 always_goto_and_chase(
4060 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004061 } else {
4062 assign(op1, get_gpr_dw0(r1));
4063 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004064 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4065 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004066 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4067 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4068
4069 }
4070 }
4071
4072 return "cgrj";
4073}
4074
florian55085f82012-11-21 00:36:55 +00004075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004076s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4077{
4078 IRTemp op1 = newTemp(Ity_I32);
4079 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004080 IRTemp cond = newTemp(Ity_I32);
4081
4082 if (m3 == 0) {
4083 } else {
4084 if (m3 == 14) {
4085 always_goto(mkexpr(op4addr));
4086 } else {
4087 assign(op1, get_gpr_w1(r1));
4088 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004089 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4090 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004091 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4092 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004093 }
4094 }
4095
4096 return "cib";
4097}
4098
florian55085f82012-11-21 00:36:55 +00004099static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004100s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4101{
4102 IRTemp op1 = newTemp(Ity_I64);
4103 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004104 IRTemp cond = newTemp(Ity_I32);
4105
4106 if (m3 == 0) {
4107 } else {
4108 if (m3 == 14) {
4109 always_goto(mkexpr(op4addr));
4110 } else {
4111 assign(op1, get_gpr_dw0(r1));
4112 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004113 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4114 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004115 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4116 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004117 }
4118 }
4119
4120 return "cgib";
4121}
4122
florian55085f82012-11-21 00:36:55 +00004123static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004124s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4125{
4126 IRTemp op1 = newTemp(Ity_I32);
4127 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004128 IRTemp cond = newTemp(Ity_I32);
4129
4130 if (m3 == 0) {
4131 } else {
4132 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004133 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004134 } else {
4135 assign(op1, get_gpr_w1(r1));
4136 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004137 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4138 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004139 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4140 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4141
4142 }
4143 }
4144
4145 return "cij";
4146}
4147
florian55085f82012-11-21 00:36:55 +00004148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004149s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4150{
4151 IRTemp op1 = newTemp(Ity_I64);
4152 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004153 IRTemp cond = newTemp(Ity_I32);
4154
4155 if (m3 == 0) {
4156 } else {
4157 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004158 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004159 } else {
4160 assign(op1, get_gpr_dw0(r1));
4161 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004162 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4163 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004164 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4165 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4166
4167 }
4168 }
4169
4170 return "cgij";
4171}
4172
florian55085f82012-11-21 00:36:55 +00004173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004174s390_irgen_CH(UChar r1, IRTemp op2addr)
4175{
4176 IRTemp op1 = newTemp(Ity_I32);
4177 IRTemp op2 = newTemp(Ity_I32);
4178
4179 assign(op1, get_gpr_w1(r1));
4180 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4181 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4182
4183 return "ch";
4184}
4185
florian55085f82012-11-21 00:36:55 +00004186static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004187s390_irgen_CHY(UChar r1, IRTemp op2addr)
4188{
4189 IRTemp op1 = newTemp(Ity_I32);
4190 IRTemp op2 = newTemp(Ity_I32);
4191
4192 assign(op1, get_gpr_w1(r1));
4193 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4194 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4195
4196 return "chy";
4197}
4198
florian55085f82012-11-21 00:36:55 +00004199static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004200s390_irgen_CGH(UChar r1, IRTemp op2addr)
4201{
4202 IRTemp op1 = newTemp(Ity_I64);
4203 IRTemp op2 = newTemp(Ity_I64);
4204
4205 assign(op1, get_gpr_dw0(r1));
4206 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4207 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4208
4209 return "cgh";
4210}
4211
florian55085f82012-11-21 00:36:55 +00004212static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004213s390_irgen_CHI(UChar r1, UShort i2)
4214{
4215 IRTemp op1 = newTemp(Ity_I32);
4216 Int op2;
4217
4218 assign(op1, get_gpr_w1(r1));
4219 op2 = (Int)(Short)i2;
4220 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4221 mkU32((UInt)op2)));
4222
4223 return "chi";
4224}
4225
florian55085f82012-11-21 00:36:55 +00004226static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004227s390_irgen_CGHI(UChar r1, UShort i2)
4228{
4229 IRTemp op1 = newTemp(Ity_I64);
4230 Long op2;
4231
4232 assign(op1, get_gpr_dw0(r1));
4233 op2 = (Long)(Short)i2;
4234 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4235 mkU64((ULong)op2)));
4236
4237 return "cghi";
4238}
4239
florian55085f82012-11-21 00:36:55 +00004240static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004241s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4242{
4243 IRTemp op1 = newTemp(Ity_I16);
4244 Short op2;
4245
4246 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4247 op2 = (Short)i2;
4248 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4249 mkU16((UShort)op2)));
4250
4251 return "chhsi";
4252}
4253
florian55085f82012-11-21 00:36:55 +00004254static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004255s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4256{
4257 IRTemp op1 = newTemp(Ity_I32);
4258 Int op2;
4259
4260 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4261 op2 = (Int)(Short)i2;
4262 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4263 mkU32((UInt)op2)));
4264
4265 return "chsi";
4266}
4267
florian55085f82012-11-21 00:36:55 +00004268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004269s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4270{
4271 IRTemp op1 = newTemp(Ity_I64);
4272 Long op2;
4273
4274 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4275 op2 = (Long)(Short)i2;
4276 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4277 mkU64((ULong)op2)));
4278
4279 return "cghsi";
4280}
4281
florian55085f82012-11-21 00:36:55 +00004282static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004283s390_irgen_CHRL(UChar r1, UInt i2)
4284{
4285 IRTemp op1 = newTemp(Ity_I32);
4286 IRTemp op2 = newTemp(Ity_I32);
4287
4288 assign(op1, get_gpr_w1(r1));
4289 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4290 ((ULong)(Long)(Int)i2 << 1)))));
4291 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4292
4293 return "chrl";
4294}
4295
florian55085f82012-11-21 00:36:55 +00004296static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004297s390_irgen_CGHRL(UChar r1, UInt i2)
4298{
4299 IRTemp op1 = newTemp(Ity_I64);
4300 IRTemp op2 = newTemp(Ity_I64);
4301
4302 assign(op1, get_gpr_dw0(r1));
4303 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4304 ((ULong)(Long)(Int)i2 << 1)))));
4305 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4306
4307 return "cghrl";
4308}
4309
florian55085f82012-11-21 00:36:55 +00004310static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004311s390_irgen_CHHR(UChar r1, UChar r2)
4312{
4313 IRTemp op1 = newTemp(Ity_I32);
4314 IRTemp op2 = newTemp(Ity_I32);
4315
4316 assign(op1, get_gpr_w0(r1));
4317 assign(op2, get_gpr_w0(r2));
4318 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4319
4320 return "chhr";
4321}
4322
florian55085f82012-11-21 00:36:55 +00004323static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004324s390_irgen_CHLR(UChar r1, UChar r2)
4325{
4326 IRTemp op1 = newTemp(Ity_I32);
4327 IRTemp op2 = newTemp(Ity_I32);
4328
4329 assign(op1, get_gpr_w0(r1));
4330 assign(op2, get_gpr_w1(r2));
4331 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4332
4333 return "chlr";
4334}
4335
florian55085f82012-11-21 00:36:55 +00004336static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004337s390_irgen_CHF(UChar r1, IRTemp op2addr)
4338{
4339 IRTemp op1 = newTemp(Ity_I32);
4340 IRTemp op2 = newTemp(Ity_I32);
4341
4342 assign(op1, get_gpr_w0(r1));
4343 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4344 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4345
4346 return "chf";
4347}
4348
florian55085f82012-11-21 00:36:55 +00004349static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004350s390_irgen_CIH(UChar r1, UInt i2)
4351{
4352 IRTemp op1 = newTemp(Ity_I32);
4353 Int op2;
4354
4355 assign(op1, get_gpr_w0(r1));
4356 op2 = (Int)i2;
4357 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4358 mkU32((UInt)op2)));
4359
4360 return "cih";
4361}
4362
florian55085f82012-11-21 00:36:55 +00004363static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004364s390_irgen_CLR(UChar r1, UChar r2)
4365{
4366 IRTemp op1 = newTemp(Ity_I32);
4367 IRTemp op2 = newTemp(Ity_I32);
4368
4369 assign(op1, get_gpr_w1(r1));
4370 assign(op2, get_gpr_w1(r2));
4371 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4372
4373 return "clr";
4374}
4375
florian55085f82012-11-21 00:36:55 +00004376static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004377s390_irgen_CLGR(UChar r1, UChar r2)
4378{
4379 IRTemp op1 = newTemp(Ity_I64);
4380 IRTemp op2 = newTemp(Ity_I64);
4381
4382 assign(op1, get_gpr_dw0(r1));
4383 assign(op2, get_gpr_dw0(r2));
4384 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4385
4386 return "clgr";
4387}
4388
florian55085f82012-11-21 00:36:55 +00004389static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004390s390_irgen_CLGFR(UChar r1, UChar r2)
4391{
4392 IRTemp op1 = newTemp(Ity_I64);
4393 IRTemp op2 = newTemp(Ity_I64);
4394
4395 assign(op1, get_gpr_dw0(r1));
4396 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4397 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4398
4399 return "clgfr";
4400}
4401
florian55085f82012-11-21 00:36:55 +00004402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004403s390_irgen_CL(UChar r1, IRTemp op2addr)
4404{
4405 IRTemp op1 = newTemp(Ity_I32);
4406 IRTemp op2 = newTemp(Ity_I32);
4407
4408 assign(op1, get_gpr_w1(r1));
4409 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4410 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4411
4412 return "cl";
4413}
4414
florian55085f82012-11-21 00:36:55 +00004415static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004416s390_irgen_CLY(UChar r1, IRTemp op2addr)
4417{
4418 IRTemp op1 = newTemp(Ity_I32);
4419 IRTemp op2 = newTemp(Ity_I32);
4420
4421 assign(op1, get_gpr_w1(r1));
4422 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4423 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4424
4425 return "cly";
4426}
4427
florian55085f82012-11-21 00:36:55 +00004428static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004429s390_irgen_CLG(UChar r1, IRTemp op2addr)
4430{
4431 IRTemp op1 = newTemp(Ity_I64);
4432 IRTemp op2 = newTemp(Ity_I64);
4433
4434 assign(op1, get_gpr_dw0(r1));
4435 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4436 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4437
4438 return "clg";
4439}
4440
florian55085f82012-11-21 00:36:55 +00004441static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004442s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4443{
4444 IRTemp op1 = newTemp(Ity_I64);
4445 IRTemp op2 = newTemp(Ity_I64);
4446
4447 assign(op1, get_gpr_dw0(r1));
4448 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4449 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4450
4451 return "clgf";
4452}
4453
florian55085f82012-11-21 00:36:55 +00004454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004455s390_irgen_CLFI(UChar r1, UInt i2)
4456{
4457 IRTemp op1 = newTemp(Ity_I32);
4458 UInt op2;
4459
4460 assign(op1, get_gpr_w1(r1));
4461 op2 = i2;
4462 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4463 mkU32(op2)));
4464
4465 return "clfi";
4466}
4467
florian55085f82012-11-21 00:36:55 +00004468static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004469s390_irgen_CLGFI(UChar r1, UInt i2)
4470{
4471 IRTemp op1 = newTemp(Ity_I64);
4472 ULong op2;
4473
4474 assign(op1, get_gpr_dw0(r1));
4475 op2 = (ULong)i2;
4476 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4477 mkU64(op2)));
4478
4479 return "clgfi";
4480}
4481
florian55085f82012-11-21 00:36:55 +00004482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004483s390_irgen_CLI(UChar i2, IRTemp op1addr)
4484{
4485 IRTemp op1 = newTemp(Ity_I8);
4486 UChar op2;
4487
4488 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4489 op2 = i2;
4490 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4491 mkU8(op2)));
4492
4493 return "cli";
4494}
4495
florian55085f82012-11-21 00:36:55 +00004496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004497s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4498{
4499 IRTemp op1 = newTemp(Ity_I8);
4500 UChar op2;
4501
4502 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4503 op2 = i2;
4504 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4505 mkU8(op2)));
4506
4507 return "cliy";
4508}
4509
florian55085f82012-11-21 00:36:55 +00004510static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004511s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4512{
4513 IRTemp op1 = newTemp(Ity_I32);
4514 UInt op2;
4515
4516 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4517 op2 = (UInt)i2;
4518 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4519 mkU32(op2)));
4520
4521 return "clfhsi";
4522}
4523
florian55085f82012-11-21 00:36:55 +00004524static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004525s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4526{
4527 IRTemp op1 = newTemp(Ity_I64);
4528 ULong op2;
4529
4530 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4531 op2 = (ULong)i2;
4532 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4533 mkU64(op2)));
4534
4535 return "clghsi";
4536}
4537
florian55085f82012-11-21 00:36:55 +00004538static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004539s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4540{
4541 IRTemp op1 = newTemp(Ity_I16);
4542 UShort op2;
4543
4544 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4545 op2 = i2;
4546 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4547 mkU16(op2)));
4548
4549 return "clhhsi";
4550}
4551
florian55085f82012-11-21 00:36:55 +00004552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004553s390_irgen_CLRL(UChar r1, UInt i2)
4554{
4555 IRTemp op1 = newTemp(Ity_I32);
4556 IRTemp op2 = newTemp(Ity_I32);
4557
4558 assign(op1, get_gpr_w1(r1));
4559 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4560 i2 << 1))));
4561 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4562
4563 return "clrl";
4564}
4565
florian55085f82012-11-21 00:36:55 +00004566static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004567s390_irgen_CLGRL(UChar r1, UInt i2)
4568{
4569 IRTemp op1 = newTemp(Ity_I64);
4570 IRTemp op2 = newTemp(Ity_I64);
4571
4572 assign(op1, get_gpr_dw0(r1));
4573 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4574 i2 << 1))));
4575 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4576
4577 return "clgrl";
4578}
4579
florian55085f82012-11-21 00:36:55 +00004580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004581s390_irgen_CLGFRL(UChar r1, UInt i2)
4582{
4583 IRTemp op1 = newTemp(Ity_I64);
4584 IRTemp op2 = newTemp(Ity_I64);
4585
4586 assign(op1, get_gpr_dw0(r1));
4587 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4588 ((ULong)(Long)(Int)i2 << 1)))));
4589 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4590
4591 return "clgfrl";
4592}
4593
florian55085f82012-11-21 00:36:55 +00004594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004595s390_irgen_CLHRL(UChar r1, UInt i2)
4596{
4597 IRTemp op1 = newTemp(Ity_I32);
4598 IRTemp op2 = newTemp(Ity_I32);
4599
4600 assign(op1, get_gpr_w1(r1));
4601 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4602 ((ULong)(Long)(Int)i2 << 1)))));
4603 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4604
4605 return "clhrl";
4606}
4607
florian55085f82012-11-21 00:36:55 +00004608static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004609s390_irgen_CLGHRL(UChar r1, UInt i2)
4610{
4611 IRTemp op1 = newTemp(Ity_I64);
4612 IRTemp op2 = newTemp(Ity_I64);
4613
4614 assign(op1, get_gpr_dw0(r1));
4615 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4616 ((ULong)(Long)(Int)i2 << 1)))));
4617 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4618
4619 return "clghrl";
4620}
4621
florian55085f82012-11-21 00:36:55 +00004622static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004623s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4624{
4625 IRTemp op1 = newTemp(Ity_I32);
4626 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004627 IRTemp cond = newTemp(Ity_I32);
4628
4629 if (m3 == 0) {
4630 } else {
4631 if (m3 == 14) {
4632 always_goto(mkexpr(op4addr));
4633 } else {
4634 assign(op1, get_gpr_w1(r1));
4635 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004636 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4637 op1, op2));
florianf321da72012-07-21 20:32:57 +00004638 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4639 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004640 }
4641 }
4642
4643 return "clrb";
4644}
4645
florian55085f82012-11-21 00:36:55 +00004646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004647s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4648{
4649 IRTemp op1 = newTemp(Ity_I64);
4650 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004651 IRTemp cond = newTemp(Ity_I32);
4652
4653 if (m3 == 0) {
4654 } else {
4655 if (m3 == 14) {
4656 always_goto(mkexpr(op4addr));
4657 } else {
4658 assign(op1, get_gpr_dw0(r1));
4659 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004660 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4661 op1, op2));
florianf321da72012-07-21 20:32:57 +00004662 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4663 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004664 }
4665 }
4666
4667 return "clgrb";
4668}
4669
florian55085f82012-11-21 00:36:55 +00004670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004671s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4672{
4673 IRTemp op1 = newTemp(Ity_I32);
4674 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004675 IRTemp cond = newTemp(Ity_I32);
4676
4677 if (m3 == 0) {
4678 } else {
4679 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004680 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004681 } else {
4682 assign(op1, get_gpr_w1(r1));
4683 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004684 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4685 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004686 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4687 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4688
4689 }
4690 }
4691
4692 return "clrj";
4693}
4694
florian55085f82012-11-21 00:36:55 +00004695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004696s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4697{
4698 IRTemp op1 = newTemp(Ity_I64);
4699 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004700 IRTemp cond = newTemp(Ity_I32);
4701
4702 if (m3 == 0) {
4703 } else {
4704 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004705 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004706 } else {
4707 assign(op1, get_gpr_dw0(r1));
4708 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004709 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4710 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004711 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4712 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4713
4714 }
4715 }
4716
4717 return "clgrj";
4718}
4719
florian55085f82012-11-21 00:36:55 +00004720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004721s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4722{
4723 IRTemp op1 = newTemp(Ity_I32);
4724 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004725 IRTemp cond = newTemp(Ity_I32);
4726
4727 if (m3 == 0) {
4728 } else {
4729 if (m3 == 14) {
4730 always_goto(mkexpr(op4addr));
4731 } else {
4732 assign(op1, get_gpr_w1(r1));
4733 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004734 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4735 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004736 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4737 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004738 }
4739 }
4740
4741 return "clib";
4742}
4743
florian55085f82012-11-21 00:36:55 +00004744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004745s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4746{
4747 IRTemp op1 = newTemp(Ity_I64);
4748 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004749 IRTemp cond = newTemp(Ity_I32);
4750
4751 if (m3 == 0) {
4752 } else {
4753 if (m3 == 14) {
4754 always_goto(mkexpr(op4addr));
4755 } else {
4756 assign(op1, get_gpr_dw0(r1));
4757 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004758 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4759 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004760 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4761 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004762 }
4763 }
4764
4765 return "clgib";
4766}
4767
florian55085f82012-11-21 00:36:55 +00004768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004769s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4770{
4771 IRTemp op1 = newTemp(Ity_I32);
4772 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004773 IRTemp cond = newTemp(Ity_I32);
4774
4775 if (m3 == 0) {
4776 } else {
4777 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004778 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004779 } else {
4780 assign(op1, get_gpr_w1(r1));
4781 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004782 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4783 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004784 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4785 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4786
4787 }
4788 }
4789
4790 return "clij";
4791}
4792
florian55085f82012-11-21 00:36:55 +00004793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004794s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4795{
4796 IRTemp op1 = newTemp(Ity_I64);
4797 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004798 IRTemp cond = newTemp(Ity_I32);
4799
4800 if (m3 == 0) {
4801 } else {
4802 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004803 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004804 } else {
4805 assign(op1, get_gpr_dw0(r1));
4806 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004807 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4808 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004809 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4810 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4811
4812 }
4813 }
4814
4815 return "clgij";
4816}
4817
florian55085f82012-11-21 00:36:55 +00004818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004819s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4820{
4821 IRTemp op1 = newTemp(Ity_I32);
4822 IRTemp op2 = newTemp(Ity_I32);
4823 IRTemp b0 = newTemp(Ity_I32);
4824 IRTemp b1 = newTemp(Ity_I32);
4825 IRTemp b2 = newTemp(Ity_I32);
4826 IRTemp b3 = newTemp(Ity_I32);
4827 IRTemp c0 = newTemp(Ity_I32);
4828 IRTemp c1 = newTemp(Ity_I32);
4829 IRTemp c2 = newTemp(Ity_I32);
4830 IRTemp c3 = newTemp(Ity_I32);
4831 UChar n;
4832
4833 n = 0;
4834 if ((r3 & 8) != 0) {
4835 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4836 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4837 n = n + 1;
4838 } else {
4839 assign(b0, mkU32(0));
4840 assign(c0, mkU32(0));
4841 }
4842 if ((r3 & 4) != 0) {
4843 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4844 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4845 mkU64(n)))));
4846 n = n + 1;
4847 } else {
4848 assign(b1, mkU32(0));
4849 assign(c1, mkU32(0));
4850 }
4851 if ((r3 & 2) != 0) {
4852 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4853 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4854 mkU64(n)))));
4855 n = n + 1;
4856 } else {
4857 assign(b2, mkU32(0));
4858 assign(c2, mkU32(0));
4859 }
4860 if ((r3 & 1) != 0) {
4861 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4862 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4863 mkU64(n)))));
4864 n = n + 1;
4865 } else {
4866 assign(b3, mkU32(0));
4867 assign(c3, mkU32(0));
4868 }
4869 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4870 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4871 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4872 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4873 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4874 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4875 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4876
4877 return "clm";
4878}
4879
florian55085f82012-11-21 00:36:55 +00004880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004881s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4882{
4883 IRTemp op1 = newTemp(Ity_I32);
4884 IRTemp op2 = newTemp(Ity_I32);
4885 IRTemp b0 = newTemp(Ity_I32);
4886 IRTemp b1 = newTemp(Ity_I32);
4887 IRTemp b2 = newTemp(Ity_I32);
4888 IRTemp b3 = newTemp(Ity_I32);
4889 IRTemp c0 = newTemp(Ity_I32);
4890 IRTemp c1 = newTemp(Ity_I32);
4891 IRTemp c2 = newTemp(Ity_I32);
4892 IRTemp c3 = newTemp(Ity_I32);
4893 UChar n;
4894
4895 n = 0;
4896 if ((r3 & 8) != 0) {
4897 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4898 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4899 n = n + 1;
4900 } else {
4901 assign(b0, mkU32(0));
4902 assign(c0, mkU32(0));
4903 }
4904 if ((r3 & 4) != 0) {
4905 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4906 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4907 mkU64(n)))));
4908 n = n + 1;
4909 } else {
4910 assign(b1, mkU32(0));
4911 assign(c1, mkU32(0));
4912 }
4913 if ((r3 & 2) != 0) {
4914 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4915 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4916 mkU64(n)))));
4917 n = n + 1;
4918 } else {
4919 assign(b2, mkU32(0));
4920 assign(c2, mkU32(0));
4921 }
4922 if ((r3 & 1) != 0) {
4923 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4924 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4925 mkU64(n)))));
4926 n = n + 1;
4927 } else {
4928 assign(b3, mkU32(0));
4929 assign(c3, mkU32(0));
4930 }
4931 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4932 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4933 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4934 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4935 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4936 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4937 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4938
4939 return "clmy";
4940}
4941
florian55085f82012-11-21 00:36:55 +00004942static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004943s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4944{
4945 IRTemp op1 = newTemp(Ity_I32);
4946 IRTemp op2 = newTemp(Ity_I32);
4947 IRTemp b0 = newTemp(Ity_I32);
4948 IRTemp b1 = newTemp(Ity_I32);
4949 IRTemp b2 = newTemp(Ity_I32);
4950 IRTemp b3 = newTemp(Ity_I32);
4951 IRTemp c0 = newTemp(Ity_I32);
4952 IRTemp c1 = newTemp(Ity_I32);
4953 IRTemp c2 = newTemp(Ity_I32);
4954 IRTemp c3 = newTemp(Ity_I32);
4955 UChar n;
4956
4957 n = 0;
4958 if ((r3 & 8) != 0) {
4959 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4960 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4961 n = n + 1;
4962 } else {
4963 assign(b0, mkU32(0));
4964 assign(c0, mkU32(0));
4965 }
4966 if ((r3 & 4) != 0) {
4967 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4968 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4969 mkU64(n)))));
4970 n = n + 1;
4971 } else {
4972 assign(b1, mkU32(0));
4973 assign(c1, mkU32(0));
4974 }
4975 if ((r3 & 2) != 0) {
4976 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4977 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4978 mkU64(n)))));
4979 n = n + 1;
4980 } else {
4981 assign(b2, mkU32(0));
4982 assign(c2, mkU32(0));
4983 }
4984 if ((r3 & 1) != 0) {
4985 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
4986 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4987 mkU64(n)))));
4988 n = n + 1;
4989 } else {
4990 assign(b3, mkU32(0));
4991 assign(c3, mkU32(0));
4992 }
4993 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4994 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4995 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4996 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4997 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4998 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4999 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5000
5001 return "clmh";
5002}
5003
florian55085f82012-11-21 00:36:55 +00005004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005005s390_irgen_CLHHR(UChar r1, UChar r2)
5006{
5007 IRTemp op1 = newTemp(Ity_I32);
5008 IRTemp op2 = newTemp(Ity_I32);
5009
5010 assign(op1, get_gpr_w0(r1));
5011 assign(op2, get_gpr_w0(r2));
5012 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5013
5014 return "clhhr";
5015}
5016
florian55085f82012-11-21 00:36:55 +00005017static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005018s390_irgen_CLHLR(UChar r1, UChar r2)
5019{
5020 IRTemp op1 = newTemp(Ity_I32);
5021 IRTemp op2 = newTemp(Ity_I32);
5022
5023 assign(op1, get_gpr_w0(r1));
5024 assign(op2, get_gpr_w1(r2));
5025 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5026
5027 return "clhlr";
5028}
5029
florian55085f82012-11-21 00:36:55 +00005030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005031s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5032{
5033 IRTemp op1 = newTemp(Ity_I32);
5034 IRTemp op2 = newTemp(Ity_I32);
5035
5036 assign(op1, get_gpr_w0(r1));
5037 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5038 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5039
5040 return "clhf";
5041}
5042
florian55085f82012-11-21 00:36:55 +00005043static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005044s390_irgen_CLIH(UChar r1, UInt i2)
5045{
5046 IRTemp op1 = newTemp(Ity_I32);
5047 UInt op2;
5048
5049 assign(op1, get_gpr_w0(r1));
5050 op2 = i2;
5051 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5052 mkU32(op2)));
5053
5054 return "clih";
5055}
5056
florian55085f82012-11-21 00:36:55 +00005057static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005058s390_irgen_CPYA(UChar r1, UChar r2)
5059{
5060 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005061 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005062 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5063
5064 return "cpya";
5065}
5066
florian55085f82012-11-21 00:36:55 +00005067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005068s390_irgen_XR(UChar r1, UChar r2)
5069{
5070 IRTemp op1 = newTemp(Ity_I32);
5071 IRTemp op2 = newTemp(Ity_I32);
5072 IRTemp result = newTemp(Ity_I32);
5073
5074 if (r1 == r2) {
5075 assign(result, mkU32(0));
5076 } else {
5077 assign(op1, get_gpr_w1(r1));
5078 assign(op2, get_gpr_w1(r2));
5079 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5080 }
5081 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5082 put_gpr_w1(r1, mkexpr(result));
5083
5084 return "xr";
5085}
5086
florian55085f82012-11-21 00:36:55 +00005087static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005088s390_irgen_XGR(UChar r1, UChar r2)
5089{
5090 IRTemp op1 = newTemp(Ity_I64);
5091 IRTemp op2 = newTemp(Ity_I64);
5092 IRTemp result = newTemp(Ity_I64);
5093
5094 if (r1 == r2) {
5095 assign(result, mkU64(0));
5096 } else {
5097 assign(op1, get_gpr_dw0(r1));
5098 assign(op2, get_gpr_dw0(r2));
5099 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5100 }
5101 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5102 put_gpr_dw0(r1, mkexpr(result));
5103
5104 return "xgr";
5105}
5106
florian55085f82012-11-21 00:36:55 +00005107static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005108s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5109{
5110 IRTemp op2 = newTemp(Ity_I32);
5111 IRTemp op3 = newTemp(Ity_I32);
5112 IRTemp result = newTemp(Ity_I32);
5113
5114 assign(op2, get_gpr_w1(r2));
5115 assign(op3, get_gpr_w1(r3));
5116 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5117 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5118 put_gpr_w1(r1, mkexpr(result));
5119
5120 return "xrk";
5121}
5122
florian55085f82012-11-21 00:36:55 +00005123static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005124s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5125{
5126 IRTemp op2 = newTemp(Ity_I64);
5127 IRTemp op3 = newTemp(Ity_I64);
5128 IRTemp result = newTemp(Ity_I64);
5129
5130 assign(op2, get_gpr_dw0(r2));
5131 assign(op3, get_gpr_dw0(r3));
5132 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5133 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5134 put_gpr_dw0(r1, mkexpr(result));
5135
5136 return "xgrk";
5137}
5138
florian55085f82012-11-21 00:36:55 +00005139static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005140s390_irgen_X(UChar r1, IRTemp op2addr)
5141{
5142 IRTemp op1 = newTemp(Ity_I32);
5143 IRTemp op2 = newTemp(Ity_I32);
5144 IRTemp result = newTemp(Ity_I32);
5145
5146 assign(op1, get_gpr_w1(r1));
5147 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5148 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5149 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5150 put_gpr_w1(r1, mkexpr(result));
5151
5152 return "x";
5153}
5154
florian55085f82012-11-21 00:36:55 +00005155static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005156s390_irgen_XY(UChar r1, IRTemp op2addr)
5157{
5158 IRTemp op1 = newTemp(Ity_I32);
5159 IRTemp op2 = newTemp(Ity_I32);
5160 IRTemp result = newTemp(Ity_I32);
5161
5162 assign(op1, get_gpr_w1(r1));
5163 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5164 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5165 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5166 put_gpr_w1(r1, mkexpr(result));
5167
5168 return "xy";
5169}
5170
florian55085f82012-11-21 00:36:55 +00005171static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005172s390_irgen_XG(UChar r1, IRTemp op2addr)
5173{
5174 IRTemp op1 = newTemp(Ity_I64);
5175 IRTemp op2 = newTemp(Ity_I64);
5176 IRTemp result = newTemp(Ity_I64);
5177
5178 assign(op1, get_gpr_dw0(r1));
5179 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5180 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5181 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5182 put_gpr_dw0(r1, mkexpr(result));
5183
5184 return "xg";
5185}
5186
florian55085f82012-11-21 00:36:55 +00005187static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005188s390_irgen_XI(UChar i2, IRTemp op1addr)
5189{
5190 IRTemp op1 = newTemp(Ity_I8);
5191 UChar op2;
5192 IRTemp result = newTemp(Ity_I8);
5193
5194 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5195 op2 = i2;
5196 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5197 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5198 store(mkexpr(op1addr), mkexpr(result));
5199
5200 return "xi";
5201}
5202
florian55085f82012-11-21 00:36:55 +00005203static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005204s390_irgen_XIY(UChar i2, IRTemp op1addr)
5205{
5206 IRTemp op1 = newTemp(Ity_I8);
5207 UChar op2;
5208 IRTemp result = newTemp(Ity_I8);
5209
5210 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5211 op2 = i2;
5212 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5213 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5214 store(mkexpr(op1addr), mkexpr(result));
5215
5216 return "xiy";
5217}
5218
florian55085f82012-11-21 00:36:55 +00005219static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005220s390_irgen_XIHF(UChar r1, UInt i2)
5221{
5222 IRTemp op1 = newTemp(Ity_I32);
5223 UInt op2;
5224 IRTemp result = newTemp(Ity_I32);
5225
5226 assign(op1, get_gpr_w0(r1));
5227 op2 = i2;
5228 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5229 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5230 put_gpr_w0(r1, mkexpr(result));
5231
5232 return "xihf";
5233}
5234
florian55085f82012-11-21 00:36:55 +00005235static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005236s390_irgen_XILF(UChar r1, UInt i2)
5237{
5238 IRTemp op1 = newTemp(Ity_I32);
5239 UInt op2;
5240 IRTemp result = newTemp(Ity_I32);
5241
5242 assign(op1, get_gpr_w1(r1));
5243 op2 = i2;
5244 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5245 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5246 put_gpr_w1(r1, mkexpr(result));
5247
5248 return "xilf";
5249}
5250
florian55085f82012-11-21 00:36:55 +00005251static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005252s390_irgen_EAR(UChar r1, UChar r2)
5253{
5254 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005255 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005256 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5257
5258 return "ear";
5259}
5260
florian55085f82012-11-21 00:36:55 +00005261static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005262s390_irgen_IC(UChar r1, IRTemp op2addr)
5263{
5264 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5265
5266 return "ic";
5267}
5268
florian55085f82012-11-21 00:36:55 +00005269static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005270s390_irgen_ICY(UChar r1, IRTemp op2addr)
5271{
5272 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5273
5274 return "icy";
5275}
5276
florian55085f82012-11-21 00:36:55 +00005277static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005278s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5279{
5280 UChar n;
5281 IRTemp result = newTemp(Ity_I32);
5282 UInt mask;
5283
5284 n = 0;
5285 mask = (UInt)r3;
5286 if ((mask & 8) != 0) {
5287 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5288 n = n + 1;
5289 }
5290 if ((mask & 4) != 0) {
5291 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5292
5293 n = n + 1;
5294 }
5295 if ((mask & 2) != 0) {
5296 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5297
5298 n = n + 1;
5299 }
5300 if ((mask & 1) != 0) {
5301 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5302
5303 n = n + 1;
5304 }
5305 assign(result, get_gpr_w1(r1));
5306 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5307 mkU32(mask)));
5308
5309 return "icm";
5310}
5311
florian55085f82012-11-21 00:36:55 +00005312static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005313s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5314{
5315 UChar n;
5316 IRTemp result = newTemp(Ity_I32);
5317 UInt mask;
5318
5319 n = 0;
5320 mask = (UInt)r3;
5321 if ((mask & 8) != 0) {
5322 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5323 n = n + 1;
5324 }
5325 if ((mask & 4) != 0) {
5326 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5327
5328 n = n + 1;
5329 }
5330 if ((mask & 2) != 0) {
5331 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5332
5333 n = n + 1;
5334 }
5335 if ((mask & 1) != 0) {
5336 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5337
5338 n = n + 1;
5339 }
5340 assign(result, get_gpr_w1(r1));
5341 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5342 mkU32(mask)));
5343
5344 return "icmy";
5345}
5346
florian55085f82012-11-21 00:36:55 +00005347static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005348s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5349{
5350 UChar n;
5351 IRTemp result = newTemp(Ity_I32);
5352 UInt mask;
5353
5354 n = 0;
5355 mask = (UInt)r3;
5356 if ((mask & 8) != 0) {
5357 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5358 n = n + 1;
5359 }
5360 if ((mask & 4) != 0) {
5361 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5362
5363 n = n + 1;
5364 }
5365 if ((mask & 2) != 0) {
5366 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5367
5368 n = n + 1;
5369 }
5370 if ((mask & 1) != 0) {
5371 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5372
5373 n = n + 1;
5374 }
5375 assign(result, get_gpr_w0(r1));
5376 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5377 mkU32(mask)));
5378
5379 return "icmh";
5380}
5381
florian55085f82012-11-21 00:36:55 +00005382static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005383s390_irgen_IIHF(UChar r1, UInt i2)
5384{
5385 put_gpr_w0(r1, mkU32(i2));
5386
5387 return "iihf";
5388}
5389
florian55085f82012-11-21 00:36:55 +00005390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005391s390_irgen_IIHH(UChar r1, UShort i2)
5392{
5393 put_gpr_hw0(r1, mkU16(i2));
5394
5395 return "iihh";
5396}
5397
florian55085f82012-11-21 00:36:55 +00005398static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005399s390_irgen_IIHL(UChar r1, UShort i2)
5400{
5401 put_gpr_hw1(r1, mkU16(i2));
5402
5403 return "iihl";
5404}
5405
florian55085f82012-11-21 00:36:55 +00005406static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005407s390_irgen_IILF(UChar r1, UInt i2)
5408{
5409 put_gpr_w1(r1, mkU32(i2));
5410
5411 return "iilf";
5412}
5413
florian55085f82012-11-21 00:36:55 +00005414static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005415s390_irgen_IILH(UChar r1, UShort i2)
5416{
5417 put_gpr_hw2(r1, mkU16(i2));
5418
5419 return "iilh";
5420}
5421
florian55085f82012-11-21 00:36:55 +00005422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005423s390_irgen_IILL(UChar r1, UShort i2)
5424{
5425 put_gpr_hw3(r1, mkU16(i2));
5426
5427 return "iill";
5428}
5429
florian55085f82012-11-21 00:36:55 +00005430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005431s390_irgen_LR(UChar r1, UChar r2)
5432{
5433 put_gpr_w1(r1, get_gpr_w1(r2));
5434
5435 return "lr";
5436}
5437
florian55085f82012-11-21 00:36:55 +00005438static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005439s390_irgen_LGR(UChar r1, UChar r2)
5440{
5441 put_gpr_dw0(r1, get_gpr_dw0(r2));
5442
5443 return "lgr";
5444}
5445
florian55085f82012-11-21 00:36:55 +00005446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005447s390_irgen_LGFR(UChar r1, UChar r2)
5448{
5449 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5450
5451 return "lgfr";
5452}
5453
florian55085f82012-11-21 00:36:55 +00005454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005455s390_irgen_L(UChar r1, IRTemp op2addr)
5456{
5457 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5458
5459 return "l";
5460}
5461
florian55085f82012-11-21 00:36:55 +00005462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005463s390_irgen_LY(UChar r1, IRTemp op2addr)
5464{
5465 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5466
5467 return "ly";
5468}
5469
florian55085f82012-11-21 00:36:55 +00005470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005471s390_irgen_LG(UChar r1, IRTemp op2addr)
5472{
5473 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5474
5475 return "lg";
5476}
5477
florian55085f82012-11-21 00:36:55 +00005478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005479s390_irgen_LGF(UChar r1, IRTemp op2addr)
5480{
5481 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5482
5483 return "lgf";
5484}
5485
florian55085f82012-11-21 00:36:55 +00005486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005487s390_irgen_LGFI(UChar r1, UInt i2)
5488{
5489 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5490
5491 return "lgfi";
5492}
5493
florian55085f82012-11-21 00:36:55 +00005494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005495s390_irgen_LRL(UChar r1, UInt i2)
5496{
5497 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5498 i2 << 1))));
5499
5500 return "lrl";
5501}
5502
florian55085f82012-11-21 00:36:55 +00005503static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005504s390_irgen_LGRL(UChar r1, UInt i2)
5505{
5506 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5507 i2 << 1))));
5508
5509 return "lgrl";
5510}
5511
florian55085f82012-11-21 00:36:55 +00005512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005513s390_irgen_LGFRL(UChar r1, UInt i2)
5514{
5515 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5516 ((ULong)(Long)(Int)i2 << 1)))));
5517
5518 return "lgfrl";
5519}
5520
florian55085f82012-11-21 00:36:55 +00005521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005522s390_irgen_LA(UChar r1, IRTemp op2addr)
5523{
5524 put_gpr_dw0(r1, mkexpr(op2addr));
5525
5526 return "la";
5527}
5528
florian55085f82012-11-21 00:36:55 +00005529static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005530s390_irgen_LAY(UChar r1, IRTemp op2addr)
5531{
5532 put_gpr_dw0(r1, mkexpr(op2addr));
5533
5534 return "lay";
5535}
5536
florian55085f82012-11-21 00:36:55 +00005537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005538s390_irgen_LAE(UChar r1, IRTemp op2addr)
5539{
5540 put_gpr_dw0(r1, mkexpr(op2addr));
5541
5542 return "lae";
5543}
5544
florian55085f82012-11-21 00:36:55 +00005545static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005546s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5547{
5548 put_gpr_dw0(r1, mkexpr(op2addr));
5549
5550 return "laey";
5551}
5552
florian55085f82012-11-21 00:36:55 +00005553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005554s390_irgen_LARL(UChar r1, UInt i2)
5555{
5556 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5557
5558 return "larl";
5559}
5560
floriana265ee72012-12-02 20:58:17 +00005561/* The IR representation of LAA and friends is an approximation of what
5562 happens natively. Essentially a loop containing a compare-and-swap is
5563 constructed which will iterate until the CAS succeeds. As a consequence,
5564 instrumenters may see more memory accesses than happen natively. See also
5565 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005566static void
5567s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005568{
floriana265ee72012-12-02 20:58:17 +00005569 IRCAS *cas;
5570 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005571 IRTemp op2 = newTemp(Ity_I32);
5572 IRTemp op3 = newTemp(Ity_I32);
5573 IRTemp result = newTemp(Ity_I32);
5574
5575 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5576 assign(op3, get_gpr_w1(r3));
5577 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005578
5579 /* Place the addition of second operand and third operand at the
5580 second-operand location everytime */
5581 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5582 Iend_BE, mkexpr(op2addr),
5583 NULL, mkexpr(op2), /* expected value */
5584 NULL, mkexpr(result) /* new value */);
5585 stmt(IRStmt_CAS(cas));
5586
florianffc94012012-12-02 21:31:15 +00005587 /* Set CC according to 32-bit addition */
5588 if (is_signed) {
5589 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5590 } else {
5591 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5592 }
floriana265ee72012-12-02 20:58:17 +00005593
5594 /* If old_mem contains the expected value, then the CAS succeeded.
5595 Otherwise, it did not */
5596 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5597 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005598}
5599
5600static void
5601s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5602{
5603 IRCAS *cas;
5604 IRTemp old_mem = newTemp(Ity_I64);
5605 IRTemp op2 = newTemp(Ity_I64);
5606 IRTemp op3 = newTemp(Ity_I64);
5607 IRTemp result = newTemp(Ity_I64);
5608
5609 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5610 assign(op3, get_gpr_dw0(r3));
5611 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5612
5613 /* Place the addition of second operand and third operand at the
5614 second-operand location everytime */
5615 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5616 Iend_BE, mkexpr(op2addr),
5617 NULL, mkexpr(op2), /* expected value */
5618 NULL, mkexpr(result) /* new value */);
5619 stmt(IRStmt_CAS(cas));
5620
5621 /* Set CC according to 64-bit addition */
5622 if (is_signed) {
5623 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5624 } else {
5625 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5626 }
5627
5628 /* If old_mem contains the expected value, then the CAS succeeded.
5629 Otherwise, it did not */
5630 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5631 put_gpr_dw0(r1, mkexpr(old_mem));
5632}
5633
5634static void
5635s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5636{
5637 IRCAS *cas;
5638 IRTemp old_mem = newTemp(Ity_I32);
5639 IRTemp op2 = newTemp(Ity_I32);
5640 IRTemp op3 = newTemp(Ity_I32);
5641 IRTemp result = newTemp(Ity_I32);
5642
5643 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5644 assign(op3, get_gpr_w1(r3));
5645 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5646
5647 /* Place the addition of second operand and third operand at the
5648 second-operand location everytime */
5649 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5650 Iend_BE, mkexpr(op2addr),
5651 NULL, mkexpr(op2), /* expected value */
5652 NULL, mkexpr(result) /* new value */);
5653 stmt(IRStmt_CAS(cas));
5654
5655 /* Set CC according to bitwise operation */
5656 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5657
5658 /* If old_mem contains the expected value, then the CAS succeeded.
5659 Otherwise, it did not */
5660 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5661 put_gpr_w1(r1, mkexpr(old_mem));
5662}
5663
5664static void
5665s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5666{
5667 IRCAS *cas;
5668 IRTemp old_mem = newTemp(Ity_I64);
5669 IRTemp op2 = newTemp(Ity_I64);
5670 IRTemp op3 = newTemp(Ity_I64);
5671 IRTemp result = newTemp(Ity_I64);
5672
5673 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5674 assign(op3, get_gpr_dw0(r3));
5675 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5676
5677 /* Place the addition of second operand and third operand at the
5678 second-operand location everytime */
5679 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5680 Iend_BE, mkexpr(op2addr),
5681 NULL, mkexpr(op2), /* expected value */
5682 NULL, mkexpr(result) /* new value */);
5683 stmt(IRStmt_CAS(cas));
5684
5685 /* Set CC according to bitwise operation */
5686 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5687
5688 /* If old_mem contains the expected value, then the CAS succeeded.
5689 Otherwise, it did not */
5690 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5691 put_gpr_dw0(r1, mkexpr(old_mem));
5692}
5693
5694static const HChar *
5695s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5696{
5697 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005698
5699 return "laa";
5700}
5701
florian55085f82012-11-21 00:36:55 +00005702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005703s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5704{
florianffc94012012-12-02 21:31:15 +00005705 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005706
5707 return "laag";
5708}
5709
florian55085f82012-11-21 00:36:55 +00005710static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005711s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5712{
florianffc94012012-12-02 21:31:15 +00005713 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005714
5715 return "laal";
5716}
5717
florian55085f82012-11-21 00:36:55 +00005718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005719s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5720{
florianffc94012012-12-02 21:31:15 +00005721 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005722
5723 return "laalg";
5724}
5725
florian55085f82012-11-21 00:36:55 +00005726static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005727s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5728{
florianffc94012012-12-02 21:31:15 +00005729 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005730
5731 return "lan";
5732}
5733
florian55085f82012-11-21 00:36:55 +00005734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005735s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5736{
florianffc94012012-12-02 21:31:15 +00005737 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005738
5739 return "lang";
5740}
5741
florian55085f82012-11-21 00:36:55 +00005742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005743s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5744{
florianffc94012012-12-02 21:31:15 +00005745 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005746
5747 return "lax";
5748}
5749
florian55085f82012-11-21 00:36:55 +00005750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005751s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5752{
florianffc94012012-12-02 21:31:15 +00005753 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005754
5755 return "laxg";
5756}
5757
florian55085f82012-11-21 00:36:55 +00005758static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005759s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5760{
florianffc94012012-12-02 21:31:15 +00005761 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005762
5763 return "lao";
5764}
5765
florian55085f82012-11-21 00:36:55 +00005766static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005767s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5768{
florianffc94012012-12-02 21:31:15 +00005769 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005770
5771 return "laog";
5772}
5773
florian55085f82012-11-21 00:36:55 +00005774static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005775s390_irgen_LTR(UChar r1, UChar r2)
5776{
5777 IRTemp op2 = newTemp(Ity_I32);
5778
5779 assign(op2, get_gpr_w1(r2));
5780 put_gpr_w1(r1, mkexpr(op2));
5781 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5782
5783 return "ltr";
5784}
5785
florian55085f82012-11-21 00:36:55 +00005786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005787s390_irgen_LTGR(UChar r1, UChar r2)
5788{
5789 IRTemp op2 = newTemp(Ity_I64);
5790
5791 assign(op2, get_gpr_dw0(r2));
5792 put_gpr_dw0(r1, mkexpr(op2));
5793 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5794
5795 return "ltgr";
5796}
5797
florian55085f82012-11-21 00:36:55 +00005798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005799s390_irgen_LTGFR(UChar r1, UChar r2)
5800{
5801 IRTemp op2 = newTemp(Ity_I64);
5802
5803 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5804 put_gpr_dw0(r1, mkexpr(op2));
5805 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5806
5807 return "ltgfr";
5808}
5809
florian55085f82012-11-21 00:36:55 +00005810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005811s390_irgen_LT(UChar r1, IRTemp op2addr)
5812{
5813 IRTemp op2 = newTemp(Ity_I32);
5814
5815 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5816 put_gpr_w1(r1, mkexpr(op2));
5817 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5818
5819 return "lt";
5820}
5821
florian55085f82012-11-21 00:36:55 +00005822static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005823s390_irgen_LTG(UChar r1, IRTemp op2addr)
5824{
5825 IRTemp op2 = newTemp(Ity_I64);
5826
5827 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5828 put_gpr_dw0(r1, mkexpr(op2));
5829 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5830
5831 return "ltg";
5832}
5833
florian55085f82012-11-21 00:36:55 +00005834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005835s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5836{
5837 IRTemp op2 = newTemp(Ity_I64);
5838
5839 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5840 put_gpr_dw0(r1, mkexpr(op2));
5841 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5842
5843 return "ltgf";
5844}
5845
florian55085f82012-11-21 00:36:55 +00005846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005847s390_irgen_LBR(UChar r1, UChar r2)
5848{
5849 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5850
5851 return "lbr";
5852}
5853
florian55085f82012-11-21 00:36:55 +00005854static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005855s390_irgen_LGBR(UChar r1, UChar r2)
5856{
5857 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5858
5859 return "lgbr";
5860}
5861
florian55085f82012-11-21 00:36:55 +00005862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005863s390_irgen_LB(UChar r1, IRTemp op2addr)
5864{
5865 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5866
5867 return "lb";
5868}
5869
florian55085f82012-11-21 00:36:55 +00005870static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005871s390_irgen_LGB(UChar r1, IRTemp op2addr)
5872{
5873 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5874
5875 return "lgb";
5876}
5877
florian55085f82012-11-21 00:36:55 +00005878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005879s390_irgen_LBH(UChar r1, IRTemp op2addr)
5880{
5881 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5882
5883 return "lbh";
5884}
5885
florian55085f82012-11-21 00:36:55 +00005886static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005887s390_irgen_LCR(UChar r1, UChar r2)
5888{
5889 Int op1;
5890 IRTemp op2 = newTemp(Ity_I32);
5891 IRTemp result = newTemp(Ity_I32);
5892
5893 op1 = 0;
5894 assign(op2, get_gpr_w1(r2));
5895 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5896 put_gpr_w1(r1, mkexpr(result));
5897 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5898 op1)), op2);
5899
5900 return "lcr";
5901}
5902
florian55085f82012-11-21 00:36:55 +00005903static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005904s390_irgen_LCGR(UChar r1, UChar r2)
5905{
5906 Long op1;
5907 IRTemp op2 = newTemp(Ity_I64);
5908 IRTemp result = newTemp(Ity_I64);
5909
5910 op1 = 0ULL;
5911 assign(op2, get_gpr_dw0(r2));
5912 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5913 put_gpr_dw0(r1, mkexpr(result));
5914 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5915 op1)), op2);
5916
5917 return "lcgr";
5918}
5919
florian55085f82012-11-21 00:36:55 +00005920static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005921s390_irgen_LCGFR(UChar r1, UChar r2)
5922{
5923 Long op1;
5924 IRTemp op2 = newTemp(Ity_I64);
5925 IRTemp result = newTemp(Ity_I64);
5926
5927 op1 = 0ULL;
5928 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5929 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5930 put_gpr_dw0(r1, mkexpr(result));
5931 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5932 op1)), op2);
5933
5934 return "lcgfr";
5935}
5936
florian55085f82012-11-21 00:36:55 +00005937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005938s390_irgen_LHR(UChar r1, UChar r2)
5939{
5940 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5941
5942 return "lhr";
5943}
5944
florian55085f82012-11-21 00:36:55 +00005945static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005946s390_irgen_LGHR(UChar r1, UChar r2)
5947{
5948 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5949
5950 return "lghr";
5951}
5952
florian55085f82012-11-21 00:36:55 +00005953static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005954s390_irgen_LH(UChar r1, IRTemp op2addr)
5955{
5956 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5957
5958 return "lh";
5959}
5960
florian55085f82012-11-21 00:36:55 +00005961static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005962s390_irgen_LHY(UChar r1, IRTemp op2addr)
5963{
5964 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5965
5966 return "lhy";
5967}
5968
florian55085f82012-11-21 00:36:55 +00005969static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005970s390_irgen_LGH(UChar r1, IRTemp op2addr)
5971{
5972 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5973
5974 return "lgh";
5975}
5976
florian55085f82012-11-21 00:36:55 +00005977static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005978s390_irgen_LHI(UChar r1, UShort i2)
5979{
5980 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5981
5982 return "lhi";
5983}
5984
florian55085f82012-11-21 00:36:55 +00005985static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005986s390_irgen_LGHI(UChar r1, UShort i2)
5987{
5988 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
5989
5990 return "lghi";
5991}
5992
florian55085f82012-11-21 00:36:55 +00005993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005994s390_irgen_LHRL(UChar r1, UInt i2)
5995{
5996 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
5997 ((ULong)(Long)(Int)i2 << 1)))));
5998
5999 return "lhrl";
6000}
6001
florian55085f82012-11-21 00:36:55 +00006002static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006003s390_irgen_LGHRL(UChar r1, UInt i2)
6004{
6005 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6006 ((ULong)(Long)(Int)i2 << 1)))));
6007
6008 return "lghrl";
6009}
6010
florian55085f82012-11-21 00:36:55 +00006011static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006012s390_irgen_LHH(UChar r1, IRTemp op2addr)
6013{
6014 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6015
6016 return "lhh";
6017}
6018
florian55085f82012-11-21 00:36:55 +00006019static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006020s390_irgen_LFH(UChar r1, IRTemp op2addr)
6021{
6022 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6023
6024 return "lfh";
6025}
6026
florian55085f82012-11-21 00:36:55 +00006027static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006028s390_irgen_LLGFR(UChar r1, UChar r2)
6029{
6030 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6031
6032 return "llgfr";
6033}
6034
florian55085f82012-11-21 00:36:55 +00006035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006036s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6037{
6038 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6039
6040 return "llgf";
6041}
6042
florian55085f82012-11-21 00:36:55 +00006043static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006044s390_irgen_LLGFRL(UChar r1, UInt i2)
6045{
6046 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6047 ((ULong)(Long)(Int)i2 << 1)))));
6048
6049 return "llgfrl";
6050}
6051
florian55085f82012-11-21 00:36:55 +00006052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006053s390_irgen_LLCR(UChar r1, UChar r2)
6054{
6055 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6056
6057 return "llcr";
6058}
6059
florian55085f82012-11-21 00:36:55 +00006060static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006061s390_irgen_LLGCR(UChar r1, UChar r2)
6062{
6063 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6064
6065 return "llgcr";
6066}
6067
florian55085f82012-11-21 00:36:55 +00006068static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006069s390_irgen_LLC(UChar r1, IRTemp op2addr)
6070{
6071 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6072
6073 return "llc";
6074}
6075
florian55085f82012-11-21 00:36:55 +00006076static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006077s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6078{
6079 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6080
6081 return "llgc";
6082}
6083
florian55085f82012-11-21 00:36:55 +00006084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006085s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6086{
6087 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6088
6089 return "llch";
6090}
6091
florian55085f82012-11-21 00:36:55 +00006092static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006093s390_irgen_LLHR(UChar r1, UChar r2)
6094{
6095 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6096
6097 return "llhr";
6098}
6099
florian55085f82012-11-21 00:36:55 +00006100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006101s390_irgen_LLGHR(UChar r1, UChar r2)
6102{
6103 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6104
6105 return "llghr";
6106}
6107
florian55085f82012-11-21 00:36:55 +00006108static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006109s390_irgen_LLH(UChar r1, IRTemp op2addr)
6110{
6111 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6112
6113 return "llh";
6114}
6115
florian55085f82012-11-21 00:36:55 +00006116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006117s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6118{
6119 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6120
6121 return "llgh";
6122}
6123
florian55085f82012-11-21 00:36:55 +00006124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006125s390_irgen_LLHRL(UChar r1, UInt i2)
6126{
6127 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6128 ((ULong)(Long)(Int)i2 << 1)))));
6129
6130 return "llhrl";
6131}
6132
florian55085f82012-11-21 00:36:55 +00006133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006134s390_irgen_LLGHRL(UChar r1, UInt i2)
6135{
6136 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6137 ((ULong)(Long)(Int)i2 << 1)))));
6138
6139 return "llghrl";
6140}
6141
florian55085f82012-11-21 00:36:55 +00006142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006143s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6144{
6145 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6146
6147 return "llhh";
6148}
6149
florian55085f82012-11-21 00:36:55 +00006150static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006151s390_irgen_LLIHF(UChar r1, UInt i2)
6152{
6153 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6154
6155 return "llihf";
6156}
6157
florian55085f82012-11-21 00:36:55 +00006158static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006159s390_irgen_LLIHH(UChar r1, UShort i2)
6160{
6161 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6162
6163 return "llihh";
6164}
6165
florian55085f82012-11-21 00:36:55 +00006166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006167s390_irgen_LLIHL(UChar r1, UShort i2)
6168{
6169 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6170
6171 return "llihl";
6172}
6173
florian55085f82012-11-21 00:36:55 +00006174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006175s390_irgen_LLILF(UChar r1, UInt i2)
6176{
6177 put_gpr_dw0(r1, mkU64(i2));
6178
6179 return "llilf";
6180}
6181
florian55085f82012-11-21 00:36:55 +00006182static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006183s390_irgen_LLILH(UChar r1, UShort i2)
6184{
6185 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6186
6187 return "llilh";
6188}
6189
florian55085f82012-11-21 00:36:55 +00006190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006191s390_irgen_LLILL(UChar r1, UShort i2)
6192{
6193 put_gpr_dw0(r1, mkU64(i2));
6194
6195 return "llill";
6196}
6197
florian55085f82012-11-21 00:36:55 +00006198static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006199s390_irgen_LLGTR(UChar r1, UChar r2)
6200{
6201 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6202 mkU32(2147483647))));
6203
6204 return "llgtr";
6205}
6206
florian55085f82012-11-21 00:36:55 +00006207static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006208s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6209{
6210 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6211 mkexpr(op2addr)), mkU32(2147483647))));
6212
6213 return "llgt";
6214}
6215
florian55085f82012-11-21 00:36:55 +00006216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006217s390_irgen_LNR(UChar r1, UChar r2)
6218{
6219 IRTemp op2 = newTemp(Ity_I32);
6220 IRTemp result = newTemp(Ity_I32);
6221
6222 assign(op2, get_gpr_w1(r2));
6223 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6224 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6225 put_gpr_w1(r1, mkexpr(result));
6226 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6227
6228 return "lnr";
6229}
6230
florian55085f82012-11-21 00:36:55 +00006231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006232s390_irgen_LNGR(UChar r1, UChar r2)
6233{
6234 IRTemp op2 = newTemp(Ity_I64);
6235 IRTemp result = newTemp(Ity_I64);
6236
6237 assign(op2, get_gpr_dw0(r2));
6238 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6239 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6240 put_gpr_dw0(r1, mkexpr(result));
6241 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6242
6243 return "lngr";
6244}
6245
florian55085f82012-11-21 00:36:55 +00006246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006247s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6248{
6249 IRTemp op2 = newTemp(Ity_I64);
6250 IRTemp result = newTemp(Ity_I64);
6251
6252 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6253 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6254 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6255 put_gpr_dw0(r1, mkexpr(result));
6256 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6257
6258 return "lngfr";
6259}
6260
florian55085f82012-11-21 00:36:55 +00006261static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006262s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6263{
florian6820ba52012-07-26 02:01:50 +00006264 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006265 put_gpr_w1(r1, get_gpr_w1(r2));
6266
6267 return "locr";
6268}
6269
florian55085f82012-11-21 00:36:55 +00006270static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006271s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6272{
florian6820ba52012-07-26 02:01:50 +00006273 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006274 put_gpr_dw0(r1, get_gpr_dw0(r2));
6275
6276 return "locgr";
6277}
6278
florian55085f82012-11-21 00:36:55 +00006279static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006280s390_irgen_LOC(UChar r1, IRTemp op2addr)
6281{
6282 /* condition is checked in format handler */
6283 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6284
6285 return "loc";
6286}
6287
florian55085f82012-11-21 00:36:55 +00006288static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006289s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6290{
6291 /* condition is checked in format handler */
6292 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6293
6294 return "locg";
6295}
6296
florian55085f82012-11-21 00:36:55 +00006297static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006298s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6299{
6300 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6301 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6302 ));
6303
6304 return "lpq";
6305}
6306
florian55085f82012-11-21 00:36:55 +00006307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006308s390_irgen_LPR(UChar r1, UChar r2)
6309{
6310 IRTemp op2 = newTemp(Ity_I32);
6311 IRTemp result = newTemp(Ity_I32);
6312
6313 assign(op2, get_gpr_w1(r2));
6314 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6315 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6316 put_gpr_w1(r1, mkexpr(result));
6317 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6318
6319 return "lpr";
6320}
6321
florian55085f82012-11-21 00:36:55 +00006322static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006323s390_irgen_LPGR(UChar r1, UChar r2)
6324{
6325 IRTemp op2 = newTemp(Ity_I64);
6326 IRTemp result = newTemp(Ity_I64);
6327
6328 assign(op2, get_gpr_dw0(r2));
6329 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6330 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6331 put_gpr_dw0(r1, mkexpr(result));
6332 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6333
6334 return "lpgr";
6335}
6336
florian55085f82012-11-21 00:36:55 +00006337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006338s390_irgen_LPGFR(UChar r1, UChar r2)
6339{
6340 IRTemp op2 = newTemp(Ity_I64);
6341 IRTemp result = newTemp(Ity_I64);
6342
6343 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6344 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6345 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6346 put_gpr_dw0(r1, mkexpr(result));
6347 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6348
6349 return "lpgfr";
6350}
6351
florian55085f82012-11-21 00:36:55 +00006352static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006353s390_irgen_LRVR(UChar r1, UChar r2)
6354{
6355 IRTemp b0 = newTemp(Ity_I8);
6356 IRTemp b1 = newTemp(Ity_I8);
6357 IRTemp b2 = newTemp(Ity_I8);
6358 IRTemp b3 = newTemp(Ity_I8);
6359
6360 assign(b3, get_gpr_b7(r2));
6361 assign(b2, get_gpr_b6(r2));
6362 assign(b1, get_gpr_b5(r2));
6363 assign(b0, get_gpr_b4(r2));
6364 put_gpr_b4(r1, mkexpr(b3));
6365 put_gpr_b5(r1, mkexpr(b2));
6366 put_gpr_b6(r1, mkexpr(b1));
6367 put_gpr_b7(r1, mkexpr(b0));
6368
6369 return "lrvr";
6370}
6371
florian55085f82012-11-21 00:36:55 +00006372static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006373s390_irgen_LRVGR(UChar r1, UChar r2)
6374{
6375 IRTemp b0 = newTemp(Ity_I8);
6376 IRTemp b1 = newTemp(Ity_I8);
6377 IRTemp b2 = newTemp(Ity_I8);
6378 IRTemp b3 = newTemp(Ity_I8);
6379 IRTemp b4 = newTemp(Ity_I8);
6380 IRTemp b5 = newTemp(Ity_I8);
6381 IRTemp b6 = newTemp(Ity_I8);
6382 IRTemp b7 = newTemp(Ity_I8);
6383
6384 assign(b7, get_gpr_b7(r2));
6385 assign(b6, get_gpr_b6(r2));
6386 assign(b5, get_gpr_b5(r2));
6387 assign(b4, get_gpr_b4(r2));
6388 assign(b3, get_gpr_b3(r2));
6389 assign(b2, get_gpr_b2(r2));
6390 assign(b1, get_gpr_b1(r2));
6391 assign(b0, get_gpr_b0(r2));
6392 put_gpr_b0(r1, mkexpr(b7));
6393 put_gpr_b1(r1, mkexpr(b6));
6394 put_gpr_b2(r1, mkexpr(b5));
6395 put_gpr_b3(r1, mkexpr(b4));
6396 put_gpr_b4(r1, mkexpr(b3));
6397 put_gpr_b5(r1, mkexpr(b2));
6398 put_gpr_b6(r1, mkexpr(b1));
6399 put_gpr_b7(r1, mkexpr(b0));
6400
6401 return "lrvgr";
6402}
6403
florian55085f82012-11-21 00:36:55 +00006404static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006405s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6406{
6407 IRTemp op2 = newTemp(Ity_I16);
6408
6409 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6410 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6411 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6412
6413 return "lrvh";
6414}
6415
florian55085f82012-11-21 00:36:55 +00006416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006417s390_irgen_LRV(UChar r1, IRTemp op2addr)
6418{
6419 IRTemp op2 = newTemp(Ity_I32);
6420
6421 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6422 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6423 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6424 mkU8(8)), mkU32(255))));
6425 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6426 mkU8(16)), mkU32(255))));
6427 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6428 mkU8(24)), mkU32(255))));
6429
6430 return "lrv";
6431}
6432
florian55085f82012-11-21 00:36:55 +00006433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006434s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6435{
6436 IRTemp op2 = newTemp(Ity_I64);
6437
6438 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6439 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6440 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6441 mkU8(8)), mkU64(255))));
6442 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6443 mkU8(16)), mkU64(255))));
6444 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6445 mkU8(24)), mkU64(255))));
6446 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6447 mkU8(32)), mkU64(255))));
6448 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6449 mkU8(40)), mkU64(255))));
6450 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6451 mkU8(48)), mkU64(255))));
6452 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6453 mkU8(56)), mkU64(255))));
6454
6455 return "lrvg";
6456}
6457
florian55085f82012-11-21 00:36:55 +00006458static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006459s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6460{
6461 store(mkexpr(op1addr), mkU16(i2));
6462
6463 return "mvhhi";
6464}
6465
florian55085f82012-11-21 00:36:55 +00006466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006467s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6468{
6469 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6470
6471 return "mvhi";
6472}
6473
florian55085f82012-11-21 00:36:55 +00006474static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006475s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6476{
6477 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6478
6479 return "mvghi";
6480}
6481
florian55085f82012-11-21 00:36:55 +00006482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006483s390_irgen_MVI(UChar i2, IRTemp op1addr)
6484{
6485 store(mkexpr(op1addr), mkU8(i2));
6486
6487 return "mvi";
6488}
6489
florian55085f82012-11-21 00:36:55 +00006490static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006491s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6492{
6493 store(mkexpr(op1addr), mkU8(i2));
6494
6495 return "mviy";
6496}
6497
florian55085f82012-11-21 00:36:55 +00006498static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006499s390_irgen_MR(UChar r1, UChar r2)
6500{
6501 IRTemp op1 = newTemp(Ity_I32);
6502 IRTemp op2 = newTemp(Ity_I32);
6503 IRTemp result = newTemp(Ity_I64);
6504
6505 assign(op1, get_gpr_w1(r1 + 1));
6506 assign(op2, get_gpr_w1(r2));
6507 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6508 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6509 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6510
6511 return "mr";
6512}
6513
florian55085f82012-11-21 00:36:55 +00006514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006515s390_irgen_M(UChar r1, IRTemp op2addr)
6516{
6517 IRTemp op1 = newTemp(Ity_I32);
6518 IRTemp op2 = newTemp(Ity_I32);
6519 IRTemp result = newTemp(Ity_I64);
6520
6521 assign(op1, get_gpr_w1(r1 + 1));
6522 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6523 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6524 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6525 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6526
6527 return "m";
6528}
6529
florian55085f82012-11-21 00:36:55 +00006530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006531s390_irgen_MFY(UChar r1, IRTemp op2addr)
6532{
6533 IRTemp op1 = newTemp(Ity_I32);
6534 IRTemp op2 = newTemp(Ity_I32);
6535 IRTemp result = newTemp(Ity_I64);
6536
6537 assign(op1, get_gpr_w1(r1 + 1));
6538 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6539 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6540 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6541 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6542
6543 return "mfy";
6544}
6545
florian55085f82012-11-21 00:36:55 +00006546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006547s390_irgen_MH(UChar r1, IRTemp op2addr)
6548{
6549 IRTemp op1 = newTemp(Ity_I32);
6550 IRTemp op2 = newTemp(Ity_I16);
6551 IRTemp result = newTemp(Ity_I64);
6552
6553 assign(op1, get_gpr_w1(r1));
6554 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6555 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6556 ));
6557 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6558
6559 return "mh";
6560}
6561
florian55085f82012-11-21 00:36:55 +00006562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006563s390_irgen_MHY(UChar r1, IRTemp op2addr)
6564{
6565 IRTemp op1 = newTemp(Ity_I32);
6566 IRTemp op2 = newTemp(Ity_I16);
6567 IRTemp result = newTemp(Ity_I64);
6568
6569 assign(op1, get_gpr_w1(r1));
6570 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6571 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6572 ));
6573 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6574
6575 return "mhy";
6576}
6577
florian55085f82012-11-21 00:36:55 +00006578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006579s390_irgen_MHI(UChar r1, UShort i2)
6580{
6581 IRTemp op1 = newTemp(Ity_I32);
6582 Short op2;
6583 IRTemp result = newTemp(Ity_I64);
6584
6585 assign(op1, get_gpr_w1(r1));
6586 op2 = (Short)i2;
6587 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6588 mkU16((UShort)op2))));
6589 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6590
6591 return "mhi";
6592}
6593
florian55085f82012-11-21 00:36:55 +00006594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006595s390_irgen_MGHI(UChar r1, UShort i2)
6596{
6597 IRTemp op1 = newTemp(Ity_I64);
6598 Short op2;
6599 IRTemp result = newTemp(Ity_I128);
6600
6601 assign(op1, get_gpr_dw0(r1));
6602 op2 = (Short)i2;
6603 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6604 mkU16((UShort)op2))));
6605 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6606
6607 return "mghi";
6608}
6609
florian55085f82012-11-21 00:36:55 +00006610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006611s390_irgen_MLR(UChar r1, UChar r2)
6612{
6613 IRTemp op1 = newTemp(Ity_I32);
6614 IRTemp op2 = newTemp(Ity_I32);
6615 IRTemp result = newTemp(Ity_I64);
6616
6617 assign(op1, get_gpr_w1(r1 + 1));
6618 assign(op2, get_gpr_w1(r2));
6619 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6620 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6621 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6622
6623 return "mlr";
6624}
6625
florian55085f82012-11-21 00:36:55 +00006626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006627s390_irgen_MLGR(UChar r1, UChar r2)
6628{
6629 IRTemp op1 = newTemp(Ity_I64);
6630 IRTemp op2 = newTemp(Ity_I64);
6631 IRTemp result = newTemp(Ity_I128);
6632
6633 assign(op1, get_gpr_dw0(r1 + 1));
6634 assign(op2, get_gpr_dw0(r2));
6635 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6636 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6637 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6638
6639 return "mlgr";
6640}
6641
florian55085f82012-11-21 00:36:55 +00006642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006643s390_irgen_ML(UChar r1, IRTemp op2addr)
6644{
6645 IRTemp op1 = newTemp(Ity_I32);
6646 IRTemp op2 = newTemp(Ity_I32);
6647 IRTemp result = newTemp(Ity_I64);
6648
6649 assign(op1, get_gpr_w1(r1 + 1));
6650 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6651 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6652 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6653 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6654
6655 return "ml";
6656}
6657
florian55085f82012-11-21 00:36:55 +00006658static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006659s390_irgen_MLG(UChar r1, IRTemp op2addr)
6660{
6661 IRTemp op1 = newTemp(Ity_I64);
6662 IRTemp op2 = newTemp(Ity_I64);
6663 IRTemp result = newTemp(Ity_I128);
6664
6665 assign(op1, get_gpr_dw0(r1 + 1));
6666 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6667 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6668 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6669 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6670
6671 return "mlg";
6672}
6673
florian55085f82012-11-21 00:36:55 +00006674static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006675s390_irgen_MSR(UChar r1, UChar r2)
6676{
6677 IRTemp op1 = newTemp(Ity_I32);
6678 IRTemp op2 = newTemp(Ity_I32);
6679 IRTemp result = newTemp(Ity_I64);
6680
6681 assign(op1, get_gpr_w1(r1));
6682 assign(op2, get_gpr_w1(r2));
6683 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6684 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6685
6686 return "msr";
6687}
6688
florian55085f82012-11-21 00:36:55 +00006689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006690s390_irgen_MSGR(UChar r1, UChar r2)
6691{
6692 IRTemp op1 = newTemp(Ity_I64);
6693 IRTemp op2 = newTemp(Ity_I64);
6694 IRTemp result = newTemp(Ity_I128);
6695
6696 assign(op1, get_gpr_dw0(r1));
6697 assign(op2, get_gpr_dw0(r2));
6698 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6699 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6700
6701 return "msgr";
6702}
6703
florian55085f82012-11-21 00:36:55 +00006704static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006705s390_irgen_MSGFR(UChar r1, UChar r2)
6706{
6707 IRTemp op1 = newTemp(Ity_I64);
6708 IRTemp op2 = newTemp(Ity_I32);
6709 IRTemp result = newTemp(Ity_I128);
6710
6711 assign(op1, get_gpr_dw0(r1));
6712 assign(op2, get_gpr_w1(r2));
6713 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6714 ));
6715 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6716
6717 return "msgfr";
6718}
6719
florian55085f82012-11-21 00:36:55 +00006720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006721s390_irgen_MS(UChar r1, IRTemp op2addr)
6722{
6723 IRTemp op1 = newTemp(Ity_I32);
6724 IRTemp op2 = newTemp(Ity_I32);
6725 IRTemp result = newTemp(Ity_I64);
6726
6727 assign(op1, get_gpr_w1(r1));
6728 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6729 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6730 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6731
6732 return "ms";
6733}
6734
florian55085f82012-11-21 00:36:55 +00006735static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006736s390_irgen_MSY(UChar r1, IRTemp op2addr)
6737{
6738 IRTemp op1 = newTemp(Ity_I32);
6739 IRTemp op2 = newTemp(Ity_I32);
6740 IRTemp result = newTemp(Ity_I64);
6741
6742 assign(op1, get_gpr_w1(r1));
6743 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6744 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6745 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6746
6747 return "msy";
6748}
6749
florian55085f82012-11-21 00:36:55 +00006750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006751s390_irgen_MSG(UChar r1, IRTemp op2addr)
6752{
6753 IRTemp op1 = newTemp(Ity_I64);
6754 IRTemp op2 = newTemp(Ity_I64);
6755 IRTemp result = newTemp(Ity_I128);
6756
6757 assign(op1, get_gpr_dw0(r1));
6758 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6759 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6760 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6761
6762 return "msg";
6763}
6764
florian55085f82012-11-21 00:36:55 +00006765static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006766s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6767{
6768 IRTemp op1 = newTemp(Ity_I64);
6769 IRTemp op2 = newTemp(Ity_I32);
6770 IRTemp result = newTemp(Ity_I128);
6771
6772 assign(op1, get_gpr_dw0(r1));
6773 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6774 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6775 ));
6776 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6777
6778 return "msgf";
6779}
6780
florian55085f82012-11-21 00:36:55 +00006781static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006782s390_irgen_MSFI(UChar r1, UInt i2)
6783{
6784 IRTemp op1 = newTemp(Ity_I32);
6785 Int op2;
6786 IRTemp result = newTemp(Ity_I64);
6787
6788 assign(op1, get_gpr_w1(r1));
6789 op2 = (Int)i2;
6790 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6791 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6792
6793 return "msfi";
6794}
6795
florian55085f82012-11-21 00:36:55 +00006796static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006797s390_irgen_MSGFI(UChar r1, UInt i2)
6798{
6799 IRTemp op1 = newTemp(Ity_I64);
6800 Int op2;
6801 IRTemp result = newTemp(Ity_I128);
6802
6803 assign(op1, get_gpr_dw0(r1));
6804 op2 = (Int)i2;
6805 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6806 op2))));
6807 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6808
6809 return "msgfi";
6810}
6811
florian55085f82012-11-21 00:36:55 +00006812static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006813s390_irgen_OR(UChar r1, UChar r2)
6814{
6815 IRTemp op1 = newTemp(Ity_I32);
6816 IRTemp op2 = newTemp(Ity_I32);
6817 IRTemp result = newTemp(Ity_I32);
6818
6819 assign(op1, get_gpr_w1(r1));
6820 assign(op2, get_gpr_w1(r2));
6821 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6822 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6823 put_gpr_w1(r1, mkexpr(result));
6824
6825 return "or";
6826}
6827
florian55085f82012-11-21 00:36:55 +00006828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006829s390_irgen_OGR(UChar r1, UChar r2)
6830{
6831 IRTemp op1 = newTemp(Ity_I64);
6832 IRTemp op2 = newTemp(Ity_I64);
6833 IRTemp result = newTemp(Ity_I64);
6834
6835 assign(op1, get_gpr_dw0(r1));
6836 assign(op2, get_gpr_dw0(r2));
6837 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6838 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6839 put_gpr_dw0(r1, mkexpr(result));
6840
6841 return "ogr";
6842}
6843
florian55085f82012-11-21 00:36:55 +00006844static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006845s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6846{
6847 IRTemp op2 = newTemp(Ity_I32);
6848 IRTemp op3 = newTemp(Ity_I32);
6849 IRTemp result = newTemp(Ity_I32);
6850
6851 assign(op2, get_gpr_w1(r2));
6852 assign(op3, get_gpr_w1(r3));
6853 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6854 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6855 put_gpr_w1(r1, mkexpr(result));
6856
6857 return "ork";
6858}
6859
florian55085f82012-11-21 00:36:55 +00006860static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006861s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6862{
6863 IRTemp op2 = newTemp(Ity_I64);
6864 IRTemp op3 = newTemp(Ity_I64);
6865 IRTemp result = newTemp(Ity_I64);
6866
6867 assign(op2, get_gpr_dw0(r2));
6868 assign(op3, get_gpr_dw0(r3));
6869 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6870 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6871 put_gpr_dw0(r1, mkexpr(result));
6872
6873 return "ogrk";
6874}
6875
florian55085f82012-11-21 00:36:55 +00006876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006877s390_irgen_O(UChar r1, IRTemp op2addr)
6878{
6879 IRTemp op1 = newTemp(Ity_I32);
6880 IRTemp op2 = newTemp(Ity_I32);
6881 IRTemp result = newTemp(Ity_I32);
6882
6883 assign(op1, get_gpr_w1(r1));
6884 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6885 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6886 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6887 put_gpr_w1(r1, mkexpr(result));
6888
6889 return "o";
6890}
6891
florian55085f82012-11-21 00:36:55 +00006892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006893s390_irgen_OY(UChar r1, IRTemp op2addr)
6894{
6895 IRTemp op1 = newTemp(Ity_I32);
6896 IRTemp op2 = newTemp(Ity_I32);
6897 IRTemp result = newTemp(Ity_I32);
6898
6899 assign(op1, get_gpr_w1(r1));
6900 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6901 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6902 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6903 put_gpr_w1(r1, mkexpr(result));
6904
6905 return "oy";
6906}
6907
florian55085f82012-11-21 00:36:55 +00006908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006909s390_irgen_OG(UChar r1, IRTemp op2addr)
6910{
6911 IRTemp op1 = newTemp(Ity_I64);
6912 IRTemp op2 = newTemp(Ity_I64);
6913 IRTemp result = newTemp(Ity_I64);
6914
6915 assign(op1, get_gpr_dw0(r1));
6916 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6917 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6918 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6919 put_gpr_dw0(r1, mkexpr(result));
6920
6921 return "og";
6922}
6923
florian55085f82012-11-21 00:36:55 +00006924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006925s390_irgen_OI(UChar i2, IRTemp op1addr)
6926{
6927 IRTemp op1 = newTemp(Ity_I8);
6928 UChar op2;
6929 IRTemp result = newTemp(Ity_I8);
6930
6931 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6932 op2 = i2;
6933 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6934 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6935 store(mkexpr(op1addr), mkexpr(result));
6936
6937 return "oi";
6938}
6939
florian55085f82012-11-21 00:36:55 +00006940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006941s390_irgen_OIY(UChar i2, IRTemp op1addr)
6942{
6943 IRTemp op1 = newTemp(Ity_I8);
6944 UChar op2;
6945 IRTemp result = newTemp(Ity_I8);
6946
6947 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6948 op2 = i2;
6949 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6950 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6951 store(mkexpr(op1addr), mkexpr(result));
6952
6953 return "oiy";
6954}
6955
florian55085f82012-11-21 00:36:55 +00006956static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006957s390_irgen_OIHF(UChar r1, UInt i2)
6958{
6959 IRTemp op1 = newTemp(Ity_I32);
6960 UInt op2;
6961 IRTemp result = newTemp(Ity_I32);
6962
6963 assign(op1, get_gpr_w0(r1));
6964 op2 = i2;
6965 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6966 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6967 put_gpr_w0(r1, mkexpr(result));
6968
6969 return "oihf";
6970}
6971
florian55085f82012-11-21 00:36:55 +00006972static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006973s390_irgen_OIHH(UChar r1, UShort i2)
6974{
6975 IRTemp op1 = newTemp(Ity_I16);
6976 UShort op2;
6977 IRTemp result = newTemp(Ity_I16);
6978
6979 assign(op1, get_gpr_hw0(r1));
6980 op2 = i2;
6981 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6982 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6983 put_gpr_hw0(r1, mkexpr(result));
6984
6985 return "oihh";
6986}
6987
florian55085f82012-11-21 00:36:55 +00006988static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006989s390_irgen_OIHL(UChar r1, UShort i2)
6990{
6991 IRTemp op1 = newTemp(Ity_I16);
6992 UShort op2;
6993 IRTemp result = newTemp(Ity_I16);
6994
6995 assign(op1, get_gpr_hw1(r1));
6996 op2 = i2;
6997 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
6998 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6999 put_gpr_hw1(r1, mkexpr(result));
7000
7001 return "oihl";
7002}
7003
florian55085f82012-11-21 00:36:55 +00007004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007005s390_irgen_OILF(UChar r1, UInt i2)
7006{
7007 IRTemp op1 = newTemp(Ity_I32);
7008 UInt op2;
7009 IRTemp result = newTemp(Ity_I32);
7010
7011 assign(op1, get_gpr_w1(r1));
7012 op2 = i2;
7013 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7014 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7015 put_gpr_w1(r1, mkexpr(result));
7016
7017 return "oilf";
7018}
7019
florian55085f82012-11-21 00:36:55 +00007020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007021s390_irgen_OILH(UChar r1, UShort i2)
7022{
7023 IRTemp op1 = newTemp(Ity_I16);
7024 UShort op2;
7025 IRTemp result = newTemp(Ity_I16);
7026
7027 assign(op1, get_gpr_hw2(r1));
7028 op2 = i2;
7029 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7030 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7031 put_gpr_hw2(r1, mkexpr(result));
7032
7033 return "oilh";
7034}
7035
florian55085f82012-11-21 00:36:55 +00007036static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007037s390_irgen_OILL(UChar r1, UShort i2)
7038{
7039 IRTemp op1 = newTemp(Ity_I16);
7040 UShort op2;
7041 IRTemp result = newTemp(Ity_I16);
7042
7043 assign(op1, get_gpr_hw3(r1));
7044 op2 = i2;
7045 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7046 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7047 put_gpr_hw3(r1, mkexpr(result));
7048
7049 return "oill";
7050}
7051
florian55085f82012-11-21 00:36:55 +00007052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007053s390_irgen_PFD(void)
7054{
7055
7056 return "pfd";
7057}
7058
florian55085f82012-11-21 00:36:55 +00007059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007060s390_irgen_PFDRL(void)
7061{
7062
7063 return "pfdrl";
7064}
7065
florian55085f82012-11-21 00:36:55 +00007066static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007067s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7068{
7069 IRTemp amount = newTemp(Ity_I64);
7070 IRTemp op = newTemp(Ity_I32);
7071
7072 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7073 assign(op, get_gpr_w1(r3));
7074 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7075 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7076 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7077
7078 return "rll";
7079}
7080
florian55085f82012-11-21 00:36:55 +00007081static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007082s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7083{
7084 IRTemp amount = newTemp(Ity_I64);
7085 IRTemp op = newTemp(Ity_I64);
7086
7087 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7088 assign(op, get_gpr_dw0(r3));
7089 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7090 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7091 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7092
7093 return "rllg";
7094}
7095
florian55085f82012-11-21 00:36:55 +00007096static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007097s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7098{
7099 UChar from;
7100 UChar to;
7101 UChar rot;
7102 UChar t_bit;
7103 ULong mask;
7104 ULong maskc;
7105 IRTemp result = newTemp(Ity_I64);
7106 IRTemp op2 = newTemp(Ity_I64);
7107
7108 from = i3 & 63;
7109 to = i4 & 63;
7110 rot = i5 & 63;
7111 t_bit = i3 & 128;
7112 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7113 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7114 mkU8(64 - rot))));
7115 if (from <= to) {
7116 mask = ~0ULL;
7117 mask = (mask >> from) & (mask << (63 - to));
7118 maskc = ~mask;
7119 } else {
7120 maskc = ~0ULL;
7121 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7122 mask = ~maskc;
7123 }
7124 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7125 ), mkU64(mask)));
7126 if (t_bit == 0) {
7127 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7128 mkU64(maskc)), mkexpr(result)));
7129 }
7130 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7131
7132 return "rnsbg";
7133}
7134
florian55085f82012-11-21 00:36:55 +00007135static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007136s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7137{
7138 UChar from;
7139 UChar to;
7140 UChar rot;
7141 UChar t_bit;
7142 ULong mask;
7143 ULong maskc;
7144 IRTemp result = newTemp(Ity_I64);
7145 IRTemp op2 = newTemp(Ity_I64);
7146
7147 from = i3 & 63;
7148 to = i4 & 63;
7149 rot = i5 & 63;
7150 t_bit = i3 & 128;
7151 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7152 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7153 mkU8(64 - rot))));
7154 if (from <= to) {
7155 mask = ~0ULL;
7156 mask = (mask >> from) & (mask << (63 - to));
7157 maskc = ~mask;
7158 } else {
7159 maskc = ~0ULL;
7160 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7161 mask = ~maskc;
7162 }
7163 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7164 ), mkU64(mask)));
7165 if (t_bit == 0) {
7166 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7167 mkU64(maskc)), mkexpr(result)));
7168 }
7169 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7170
7171 return "rxsbg";
7172}
7173
florian55085f82012-11-21 00:36:55 +00007174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007175s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7176{
7177 UChar from;
7178 UChar to;
7179 UChar rot;
7180 UChar t_bit;
7181 ULong mask;
7182 ULong maskc;
7183 IRTemp result = newTemp(Ity_I64);
7184 IRTemp op2 = newTemp(Ity_I64);
7185
7186 from = i3 & 63;
7187 to = i4 & 63;
7188 rot = i5 & 63;
7189 t_bit = i3 & 128;
7190 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7191 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7192 mkU8(64 - rot))));
7193 if (from <= to) {
7194 mask = ~0ULL;
7195 mask = (mask >> from) & (mask << (63 - to));
7196 maskc = ~mask;
7197 } else {
7198 maskc = ~0ULL;
7199 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7200 mask = ~maskc;
7201 }
7202 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7203 ), mkU64(mask)));
7204 if (t_bit == 0) {
7205 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7206 mkU64(maskc)), mkexpr(result)));
7207 }
7208 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7209
7210 return "rosbg";
7211}
7212
florian55085f82012-11-21 00:36:55 +00007213static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007214s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7215{
7216 UChar from;
7217 UChar to;
7218 UChar rot;
7219 UChar z_bit;
7220 ULong mask;
7221 ULong maskc;
7222 IRTemp op2 = newTemp(Ity_I64);
7223 IRTemp result = newTemp(Ity_I64);
7224
7225 from = i3 & 63;
7226 to = i4 & 63;
7227 rot = i5 & 63;
7228 z_bit = i4 & 128;
7229 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7230 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7231 mkU8(64 - rot))));
7232 if (from <= to) {
7233 mask = ~0ULL;
7234 mask = (mask >> from) & (mask << (63 - to));
7235 maskc = ~mask;
7236 } else {
7237 maskc = ~0ULL;
7238 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7239 mask = ~maskc;
7240 }
7241 if (z_bit == 0) {
7242 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7243 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7244 } else {
7245 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7246 }
7247 assign(result, get_gpr_dw0(r1));
7248 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7249
7250 return "risbg";
7251}
7252
florian55085f82012-11-21 00:36:55 +00007253static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007254s390_irgen_SAR(UChar r1, UChar r2)
7255{
7256 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007257 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007258 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7259
7260 return "sar";
7261}
7262
florian55085f82012-11-21 00:36:55 +00007263static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007264s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7265{
7266 IRTemp p1 = newTemp(Ity_I64);
7267 IRTemp p2 = newTemp(Ity_I64);
7268 IRTemp op = newTemp(Ity_I64);
7269 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007270 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007271 IRTemp shift_amount = newTemp(Ity_I64);
7272
7273 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7274 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7275 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7276 ));
7277 sign_mask = 1ULL << 63;
7278 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7279 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007280 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7281 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007282 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7283 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7284 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7285
7286 return "slda";
7287}
7288
florian55085f82012-11-21 00:36:55 +00007289static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007290s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7291{
7292 IRTemp p1 = newTemp(Ity_I64);
7293 IRTemp p2 = newTemp(Ity_I64);
7294 IRTemp result = newTemp(Ity_I64);
7295
7296 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7297 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7298 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7299 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7300 mkexpr(op2addr), mkU64(63)))));
7301 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7302 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7303
7304 return "sldl";
7305}
7306
florian55085f82012-11-21 00:36:55 +00007307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007308s390_irgen_SLA(UChar r1, IRTemp op2addr)
7309{
7310 IRTemp uop = newTemp(Ity_I32);
7311 IRTemp result = newTemp(Ity_I32);
7312 UInt sign_mask;
7313 IRTemp shift_amount = newTemp(Ity_I64);
7314 IRTemp op = newTemp(Ity_I32);
7315
7316 assign(op, get_gpr_w1(r1));
7317 assign(uop, get_gpr_w1(r1));
7318 sign_mask = 2147483648U;
7319 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7320 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7321 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7322 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7323 put_gpr_w1(r1, mkexpr(result));
7324 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7325
7326 return "sla";
7327}
7328
florian55085f82012-11-21 00:36:55 +00007329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007330s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7331{
7332 IRTemp uop = newTemp(Ity_I32);
7333 IRTemp result = newTemp(Ity_I32);
7334 UInt sign_mask;
7335 IRTemp shift_amount = newTemp(Ity_I64);
7336 IRTemp op = newTemp(Ity_I32);
7337
7338 assign(op, get_gpr_w1(r3));
7339 assign(uop, get_gpr_w1(r3));
7340 sign_mask = 2147483648U;
7341 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7342 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7343 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7344 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7345 put_gpr_w1(r1, mkexpr(result));
7346 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7347
7348 return "slak";
7349}
7350
florian55085f82012-11-21 00:36:55 +00007351static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007352s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7353{
7354 IRTemp uop = newTemp(Ity_I64);
7355 IRTemp result = newTemp(Ity_I64);
7356 ULong sign_mask;
7357 IRTemp shift_amount = newTemp(Ity_I64);
7358 IRTemp op = newTemp(Ity_I64);
7359
7360 assign(op, get_gpr_dw0(r3));
7361 assign(uop, get_gpr_dw0(r3));
7362 sign_mask = 9223372036854775808ULL;
7363 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7364 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7365 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7366 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7367 put_gpr_dw0(r1, mkexpr(result));
7368 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7369
7370 return "slag";
7371}
7372
florian55085f82012-11-21 00:36:55 +00007373static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007374s390_irgen_SLL(UChar r1, IRTemp op2addr)
7375{
7376 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7377 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7378
7379 return "sll";
7380}
7381
florian55085f82012-11-21 00:36:55 +00007382static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007383s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7384{
7385 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7386 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7387
7388 return "sllk";
7389}
7390
florian55085f82012-11-21 00:36:55 +00007391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007392s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7393{
7394 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7395 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7396
7397 return "sllg";
7398}
7399
florian55085f82012-11-21 00:36:55 +00007400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007401s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7402{
7403 IRTemp p1 = newTemp(Ity_I64);
7404 IRTemp p2 = newTemp(Ity_I64);
7405 IRTemp result = newTemp(Ity_I64);
7406
7407 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7408 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7409 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7410 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7411 mkexpr(op2addr), mkU64(63)))));
7412 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7413 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7414 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7415
7416 return "srda";
7417}
7418
florian55085f82012-11-21 00:36:55 +00007419static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007420s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7421{
7422 IRTemp p1 = newTemp(Ity_I64);
7423 IRTemp p2 = newTemp(Ity_I64);
7424 IRTemp result = newTemp(Ity_I64);
7425
7426 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7427 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7428 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7429 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7430 mkexpr(op2addr), mkU64(63)))));
7431 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7432 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7433
7434 return "srdl";
7435}
7436
florian55085f82012-11-21 00:36:55 +00007437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007438s390_irgen_SRA(UChar r1, IRTemp op2addr)
7439{
7440 IRTemp result = newTemp(Ity_I32);
7441 IRTemp op = newTemp(Ity_I32);
7442
7443 assign(op, get_gpr_w1(r1));
7444 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7445 mkexpr(op2addr), mkU64(63)))));
7446 put_gpr_w1(r1, mkexpr(result));
7447 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7448
7449 return "sra";
7450}
7451
florian55085f82012-11-21 00:36:55 +00007452static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007453s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7454{
7455 IRTemp result = newTemp(Ity_I32);
7456 IRTemp op = newTemp(Ity_I32);
7457
7458 assign(op, get_gpr_w1(r3));
7459 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7460 mkexpr(op2addr), mkU64(63)))));
7461 put_gpr_w1(r1, mkexpr(result));
7462 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7463
7464 return "srak";
7465}
7466
florian55085f82012-11-21 00:36:55 +00007467static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007468s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7469{
7470 IRTemp result = newTemp(Ity_I64);
7471 IRTemp op = newTemp(Ity_I64);
7472
7473 assign(op, get_gpr_dw0(r3));
7474 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7475 mkexpr(op2addr), mkU64(63)))));
7476 put_gpr_dw0(r1, mkexpr(result));
7477 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7478
7479 return "srag";
7480}
7481
florian55085f82012-11-21 00:36:55 +00007482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007483s390_irgen_SRL(UChar r1, IRTemp op2addr)
7484{
7485 IRTemp op = newTemp(Ity_I32);
7486
7487 assign(op, get_gpr_w1(r1));
7488 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7489 mkexpr(op2addr), mkU64(63)))));
7490
7491 return "srl";
7492}
7493
florian55085f82012-11-21 00:36:55 +00007494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007495s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7496{
7497 IRTemp op = newTemp(Ity_I32);
7498
7499 assign(op, get_gpr_w1(r3));
7500 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7501 mkexpr(op2addr), mkU64(63)))));
7502
7503 return "srlk";
7504}
7505
florian55085f82012-11-21 00:36:55 +00007506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007507s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7508{
7509 IRTemp op = newTemp(Ity_I64);
7510
7511 assign(op, get_gpr_dw0(r3));
7512 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7513 mkexpr(op2addr), mkU64(63)))));
7514
7515 return "srlg";
7516}
7517
florian55085f82012-11-21 00:36:55 +00007518static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007519s390_irgen_ST(UChar r1, IRTemp op2addr)
7520{
7521 store(mkexpr(op2addr), get_gpr_w1(r1));
7522
7523 return "st";
7524}
7525
florian55085f82012-11-21 00:36:55 +00007526static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007527s390_irgen_STY(UChar r1, IRTemp op2addr)
7528{
7529 store(mkexpr(op2addr), get_gpr_w1(r1));
7530
7531 return "sty";
7532}
7533
florian55085f82012-11-21 00:36:55 +00007534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007535s390_irgen_STG(UChar r1, IRTemp op2addr)
7536{
7537 store(mkexpr(op2addr), get_gpr_dw0(r1));
7538
7539 return "stg";
7540}
7541
florian55085f82012-11-21 00:36:55 +00007542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007543s390_irgen_STRL(UChar r1, UInt i2)
7544{
7545 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7546 get_gpr_w1(r1));
7547
7548 return "strl";
7549}
7550
florian55085f82012-11-21 00:36:55 +00007551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007552s390_irgen_STGRL(UChar r1, UInt i2)
7553{
7554 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7555 get_gpr_dw0(r1));
7556
7557 return "stgrl";
7558}
7559
florian55085f82012-11-21 00:36:55 +00007560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007561s390_irgen_STC(UChar r1, IRTemp op2addr)
7562{
7563 store(mkexpr(op2addr), get_gpr_b7(r1));
7564
7565 return "stc";
7566}
7567
florian55085f82012-11-21 00:36:55 +00007568static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007569s390_irgen_STCY(UChar r1, IRTemp op2addr)
7570{
7571 store(mkexpr(op2addr), get_gpr_b7(r1));
7572
7573 return "stcy";
7574}
7575
florian55085f82012-11-21 00:36:55 +00007576static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007577s390_irgen_STCH(UChar r1, IRTemp op2addr)
7578{
7579 store(mkexpr(op2addr), get_gpr_b3(r1));
7580
7581 return "stch";
7582}
7583
florian55085f82012-11-21 00:36:55 +00007584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007585s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7586{
7587 UChar mask;
7588 UChar n;
7589
7590 mask = (UChar)r3;
7591 n = 0;
7592 if ((mask & 8) != 0) {
7593 store(mkexpr(op2addr), get_gpr_b4(r1));
7594 n = n + 1;
7595 }
7596 if ((mask & 4) != 0) {
7597 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7598 n = n + 1;
7599 }
7600 if ((mask & 2) != 0) {
7601 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7602 n = n + 1;
7603 }
7604 if ((mask & 1) != 0) {
7605 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7606 }
7607
7608 return "stcm";
7609}
7610
florian55085f82012-11-21 00:36:55 +00007611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007612s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7613{
7614 UChar mask;
7615 UChar n;
7616
7617 mask = (UChar)r3;
7618 n = 0;
7619 if ((mask & 8) != 0) {
7620 store(mkexpr(op2addr), get_gpr_b4(r1));
7621 n = n + 1;
7622 }
7623 if ((mask & 4) != 0) {
7624 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7625 n = n + 1;
7626 }
7627 if ((mask & 2) != 0) {
7628 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7629 n = n + 1;
7630 }
7631 if ((mask & 1) != 0) {
7632 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7633 }
7634
7635 return "stcmy";
7636}
7637
florian55085f82012-11-21 00:36:55 +00007638static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007639s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7640{
7641 UChar mask;
7642 UChar n;
7643
7644 mask = (UChar)r3;
7645 n = 0;
7646 if ((mask & 8) != 0) {
7647 store(mkexpr(op2addr), get_gpr_b0(r1));
7648 n = n + 1;
7649 }
7650 if ((mask & 4) != 0) {
7651 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7652 n = n + 1;
7653 }
7654 if ((mask & 2) != 0) {
7655 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7656 n = n + 1;
7657 }
7658 if ((mask & 1) != 0) {
7659 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7660 }
7661
7662 return "stcmh";
7663}
7664
florian55085f82012-11-21 00:36:55 +00007665static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007666s390_irgen_STH(UChar r1, IRTemp op2addr)
7667{
7668 store(mkexpr(op2addr), get_gpr_hw3(r1));
7669
7670 return "sth";
7671}
7672
florian55085f82012-11-21 00:36:55 +00007673static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007674s390_irgen_STHY(UChar r1, IRTemp op2addr)
7675{
7676 store(mkexpr(op2addr), get_gpr_hw3(r1));
7677
7678 return "sthy";
7679}
7680
florian55085f82012-11-21 00:36:55 +00007681static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007682s390_irgen_STHRL(UChar r1, UInt i2)
7683{
7684 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7685 get_gpr_hw3(r1));
7686
7687 return "sthrl";
7688}
7689
florian55085f82012-11-21 00:36:55 +00007690static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007691s390_irgen_STHH(UChar r1, IRTemp op2addr)
7692{
7693 store(mkexpr(op2addr), get_gpr_hw1(r1));
7694
7695 return "sthh";
7696}
7697
florian55085f82012-11-21 00:36:55 +00007698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007699s390_irgen_STFH(UChar r1, IRTemp op2addr)
7700{
7701 store(mkexpr(op2addr), get_gpr_w0(r1));
7702
7703 return "stfh";
7704}
7705
florian55085f82012-11-21 00:36:55 +00007706static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007707s390_irgen_STOC(UChar r1, IRTemp op2addr)
7708{
7709 /* condition is checked in format handler */
7710 store(mkexpr(op2addr), get_gpr_w1(r1));
7711
7712 return "stoc";
7713}
7714
florian55085f82012-11-21 00:36:55 +00007715static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007716s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7717{
7718 /* condition is checked in format handler */
7719 store(mkexpr(op2addr), get_gpr_dw0(r1));
7720
7721 return "stocg";
7722}
7723
florian55085f82012-11-21 00:36:55 +00007724static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007725s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7726{
7727 store(mkexpr(op2addr), get_gpr_dw0(r1));
7728 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7729
7730 return "stpq";
7731}
7732
florian55085f82012-11-21 00:36:55 +00007733static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007734s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7735{
7736 store(mkexpr(op2addr), get_gpr_b7(r1));
7737 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7738
7739 return "strvh";
7740}
7741
florian55085f82012-11-21 00:36:55 +00007742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007743s390_irgen_STRV(UChar r1, IRTemp op2addr)
7744{
7745 store(mkexpr(op2addr), get_gpr_b7(r1));
7746 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7747 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7748 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7749
7750 return "strv";
7751}
7752
florian55085f82012-11-21 00:36:55 +00007753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007754s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7755{
7756 store(mkexpr(op2addr), get_gpr_b7(r1));
7757 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7758 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7759 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7760 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7761 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7762 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7763 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7764
7765 return "strvg";
7766}
7767
florian55085f82012-11-21 00:36:55 +00007768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007769s390_irgen_SR(UChar r1, UChar r2)
7770{
7771 IRTemp op1 = newTemp(Ity_I32);
7772 IRTemp op2 = newTemp(Ity_I32);
7773 IRTemp result = newTemp(Ity_I32);
7774
7775 assign(op1, get_gpr_w1(r1));
7776 assign(op2, get_gpr_w1(r2));
7777 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7778 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7779 put_gpr_w1(r1, mkexpr(result));
7780
7781 return "sr";
7782}
7783
florian55085f82012-11-21 00:36:55 +00007784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007785s390_irgen_SGR(UChar r1, UChar r2)
7786{
7787 IRTemp op1 = newTemp(Ity_I64);
7788 IRTemp op2 = newTemp(Ity_I64);
7789 IRTemp result = newTemp(Ity_I64);
7790
7791 assign(op1, get_gpr_dw0(r1));
7792 assign(op2, get_gpr_dw0(r2));
7793 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7794 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7795 put_gpr_dw0(r1, mkexpr(result));
7796
7797 return "sgr";
7798}
7799
florian55085f82012-11-21 00:36:55 +00007800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007801s390_irgen_SGFR(UChar r1, UChar r2)
7802{
7803 IRTemp op1 = newTemp(Ity_I64);
7804 IRTemp op2 = newTemp(Ity_I64);
7805 IRTemp result = newTemp(Ity_I64);
7806
7807 assign(op1, get_gpr_dw0(r1));
7808 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7809 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7810 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7811 put_gpr_dw0(r1, mkexpr(result));
7812
7813 return "sgfr";
7814}
7815
florian55085f82012-11-21 00:36:55 +00007816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007817s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7818{
7819 IRTemp op2 = newTemp(Ity_I32);
7820 IRTemp op3 = newTemp(Ity_I32);
7821 IRTemp result = newTemp(Ity_I32);
7822
7823 assign(op2, get_gpr_w1(r2));
7824 assign(op3, get_gpr_w1(r3));
7825 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7826 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7827 put_gpr_w1(r1, mkexpr(result));
7828
7829 return "srk";
7830}
7831
florian55085f82012-11-21 00:36:55 +00007832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007833s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7834{
7835 IRTemp op2 = newTemp(Ity_I64);
7836 IRTemp op3 = newTemp(Ity_I64);
7837 IRTemp result = newTemp(Ity_I64);
7838
7839 assign(op2, get_gpr_dw0(r2));
7840 assign(op3, get_gpr_dw0(r3));
7841 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7842 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7843 put_gpr_dw0(r1, mkexpr(result));
7844
7845 return "sgrk";
7846}
7847
florian55085f82012-11-21 00:36:55 +00007848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007849s390_irgen_S(UChar r1, IRTemp op2addr)
7850{
7851 IRTemp op1 = newTemp(Ity_I32);
7852 IRTemp op2 = newTemp(Ity_I32);
7853 IRTemp result = newTemp(Ity_I32);
7854
7855 assign(op1, get_gpr_w1(r1));
7856 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7857 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7858 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7859 put_gpr_w1(r1, mkexpr(result));
7860
7861 return "s";
7862}
7863
florian55085f82012-11-21 00:36:55 +00007864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007865s390_irgen_SY(UChar r1, IRTemp op2addr)
7866{
7867 IRTemp op1 = newTemp(Ity_I32);
7868 IRTemp op2 = newTemp(Ity_I32);
7869 IRTemp result = newTemp(Ity_I32);
7870
7871 assign(op1, get_gpr_w1(r1));
7872 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7873 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7874 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7875 put_gpr_w1(r1, mkexpr(result));
7876
7877 return "sy";
7878}
7879
florian55085f82012-11-21 00:36:55 +00007880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007881s390_irgen_SG(UChar r1, IRTemp op2addr)
7882{
7883 IRTemp op1 = newTemp(Ity_I64);
7884 IRTemp op2 = newTemp(Ity_I64);
7885 IRTemp result = newTemp(Ity_I64);
7886
7887 assign(op1, get_gpr_dw0(r1));
7888 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7889 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7890 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7891 put_gpr_dw0(r1, mkexpr(result));
7892
7893 return "sg";
7894}
7895
florian55085f82012-11-21 00:36:55 +00007896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007897s390_irgen_SGF(UChar r1, IRTemp op2addr)
7898{
7899 IRTemp op1 = newTemp(Ity_I64);
7900 IRTemp op2 = newTemp(Ity_I64);
7901 IRTemp result = newTemp(Ity_I64);
7902
7903 assign(op1, get_gpr_dw0(r1));
7904 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7905 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7906 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7907 put_gpr_dw0(r1, mkexpr(result));
7908
7909 return "sgf";
7910}
7911
florian55085f82012-11-21 00:36:55 +00007912static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007913s390_irgen_SH(UChar r1, IRTemp op2addr)
7914{
7915 IRTemp op1 = newTemp(Ity_I32);
7916 IRTemp op2 = newTemp(Ity_I32);
7917 IRTemp result = newTemp(Ity_I32);
7918
7919 assign(op1, get_gpr_w1(r1));
7920 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7921 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7922 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7923 put_gpr_w1(r1, mkexpr(result));
7924
7925 return "sh";
7926}
7927
florian55085f82012-11-21 00:36:55 +00007928static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007929s390_irgen_SHY(UChar r1, IRTemp op2addr)
7930{
7931 IRTemp op1 = newTemp(Ity_I32);
7932 IRTemp op2 = newTemp(Ity_I32);
7933 IRTemp result = newTemp(Ity_I32);
7934
7935 assign(op1, get_gpr_w1(r1));
7936 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7937 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7938 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7939 put_gpr_w1(r1, mkexpr(result));
7940
7941 return "shy";
7942}
7943
florian55085f82012-11-21 00:36:55 +00007944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007945s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7946{
7947 IRTemp op2 = newTemp(Ity_I32);
7948 IRTemp op3 = newTemp(Ity_I32);
7949 IRTemp result = newTemp(Ity_I32);
7950
7951 assign(op2, get_gpr_w0(r1));
7952 assign(op3, get_gpr_w0(r2));
7953 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7954 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7955 put_gpr_w0(r1, mkexpr(result));
7956
7957 return "shhhr";
7958}
7959
florian55085f82012-11-21 00:36:55 +00007960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007961s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7962{
7963 IRTemp op2 = newTemp(Ity_I32);
7964 IRTemp op3 = newTemp(Ity_I32);
7965 IRTemp result = newTemp(Ity_I32);
7966
7967 assign(op2, get_gpr_w0(r1));
7968 assign(op3, get_gpr_w1(r2));
7969 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7970 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7971 put_gpr_w0(r1, mkexpr(result));
7972
7973 return "shhlr";
7974}
7975
florian55085f82012-11-21 00:36:55 +00007976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007977s390_irgen_SLR(UChar r1, UChar r2)
7978{
7979 IRTemp op1 = newTemp(Ity_I32);
7980 IRTemp op2 = newTemp(Ity_I32);
7981 IRTemp result = newTemp(Ity_I32);
7982
7983 assign(op1, get_gpr_w1(r1));
7984 assign(op2, get_gpr_w1(r2));
7985 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7986 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
7987 put_gpr_w1(r1, mkexpr(result));
7988
7989 return "slr";
7990}
7991
florian55085f82012-11-21 00:36:55 +00007992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007993s390_irgen_SLGR(UChar r1, UChar r2)
7994{
7995 IRTemp op1 = newTemp(Ity_I64);
7996 IRTemp op2 = newTemp(Ity_I64);
7997 IRTemp result = newTemp(Ity_I64);
7998
7999 assign(op1, get_gpr_dw0(r1));
8000 assign(op2, get_gpr_dw0(r2));
8001 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8002 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8003 put_gpr_dw0(r1, mkexpr(result));
8004
8005 return "slgr";
8006}
8007
florian55085f82012-11-21 00:36:55 +00008008static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008009s390_irgen_SLGFR(UChar r1, UChar r2)
8010{
8011 IRTemp op1 = newTemp(Ity_I64);
8012 IRTemp op2 = newTemp(Ity_I64);
8013 IRTemp result = newTemp(Ity_I64);
8014
8015 assign(op1, get_gpr_dw0(r1));
8016 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8017 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8018 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8019 put_gpr_dw0(r1, mkexpr(result));
8020
8021 return "slgfr";
8022}
8023
florian55085f82012-11-21 00:36:55 +00008024static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008025s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8026{
8027 IRTemp op2 = newTemp(Ity_I32);
8028 IRTemp op3 = newTemp(Ity_I32);
8029 IRTemp result = newTemp(Ity_I32);
8030
8031 assign(op2, get_gpr_w1(r2));
8032 assign(op3, get_gpr_w1(r3));
8033 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8034 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8035 put_gpr_w1(r1, mkexpr(result));
8036
8037 return "slrk";
8038}
8039
florian55085f82012-11-21 00:36:55 +00008040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008041s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8042{
8043 IRTemp op2 = newTemp(Ity_I64);
8044 IRTemp op3 = newTemp(Ity_I64);
8045 IRTemp result = newTemp(Ity_I64);
8046
8047 assign(op2, get_gpr_dw0(r2));
8048 assign(op3, get_gpr_dw0(r3));
8049 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8050 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8051 put_gpr_dw0(r1, mkexpr(result));
8052
8053 return "slgrk";
8054}
8055
florian55085f82012-11-21 00:36:55 +00008056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008057s390_irgen_SL(UChar r1, IRTemp op2addr)
8058{
8059 IRTemp op1 = newTemp(Ity_I32);
8060 IRTemp op2 = newTemp(Ity_I32);
8061 IRTemp result = newTemp(Ity_I32);
8062
8063 assign(op1, get_gpr_w1(r1));
8064 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8065 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8066 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8067 put_gpr_w1(r1, mkexpr(result));
8068
8069 return "sl";
8070}
8071
florian55085f82012-11-21 00:36:55 +00008072static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008073s390_irgen_SLY(UChar r1, IRTemp op2addr)
8074{
8075 IRTemp op1 = newTemp(Ity_I32);
8076 IRTemp op2 = newTemp(Ity_I32);
8077 IRTemp result = newTemp(Ity_I32);
8078
8079 assign(op1, get_gpr_w1(r1));
8080 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8081 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8082 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8083 put_gpr_w1(r1, mkexpr(result));
8084
8085 return "sly";
8086}
8087
florian55085f82012-11-21 00:36:55 +00008088static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008089s390_irgen_SLG(UChar r1, IRTemp op2addr)
8090{
8091 IRTemp op1 = newTemp(Ity_I64);
8092 IRTemp op2 = newTemp(Ity_I64);
8093 IRTemp result = newTemp(Ity_I64);
8094
8095 assign(op1, get_gpr_dw0(r1));
8096 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8097 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8098 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8099 put_gpr_dw0(r1, mkexpr(result));
8100
8101 return "slg";
8102}
8103
florian55085f82012-11-21 00:36:55 +00008104static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008105s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8106{
8107 IRTemp op1 = newTemp(Ity_I64);
8108 IRTemp op2 = newTemp(Ity_I64);
8109 IRTemp result = newTemp(Ity_I64);
8110
8111 assign(op1, get_gpr_dw0(r1));
8112 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8113 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8114 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8115 put_gpr_dw0(r1, mkexpr(result));
8116
8117 return "slgf";
8118}
8119
florian55085f82012-11-21 00:36:55 +00008120static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008121s390_irgen_SLFI(UChar r1, UInt i2)
8122{
8123 IRTemp op1 = newTemp(Ity_I32);
8124 UInt op2;
8125 IRTemp result = newTemp(Ity_I32);
8126
8127 assign(op1, get_gpr_w1(r1));
8128 op2 = i2;
8129 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8130 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8131 mkU32(op2)));
8132 put_gpr_w1(r1, mkexpr(result));
8133
8134 return "slfi";
8135}
8136
florian55085f82012-11-21 00:36:55 +00008137static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008138s390_irgen_SLGFI(UChar r1, UInt i2)
8139{
8140 IRTemp op1 = newTemp(Ity_I64);
8141 ULong op2;
8142 IRTemp result = newTemp(Ity_I64);
8143
8144 assign(op1, get_gpr_dw0(r1));
8145 op2 = (ULong)i2;
8146 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8147 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8148 mkU64(op2)));
8149 put_gpr_dw0(r1, mkexpr(result));
8150
8151 return "slgfi";
8152}
8153
florian55085f82012-11-21 00:36:55 +00008154static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008155s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8156{
8157 IRTemp op2 = newTemp(Ity_I32);
8158 IRTemp op3 = newTemp(Ity_I32);
8159 IRTemp result = newTemp(Ity_I32);
8160
8161 assign(op2, get_gpr_w0(r1));
8162 assign(op3, get_gpr_w0(r2));
8163 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8164 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8165 put_gpr_w0(r1, mkexpr(result));
8166
8167 return "slhhhr";
8168}
8169
florian55085f82012-11-21 00:36:55 +00008170static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008171s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8172{
8173 IRTemp op2 = newTemp(Ity_I32);
8174 IRTemp op3 = newTemp(Ity_I32);
8175 IRTemp result = newTemp(Ity_I32);
8176
8177 assign(op2, get_gpr_w0(r1));
8178 assign(op3, get_gpr_w1(r2));
8179 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8180 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8181 put_gpr_w0(r1, mkexpr(result));
8182
8183 return "slhhlr";
8184}
8185
florian55085f82012-11-21 00:36:55 +00008186static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008187s390_irgen_SLBR(UChar r1, UChar r2)
8188{
8189 IRTemp op1 = newTemp(Ity_I32);
8190 IRTemp op2 = newTemp(Ity_I32);
8191 IRTemp result = newTemp(Ity_I32);
8192 IRTemp borrow_in = newTemp(Ity_I32);
8193
8194 assign(op1, get_gpr_w1(r1));
8195 assign(op2, get_gpr_w1(r2));
8196 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8197 s390_call_calculate_cc(), mkU8(1))));
8198 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8199 mkexpr(borrow_in)));
8200 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8201 put_gpr_w1(r1, mkexpr(result));
8202
8203 return "slbr";
8204}
8205
florian55085f82012-11-21 00:36:55 +00008206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008207s390_irgen_SLBGR(UChar r1, UChar r2)
8208{
8209 IRTemp op1 = newTemp(Ity_I64);
8210 IRTemp op2 = newTemp(Ity_I64);
8211 IRTemp result = newTemp(Ity_I64);
8212 IRTemp borrow_in = newTemp(Ity_I64);
8213
8214 assign(op1, get_gpr_dw0(r1));
8215 assign(op2, get_gpr_dw0(r2));
8216 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8217 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8218 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8219 mkexpr(borrow_in)));
8220 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8221 put_gpr_dw0(r1, mkexpr(result));
8222
8223 return "slbgr";
8224}
8225
florian55085f82012-11-21 00:36:55 +00008226static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008227s390_irgen_SLB(UChar r1, IRTemp op2addr)
8228{
8229 IRTemp op1 = newTemp(Ity_I32);
8230 IRTemp op2 = newTemp(Ity_I32);
8231 IRTemp result = newTemp(Ity_I32);
8232 IRTemp borrow_in = newTemp(Ity_I32);
8233
8234 assign(op1, get_gpr_w1(r1));
8235 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8236 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8237 s390_call_calculate_cc(), mkU8(1))));
8238 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8239 mkexpr(borrow_in)));
8240 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8241 put_gpr_w1(r1, mkexpr(result));
8242
8243 return "slb";
8244}
8245
florian55085f82012-11-21 00:36:55 +00008246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008247s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8248{
8249 IRTemp op1 = newTemp(Ity_I64);
8250 IRTemp op2 = newTemp(Ity_I64);
8251 IRTemp result = newTemp(Ity_I64);
8252 IRTemp borrow_in = newTemp(Ity_I64);
8253
8254 assign(op1, get_gpr_dw0(r1));
8255 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8256 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8257 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8258 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8259 mkexpr(borrow_in)));
8260 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8261 put_gpr_dw0(r1, mkexpr(result));
8262
8263 return "slbg";
8264}
8265
florian55085f82012-11-21 00:36:55 +00008266static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008267s390_irgen_SVC(UChar i)
8268{
8269 IRTemp sysno = newTemp(Ity_I64);
8270
8271 if (i != 0) {
8272 assign(sysno, mkU64(i));
8273 } else {
8274 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8275 }
8276 system_call(mkexpr(sysno));
8277
8278 return "svc";
8279}
8280
florian55085f82012-11-21 00:36:55 +00008281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008282s390_irgen_TM(UChar i2, IRTemp op1addr)
8283{
8284 UChar mask;
8285 IRTemp value = newTemp(Ity_I8);
8286
8287 mask = i2;
8288 assign(value, load(Ity_I8, mkexpr(op1addr)));
8289 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8290 mkU8(mask)));
8291
8292 return "tm";
8293}
8294
florian55085f82012-11-21 00:36:55 +00008295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008296s390_irgen_TMY(UChar i2, IRTemp op1addr)
8297{
8298 UChar mask;
8299 IRTemp value = newTemp(Ity_I8);
8300
8301 mask = i2;
8302 assign(value, load(Ity_I8, mkexpr(op1addr)));
8303 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8304 mkU8(mask)));
8305
8306 return "tmy";
8307}
8308
florian55085f82012-11-21 00:36:55 +00008309static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008310s390_irgen_TMHH(UChar r1, UShort i2)
8311{
8312 UShort mask;
8313 IRTemp value = newTemp(Ity_I16);
8314
8315 mask = i2;
8316 assign(value, get_gpr_hw0(r1));
8317 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8318 mkU16(mask)));
8319
8320 return "tmhh";
8321}
8322
florian55085f82012-11-21 00:36:55 +00008323static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008324s390_irgen_TMHL(UChar r1, UShort i2)
8325{
8326 UShort mask;
8327 IRTemp value = newTemp(Ity_I16);
8328
8329 mask = i2;
8330 assign(value, get_gpr_hw1(r1));
8331 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8332 mkU16(mask)));
8333
8334 return "tmhl";
8335}
8336
florian55085f82012-11-21 00:36:55 +00008337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008338s390_irgen_TMLH(UChar r1, UShort i2)
8339{
8340 UShort mask;
8341 IRTemp value = newTemp(Ity_I16);
8342
8343 mask = i2;
8344 assign(value, get_gpr_hw2(r1));
8345 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8346 mkU16(mask)));
8347
8348 return "tmlh";
8349}
8350
florian55085f82012-11-21 00:36:55 +00008351static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008352s390_irgen_TMLL(UChar r1, UShort i2)
8353{
8354 UShort mask;
8355 IRTemp value = newTemp(Ity_I16);
8356
8357 mask = i2;
8358 assign(value, get_gpr_hw3(r1));
8359 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8360 mkU16(mask)));
8361
8362 return "tmll";
8363}
8364
florian55085f82012-11-21 00:36:55 +00008365static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008366s390_irgen_EFPC(UChar r1)
8367{
8368 put_gpr_w1(r1, get_fpc_w0());
8369
8370 return "efpc";
8371}
8372
florian55085f82012-11-21 00:36:55 +00008373static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008374s390_irgen_LER(UChar r1, UChar r2)
8375{
8376 put_fpr_w0(r1, get_fpr_w0(r2));
8377
8378 return "ler";
8379}
8380
florian55085f82012-11-21 00:36:55 +00008381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008382s390_irgen_LDR(UChar r1, UChar r2)
8383{
8384 put_fpr_dw0(r1, get_fpr_dw0(r2));
8385
8386 return "ldr";
8387}
8388
florian55085f82012-11-21 00:36:55 +00008389static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008390s390_irgen_LXR(UChar r1, UChar r2)
8391{
8392 put_fpr_dw0(r1, get_fpr_dw0(r2));
8393 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8394
8395 return "lxr";
8396}
8397
florian55085f82012-11-21 00:36:55 +00008398static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008399s390_irgen_LE(UChar r1, IRTemp op2addr)
8400{
8401 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8402
8403 return "le";
8404}
8405
florian55085f82012-11-21 00:36:55 +00008406static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008407s390_irgen_LD(UChar r1, IRTemp op2addr)
8408{
8409 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8410
8411 return "ld";
8412}
8413
florian55085f82012-11-21 00:36:55 +00008414static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008415s390_irgen_LEY(UChar r1, IRTemp op2addr)
8416{
8417 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8418
8419 return "ley";
8420}
8421
florian55085f82012-11-21 00:36:55 +00008422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008423s390_irgen_LDY(UChar r1, IRTemp op2addr)
8424{
8425 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8426
8427 return "ldy";
8428}
8429
florian55085f82012-11-21 00:36:55 +00008430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008431s390_irgen_LFPC(IRTemp op2addr)
8432{
8433 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8434
8435 return "lfpc";
8436}
8437
florian55085f82012-11-21 00:36:55 +00008438static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008439s390_irgen_LZER(UChar r1)
8440{
8441 put_fpr_w0(r1, mkF32i(0x0));
8442
8443 return "lzer";
8444}
8445
florian55085f82012-11-21 00:36:55 +00008446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008447s390_irgen_LZDR(UChar r1)
8448{
8449 put_fpr_dw0(r1, mkF64i(0x0));
8450
8451 return "lzdr";
8452}
8453
florian55085f82012-11-21 00:36:55 +00008454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008455s390_irgen_LZXR(UChar r1)
8456{
8457 put_fpr_dw0(r1, mkF64i(0x0));
8458 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8459
8460 return "lzxr";
8461}
8462
florian55085f82012-11-21 00:36:55 +00008463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008464s390_irgen_SRNM(IRTemp op2addr)
8465{
florianf0fa1be2012-09-18 20:24:38 +00008466 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008467
florianf0fa1be2012-09-18 20:24:38 +00008468 input_mask = 3;
8469 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008470
florianf0fa1be2012-09-18 20:24:38 +00008471 put_fpc_w0(binop(Iop_Or32,
8472 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8473 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8474 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008475 return "srnm";
8476}
8477
florian55085f82012-11-21 00:36:55 +00008478static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008479s390_irgen_SRNMB(IRTemp op2addr)
8480{
8481 UInt input_mask, fpc_mask;
8482
8483 input_mask = 7;
8484 fpc_mask = 7;
8485
8486 put_fpc_w0(binop(Iop_Or32,
8487 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8488 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8489 mkU32(input_mask))));
8490 return "srnmb";
8491}
8492
florian81a4bfe2012-09-20 01:25:28 +00008493static void
florianf0fa1be2012-09-18 20:24:38 +00008494s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8495{
8496 if (b2 == 0) { /* This is the typical case */
8497 if (d2 > 3) {
8498 if (s390_host_has_fpext && d2 == 7) {
8499 /* ok */
8500 } else {
8501 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008502 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008503 }
8504 }
8505 }
8506
8507 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8508}
8509
8510
florian55085f82012-11-21 00:36:55 +00008511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008512s390_irgen_SFPC(UChar r1)
8513{
8514 put_fpc_w0(get_gpr_w1(r1));
8515
8516 return "sfpc";
8517}
8518
florian55085f82012-11-21 00:36:55 +00008519static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008520s390_irgen_STE(UChar r1, IRTemp op2addr)
8521{
8522 store(mkexpr(op2addr), get_fpr_w0(r1));
8523
8524 return "ste";
8525}
8526
florian55085f82012-11-21 00:36:55 +00008527static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008528s390_irgen_STD(UChar r1, IRTemp op2addr)
8529{
8530 store(mkexpr(op2addr), get_fpr_dw0(r1));
8531
8532 return "std";
8533}
8534
florian55085f82012-11-21 00:36:55 +00008535static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008536s390_irgen_STEY(UChar r1, IRTemp op2addr)
8537{
8538 store(mkexpr(op2addr), get_fpr_w0(r1));
8539
8540 return "stey";
8541}
8542
florian55085f82012-11-21 00:36:55 +00008543static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008544s390_irgen_STDY(UChar r1, IRTemp op2addr)
8545{
8546 store(mkexpr(op2addr), get_fpr_dw0(r1));
8547
8548 return "stdy";
8549}
8550
florian55085f82012-11-21 00:36:55 +00008551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008552s390_irgen_STFPC(IRTemp op2addr)
8553{
8554 store(mkexpr(op2addr), get_fpc_w0());
8555
8556 return "stfpc";
8557}
8558
florian55085f82012-11-21 00:36:55 +00008559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008560s390_irgen_AEBR(UChar r1, UChar r2)
8561{
8562 IRTemp op1 = newTemp(Ity_F32);
8563 IRTemp op2 = newTemp(Ity_F32);
8564 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008565 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008566
8567 assign(op1, get_fpr_w0(r1));
8568 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008569 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008570 mkexpr(op2)));
8571 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8572 put_fpr_w0(r1, mkexpr(result));
8573
8574 return "aebr";
8575}
8576
florian55085f82012-11-21 00:36:55 +00008577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008578s390_irgen_ADBR(UChar r1, UChar r2)
8579{
8580 IRTemp op1 = newTemp(Ity_F64);
8581 IRTemp op2 = newTemp(Ity_F64);
8582 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008583 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008584
8585 assign(op1, get_fpr_dw0(r1));
8586 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008587 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008588 mkexpr(op2)));
8589 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8590 put_fpr_dw0(r1, mkexpr(result));
8591
8592 return "adbr";
8593}
8594
florian55085f82012-11-21 00:36:55 +00008595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008596s390_irgen_AEB(UChar r1, IRTemp op2addr)
8597{
8598 IRTemp op1 = newTemp(Ity_F32);
8599 IRTemp op2 = newTemp(Ity_F32);
8600 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008601 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008602
8603 assign(op1, get_fpr_w0(r1));
8604 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008605 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008606 mkexpr(op2)));
8607 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8608 put_fpr_w0(r1, mkexpr(result));
8609
8610 return "aeb";
8611}
8612
florian55085f82012-11-21 00:36:55 +00008613static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008614s390_irgen_ADB(UChar r1, IRTemp op2addr)
8615{
8616 IRTemp op1 = newTemp(Ity_F64);
8617 IRTemp op2 = newTemp(Ity_F64);
8618 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008619 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008620
8621 assign(op1, get_fpr_dw0(r1));
8622 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008623 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008624 mkexpr(op2)));
8625 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8626 put_fpr_dw0(r1, mkexpr(result));
8627
8628 return "adb";
8629}
8630
florian55085f82012-11-21 00:36:55 +00008631static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008632s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8633 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008634{
florian125e20d2012-10-07 15:42:37 +00008635 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008636 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008637 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008638 }
sewardj2019a972011-03-07 16:04:07 +00008639 IRTemp op2 = newTemp(Ity_I32);
8640
8641 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008642 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008643 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008644
8645 return "cefbr";
8646}
8647
florian55085f82012-11-21 00:36:55 +00008648static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008649s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8650 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008651{
8652 IRTemp op2 = newTemp(Ity_I32);
8653
8654 assign(op2, get_gpr_w1(r2));
8655 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8656
8657 return "cdfbr";
8658}
8659
florian55085f82012-11-21 00:36:55 +00008660static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008661s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8662 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008663{
florian125e20d2012-10-07 15:42:37 +00008664 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008665 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008666 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008667 }
sewardj2019a972011-03-07 16:04:07 +00008668 IRTemp op2 = newTemp(Ity_I64);
8669
8670 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008671 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008672 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008673
8674 return "cegbr";
8675}
8676
florian55085f82012-11-21 00:36:55 +00008677static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008678s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8679 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008680{
florian125e20d2012-10-07 15:42:37 +00008681 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008682 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008683 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008684 }
sewardj2019a972011-03-07 16:04:07 +00008685 IRTemp op2 = newTemp(Ity_I64);
8686
8687 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008688 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008689 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008690
8691 return "cdgbr";
8692}
8693
florian55085f82012-11-21 00:36:55 +00008694static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008695s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8696 UChar r1, UChar r2)
8697{
floriane75dafa2012-09-01 17:54:09 +00008698 if (! s390_host_has_fpext) {
8699 emulation_failure(EmFail_S390X_fpext);
8700 } else {
8701 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008702
floriane75dafa2012-09-01 17:54:09 +00008703 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008704 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008705 mkexpr(op2)));
8706 }
florian1c8f7ff2012-09-01 00:12:11 +00008707 return "celfbr";
8708}
8709
florian55085f82012-11-21 00:36:55 +00008710static const HChar *
floriand2129202012-09-01 20:01:39 +00008711s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8712 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008713{
floriane75dafa2012-09-01 17:54:09 +00008714 if (! s390_host_has_fpext) {
8715 emulation_failure(EmFail_S390X_fpext);
8716 } else {
8717 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008718
floriane75dafa2012-09-01 17:54:09 +00008719 assign(op2, get_gpr_w1(r2));
8720 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8721 }
florian1c8f7ff2012-09-01 00:12:11 +00008722 return "cdlfbr";
8723}
8724
florian55085f82012-11-21 00:36:55 +00008725static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008726s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8727 UChar r1, UChar r2)
8728{
floriane75dafa2012-09-01 17:54:09 +00008729 if (! s390_host_has_fpext) {
8730 emulation_failure(EmFail_S390X_fpext);
8731 } else {
8732 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008733
floriane75dafa2012-09-01 17:54:09 +00008734 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008735 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008736 mkexpr(op2)));
8737 }
florian1c8f7ff2012-09-01 00:12:11 +00008738 return "celgbr";
8739}
8740
florian55085f82012-11-21 00:36:55 +00008741static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008742s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8743 UChar r1, UChar r2)
8744{
floriane75dafa2012-09-01 17:54:09 +00008745 if (! s390_host_has_fpext) {
8746 emulation_failure(EmFail_S390X_fpext);
8747 } else {
8748 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008749
floriane75dafa2012-09-01 17:54:09 +00008750 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008751 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8752 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008753 mkexpr(op2)));
8754 }
florian1c8f7ff2012-09-01 00:12:11 +00008755 return "cdlgbr";
8756}
8757
florian55085f82012-11-21 00:36:55 +00008758static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008759s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8760 UChar r1, UChar r2)
8761{
floriane75dafa2012-09-01 17:54:09 +00008762 if (! s390_host_has_fpext) {
8763 emulation_failure(EmFail_S390X_fpext);
8764 } else {
8765 IRTemp op = newTemp(Ity_F32);
8766 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008767 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008768
floriane75dafa2012-09-01 17:54:09 +00008769 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008770 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008771 mkexpr(op)));
8772 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008773 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008774 }
florian1c8f7ff2012-09-01 00:12:11 +00008775 return "clfebr";
8776}
8777
florian55085f82012-11-21 00:36:55 +00008778static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008779s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8780 UChar r1, UChar r2)
8781{
floriane75dafa2012-09-01 17:54:09 +00008782 if (! s390_host_has_fpext) {
8783 emulation_failure(EmFail_S390X_fpext);
8784 } else {
8785 IRTemp op = newTemp(Ity_F64);
8786 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008787 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008788
floriane75dafa2012-09-01 17:54:09 +00008789 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008790 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008791 mkexpr(op)));
8792 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008793 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008794 }
florian1c8f7ff2012-09-01 00:12:11 +00008795 return "clfdbr";
8796}
8797
florian55085f82012-11-21 00:36:55 +00008798static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008799s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8800 UChar r1, UChar r2)
8801{
floriane75dafa2012-09-01 17:54:09 +00008802 if (! s390_host_has_fpext) {
8803 emulation_failure(EmFail_S390X_fpext);
8804 } else {
8805 IRTemp op = newTemp(Ity_F32);
8806 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008807 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008808
floriane75dafa2012-09-01 17:54:09 +00008809 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008810 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008811 mkexpr(op)));
8812 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008813 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008814 }
florian1c8f7ff2012-09-01 00:12:11 +00008815 return "clgebr";
8816}
8817
florian55085f82012-11-21 00:36:55 +00008818static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008819s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8820 UChar r1, UChar r2)
8821{
floriane75dafa2012-09-01 17:54:09 +00008822 if (! s390_host_has_fpext) {
8823 emulation_failure(EmFail_S390X_fpext);
8824 } else {
8825 IRTemp op = newTemp(Ity_F64);
8826 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008827 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008828
floriane75dafa2012-09-01 17:54:09 +00008829 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008830 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008831 mkexpr(op)));
8832 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008833 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008834 }
florian1c8f7ff2012-09-01 00:12:11 +00008835 return "clgdbr";
8836}
8837
florian55085f82012-11-21 00:36:55 +00008838static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008839s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8840 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008841{
8842 IRTemp op = newTemp(Ity_F32);
8843 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008844 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008845
8846 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008847 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008848 mkexpr(op)));
8849 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008850 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008851
8852 return "cfebr";
8853}
8854
florian55085f82012-11-21 00:36:55 +00008855static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008856s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8857 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008858{
8859 IRTemp op = newTemp(Ity_F64);
8860 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008861 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008862
8863 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008864 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008865 mkexpr(op)));
8866 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008867 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008868
8869 return "cfdbr";
8870}
8871
florian55085f82012-11-21 00:36:55 +00008872static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008873s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8874 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008875{
8876 IRTemp op = newTemp(Ity_F32);
8877 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008878 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008879
8880 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008881 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008882 mkexpr(op)));
8883 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008884 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008885
8886 return "cgebr";
8887}
8888
florian55085f82012-11-21 00:36:55 +00008889static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008890s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8891 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008892{
8893 IRTemp op = newTemp(Ity_F64);
8894 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008895 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008896
8897 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008898 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008899 mkexpr(op)));
8900 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008901 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008902
8903 return "cgdbr";
8904}
8905
florian55085f82012-11-21 00:36:55 +00008906static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008907s390_irgen_DEBR(UChar r1, UChar r2)
8908{
8909 IRTemp op1 = newTemp(Ity_F32);
8910 IRTemp op2 = newTemp(Ity_F32);
8911 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008912 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008913
8914 assign(op1, get_fpr_w0(r1));
8915 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008916 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008917 mkexpr(op2)));
8918 put_fpr_w0(r1, mkexpr(result));
8919
8920 return "debr";
8921}
8922
florian55085f82012-11-21 00:36:55 +00008923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008924s390_irgen_DDBR(UChar r1, UChar r2)
8925{
8926 IRTemp op1 = newTemp(Ity_F64);
8927 IRTemp op2 = newTemp(Ity_F64);
8928 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008929 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008930
8931 assign(op1, get_fpr_dw0(r1));
8932 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008933 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008934 mkexpr(op2)));
8935 put_fpr_dw0(r1, mkexpr(result));
8936
8937 return "ddbr";
8938}
8939
florian55085f82012-11-21 00:36:55 +00008940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008941s390_irgen_DEB(UChar r1, IRTemp op2addr)
8942{
8943 IRTemp op1 = newTemp(Ity_F32);
8944 IRTemp op2 = newTemp(Ity_F32);
8945 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008946 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008947
8948 assign(op1, get_fpr_w0(r1));
8949 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008950 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008951 mkexpr(op2)));
8952 put_fpr_w0(r1, mkexpr(result));
8953
8954 return "deb";
8955}
8956
florian55085f82012-11-21 00:36:55 +00008957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008958s390_irgen_DDB(UChar r1, IRTemp op2addr)
8959{
8960 IRTemp op1 = newTemp(Ity_F64);
8961 IRTemp op2 = newTemp(Ity_F64);
8962 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008963 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008964
8965 assign(op1, get_fpr_dw0(r1));
8966 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008967 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008968 mkexpr(op2)));
8969 put_fpr_dw0(r1, mkexpr(result));
8970
8971 return "ddb";
8972}
8973
florian55085f82012-11-21 00:36:55 +00008974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008975s390_irgen_LTEBR(UChar r1, UChar r2)
8976{
8977 IRTemp result = newTemp(Ity_F32);
8978
8979 assign(result, get_fpr_w0(r2));
8980 put_fpr_w0(r1, mkexpr(result));
8981 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8982
8983 return "ltebr";
8984}
8985
florian55085f82012-11-21 00:36:55 +00008986static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008987s390_irgen_LTDBR(UChar r1, UChar r2)
8988{
8989 IRTemp result = newTemp(Ity_F64);
8990
8991 assign(result, get_fpr_dw0(r2));
8992 put_fpr_dw0(r1, mkexpr(result));
8993 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8994
8995 return "ltdbr";
8996}
8997
florian55085f82012-11-21 00:36:55 +00008998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008999s390_irgen_LCEBR(UChar r1, UChar r2)
9000{
9001 IRTemp result = newTemp(Ity_F32);
9002
9003 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9004 put_fpr_w0(r1, mkexpr(result));
9005 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9006
9007 return "lcebr";
9008}
9009
florian55085f82012-11-21 00:36:55 +00009010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009011s390_irgen_LCDBR(UChar r1, UChar r2)
9012{
9013 IRTemp result = newTemp(Ity_F64);
9014
9015 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9016 put_fpr_dw0(r1, mkexpr(result));
9017 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9018
9019 return "lcdbr";
9020}
9021
florian55085f82012-11-21 00:36:55 +00009022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009023s390_irgen_LDEBR(UChar r1, UChar r2)
9024{
9025 IRTemp op = newTemp(Ity_F32);
9026
9027 assign(op, get_fpr_w0(r2));
9028 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9029
9030 return "ldebr";
9031}
9032
florian55085f82012-11-21 00:36:55 +00009033static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009034s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9035{
9036 IRTemp op = newTemp(Ity_F32);
9037
9038 assign(op, load(Ity_F32, mkexpr(op2addr)));
9039 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9040
9041 return "ldeb";
9042}
9043
florian55085f82012-11-21 00:36:55 +00009044static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009045s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9046 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009047{
florian125e20d2012-10-07 15:42:37 +00009048 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009049 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009050 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009051 }
sewardj2019a972011-03-07 16:04:07 +00009052 IRTemp op = newTemp(Ity_F64);
9053
9054 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009055 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009056 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009057
9058 return "ledbr";
9059}
9060
florian55085f82012-11-21 00:36:55 +00009061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009062s390_irgen_MEEBR(UChar r1, UChar r2)
9063{
9064 IRTemp op1 = newTemp(Ity_F32);
9065 IRTemp op2 = newTemp(Ity_F32);
9066 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009067 IRRoundingMode rounding_mode =
9068 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009069
9070 assign(op1, get_fpr_w0(r1));
9071 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009072 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009073 mkexpr(op2)));
9074 put_fpr_w0(r1, mkexpr(result));
9075
9076 return "meebr";
9077}
9078
florian55085f82012-11-21 00:36:55 +00009079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009080s390_irgen_MDBR(UChar r1, UChar r2)
9081{
9082 IRTemp op1 = newTemp(Ity_F64);
9083 IRTemp op2 = newTemp(Ity_F64);
9084 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009085 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009086
9087 assign(op1, get_fpr_dw0(r1));
9088 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009089 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009090 mkexpr(op2)));
9091 put_fpr_dw0(r1, mkexpr(result));
9092
9093 return "mdbr";
9094}
9095
florian55085f82012-11-21 00:36:55 +00009096static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009097s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9098{
9099 IRTemp op1 = newTemp(Ity_F32);
9100 IRTemp op2 = newTemp(Ity_F32);
9101 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009102 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009103
9104 assign(op1, get_fpr_w0(r1));
9105 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009106 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009107 mkexpr(op2)));
9108 put_fpr_w0(r1, mkexpr(result));
9109
9110 return "meeb";
9111}
9112
florian55085f82012-11-21 00:36:55 +00009113static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009114s390_irgen_MDB(UChar r1, IRTemp op2addr)
9115{
9116 IRTemp op1 = newTemp(Ity_F64);
9117 IRTemp op2 = newTemp(Ity_F64);
9118 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009119 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009120
9121 assign(op1, get_fpr_dw0(r1));
9122 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009123 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009124 mkexpr(op2)));
9125 put_fpr_dw0(r1, mkexpr(result));
9126
9127 return "mdb";
9128}
9129
florian55085f82012-11-21 00:36:55 +00009130static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009131s390_irgen_SEBR(UChar r1, UChar r2)
9132{
9133 IRTemp op1 = newTemp(Ity_F32);
9134 IRTemp op2 = newTemp(Ity_F32);
9135 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009136 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009137
9138 assign(op1, get_fpr_w0(r1));
9139 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009140 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009141 mkexpr(op2)));
9142 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9143 put_fpr_w0(r1, mkexpr(result));
9144
9145 return "sebr";
9146}
9147
florian55085f82012-11-21 00:36:55 +00009148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009149s390_irgen_SDBR(UChar r1, UChar r2)
9150{
9151 IRTemp op1 = newTemp(Ity_F64);
9152 IRTemp op2 = newTemp(Ity_F64);
9153 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009154 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009155
9156 assign(op1, get_fpr_dw0(r1));
9157 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009158 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009159 mkexpr(op2)));
9160 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9161 put_fpr_dw0(r1, mkexpr(result));
9162
9163 return "sdbr";
9164}
9165
florian55085f82012-11-21 00:36:55 +00009166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009167s390_irgen_SEB(UChar r1, IRTemp op2addr)
9168{
9169 IRTemp op1 = newTemp(Ity_F32);
9170 IRTemp op2 = newTemp(Ity_F32);
9171 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009172 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009173
9174 assign(op1, get_fpr_w0(r1));
9175 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009176 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009177 mkexpr(op2)));
9178 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9179 put_fpr_w0(r1, mkexpr(result));
9180
9181 return "seb";
9182}
9183
florian55085f82012-11-21 00:36:55 +00009184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009185s390_irgen_SDB(UChar r1, IRTemp op2addr)
9186{
9187 IRTemp op1 = newTemp(Ity_F64);
9188 IRTemp op2 = newTemp(Ity_F64);
9189 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009190 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009191
9192 assign(op1, get_fpr_dw0(r1));
9193 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009194 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009195 mkexpr(op2)));
9196 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9197 put_fpr_dw0(r1, mkexpr(result));
9198
9199 return "sdb";
9200}
9201
florian55085f82012-11-21 00:36:55 +00009202static const HChar *
florian12390202012-11-10 22:34:14 +00009203s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9204{
9205 IRTemp op1 = newTemp(Ity_D64);
9206 IRTemp op2 = newTemp(Ity_D64);
9207 IRTemp result = newTemp(Ity_D64);
9208 IRTemp rounding_mode;
9209
9210 vassert(s390_host_has_dfp);
9211 vassert(m4 == 0 || s390_host_has_fpext);
9212 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9213 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9214 rounding_mode = encode_dfp_rounding_mode(m4);
9215 assign(op1, get_dpr_dw0(r2));
9216 assign(op2, get_dpr_dw0(r3));
9217 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9218 mkexpr(op2)));
9219 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9220 put_dpr_dw0(r1, mkexpr(result));
9221
9222 return (m4 == 0) ? "adtr" : "adtra";
9223}
9224
florian55085f82012-11-21 00:36:55 +00009225static const HChar *
floriane38f6412012-12-21 17:32:12 +00009226s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9227{
9228 IRTemp op1 = newTemp(Ity_D128);
9229 IRTemp op2 = newTemp(Ity_D128);
9230 IRTemp result = newTemp(Ity_D128);
9231 IRTemp rounding_mode;
9232
9233 vassert(s390_host_has_dfp);
9234 vassert(m4 == 0 || s390_host_has_fpext);
9235 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9236 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9237 rounding_mode = encode_dfp_rounding_mode(m4);
9238 assign(op1, get_dpr_pair(r2));
9239 assign(op2, get_dpr_pair(r3));
9240 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9241 mkexpr(op2)));
9242 put_dpr_pair(r1, mkexpr(result));
9243
9244 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9245
9246 return (m4 == 0) ? "axtr" : "axtra";
9247}
9248
9249static const HChar *
9250s390_irgen_CDTR(UChar r1, UChar r2)
9251{
9252 IRTemp op1 = newTemp(Ity_D64);
9253 IRTemp op2 = newTemp(Ity_D64);
9254 IRTemp cc_vex = newTemp(Ity_I32);
9255 IRTemp cc_s390 = newTemp(Ity_I32);
9256
9257 assign(op1, get_dpr_dw0(r1));
9258 assign(op2, get_dpr_dw0(r2));
9259 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9260
florian2d3d87f2012-12-21 21:05:17 +00009261 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009262 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9263
9264 return "cdtr";
9265}
9266
9267static const HChar *
9268s390_irgen_CXTR(UChar r1, UChar r2)
9269{
9270 IRTemp op1 = newTemp(Ity_D128);
9271 IRTemp op2 = newTemp(Ity_D128);
9272 IRTemp cc_vex = newTemp(Ity_I32);
9273 IRTemp cc_s390 = newTemp(Ity_I32);
9274
9275 assign(op1, get_dpr_pair(r1));
9276 assign(op2, get_dpr_pair(r2));
9277 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9278
florian2d3d87f2012-12-21 21:05:17 +00009279 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009280 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9281
9282 return "cxtr";
9283}
9284
9285static const HChar *
florian12390202012-11-10 22:34:14 +00009286s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9287{
9288 IRTemp op1 = newTemp(Ity_D64);
9289 IRTemp op2 = newTemp(Ity_D64);
9290 IRTemp result = newTemp(Ity_D64);
9291 IRTemp rounding_mode;
9292
9293 vassert(s390_host_has_dfp);
9294 vassert(m4 == 0 || s390_host_has_fpext);
9295 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9296 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9297 rounding_mode = encode_dfp_rounding_mode(m4);
9298 assign(op1, get_dpr_dw0(r2));
9299 assign(op2, get_dpr_dw0(r3));
9300 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9301 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009302 put_dpr_dw0(r1, mkexpr(result));
9303
9304 return (m4 == 0) ? "ddtr" : "ddtra";
9305}
9306
florian55085f82012-11-21 00:36:55 +00009307static const HChar *
floriane38f6412012-12-21 17:32:12 +00009308s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9309{
9310 IRTemp op1 = newTemp(Ity_D128);
9311 IRTemp op2 = newTemp(Ity_D128);
9312 IRTemp result = newTemp(Ity_D128);
9313 IRTemp rounding_mode;
9314
9315 vassert(s390_host_has_dfp);
9316 vassert(m4 == 0 || s390_host_has_fpext);
9317 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9318 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9319 rounding_mode = encode_dfp_rounding_mode(m4);
9320 assign(op1, get_dpr_pair(r2));
9321 assign(op2, get_dpr_pair(r3));
9322 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9323 mkexpr(op2)));
9324 put_dpr_pair(r1, mkexpr(result));
9325
9326 return (m4 == 0) ? "dxtr" : "dxtra";
9327}
9328
9329static const HChar *
9330s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9331{
9332 IRTemp op = newTemp(Ity_D32);
9333
9334 vassert(s390_host_has_dfp);
9335
9336 assign(op, get_dpr_w0(r2));
9337 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
9338
9339 return "ldetr";
9340}
9341
9342static const HChar *
9343s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9344{
9345 IRTemp op = newTemp(Ity_D64);
9346
9347 assign(op, get_dpr_dw0(r2));
9348 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
9349
9350 return "lxdtr";
9351}
9352
9353static const HChar *
9354s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
9355 UChar r1, UChar r2)
9356{
9357 vassert(s390_host_has_dfp);
9358 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9359 emulation_warning(EmWarn_S390X_fpext_rounding);
9360 m3 = S390_DFP_ROUND_PER_FPC_0;
9361 }
9362 IRTemp result = newTemp(Ity_D64);
9363
9364 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
9365 get_dpr_pair(r2)));
9366 put_dpr_dw0(r1, mkexpr(result));
9367
9368 return "ldxtr";
9369}
9370
9371static const HChar *
9372s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
9373 UChar r1, UChar r2)
9374{
9375 vassert(s390_host_has_dfp);
9376 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9377 emulation_warning(EmWarn_S390X_fpext_rounding);
9378 m3 = S390_DFP_ROUND_PER_FPC_0;
9379 }
9380 IRTemp op = newTemp(Ity_D64);
9381
9382 assign(op, get_dpr_dw0(r2));
9383 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
9384 mkexpr(op)));
9385
9386 return "ledtr";
9387}
9388
9389static const HChar *
9390s390_irgen_LTDTR(UChar r1, UChar r2)
9391{
9392 IRTemp result = newTemp(Ity_D64);
9393
9394 assign(result, get_dpr_dw0(r2));
9395 put_dpr_dw0(r1, mkexpr(result));
9396 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9397
9398 return "ltdtr";
9399}
9400
9401static const HChar *
9402s390_irgen_LTXTR(UChar r1, UChar r2)
9403{
9404 IRTemp result = newTemp(Ity_D128);
9405
9406 assign(result, get_dpr_pair(r2));
9407 put_dpr_pair(r1, mkexpr(result));
9408 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9409
9410 return "ltxtr";
9411}
9412
9413static const HChar *
florian12390202012-11-10 22:34:14 +00009414s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9415{
9416 IRTemp op1 = newTemp(Ity_D64);
9417 IRTemp op2 = newTemp(Ity_D64);
9418 IRTemp result = newTemp(Ity_D64);
9419 IRTemp rounding_mode;
9420
9421 vassert(s390_host_has_dfp);
9422 vassert(m4 == 0 || s390_host_has_fpext);
9423 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9424 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9425 rounding_mode = encode_dfp_rounding_mode(m4);
9426 assign(op1, get_dpr_dw0(r2));
9427 assign(op2, get_dpr_dw0(r3));
9428 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9429 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009430 put_dpr_dw0(r1, mkexpr(result));
9431
9432 return (m4 == 0) ? "mdtr" : "mdtra";
9433}
9434
florian55085f82012-11-21 00:36:55 +00009435static const HChar *
floriane38f6412012-12-21 17:32:12 +00009436s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9437{
9438 IRTemp op1 = newTemp(Ity_D128);
9439 IRTemp op2 = newTemp(Ity_D128);
9440 IRTemp result = newTemp(Ity_D128);
9441 IRTemp rounding_mode;
9442
9443 vassert(s390_host_has_dfp);
9444 vassert(m4 == 0 || s390_host_has_fpext);
9445 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9446 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9447 rounding_mode = encode_dfp_rounding_mode(m4);
9448 assign(op1, get_dpr_pair(r2));
9449 assign(op2, get_dpr_pair(r3));
9450 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
9451 mkexpr(op2)));
9452 put_dpr_pair(r1, mkexpr(result));
9453
9454 return (m4 == 0) ? "mxtr" : "mxtra";
9455}
9456
9457static const HChar *
florian12390202012-11-10 22:34:14 +00009458s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9459{
9460 IRTemp op1 = newTemp(Ity_D64);
9461 IRTemp op2 = newTemp(Ity_D64);
9462 IRTemp result = newTemp(Ity_D64);
9463 IRTemp rounding_mode;
9464
9465 vassert(s390_host_has_dfp);
9466 vassert(m4 == 0 || s390_host_has_fpext);
9467 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9468 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9469 rounding_mode = encode_dfp_rounding_mode(m4);
9470 assign(op1, get_dpr_dw0(r2));
9471 assign(op2, get_dpr_dw0(r3));
9472 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9473 mkexpr(op2)));
9474 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9475 put_dpr_dw0(r1, mkexpr(result));
9476
9477 return (m4 == 0) ? "sdtr" : "sdtra";
9478}
9479
floriane38f6412012-12-21 17:32:12 +00009480static const HChar *
9481s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9482{
9483 IRTemp op1 = newTemp(Ity_D128);
9484 IRTemp op2 = newTemp(Ity_D128);
9485 IRTemp result = newTemp(Ity_D128);
9486 IRTemp rounding_mode;
9487
9488 vassert(s390_host_has_dfp);
9489 vassert(m4 == 0 || s390_host_has_fpext);
9490 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9491 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9492 rounding_mode = encode_dfp_rounding_mode(m4);
9493 assign(op1, get_dpr_pair(r2));
9494 assign(op2, get_dpr_pair(r3));
9495 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
9496 mkexpr(op2)));
9497 put_dpr_pair(r1, mkexpr(result));
9498
9499 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9500
9501 return (m4 == 0) ? "sxtr" : "sxtra";
9502}
sewardj2019a972011-03-07 16:04:07 +00009503
florian55085f82012-11-21 00:36:55 +00009504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009505s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9506{
florian79e839e2012-05-05 02:20:30 +00009507 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009508
florian79e839e2012-05-05 02:20:30 +00009509 assign(len, mkU64(length));
9510 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009511
9512 return "clc";
9513}
9514
florian55085f82012-11-21 00:36:55 +00009515static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009516s390_irgen_CLCL(UChar r1, UChar r2)
9517{
9518 IRTemp addr1 = newTemp(Ity_I64);
9519 IRTemp addr2 = newTemp(Ity_I64);
9520 IRTemp addr1_load = newTemp(Ity_I64);
9521 IRTemp addr2_load = newTemp(Ity_I64);
9522 IRTemp len1 = newTemp(Ity_I32);
9523 IRTemp len2 = newTemp(Ity_I32);
9524 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9525 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9526 IRTemp single1 = newTemp(Ity_I8);
9527 IRTemp single2 = newTemp(Ity_I8);
9528 IRTemp pad = newTemp(Ity_I8);
9529
9530 assign(addr1, get_gpr_dw0(r1));
9531 assign(r1p1, get_gpr_w1(r1 + 1));
9532 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9533 assign(addr2, get_gpr_dw0(r2));
9534 assign(r2p1, get_gpr_w1(r2 + 1));
9535 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9536 assign(pad, get_gpr_b4(r2 + 1));
9537
9538 /* len1 == 0 and len2 == 0? Exit */
9539 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009540 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9541 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009542
9543 /* Because mkite evaluates both the then-clause and the else-clause
9544 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9545 may be NULL and loading from there would segfault. So we provide a
9546 valid dummy address in that case. Loading from there does no harm and
9547 the value will be discarded at runtime. */
9548 assign(addr1_load,
9549 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9550 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9551 assign(single1,
9552 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9553 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9554
9555 assign(addr2_load,
9556 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9557 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9558 assign(single2,
9559 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9560 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9561
9562 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9563 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009564 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009565
9566 /* Update len1 and addr1, unless len1 == 0. */
9567 put_gpr_dw0(r1,
9568 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9569 mkexpr(addr1),
9570 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9571
9572 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9573 put_gpr_w1(r1 + 1,
9574 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9575 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9576 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9577
9578 /* Update len2 and addr2, unless len2 == 0. */
9579 put_gpr_dw0(r2,
9580 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9581 mkexpr(addr2),
9582 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9583
9584 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9585 put_gpr_w1(r2 + 1,
9586 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9587 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9588 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9589
florian6820ba52012-07-26 02:01:50 +00009590 iterate();
florianb0c9a132011-09-08 15:37:39 +00009591
9592 return "clcl";
9593}
9594
florian55085f82012-11-21 00:36:55 +00009595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009596s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9597{
9598 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9599
9600 addr1 = newTemp(Ity_I64);
9601 addr3 = newTemp(Ity_I64);
9602 addr1_load = newTemp(Ity_I64);
9603 addr3_load = newTemp(Ity_I64);
9604 len1 = newTemp(Ity_I64);
9605 len3 = newTemp(Ity_I64);
9606 single1 = newTemp(Ity_I8);
9607 single3 = newTemp(Ity_I8);
9608
9609 assign(addr1, get_gpr_dw0(r1));
9610 assign(len1, get_gpr_dw0(r1 + 1));
9611 assign(addr3, get_gpr_dw0(r3));
9612 assign(len3, get_gpr_dw0(r3 + 1));
9613
9614 /* len1 == 0 and len3 == 0? Exit */
9615 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009616 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9617 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009618
9619 /* A mux requires both ways to be possible. This is a way to prevent clcle
9620 from reading from addr1 if it should read from the pad. Since the pad
9621 has no address, just read from the instruction, we discard that anyway */
9622 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009623 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9624 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009625
9626 /* same for addr3 */
9627 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009628 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9629 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009630
9631 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009632 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9633 unop(Iop_64to8, mkexpr(pad2)),
9634 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009635
9636 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009637 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9638 unop(Iop_64to8, mkexpr(pad2)),
9639 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009640
9641 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9642 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009643 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009644
9645 /* If a length in 0 we must not change this length and the address */
9646 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009647 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9648 mkexpr(addr1),
9649 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009650
9651 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009652 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9653 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009654
9655 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009656 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9657 mkexpr(addr3),
9658 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009659
9660 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009661 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9662 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009663
florian6820ba52012-07-26 02:01:50 +00009664 iterate();
sewardj2019a972011-03-07 16:04:07 +00009665
9666 return "clcle";
9667}
floriana64c2432011-07-16 02:11:50 +00009668
florianb0bf6602012-05-05 00:01:16 +00009669
sewardj2019a972011-03-07 16:04:07 +00009670static void
9671s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9672{
florianb0bf6602012-05-05 00:01:16 +00009673 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9674}
sewardj2019a972011-03-07 16:04:07 +00009675
sewardj2019a972011-03-07 16:04:07 +00009676
florianb0bf6602012-05-05 00:01:16 +00009677static void
9678s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9679{
9680 s390_irgen_xonc(Iop_And8, length, start1, start2);
9681}
sewardj2019a972011-03-07 16:04:07 +00009682
sewardj2019a972011-03-07 16:04:07 +00009683
florianb0bf6602012-05-05 00:01:16 +00009684static void
9685s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9686{
9687 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009688}
9689
9690
9691static void
9692s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9693{
9694 IRTemp current1 = newTemp(Ity_I8);
9695 IRTemp current2 = newTemp(Ity_I8);
9696 IRTemp counter = newTemp(Ity_I64);
9697
9698 assign(counter, get_counter_dw0());
9699 put_counter_dw0(mkU64(0));
9700
9701 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9702 mkexpr(counter))));
9703 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9704 mkexpr(counter))));
9705 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9706 False);
9707
9708 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009709 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009710
9711 /* Check for end of field */
9712 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009713 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009714 put_counter_dw0(mkU64(0));
9715}
9716
9717static void
9718s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9719{
9720 IRTemp counter = newTemp(Ity_I64);
9721
9722 assign(counter, get_counter_dw0());
9723
9724 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9725 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9726
9727 /* Check for end of field */
9728 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009729 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009730 put_counter_dw0(mkU64(0));
9731}
9732
florianf87d4fb2012-05-05 02:55:24 +00009733static void
9734s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9735{
9736 IRTemp op = newTemp(Ity_I8);
9737 IRTemp op1 = newTemp(Ity_I8);
9738 IRTemp result = newTemp(Ity_I64);
9739 IRTemp counter = newTemp(Ity_I64);
9740
9741 assign(counter, get_counter_dw0());
9742
9743 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9744
9745 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9746
9747 assign(op1, load(Ity_I8, mkexpr(result)));
9748 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9749
9750 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009751 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009752 put_counter_dw0(mkU64(0));
9753}
sewardj2019a972011-03-07 16:04:07 +00009754
9755
9756static void
9757s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009758 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +00009759 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +00009760{
9761 struct SS {
9762 unsigned int op : 8;
9763 unsigned int l : 8;
9764 unsigned int b1 : 4;
9765 unsigned int d1 : 12;
9766 unsigned int b2 : 4;
9767 unsigned int d2 : 12;
9768 };
9769 union {
9770 struct SS dec;
9771 unsigned long bytes;
9772 } ss;
9773 IRTemp cond;
9774 IRDirty *d;
9775 IRTemp torun;
9776
9777 IRTemp start1 = newTemp(Ity_I64);
9778 IRTemp start2 = newTemp(Ity_I64);
9779 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9780 cond = newTemp(Ity_I1);
9781 torun = newTemp(Ity_I64);
9782
9783 assign(torun, load(Ity_I64, mkexpr(addr2)));
9784 /* Start with a check that the saved code is still correct */
9785 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9786 /* If not, save the new value */
9787 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9788 mkIRExprVec_1(mkexpr(torun)));
9789 d->guard = mkexpr(cond);
9790 stmt(IRStmt_Dirty(d));
9791
9792 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009793 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9794 mkU64(guest_IA_curr_instr)));
9795 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009796 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009797
9798 ss.bytes = last_execute_target;
9799 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
9800 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
9801 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
9802 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
9803 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
9804 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
9805 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +00009806
sewardj2019a972011-03-07 16:04:07 +00009807 last_execute_target = 0;
9808}
9809
florian55085f82012-11-21 00:36:55 +00009810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009811s390_irgen_EX(UChar r1, IRTemp addr2)
9812{
9813 switch(last_execute_target & 0xff00000000000000ULL) {
9814 case 0:
9815 {
9816 /* no code information yet */
9817 IRDirty *d;
9818
9819 /* so safe the code... */
9820 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9821 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
9822 stmt(IRStmt_Dirty(d));
9823 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009824 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
9825 mkU64(guest_IA_curr_instr)));
9826 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009827 restart_if(IRExpr_Const(IRConst_U1(True)));
9828
sewardj2019a972011-03-07 16:04:07 +00009829 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +00009830 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +00009831 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +00009832 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +00009833 break;
9834 }
9835
9836 case 0xd200000000000000ULL:
9837 /* special case MVC */
9838 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +00009839 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +00009840
9841 case 0xd500000000000000ULL:
9842 /* special case CLC */
9843 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +00009844 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +00009845
9846 case 0xd700000000000000ULL:
9847 /* special case XC */
9848 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +00009849 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +00009850
florianb0bf6602012-05-05 00:01:16 +00009851 case 0xd600000000000000ULL:
9852 /* special case OC */
9853 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +00009854 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +00009855
9856 case 0xd400000000000000ULL:
9857 /* special case NC */
9858 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +00009859 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +00009860
florianf87d4fb2012-05-05 02:55:24 +00009861 case 0xdc00000000000000ULL:
9862 /* special case TR */
9863 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +00009864 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +00009865
sewardj2019a972011-03-07 16:04:07 +00009866 default:
9867 {
9868 /* everything else will get a self checking prefix that also checks the
9869 register content */
9870 IRDirty *d;
9871 UChar *bytes;
9872 IRTemp cond;
9873 IRTemp orperand;
9874 IRTemp torun;
9875
9876 cond = newTemp(Ity_I1);
9877 orperand = newTemp(Ity_I64);
9878 torun = newTemp(Ity_I64);
9879
9880 if (r1 == 0)
9881 assign(orperand, mkU64(0));
9882 else
9883 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
9884 /* This code is going to be translated */
9885 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
9886 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
9887
9888 /* Start with a check that saved code is still correct */
9889 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
9890 mkU64(last_execute_target)));
9891 /* If not, save the new value */
9892 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9893 mkIRExprVec_1(mkexpr(torun)));
9894 d->guard = mkexpr(cond);
9895 stmt(IRStmt_Dirty(d));
9896
9897 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009898 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
9899 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +00009900 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +00009901
9902 /* Now comes the actual translation */
9903 bytes = (UChar *) &last_execute_target;
9904 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
9905 dis_res);
sewardj7ee97522011-05-09 21:45:04 +00009906 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00009907 vex_printf(" which was executed by\n");
9908 /* dont make useless translations in the next execute */
9909 last_execute_target = 0;
9910 }
9911 }
9912 return "ex";
9913}
9914
florian55085f82012-11-21 00:36:55 +00009915static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009916s390_irgen_EXRL(UChar r1, UInt offset)
9917{
9918 IRTemp addr = newTemp(Ity_I64);
9919 /* we might save one round trip because we know the target */
9920 if (!last_execute_target)
9921 last_execute_target = *(ULong *)(HWord)
9922 (guest_IA_curr_instr + offset * 2UL);
9923 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
9924 s390_irgen_EX(r1, addr);
9925 return "exrl";
9926}
9927
florian55085f82012-11-21 00:36:55 +00009928static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009929s390_irgen_IPM(UChar r1)
9930{
9931 // As long as we dont support SPM, lets just assume 0 as program mask
9932 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
9933 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
9934
9935 return "ipm";
9936}
9937
9938
florian55085f82012-11-21 00:36:55 +00009939static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009940s390_irgen_SRST(UChar r1, UChar r2)
9941{
9942 IRTemp address = newTemp(Ity_I64);
9943 IRTemp next = newTemp(Ity_I64);
9944 IRTemp delim = newTemp(Ity_I8);
9945 IRTemp counter = newTemp(Ity_I64);
9946 IRTemp byte = newTemp(Ity_I8);
9947
9948 assign(address, get_gpr_dw0(r2));
9949 assign(next, get_gpr_dw0(r1));
9950
9951 assign(counter, get_counter_dw0());
9952 put_counter_dw0(mkU64(0));
9953
9954 // start = next? CC=2 and out r1 and r2 unchanged
9955 s390_cc_set(2);
9956 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009957 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +00009958
9959 assign(byte, load(Ity_I8, mkexpr(address)));
9960 assign(delim, get_gpr_b7(0));
9961
9962 // byte = delim? CC=1, R1=address
9963 s390_cc_set(1);
9964 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +00009965 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +00009966
9967 // else: all equal, no end yet, loop
9968 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
9969 put_gpr_dw0(r1, mkexpr(next));
9970 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +00009971
florian6820ba52012-07-26 02:01:50 +00009972 iterate();
sewardj2019a972011-03-07 16:04:07 +00009973
9974 return "srst";
9975}
9976
florian55085f82012-11-21 00:36:55 +00009977static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009978s390_irgen_CLST(UChar r1, UChar r2)
9979{
9980 IRTemp address1 = newTemp(Ity_I64);
9981 IRTemp address2 = newTemp(Ity_I64);
9982 IRTemp end = newTemp(Ity_I8);
9983 IRTemp counter = newTemp(Ity_I64);
9984 IRTemp byte1 = newTemp(Ity_I8);
9985 IRTemp byte2 = newTemp(Ity_I8);
9986
9987 assign(address1, get_gpr_dw0(r1));
9988 assign(address2, get_gpr_dw0(r2));
9989 assign(end, get_gpr_b7(0));
9990 assign(counter, get_counter_dw0());
9991 put_counter_dw0(mkU64(0));
9992 assign(byte1, load(Ity_I8, mkexpr(address1)));
9993 assign(byte2, load(Ity_I8, mkexpr(address2)));
9994
9995 // end in both? all equal, reset r1 and r2 to start values
9996 s390_cc_set(0);
9997 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
9998 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +00009999 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10000 binop(Iop_Or8,
10001 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10002 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010003
10004 put_gpr_dw0(r1, mkexpr(address1));
10005 put_gpr_dw0(r2, mkexpr(address2));
10006
10007 // End found in string1
10008 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010009 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010010
10011 // End found in string2
10012 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010013 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010014
10015 // string1 < string2
10016 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010017 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10018 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010019
10020 // string2 < string1
10021 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010022 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10023 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010024
10025 // else: all equal, no end yet, loop
10026 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10027 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10028 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010029
florian6820ba52012-07-26 02:01:50 +000010030 iterate();
sewardj2019a972011-03-07 16:04:07 +000010031
10032 return "clst";
10033}
10034
10035static void
10036s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10037{
10038 UChar reg;
10039 IRTemp addr = newTemp(Ity_I64);
10040
10041 assign(addr, mkexpr(op2addr));
10042 reg = r1;
10043 do {
10044 IRTemp old = addr;
10045
10046 reg %= 16;
10047 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10048 addr = newTemp(Ity_I64);
10049 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10050 reg++;
10051 } while (reg != (r3 + 1));
10052}
10053
florian55085f82012-11-21 00:36:55 +000010054static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010055s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10056{
10057 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10058
10059 return "lm";
10060}
10061
florian55085f82012-11-21 00:36:55 +000010062static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010063s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
10064{
10065 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10066
10067 return "lmy";
10068}
10069
florian55085f82012-11-21 00:36:55 +000010070static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010071s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
10072{
10073 UChar reg;
10074 IRTemp addr = newTemp(Ity_I64);
10075
10076 assign(addr, mkexpr(op2addr));
10077 reg = r1;
10078 do {
10079 IRTemp old = addr;
10080
10081 reg %= 16;
10082 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
10083 addr = newTemp(Ity_I64);
10084 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10085 reg++;
10086 } while (reg != (r3 + 1));
10087
10088 return "lmh";
10089}
10090
florian55085f82012-11-21 00:36:55 +000010091static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010092s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
10093{
10094 UChar reg;
10095 IRTemp addr = newTemp(Ity_I64);
10096
10097 assign(addr, mkexpr(op2addr));
10098 reg = r1;
10099 do {
10100 IRTemp old = addr;
10101
10102 reg %= 16;
10103 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
10104 addr = newTemp(Ity_I64);
10105 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10106 reg++;
10107 } while (reg != (r3 + 1));
10108
10109 return "lmg";
10110}
10111
10112static void
10113s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10114{
10115 UChar reg;
10116 IRTemp addr = newTemp(Ity_I64);
10117
10118 assign(addr, mkexpr(op2addr));
10119 reg = r1;
10120 do {
10121 IRTemp old = addr;
10122
10123 reg %= 16;
10124 store(mkexpr(addr), get_gpr_w1(reg));
10125 addr = newTemp(Ity_I64);
10126 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10127 reg++;
10128 } while( reg != (r3 + 1));
10129}
10130
florian55085f82012-11-21 00:36:55 +000010131static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010132s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
10133{
10134 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10135
10136 return "stm";
10137}
10138
florian55085f82012-11-21 00:36:55 +000010139static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010140s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
10141{
10142 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10143
10144 return "stmy";
10145}
10146
florian55085f82012-11-21 00:36:55 +000010147static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010148s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
10149{
10150 UChar reg;
10151 IRTemp addr = newTemp(Ity_I64);
10152
10153 assign(addr, mkexpr(op2addr));
10154 reg = r1;
10155 do {
10156 IRTemp old = addr;
10157
10158 reg %= 16;
10159 store(mkexpr(addr), get_gpr_w0(reg));
10160 addr = newTemp(Ity_I64);
10161 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10162 reg++;
10163 } while( reg != (r3 + 1));
10164
10165 return "stmh";
10166}
10167
florian55085f82012-11-21 00:36:55 +000010168static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010169s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
10170{
10171 UChar reg;
10172 IRTemp addr = newTemp(Ity_I64);
10173
10174 assign(addr, mkexpr(op2addr));
10175 reg = r1;
10176 do {
10177 IRTemp old = addr;
10178
10179 reg %= 16;
10180 store(mkexpr(addr), get_gpr_dw0(reg));
10181 addr = newTemp(Ity_I64);
10182 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10183 reg++;
10184 } while( reg != (r3 + 1));
10185
10186 return "stmg";
10187}
10188
10189static void
florianb0bf6602012-05-05 00:01:16 +000010190s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000010191{
10192 IRTemp old1 = newTemp(Ity_I8);
10193 IRTemp old2 = newTemp(Ity_I8);
10194 IRTemp new1 = newTemp(Ity_I8);
10195 IRTemp counter = newTemp(Ity_I32);
10196 IRTemp addr1 = newTemp(Ity_I64);
10197
10198 assign(counter, get_counter_w0());
10199
10200 assign(addr1, binop(Iop_Add64, mkexpr(start1),
10201 unop(Iop_32Uto64, mkexpr(counter))));
10202
10203 assign(old1, load(Ity_I8, mkexpr(addr1)));
10204 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10205 unop(Iop_32Uto64,mkexpr(counter)))));
10206 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
10207
10208 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000010209 if (op == Iop_Xor8) {
10210 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000010211 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
10212 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000010213 } else
10214 store(mkexpr(addr1), mkexpr(new1));
10215 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
10216 get_counter_w1()));
10217
10218 /* Check for end of field */
10219 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010220 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010221 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
10222 False);
10223 put_counter_dw0(mkU64(0));
10224}
10225
florian55085f82012-11-21 00:36:55 +000010226static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010227s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
10228{
florianb0bf6602012-05-05 00:01:16 +000010229 IRTemp len = newTemp(Ity_I32);
10230
10231 assign(len, mkU32(length));
10232 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010233
10234 return "xc";
10235}
10236
sewardjb63967e2011-03-24 08:50:04 +000010237static void
10238s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
10239{
10240 IRTemp counter = newTemp(Ity_I32);
10241 IRTemp start = newTemp(Ity_I64);
10242 IRTemp addr = newTemp(Ity_I64);
10243
10244 assign(start,
10245 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
10246
10247 if (length < 8) {
10248 UInt i;
10249
10250 for (i = 0; i <= length; ++i) {
10251 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
10252 }
10253 } else {
10254 assign(counter, get_counter_w0());
10255
10256 assign(addr, binop(Iop_Add64, mkexpr(start),
10257 unop(Iop_32Uto64, mkexpr(counter))));
10258
10259 store(mkexpr(addr), mkU8(0));
10260
10261 /* Check for end of field */
10262 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010263 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000010264
10265 /* Reset counter */
10266 put_counter_dw0(mkU64(0));
10267 }
10268
10269 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
10270
sewardj7ee97522011-05-09 21:45:04 +000010271 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000010272 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
10273}
10274
florian55085f82012-11-21 00:36:55 +000010275static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010276s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
10277{
florianb0bf6602012-05-05 00:01:16 +000010278 IRTemp len = newTemp(Ity_I32);
10279
10280 assign(len, mkU32(length));
10281 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010282
10283 return "nc";
10284}
10285
florian55085f82012-11-21 00:36:55 +000010286static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010287s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
10288{
florianb0bf6602012-05-05 00:01:16 +000010289 IRTemp len = newTemp(Ity_I32);
10290
10291 assign(len, mkU32(length));
10292 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010293
10294 return "oc";
10295}
10296
10297
florian55085f82012-11-21 00:36:55 +000010298static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010299s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
10300{
florian79e839e2012-05-05 02:20:30 +000010301 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010302
florian79e839e2012-05-05 02:20:30 +000010303 assign(len, mkU64(length));
10304 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010305
10306 return "mvc";
10307}
10308
florian55085f82012-11-21 00:36:55 +000010309static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010310s390_irgen_MVCL(UChar r1, UChar r2)
10311{
10312 IRTemp addr1 = newTemp(Ity_I64);
10313 IRTemp addr2 = newTemp(Ity_I64);
10314 IRTemp addr2_load = newTemp(Ity_I64);
10315 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10316 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10317 IRTemp len1 = newTemp(Ity_I32);
10318 IRTemp len2 = newTemp(Ity_I32);
10319 IRTemp pad = newTemp(Ity_I8);
10320 IRTemp single = newTemp(Ity_I8);
10321
10322 assign(addr1, get_gpr_dw0(r1));
10323 assign(r1p1, get_gpr_w1(r1 + 1));
10324 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10325 assign(addr2, get_gpr_dw0(r2));
10326 assign(r2p1, get_gpr_w1(r2 + 1));
10327 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10328 assign(pad, get_gpr_b4(r2 + 1));
10329
10330 /* len1 == 0 ? */
10331 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010332 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010333
10334 /* Check for destructive overlap:
10335 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
10336 s390_cc_set(3);
10337 IRTemp cond1 = newTemp(Ity_I32);
10338 assign(cond1, unop(Iop_1Uto32,
10339 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
10340 IRTemp cond2 = newTemp(Ity_I32);
10341 assign(cond2, unop(Iop_1Uto32,
10342 binop(Iop_CmpLT64U, mkexpr(addr1),
10343 binop(Iop_Add64, mkexpr(addr2),
10344 unop(Iop_32Uto64, mkexpr(len1))))));
10345 IRTemp cond3 = newTemp(Ity_I32);
10346 assign(cond3, unop(Iop_1Uto32,
10347 binop(Iop_CmpLT64U,
10348 mkexpr(addr1),
10349 binop(Iop_Add64, mkexpr(addr2),
10350 unop(Iop_32Uto64, mkexpr(len2))))));
10351
florian6820ba52012-07-26 02:01:50 +000010352 next_insn_if(binop(Iop_CmpEQ32,
10353 binop(Iop_And32,
10354 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10355 mkexpr(cond3)),
10356 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010357
10358 /* See s390_irgen_CLCL for explanation why we cannot load directly
10359 and need two steps. */
10360 assign(addr2_load,
10361 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10362 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10363 assign(single,
10364 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10365 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10366
10367 store(mkexpr(addr1), mkexpr(single));
10368
10369 /* Update addr1 and len1 */
10370 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10371 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10372
10373 /* Update addr2 and len2 */
10374 put_gpr_dw0(r2,
10375 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10376 mkexpr(addr2),
10377 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10378
10379 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10380 put_gpr_w1(r2 + 1,
10381 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10382 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10383 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10384
10385 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010386 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010387
10388 return "mvcl";
10389}
10390
10391
florian55085f82012-11-21 00:36:55 +000010392static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010393s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10394{
10395 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10396
10397 addr1 = newTemp(Ity_I64);
10398 addr3 = newTemp(Ity_I64);
10399 addr3_load = newTemp(Ity_I64);
10400 len1 = newTemp(Ity_I64);
10401 len3 = newTemp(Ity_I64);
10402 single = newTemp(Ity_I8);
10403
10404 assign(addr1, get_gpr_dw0(r1));
10405 assign(len1, get_gpr_dw0(r1 + 1));
10406 assign(addr3, get_gpr_dw0(r3));
10407 assign(len3, get_gpr_dw0(r3 + 1));
10408
10409 // len1 == 0 ?
10410 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010411 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010412
10413 /* This is a hack to prevent mvcle from reading from addr3 if it
10414 should read from the pad. Since the pad has no address, just
10415 read from the instruction, we discard that anyway */
10416 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010417 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10418 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010419
10420 assign(single,
florian6ad49522011-09-09 02:38:55 +000010421 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10422 unop(Iop_64to8, mkexpr(pad2)),
10423 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010424 store(mkexpr(addr1), mkexpr(single));
10425
10426 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10427
10428 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10429
10430 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010431 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10432 mkexpr(addr3),
10433 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010434
10435 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010436 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10437 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010438
sewardj2019a972011-03-07 16:04:07 +000010439 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010440 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010441
10442 return "mvcle";
10443}
10444
florian55085f82012-11-21 00:36:55 +000010445static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010446s390_irgen_MVST(UChar r1, UChar r2)
10447{
10448 IRTemp addr1 = newTemp(Ity_I64);
10449 IRTemp addr2 = newTemp(Ity_I64);
10450 IRTemp end = newTemp(Ity_I8);
10451 IRTemp byte = newTemp(Ity_I8);
10452 IRTemp counter = newTemp(Ity_I64);
10453
10454 assign(addr1, get_gpr_dw0(r1));
10455 assign(addr2, get_gpr_dw0(r2));
10456 assign(counter, get_counter_dw0());
10457 assign(end, get_gpr_b7(0));
10458 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10459 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10460
10461 // We use unlimited as cpu-determined number
10462 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010463 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010464
10465 // and always set cc=1 at the end + update r1
10466 s390_cc_set(1);
10467 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10468 put_counter_dw0(mkU64(0));
10469
10470 return "mvst";
10471}
10472
10473static void
10474s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10475{
10476 IRTemp op1 = newTemp(Ity_I64);
10477 IRTemp result = newTemp(Ity_I64);
10478
10479 assign(op1, binop(Iop_32HLto64,
10480 get_gpr_w1(r1), // high 32 bits
10481 get_gpr_w1(r1 + 1))); // low 32 bits
10482 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10483 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10484 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10485}
10486
10487static void
10488s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10489{
10490 IRTemp op1 = newTemp(Ity_I128);
10491 IRTemp result = newTemp(Ity_I128);
10492
10493 assign(op1, binop(Iop_64HLto128,
10494 get_gpr_dw0(r1), // high 64 bits
10495 get_gpr_dw0(r1 + 1))); // low 64 bits
10496 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10497 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10498 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10499}
10500
10501static void
10502s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10503{
10504 IRTemp op1 = newTemp(Ity_I64);
10505 IRTemp result = newTemp(Ity_I128);
10506
10507 assign(op1, get_gpr_dw0(r1 + 1));
10508 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10509 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10510 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10511}
10512
florian55085f82012-11-21 00:36:55 +000010513static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010514s390_irgen_DR(UChar r1, UChar r2)
10515{
10516 IRTemp op2 = newTemp(Ity_I32);
10517
10518 assign(op2, get_gpr_w1(r2));
10519
10520 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10521
10522 return "dr";
10523}
10524
florian55085f82012-11-21 00:36:55 +000010525static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010526s390_irgen_D(UChar r1, IRTemp op2addr)
10527{
10528 IRTemp op2 = newTemp(Ity_I32);
10529
10530 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10531
10532 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10533
10534 return "d";
10535}
10536
florian55085f82012-11-21 00:36:55 +000010537static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010538s390_irgen_DLR(UChar r1, UChar r2)
10539{
10540 IRTemp op2 = newTemp(Ity_I32);
10541
10542 assign(op2, get_gpr_w1(r2));
10543
10544 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10545
florian7cd1cde2012-08-16 23:57:43 +000010546 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010547}
10548
florian55085f82012-11-21 00:36:55 +000010549static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010550s390_irgen_DL(UChar r1, IRTemp op2addr)
10551{
10552 IRTemp op2 = newTemp(Ity_I32);
10553
10554 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10555
10556 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10557
10558 return "dl";
10559}
10560
florian55085f82012-11-21 00:36:55 +000010561static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010562s390_irgen_DLG(UChar r1, IRTemp op2addr)
10563{
10564 IRTemp op2 = newTemp(Ity_I64);
10565
10566 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10567
10568 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10569
10570 return "dlg";
10571}
10572
florian55085f82012-11-21 00:36:55 +000010573static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010574s390_irgen_DLGR(UChar r1, UChar r2)
10575{
10576 IRTemp op2 = newTemp(Ity_I64);
10577
10578 assign(op2, get_gpr_dw0(r2));
10579
10580 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10581
10582 return "dlgr";
10583}
10584
florian55085f82012-11-21 00:36:55 +000010585static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010586s390_irgen_DSGR(UChar r1, UChar r2)
10587{
10588 IRTemp op2 = newTemp(Ity_I64);
10589
10590 assign(op2, get_gpr_dw0(r2));
10591
10592 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10593
10594 return "dsgr";
10595}
10596
florian55085f82012-11-21 00:36:55 +000010597static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010598s390_irgen_DSG(UChar r1, IRTemp op2addr)
10599{
10600 IRTemp op2 = newTemp(Ity_I64);
10601
10602 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10603
10604 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10605
10606 return "dsg";
10607}
10608
florian55085f82012-11-21 00:36:55 +000010609static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010610s390_irgen_DSGFR(UChar r1, UChar r2)
10611{
10612 IRTemp op2 = newTemp(Ity_I64);
10613
10614 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10615
10616 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10617
10618 return "dsgfr";
10619}
10620
florian55085f82012-11-21 00:36:55 +000010621static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010622s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10623{
10624 IRTemp op2 = newTemp(Ity_I64);
10625
10626 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10627
10628 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10629
10630 return "dsgf";
10631}
10632
10633static void
10634s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10635{
10636 UChar reg;
10637 IRTemp addr = newTemp(Ity_I64);
10638
10639 assign(addr, mkexpr(op2addr));
10640 reg = r1;
10641 do {
10642 IRTemp old = addr;
10643
10644 reg %= 16;
10645 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10646 addr = newTemp(Ity_I64);
10647 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10648 reg++;
10649 } while (reg != (r3 + 1));
10650}
10651
florian55085f82012-11-21 00:36:55 +000010652static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010653s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10654{
10655 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10656
10657 return "lam";
10658}
10659
florian55085f82012-11-21 00:36:55 +000010660static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010661s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10662{
10663 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10664
10665 return "lamy";
10666}
10667
10668static void
10669s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10670{
10671 UChar reg;
10672 IRTemp addr = newTemp(Ity_I64);
10673
10674 assign(addr, mkexpr(op2addr));
10675 reg = r1;
10676 do {
10677 IRTemp old = addr;
10678
10679 reg %= 16;
10680 store(mkexpr(addr), get_ar_w0(reg));
10681 addr = newTemp(Ity_I64);
10682 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10683 reg++;
10684 } while (reg != (r3 + 1));
10685}
10686
florian55085f82012-11-21 00:36:55 +000010687static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010688s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10689{
10690 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10691
10692 return "stam";
10693}
10694
florian55085f82012-11-21 00:36:55 +000010695static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010696s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10697{
10698 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10699
10700 return "stamy";
10701}
10702
10703
10704/* Implementation for 32-bit compare-and-swap */
10705static void
10706s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10707{
10708 IRCAS *cas;
10709 IRTemp op1 = newTemp(Ity_I32);
10710 IRTemp old_mem = newTemp(Ity_I32);
10711 IRTemp op3 = newTemp(Ity_I32);
10712 IRTemp result = newTemp(Ity_I32);
10713 IRTemp nequal = newTemp(Ity_I1);
10714
10715 assign(op1, get_gpr_w1(r1));
10716 assign(op3, get_gpr_w1(r3));
10717
10718 /* The first and second operands are compared. If they are equal,
10719 the third operand is stored at the second- operand location. */
10720 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10721 Iend_BE, mkexpr(op2addr),
10722 NULL, mkexpr(op1), /* expected value */
10723 NULL, mkexpr(op3) /* new value */);
10724 stmt(IRStmt_CAS(cas));
10725
10726 /* Set CC. Operands compared equal -> 0, else 1. */
10727 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10728 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10729
10730 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10731 Otherwise, store the old_value from memory in r1 and yield. */
10732 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10733 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010734 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010735}
10736
florian55085f82012-11-21 00:36:55 +000010737static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010738s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10739{
10740 s390_irgen_cas_32(r1, r3, op2addr);
10741
10742 return "cs";
10743}
10744
florian55085f82012-11-21 00:36:55 +000010745static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010746s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10747{
10748 s390_irgen_cas_32(r1, r3, op2addr);
10749
10750 return "csy";
10751}
10752
florian55085f82012-11-21 00:36:55 +000010753static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010754s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10755{
10756 IRCAS *cas;
10757 IRTemp op1 = newTemp(Ity_I64);
10758 IRTemp old_mem = newTemp(Ity_I64);
10759 IRTemp op3 = newTemp(Ity_I64);
10760 IRTemp result = newTemp(Ity_I64);
10761 IRTemp nequal = newTemp(Ity_I1);
10762
10763 assign(op1, get_gpr_dw0(r1));
10764 assign(op3, get_gpr_dw0(r3));
10765
10766 /* The first and second operands are compared. If they are equal,
10767 the third operand is stored at the second- operand location. */
10768 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10769 Iend_BE, mkexpr(op2addr),
10770 NULL, mkexpr(op1), /* expected value */
10771 NULL, mkexpr(op3) /* new value */);
10772 stmt(IRStmt_CAS(cas));
10773
10774 /* Set CC. Operands compared equal -> 0, else 1. */
10775 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10776 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10777
10778 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10779 Otherwise, store the old_value from memory in r1 and yield. */
10780 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10781 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010782 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010783
10784 return "csg";
10785}
10786
florian448cbba2012-06-06 02:26:01 +000010787/* Implementation for 32-bit compare-double-and-swap */
10788static void
10789s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10790{
10791 IRCAS *cas;
10792 IRTemp op1_high = newTemp(Ity_I32);
10793 IRTemp op1_low = newTemp(Ity_I32);
10794 IRTemp old_mem_high = newTemp(Ity_I32);
10795 IRTemp old_mem_low = newTemp(Ity_I32);
10796 IRTemp op3_high = newTemp(Ity_I32);
10797 IRTemp op3_low = newTemp(Ity_I32);
10798 IRTemp result = newTemp(Ity_I32);
10799 IRTemp nequal = newTemp(Ity_I1);
10800
10801 assign(op1_high, get_gpr_w1(r1));
10802 assign(op1_low, get_gpr_w1(r1+1));
10803 assign(op3_high, get_gpr_w1(r3));
10804 assign(op3_low, get_gpr_w1(r3+1));
10805
10806 /* The first and second operands are compared. If they are equal,
10807 the third operand is stored at the second-operand location. */
10808 cas = mkIRCAS(old_mem_high, old_mem_low,
10809 Iend_BE, mkexpr(op2addr),
10810 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10811 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10812 stmt(IRStmt_CAS(cas));
10813
10814 /* Set CC. Operands compared equal -> 0, else 1. */
10815 assign(result, unop(Iop_1Uto32,
10816 binop(Iop_CmpNE32,
10817 binop(Iop_Or32,
10818 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
10819 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
10820 mkU32(0))));
10821
10822 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10823
10824 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10825 Otherwise, store the old_value from memory in r1 and yield. */
10826 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10827 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10828 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010829 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000010830}
10831
florian55085f82012-11-21 00:36:55 +000010832static const HChar *
florian448cbba2012-06-06 02:26:01 +000010833s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
10834{
10835 s390_irgen_cdas_32(r1, r3, op2addr);
10836
10837 return "cds";
10838}
10839
florian55085f82012-11-21 00:36:55 +000010840static const HChar *
florian448cbba2012-06-06 02:26:01 +000010841s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
10842{
10843 s390_irgen_cdas_32(r1, r3, op2addr);
10844
10845 return "cdsy";
10846}
10847
florian55085f82012-11-21 00:36:55 +000010848static const HChar *
florian448cbba2012-06-06 02:26:01 +000010849s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
10850{
10851 IRCAS *cas;
10852 IRTemp op1_high = newTemp(Ity_I64);
10853 IRTemp op1_low = newTemp(Ity_I64);
10854 IRTemp old_mem_high = newTemp(Ity_I64);
10855 IRTemp old_mem_low = newTemp(Ity_I64);
10856 IRTemp op3_high = newTemp(Ity_I64);
10857 IRTemp op3_low = newTemp(Ity_I64);
10858 IRTemp result = newTemp(Ity_I64);
10859 IRTemp nequal = newTemp(Ity_I1);
10860
10861 assign(op1_high, get_gpr_dw0(r1));
10862 assign(op1_low, get_gpr_dw0(r1+1));
10863 assign(op3_high, get_gpr_dw0(r3));
10864 assign(op3_low, get_gpr_dw0(r3+1));
10865
10866 /* The first and second operands are compared. If they are equal,
10867 the third operand is stored at the second-operand location. */
10868 cas = mkIRCAS(old_mem_high, old_mem_low,
10869 Iend_BE, mkexpr(op2addr),
10870 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
10871 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
10872 stmt(IRStmt_CAS(cas));
10873
10874 /* Set CC. Operands compared equal -> 0, else 1. */
10875 assign(result, unop(Iop_1Uto64,
10876 binop(Iop_CmpNE64,
10877 binop(Iop_Or64,
10878 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
10879 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
10880 mkU64(0))));
10881
10882 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10883
10884 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10885 Otherwise, store the old_value from memory in r1 and yield. */
10886 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10887 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
10888 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000010889 yield_if(mkexpr(nequal));
10890
florian448cbba2012-06-06 02:26:01 +000010891 return "cdsg";
10892}
10893
sewardj2019a972011-03-07 16:04:07 +000010894
10895/* Binary floating point */
10896
florian55085f82012-11-21 00:36:55 +000010897static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010898s390_irgen_AXBR(UChar r1, UChar r2)
10899{
10900 IRTemp op1 = newTemp(Ity_F128);
10901 IRTemp op2 = newTemp(Ity_F128);
10902 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000010903 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000010904
10905 assign(op1, get_fpr_pair(r1));
10906 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000010907 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000010908 mkexpr(op2)));
10909 put_fpr_pair(r1, mkexpr(result));
10910
10911 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
10912
10913 return "axbr";
10914}
10915
florian55085f82012-11-21 00:36:55 +000010916static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010917s390_irgen_CEBR(UChar r1, UChar r2)
10918{
10919 IRTemp op1 = newTemp(Ity_F32);
10920 IRTemp op2 = newTemp(Ity_F32);
10921 IRTemp cc_vex = newTemp(Ity_I32);
10922 IRTemp cc_s390 = newTemp(Ity_I32);
10923
10924 assign(op1, get_fpr_w0(r1));
10925 assign(op2, get_fpr_w0(r2));
10926 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10927
florian2d3d87f2012-12-21 21:05:17 +000010928 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000010929 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10930
10931 return "cebr";
10932}
10933
florian55085f82012-11-21 00:36:55 +000010934static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010935s390_irgen_CDBR(UChar r1, UChar r2)
10936{
10937 IRTemp op1 = newTemp(Ity_F64);
10938 IRTemp op2 = newTemp(Ity_F64);
10939 IRTemp cc_vex = newTemp(Ity_I32);
10940 IRTemp cc_s390 = newTemp(Ity_I32);
10941
10942 assign(op1, get_fpr_dw0(r1));
10943 assign(op2, get_fpr_dw0(r2));
10944 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10945
florian2d3d87f2012-12-21 21:05:17 +000010946 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000010947 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10948
10949 return "cdbr";
10950}
10951
florian55085f82012-11-21 00:36:55 +000010952static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010953s390_irgen_CXBR(UChar r1, UChar r2)
10954{
10955 IRTemp op1 = newTemp(Ity_F128);
10956 IRTemp op2 = newTemp(Ity_F128);
10957 IRTemp cc_vex = newTemp(Ity_I32);
10958 IRTemp cc_s390 = newTemp(Ity_I32);
10959
10960 assign(op1, get_fpr_pair(r1));
10961 assign(op2, get_fpr_pair(r2));
10962 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
10963
florian2d3d87f2012-12-21 21:05:17 +000010964 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000010965 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10966
10967 return "cxbr";
10968}
10969
florian55085f82012-11-21 00:36:55 +000010970static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010971s390_irgen_CEB(UChar r1, IRTemp op2addr)
10972{
10973 IRTemp op1 = newTemp(Ity_F32);
10974 IRTemp op2 = newTemp(Ity_F32);
10975 IRTemp cc_vex = newTemp(Ity_I32);
10976 IRTemp cc_s390 = newTemp(Ity_I32);
10977
10978 assign(op1, get_fpr_w0(r1));
10979 assign(op2, load(Ity_F32, mkexpr(op2addr)));
10980 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
10981
florian2d3d87f2012-12-21 21:05:17 +000010982 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000010983 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
10984
10985 return "ceb";
10986}
10987
florian55085f82012-11-21 00:36:55 +000010988static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010989s390_irgen_CDB(UChar r1, IRTemp op2addr)
10990{
10991 IRTemp op1 = newTemp(Ity_F64);
10992 IRTemp op2 = newTemp(Ity_F64);
10993 IRTemp cc_vex = newTemp(Ity_I32);
10994 IRTemp cc_s390 = newTemp(Ity_I32);
10995
10996 assign(op1, get_fpr_dw0(r1));
10997 assign(op2, load(Ity_F64, mkexpr(op2addr)));
10998 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
10999
florian2d3d87f2012-12-21 21:05:17 +000011000 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011001 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11002
11003 return "cdb";
11004}
11005
florian55085f82012-11-21 00:36:55 +000011006static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011007s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11008 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011009{
11010 IRTemp op2 = newTemp(Ity_I32);
11011
11012 assign(op2, get_gpr_w1(r2));
11013 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11014
11015 return "cxfbr";
11016}
11017
florian55085f82012-11-21 00:36:55 +000011018static const HChar *
floriand2129202012-09-01 20:01:39 +000011019s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11020 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011021{
floriane75dafa2012-09-01 17:54:09 +000011022 if (! s390_host_has_fpext) {
11023 emulation_failure(EmFail_S390X_fpext);
11024 } else {
11025 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011026
floriane75dafa2012-09-01 17:54:09 +000011027 assign(op2, get_gpr_w1(r2));
11028 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11029 }
florian1c8f7ff2012-09-01 00:12:11 +000011030 return "cxlfbr";
11031}
11032
11033
florian55085f82012-11-21 00:36:55 +000011034static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011035s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11036 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011037{
11038 IRTemp op2 = newTemp(Ity_I64);
11039
11040 assign(op2, get_gpr_dw0(r2));
11041 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11042
11043 return "cxgbr";
11044}
11045
florian55085f82012-11-21 00:36:55 +000011046static const HChar *
floriand2129202012-09-01 20:01:39 +000011047s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11048 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011049{
floriane75dafa2012-09-01 17:54:09 +000011050 if (! s390_host_has_fpext) {
11051 emulation_failure(EmFail_S390X_fpext);
11052 } else {
11053 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011054
floriane75dafa2012-09-01 17:54:09 +000011055 assign(op2, get_gpr_dw0(r2));
11056 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11057 }
florian1c8f7ff2012-09-01 00:12:11 +000011058 return "cxlgbr";
11059}
11060
florian55085f82012-11-21 00:36:55 +000011061static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011062s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11063 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011064{
11065 IRTemp op = newTemp(Ity_F128);
11066 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011067 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011068
11069 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011070 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011071 mkexpr(op)));
11072 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011073 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011074
11075 return "cfxbr";
11076}
11077
florian55085f82012-11-21 00:36:55 +000011078static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011079s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
11080 UChar r1, UChar r2)
11081{
floriane75dafa2012-09-01 17:54:09 +000011082 if (! s390_host_has_fpext) {
11083 emulation_failure(EmFail_S390X_fpext);
11084 } else {
11085 IRTemp op = newTemp(Ity_F128);
11086 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011087 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011088
floriane75dafa2012-09-01 17:54:09 +000011089 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011090 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011091 mkexpr(op)));
11092 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011093 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011094 }
florian1c8f7ff2012-09-01 00:12:11 +000011095 return "clfxbr";
11096}
11097
11098
florian55085f82012-11-21 00:36:55 +000011099static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011100s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
11101 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011102{
11103 IRTemp op = newTemp(Ity_F128);
11104 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011105 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011106
11107 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011108 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011109 mkexpr(op)));
11110 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011111 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011112
11113 return "cgxbr";
11114}
11115
florian55085f82012-11-21 00:36:55 +000011116static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011117s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
11118 UChar r1, UChar r2)
11119{
floriane75dafa2012-09-01 17:54:09 +000011120 if (! s390_host_has_fpext) {
11121 emulation_failure(EmFail_S390X_fpext);
11122 } else {
11123 IRTemp op = newTemp(Ity_F128);
11124 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011125 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011126
floriane75dafa2012-09-01 17:54:09 +000011127 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011128 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011129 mkexpr(op)));
11130 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011131 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
11132 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011133 }
florian1c8f7ff2012-09-01 00:12:11 +000011134 return "clgxbr";
11135}
11136
florian55085f82012-11-21 00:36:55 +000011137static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011138s390_irgen_DXBR(UChar r1, UChar r2)
11139{
11140 IRTemp op1 = newTemp(Ity_F128);
11141 IRTemp op2 = newTemp(Ity_F128);
11142 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011143 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011144
11145 assign(op1, get_fpr_pair(r1));
11146 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011147 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011148 mkexpr(op2)));
11149 put_fpr_pair(r1, mkexpr(result));
11150
11151 return "dxbr";
11152}
11153
florian55085f82012-11-21 00:36:55 +000011154static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011155s390_irgen_LTXBR(UChar r1, UChar r2)
11156{
11157 IRTemp result = newTemp(Ity_F128);
11158
11159 assign(result, get_fpr_pair(r2));
11160 put_fpr_pair(r1, mkexpr(result));
11161 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11162
11163 return "ltxbr";
11164}
11165
florian55085f82012-11-21 00:36:55 +000011166static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011167s390_irgen_LCXBR(UChar r1, UChar r2)
11168{
11169 IRTemp result = newTemp(Ity_F128);
11170
11171 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
11172 put_fpr_pair(r1, mkexpr(result));
11173 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11174
11175 return "lcxbr";
11176}
11177
florian55085f82012-11-21 00:36:55 +000011178static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011179s390_irgen_LXDBR(UChar r1, UChar r2)
11180{
11181 IRTemp op = newTemp(Ity_F64);
11182
11183 assign(op, get_fpr_dw0(r2));
11184 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11185
11186 return "lxdbr";
11187}
11188
florian55085f82012-11-21 00:36:55 +000011189static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011190s390_irgen_LXEBR(UChar r1, UChar r2)
11191{
11192 IRTemp op = newTemp(Ity_F32);
11193
11194 assign(op, get_fpr_w0(r2));
11195 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11196
11197 return "lxebr";
11198}
11199
florian55085f82012-11-21 00:36:55 +000011200static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011201s390_irgen_LXDB(UChar r1, IRTemp op2addr)
11202{
11203 IRTemp op = newTemp(Ity_F64);
11204
11205 assign(op, load(Ity_F64, mkexpr(op2addr)));
11206 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11207
11208 return "lxdb";
11209}
11210
florian55085f82012-11-21 00:36:55 +000011211static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011212s390_irgen_LXEB(UChar r1, IRTemp op2addr)
11213{
11214 IRTemp op = newTemp(Ity_F32);
11215
11216 assign(op, load(Ity_F32, mkexpr(op2addr)));
11217 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11218
11219 return "lxeb";
11220}
11221
florian55085f82012-11-21 00:36:55 +000011222static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011223s390_irgen_LNEBR(UChar r1, UChar r2)
11224{
11225 IRTemp result = newTemp(Ity_F32);
11226
11227 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
11228 put_fpr_w0(r1, mkexpr(result));
11229 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11230
11231 return "lnebr";
11232}
11233
florian55085f82012-11-21 00:36:55 +000011234static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011235s390_irgen_LNDBR(UChar r1, UChar r2)
11236{
11237 IRTemp result = newTemp(Ity_F64);
11238
11239 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11240 put_fpr_dw0(r1, mkexpr(result));
11241 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11242
11243 return "lndbr";
11244}
11245
florian55085f82012-11-21 00:36:55 +000011246static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011247s390_irgen_LNXBR(UChar r1, UChar r2)
11248{
11249 IRTemp result = newTemp(Ity_F128);
11250
11251 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
11252 put_fpr_pair(r1, mkexpr(result));
11253 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11254
11255 return "lnxbr";
11256}
11257
florian55085f82012-11-21 00:36:55 +000011258static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011259s390_irgen_LPEBR(UChar r1, UChar r2)
11260{
11261 IRTemp result = newTemp(Ity_F32);
11262
11263 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
11264 put_fpr_w0(r1, mkexpr(result));
11265 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11266
11267 return "lpebr";
11268}
11269
florian55085f82012-11-21 00:36:55 +000011270static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011271s390_irgen_LPDBR(UChar r1, UChar r2)
11272{
11273 IRTemp result = newTemp(Ity_F64);
11274
11275 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11276 put_fpr_dw0(r1, mkexpr(result));
11277 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11278
11279 return "lpdbr";
11280}
11281
florian55085f82012-11-21 00:36:55 +000011282static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011283s390_irgen_LPXBR(UChar r1, UChar r2)
11284{
11285 IRTemp result = newTemp(Ity_F128);
11286
11287 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
11288 put_fpr_pair(r1, mkexpr(result));
11289 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11290
11291 return "lpxbr";
11292}
11293
florian55085f82012-11-21 00:36:55 +000011294static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011295s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
11296 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011297{
florian125e20d2012-10-07 15:42:37 +000011298 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011299 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011300 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011301 }
sewardj2019a972011-03-07 16:04:07 +000011302 IRTemp result = newTemp(Ity_F64);
11303
floriandb4fcaa2012-09-05 19:54:08 +000011304 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011305 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011306 put_fpr_dw0(r1, mkexpr(result));
11307
11308 return "ldxbr";
11309}
11310
florian55085f82012-11-21 00:36:55 +000011311static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011312s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11313 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011314{
florian125e20d2012-10-07 15:42:37 +000011315 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011316 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011317 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011318 }
sewardj2019a972011-03-07 16:04:07 +000011319 IRTemp result = newTemp(Ity_F32);
11320
floriandb4fcaa2012-09-05 19:54:08 +000011321 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011322 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011323 put_fpr_w0(r1, mkexpr(result));
11324
11325 return "lexbr";
11326}
11327
florian55085f82012-11-21 00:36:55 +000011328static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011329s390_irgen_MXBR(UChar r1, UChar r2)
11330{
11331 IRTemp op1 = newTemp(Ity_F128);
11332 IRTemp op2 = newTemp(Ity_F128);
11333 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011334 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011335
11336 assign(op1, get_fpr_pair(r1));
11337 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011338 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011339 mkexpr(op2)));
11340 put_fpr_pair(r1, mkexpr(result));
11341
11342 return "mxbr";
11343}
11344
florian55085f82012-11-21 00:36:55 +000011345static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011346s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11347{
florian125e20d2012-10-07 15:42:37 +000011348 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011349
floriandb4fcaa2012-09-05 19:54:08 +000011350 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011351 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011352
11353 return "maebr";
11354}
11355
florian55085f82012-11-21 00:36:55 +000011356static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011357s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11358{
florian125e20d2012-10-07 15:42:37 +000011359 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011360
floriandb4fcaa2012-09-05 19:54:08 +000011361 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011362 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011363
11364 return "madbr";
11365}
11366
florian55085f82012-11-21 00:36:55 +000011367static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011368s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11369{
11370 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011371 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011372
floriandb4fcaa2012-09-05 19:54:08 +000011373 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011374 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011375
11376 return "maeb";
11377}
11378
florian55085f82012-11-21 00:36:55 +000011379static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011380s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11381{
11382 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011383 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011384
floriandb4fcaa2012-09-05 19:54:08 +000011385 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011386 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011387
11388 return "madb";
11389}
11390
florian55085f82012-11-21 00:36:55 +000011391static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011392s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11393{
florian125e20d2012-10-07 15:42:37 +000011394 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011395
floriandb4fcaa2012-09-05 19:54:08 +000011396 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011397 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011398
11399 return "msebr";
11400}
11401
florian55085f82012-11-21 00:36:55 +000011402static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011403s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11404{
florian125e20d2012-10-07 15:42:37 +000011405 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011406
floriandb4fcaa2012-09-05 19:54:08 +000011407 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011408 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011409
11410 return "msdbr";
11411}
11412
florian55085f82012-11-21 00:36:55 +000011413static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011414s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11415{
11416 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011417 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011418
floriandb4fcaa2012-09-05 19:54:08 +000011419 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011420 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011421
11422 return "mseb";
11423}
11424
florian55085f82012-11-21 00:36:55 +000011425static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011426s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11427{
11428 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011429 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011430
floriandb4fcaa2012-09-05 19:54:08 +000011431 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011432 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011433
11434 return "msdb";
11435}
11436
florian55085f82012-11-21 00:36:55 +000011437static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011438s390_irgen_SQEBR(UChar r1, UChar r2)
11439{
11440 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011441 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011442
floriandb4fcaa2012-09-05 19:54:08 +000011443 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011444 put_fpr_w0(r1, mkexpr(result));
11445
11446 return "sqebr";
11447}
11448
florian55085f82012-11-21 00:36:55 +000011449static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011450s390_irgen_SQDBR(UChar r1, UChar r2)
11451{
11452 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011453 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011454
floriandb4fcaa2012-09-05 19:54:08 +000011455 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011456 put_fpr_dw0(r1, mkexpr(result));
11457
11458 return "sqdbr";
11459}
11460
florian55085f82012-11-21 00:36:55 +000011461static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011462s390_irgen_SQXBR(UChar r1, UChar r2)
11463{
11464 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011465 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011466
floriandb4fcaa2012-09-05 19:54:08 +000011467 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11468 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011469 put_fpr_pair(r1, mkexpr(result));
11470
11471 return "sqxbr";
11472}
11473
florian55085f82012-11-21 00:36:55 +000011474static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011475s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11476{
11477 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011478 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011479
11480 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011481 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011482
11483 return "sqeb";
11484}
11485
florian55085f82012-11-21 00:36:55 +000011486static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011487s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11488{
11489 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011490 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011491
11492 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011493 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011494
11495 return "sqdb";
11496}
11497
florian55085f82012-11-21 00:36:55 +000011498static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011499s390_irgen_SXBR(UChar r1, UChar r2)
11500{
11501 IRTemp op1 = newTemp(Ity_F128);
11502 IRTemp op2 = newTemp(Ity_F128);
11503 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011504 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011505
11506 assign(op1, get_fpr_pair(r1));
11507 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011508 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011509 mkexpr(op2)));
11510 put_fpr_pair(r1, mkexpr(result));
11511 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11512
11513 return "sxbr";
11514}
11515
florian55085f82012-11-21 00:36:55 +000011516static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011517s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11518{
11519 IRTemp value = newTemp(Ity_F32);
11520
11521 assign(value, get_fpr_w0(r1));
11522
11523 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11524
11525 return "tceb";
11526}
11527
florian55085f82012-11-21 00:36:55 +000011528static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011529s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11530{
11531 IRTemp value = newTemp(Ity_F64);
11532
11533 assign(value, get_fpr_dw0(r1));
11534
11535 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11536
11537 return "tcdb";
11538}
11539
florian55085f82012-11-21 00:36:55 +000011540static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011541s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11542{
11543 IRTemp value = newTemp(Ity_F128);
11544
11545 assign(value, get_fpr_pair(r1));
11546
11547 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11548
11549 return "tcxb";
11550}
11551
florian55085f82012-11-21 00:36:55 +000011552static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011553s390_irgen_LCDFR(UChar r1, UChar r2)
11554{
11555 IRTemp result = newTemp(Ity_F64);
11556
11557 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11558 put_fpr_dw0(r1, mkexpr(result));
11559
11560 return "lcdfr";
11561}
11562
florian55085f82012-11-21 00:36:55 +000011563static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011564s390_irgen_LNDFR(UChar r1, UChar r2)
11565{
11566 IRTemp result = newTemp(Ity_F64);
11567
11568 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11569 put_fpr_dw0(r1, mkexpr(result));
11570
11571 return "lndfr";
11572}
11573
florian55085f82012-11-21 00:36:55 +000011574static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011575s390_irgen_LPDFR(UChar r1, UChar r2)
11576{
11577 IRTemp result = newTemp(Ity_F64);
11578
11579 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11580 put_fpr_dw0(r1, mkexpr(result));
11581
11582 return "lpdfr";
11583}
11584
florian55085f82012-11-21 00:36:55 +000011585static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011586s390_irgen_LDGR(UChar r1, UChar r2)
11587{
11588 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11589
11590 return "ldgr";
11591}
11592
florian55085f82012-11-21 00:36:55 +000011593static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011594s390_irgen_LGDR(UChar r1, UChar r2)
11595{
11596 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11597
11598 return "lgdr";
11599}
11600
11601
florian55085f82012-11-21 00:36:55 +000011602static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011603s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11604{
11605 IRTemp sign = newTemp(Ity_I64);
11606 IRTemp value = newTemp(Ity_I64);
11607
11608 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11609 mkU64(1ULL << 63)));
11610 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11611 mkU64((1ULL << 63) - 1)));
11612 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11613 mkexpr(sign))));
11614
11615 return "cpsdr";
11616}
11617
11618
sewardj2019a972011-03-07 16:04:07 +000011619static IRExpr *
11620s390_call_cvb(IRExpr *in)
11621{
11622 IRExpr **args, *call;
11623
11624 args = mkIRExprVec_1(in);
11625 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11626 "s390_do_cvb", &s390_do_cvb, args);
11627
11628 /* Nothing is excluded from definedness checking. */
11629 call->Iex.CCall.cee->mcx_mask = 0;
11630
11631 return call;
11632}
11633
florian55085f82012-11-21 00:36:55 +000011634static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011635s390_irgen_CVB(UChar r1, IRTemp op2addr)
11636{
11637 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11638
11639 return "cvb";
11640}
11641
florian55085f82012-11-21 00:36:55 +000011642static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011643s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11644{
11645 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11646
11647 return "cvby";
11648}
11649
11650
sewardj2019a972011-03-07 16:04:07 +000011651static IRExpr *
11652s390_call_cvd(IRExpr *in)
11653{
11654 IRExpr **args, *call;
11655
11656 args = mkIRExprVec_1(in);
11657 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11658 "s390_do_cvd", &s390_do_cvd, args);
11659
11660 /* Nothing is excluded from definedness checking. */
11661 call->Iex.CCall.cee->mcx_mask = 0;
11662
11663 return call;
11664}
11665
florian55085f82012-11-21 00:36:55 +000011666static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011667s390_irgen_CVD(UChar r1, IRTemp op2addr)
11668{
florian11b8ee82012-08-06 13:35:33 +000011669 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011670
11671 return "cvd";
11672}
11673
florian55085f82012-11-21 00:36:55 +000011674static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011675s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11676{
11677 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11678
11679 return "cvdy";
11680}
11681
florian55085f82012-11-21 00:36:55 +000011682static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011683s390_irgen_FLOGR(UChar r1, UChar r2)
11684{
11685 IRTemp input = newTemp(Ity_I64);
11686 IRTemp not_zero = newTemp(Ity_I64);
11687 IRTemp tmpnum = newTemp(Ity_I64);
11688 IRTemp num = newTemp(Ity_I64);
11689 IRTemp shift_amount = newTemp(Ity_I8);
11690
11691 /* We use the "count leading zeroes" operator because the number of
11692 leading zeroes is identical with the bit position of the first '1' bit.
11693 However, that operator does not work when the input value is zero.
11694 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11695 the modified value. If input == 0, then the result is 64. Otherwise,
11696 the result of Clz64 is what we want. */
11697
11698 assign(input, get_gpr_dw0(r2));
11699 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11700 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11701
11702 /* num = (input == 0) ? 64 : tmpnum */
11703 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11704 /* == 0 */ mkU64(64),
11705 /* != 0 */ mkexpr(tmpnum)));
11706
11707 put_gpr_dw0(r1, mkexpr(num));
11708
11709 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11710 is to first shift the input value by NUM + 1 bits to the left which
11711 causes the leftmost '1' bit to disappear. Then we shift logically to
11712 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11713 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11714 the width of the value-to-be-shifted, we need to special case
11715 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11716 For both such INPUT values the result will be 0. */
11717
11718 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11719 mkU64(1))));
11720
11721 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011722 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11723 /* == 0 || == 1*/ mkU64(0),
11724 /* otherwise */
11725 binop(Iop_Shr64,
11726 binop(Iop_Shl64, mkexpr(input),
11727 mkexpr(shift_amount)),
11728 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011729
11730 /* Compare the original value as an unsigned integer with 0. */
11731 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11732 mktemp(Ity_I64, mkU64(0)), False);
11733
11734 return "flogr";
11735}
11736
florian55085f82012-11-21 00:36:55 +000011737static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011738s390_irgen_STCK(IRTemp op2addr)
11739{
11740 IRDirty *d;
11741 IRTemp cc = newTemp(Ity_I64);
11742
11743 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11744 &s390x_dirtyhelper_STCK,
11745 mkIRExprVec_1(mkexpr(op2addr)));
11746 d->mFx = Ifx_Write;
11747 d->mAddr = mkexpr(op2addr);
11748 d->mSize = 8;
11749 stmt(IRStmt_Dirty(d));
11750 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11751 mkexpr(cc), mkU64(0), mkU64(0));
11752 return "stck";
11753}
11754
florian55085f82012-11-21 00:36:55 +000011755static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011756s390_irgen_STCKF(IRTemp op2addr)
11757{
florianc5c669b2012-08-26 14:32:28 +000011758 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011759 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011760 } else {
11761 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011762
florianc5c669b2012-08-26 14:32:28 +000011763 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11764 &s390x_dirtyhelper_STCKF,
11765 mkIRExprVec_1(mkexpr(op2addr)));
11766 d->mFx = Ifx_Write;
11767 d->mAddr = mkexpr(op2addr);
11768 d->mSize = 8;
11769 stmt(IRStmt_Dirty(d));
11770 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11771 mkexpr(cc), mkU64(0), mkU64(0));
11772 }
sewardj1e5fea62011-05-17 16:18:36 +000011773 return "stckf";
11774}
11775
florian55085f82012-11-21 00:36:55 +000011776static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011777s390_irgen_STCKE(IRTemp op2addr)
11778{
11779 IRDirty *d;
11780 IRTemp cc = newTemp(Ity_I64);
11781
11782 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11783 &s390x_dirtyhelper_STCKE,
11784 mkIRExprVec_1(mkexpr(op2addr)));
11785 d->mFx = Ifx_Write;
11786 d->mAddr = mkexpr(op2addr);
11787 d->mSize = 16;
11788 stmt(IRStmt_Dirty(d));
11789 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11790 mkexpr(cc), mkU64(0), mkU64(0));
11791 return "stcke";
11792}
11793
florian55085f82012-11-21 00:36:55 +000011794static const HChar *
florian933065d2011-07-11 01:48:02 +000011795s390_irgen_STFLE(IRTemp op2addr)
11796{
florian4e0083e2012-08-26 03:41:56 +000011797 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000011798 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000011799 return "stfle";
11800 }
11801
florian933065d2011-07-11 01:48:02 +000011802 IRDirty *d;
11803 IRTemp cc = newTemp(Ity_I64);
11804
11805 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
11806 &s390x_dirtyhelper_STFLE,
11807 mkIRExprVec_1(mkexpr(op2addr)));
11808
11809 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
11810
sewardjc9069f22012-06-01 16:09:50 +000011811 d->nFxState = 1;
11812 vex_bzero(&d->fxState, sizeof(d->fxState));
11813
florian933065d2011-07-11 01:48:02 +000011814 d->fxState[0].fx = Ifx_Modify; /* read then write */
11815 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
11816 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000011817
11818 d->mAddr = mkexpr(op2addr);
11819 /* Pretend all double words are written */
11820 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
11821 d->mFx = Ifx_Write;
11822
11823 stmt(IRStmt_Dirty(d));
11824
11825 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
11826
11827 return "stfle";
11828}
11829
florian55085f82012-11-21 00:36:55 +000011830static const HChar *
floriana4384a32011-08-11 16:58:45 +000011831s390_irgen_CKSM(UChar r1,UChar r2)
11832{
11833 IRTemp addr = newTemp(Ity_I64);
11834 IRTemp op = newTemp(Ity_I32);
11835 IRTemp len = newTemp(Ity_I64);
11836 IRTemp oldval = newTemp(Ity_I32);
11837 IRTemp mask = newTemp(Ity_I32);
11838 IRTemp newop = newTemp(Ity_I32);
11839 IRTemp result = newTemp(Ity_I32);
11840 IRTemp result1 = newTemp(Ity_I32);
11841 IRTemp inc = newTemp(Ity_I64);
11842
11843 assign(oldval, get_gpr_w1(r1));
11844 assign(addr, get_gpr_dw0(r2));
11845 assign(len, get_gpr_dw0(r2+1));
11846
11847 /* Condition code is always zero. */
11848 s390_cc_set(0);
11849
11850 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000011851 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011852
11853 /* Assiging the increment variable to adjust address and length
11854 later on. */
11855 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11856 mkexpr(len), mkU64(4)));
11857
11858 /* If length < 4 the final 4-byte 2nd operand value is computed by
11859 appending the remaining bytes to the right with 0. This is done
11860 by AND'ing the 4 bytes loaded from memory with an appropriate
11861 mask. If length >= 4, that mask is simply 0xffffffff. */
11862
11863 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
11864 /* Mask computation when len < 4:
11865 0xffffffff << (32 - (len % 4)*8) */
11866 binop(Iop_Shl32, mkU32(0xffffffff),
11867 unop(Iop_32to8,
11868 binop(Iop_Sub32, mkU32(32),
11869 binop(Iop_Shl32,
11870 unop(Iop_64to32,
11871 binop(Iop_And64,
11872 mkexpr(len), mkU64(3))),
11873 mkU8(3))))),
11874 mkU32(0xffffffff)));
11875
11876 assign(op, load(Ity_I32, mkexpr(addr)));
11877 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
11878 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
11879
11880 /* Checking for carry */
11881 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
11882 binop(Iop_Add32, mkexpr(result), mkU32(1)),
11883 mkexpr(result)));
11884
11885 put_gpr_w1(r1, mkexpr(result1));
11886 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
11887 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
11888
florian6820ba52012-07-26 02:01:50 +000011889 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000011890
11891 return "cksm";
11892}
11893
florian55085f82012-11-21 00:36:55 +000011894static const HChar *
florian9af37692012-01-15 21:01:16 +000011895s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
11896{
11897 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11898 src_addr = newTemp(Ity_I64);
11899 des_addr = newTemp(Ity_I64);
11900 tab_addr = newTemp(Ity_I64);
11901 test_byte = newTemp(Ity_I8);
11902 src_len = newTemp(Ity_I64);
11903
11904 assign(src_addr, get_gpr_dw0(r2));
11905 assign(des_addr, get_gpr_dw0(r1));
11906 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000011907 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000011908 assign(test_byte, get_gpr_b7(0));
11909
11910 IRTemp op = newTemp(Ity_I8);
11911 IRTemp op1 = newTemp(Ity_I8);
11912 IRTemp result = newTemp(Ity_I64);
11913
11914 /* End of source string? We're done; proceed to next insn */
11915 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011916 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000011917
11918 /* Load character from source string, index translation table and
11919 store translated character in op1. */
11920 assign(op, load(Ity_I8, mkexpr(src_addr)));
11921
11922 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
11923 mkexpr(tab_addr)));
11924 assign(op1, load(Ity_I8, mkexpr(result)));
11925
11926 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11927 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011928 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000011929 }
11930 store(get_gpr_dw0(r1), mkexpr(op1));
11931
11932 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11933 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
11934 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
11935
florian6820ba52012-07-26 02:01:50 +000011936 iterate();
florian9af37692012-01-15 21:01:16 +000011937
11938 return "troo";
11939}
11940
florian55085f82012-11-21 00:36:55 +000011941static const HChar *
florian730448f2012-02-04 17:07:07 +000011942s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
11943{
11944 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11945 src_addr = newTemp(Ity_I64);
11946 des_addr = newTemp(Ity_I64);
11947 tab_addr = newTemp(Ity_I64);
11948 test_byte = newTemp(Ity_I8);
11949 src_len = newTemp(Ity_I64);
11950
11951 assign(src_addr, get_gpr_dw0(r2));
11952 assign(des_addr, get_gpr_dw0(r1));
11953 assign(tab_addr, get_gpr_dw0(1));
11954 assign(src_len, get_gpr_dw0(r1+1));
11955 assign(test_byte, get_gpr_b7(0));
11956
11957 IRTemp op = newTemp(Ity_I16);
11958 IRTemp op1 = newTemp(Ity_I8);
11959 IRTemp result = newTemp(Ity_I64);
11960
11961 /* End of source string? We're done; proceed to next insn */
11962 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000011963 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000011964
11965 /* Load character from source string, index translation table and
11966 store translated character in op1. */
11967 assign(op, load(Ity_I16, mkexpr(src_addr)));
11968
11969 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
11970 mkexpr(tab_addr)));
11971
11972 assign(op1, load(Ity_I8, mkexpr(result)));
11973
11974 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
11975 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011976 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000011977 }
11978 store(get_gpr_dw0(r1), mkexpr(op1));
11979
11980 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
11981 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
11982 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
11983
florian6820ba52012-07-26 02:01:50 +000011984 iterate();
florian730448f2012-02-04 17:07:07 +000011985
11986 return "trto";
11987}
11988
florian55085f82012-11-21 00:36:55 +000011989static const HChar *
florian730448f2012-02-04 17:07:07 +000011990s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
11991{
11992 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
11993 src_addr = newTemp(Ity_I64);
11994 des_addr = newTemp(Ity_I64);
11995 tab_addr = newTemp(Ity_I64);
11996 test_byte = newTemp(Ity_I16);
11997 src_len = newTemp(Ity_I64);
11998
11999 assign(src_addr, get_gpr_dw0(r2));
12000 assign(des_addr, get_gpr_dw0(r1));
12001 assign(tab_addr, get_gpr_dw0(1));
12002 assign(src_len, get_gpr_dw0(r1+1));
12003 assign(test_byte, get_gpr_hw3(0));
12004
12005 IRTemp op = newTemp(Ity_I8);
12006 IRTemp op1 = newTemp(Ity_I16);
12007 IRTemp result = newTemp(Ity_I64);
12008
12009 /* End of source string? We're done; proceed to next insn */
12010 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012011 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012012
12013 /* Load character from source string, index translation table and
12014 store translated character in op1. */
12015 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12016
12017 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12018 mkexpr(tab_addr)));
12019 assign(op1, load(Ity_I16, mkexpr(result)));
12020
12021 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12022 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012023 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012024 }
12025 store(get_gpr_dw0(r1), mkexpr(op1));
12026
12027 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12028 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12029 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12030
florian6820ba52012-07-26 02:01:50 +000012031 iterate();
florian730448f2012-02-04 17:07:07 +000012032
12033 return "trot";
12034}
12035
florian55085f82012-11-21 00:36:55 +000012036static const HChar *
florian730448f2012-02-04 17:07:07 +000012037s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12038{
12039 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12040 src_addr = newTemp(Ity_I64);
12041 des_addr = newTemp(Ity_I64);
12042 tab_addr = newTemp(Ity_I64);
12043 test_byte = newTemp(Ity_I16);
12044 src_len = newTemp(Ity_I64);
12045
12046 assign(src_addr, get_gpr_dw0(r2));
12047 assign(des_addr, get_gpr_dw0(r1));
12048 assign(tab_addr, get_gpr_dw0(1));
12049 assign(src_len, get_gpr_dw0(r1+1));
12050 assign(test_byte, get_gpr_hw3(0));
12051
12052 IRTemp op = newTemp(Ity_I16);
12053 IRTemp op1 = newTemp(Ity_I16);
12054 IRTemp result = newTemp(Ity_I64);
12055
12056 /* End of source string? We're done; proceed to next insn */
12057 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012058 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012059
12060 /* Load character from source string, index translation table and
12061 store translated character in op1. */
12062 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12063
12064 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12065 mkexpr(tab_addr)));
12066 assign(op1, load(Ity_I16, mkexpr(result)));
12067
12068 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12069 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012070 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012071 }
12072
12073 store(get_gpr_dw0(r1), mkexpr(op1));
12074
12075 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12076 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12077 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12078
florian6820ba52012-07-26 02:01:50 +000012079 iterate();
florian730448f2012-02-04 17:07:07 +000012080
12081 return "trtt";
12082}
12083
florian55085f82012-11-21 00:36:55 +000012084static const HChar *
florian730448f2012-02-04 17:07:07 +000012085s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
12086{
florianf87d4fb2012-05-05 02:55:24 +000012087 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000012088
florianf87d4fb2012-05-05 02:55:24 +000012089 assign(len, mkU64(length));
12090 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000012091
12092 return "tr";
12093}
12094
florian55085f82012-11-21 00:36:55 +000012095static const HChar *
florian730448f2012-02-04 17:07:07 +000012096s390_irgen_TRE(UChar r1,UChar r2)
12097{
12098 IRTemp src_addr, tab_addr, src_len, test_byte;
12099 src_addr = newTemp(Ity_I64);
12100 tab_addr = newTemp(Ity_I64);
12101 src_len = newTemp(Ity_I64);
12102 test_byte = newTemp(Ity_I8);
12103
12104 assign(src_addr, get_gpr_dw0(r1));
12105 assign(src_len, get_gpr_dw0(r1+1));
12106 assign(tab_addr, get_gpr_dw0(r2));
12107 assign(test_byte, get_gpr_b7(0));
12108
12109 IRTemp op = newTemp(Ity_I8);
12110 IRTemp op1 = newTemp(Ity_I8);
12111 IRTemp result = newTemp(Ity_I64);
12112
12113 /* End of source string? We're done; proceed to next insn */
12114 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012115 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012116
12117 /* Load character from source string and compare with test byte */
12118 assign(op, load(Ity_I8, mkexpr(src_addr)));
12119
12120 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012121 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012122
12123 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12124 mkexpr(tab_addr)));
12125
12126 assign(op1, load(Ity_I8, mkexpr(result)));
12127
12128 store(get_gpr_dw0(r1), mkexpr(op1));
12129 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12130 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12131
florian6820ba52012-07-26 02:01:50 +000012132 iterate();
florian730448f2012-02-04 17:07:07 +000012133
12134 return "tre";
12135}
12136
floriana0100c92012-07-20 00:06:35 +000012137static IRExpr *
12138s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
12139{
12140 IRExpr **args, *call;
12141 args = mkIRExprVec_2(srcval, low_surrogate);
12142 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12143 "s390_do_cu21", &s390_do_cu21, args);
12144
12145 /* Nothing is excluded from definedness checking. */
12146 call->Iex.CCall.cee->mcx_mask = 0;
12147
12148 return call;
12149}
12150
florian55085f82012-11-21 00:36:55 +000012151static const HChar *
floriana0100c92012-07-20 00:06:35 +000012152s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
12153{
12154 IRTemp addr1 = newTemp(Ity_I64);
12155 IRTemp addr2 = newTemp(Ity_I64);
12156 IRTemp len1 = newTemp(Ity_I64);
12157 IRTemp len2 = newTemp(Ity_I64);
12158
12159 assign(addr1, get_gpr_dw0(r1));
12160 assign(addr2, get_gpr_dw0(r2));
12161 assign(len1, get_gpr_dw0(r1 + 1));
12162 assign(len2, get_gpr_dw0(r2 + 1));
12163
12164 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12165 there are less than 2 bytes left, then the 2nd operand is exhausted
12166 and we're done here. cc = 0 */
12167 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012168 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000012169
12170 /* There are at least two bytes there. Read them. */
12171 IRTemp srcval = newTemp(Ity_I32);
12172 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12173
12174 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12175 inside the interval [0xd800 - 0xdbff] */
12176 IRTemp is_high_surrogate = newTemp(Ity_I32);
12177 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12178 mkU32(1), mkU32(0));
12179 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12180 mkU32(1), mkU32(0));
12181 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12182
12183 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12184 then the 2nd operand is exhausted and we're done here. cc = 0 */
12185 IRExpr *not_enough_bytes =
12186 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12187
florian6820ba52012-07-26 02:01:50 +000012188 next_insn_if(binop(Iop_CmpEQ32,
12189 binop(Iop_And32, mkexpr(is_high_surrogate),
12190 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000012191
12192 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12193 surrogate, read the next two bytes (low surrogate). */
12194 IRTemp low_surrogate = newTemp(Ity_I32);
12195 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12196
12197 assign(low_surrogate,
12198 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12199 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12200 mkU32(0))); // any value is fine; it will not be used
12201
12202 /* Call the helper */
12203 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012204 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
12205 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000012206
12207 /* Before we can test whether the 1st operand is exhausted we need to
12208 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12209 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12210 IRExpr *invalid_low_surrogate =
12211 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12212
12213 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012214 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000012215 }
12216
12217 /* Now test whether the 1st operand is exhausted */
12218 IRTemp num_bytes = newTemp(Ity_I64);
12219 assign(num_bytes, binop(Iop_And64,
12220 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12221 mkU64(0xff)));
12222 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012223 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000012224
12225 /* Extract the bytes to be stored at addr1 */
12226 IRTemp data = newTemp(Ity_I64);
12227 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12228
12229 /* To store the bytes construct 4 dirty helper calls. The helper calls
12230 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12231 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012232 UInt i;
floriana0100c92012-07-20 00:06:35 +000012233 for (i = 1; i <= 4; ++i) {
12234 IRDirty *d;
12235
12236 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12237 &s390x_dirtyhelper_CUxy,
12238 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12239 mkexpr(num_bytes)));
12240 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12241 d->mFx = Ifx_Write;
12242 d->mAddr = mkexpr(addr1);
12243 d->mSize = i;
12244 stmt(IRStmt_Dirty(d));
12245 }
12246
12247 /* Update source address and length */
12248 IRTemp num_src_bytes = newTemp(Ity_I64);
12249 assign(num_src_bytes,
12250 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12251 mkU64(4), mkU64(2)));
12252 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12253 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12254
12255 /* Update destination address and length */
12256 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12257 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12258
florian6820ba52012-07-26 02:01:50 +000012259 iterate();
floriana0100c92012-07-20 00:06:35 +000012260
12261 return "cu21";
12262}
12263
florian2a415a12012-07-21 17:41:36 +000012264static IRExpr *
12265s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
12266{
12267 IRExpr **args, *call;
12268 args = mkIRExprVec_2(srcval, low_surrogate);
12269 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12270 "s390_do_cu24", &s390_do_cu24, args);
12271
12272 /* Nothing is excluded from definedness checking. */
12273 call->Iex.CCall.cee->mcx_mask = 0;
12274
12275 return call;
12276}
12277
florian55085f82012-11-21 00:36:55 +000012278static const HChar *
florian2a415a12012-07-21 17:41:36 +000012279s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
12280{
12281 IRTemp addr1 = newTemp(Ity_I64);
12282 IRTemp addr2 = newTemp(Ity_I64);
12283 IRTemp len1 = newTemp(Ity_I64);
12284 IRTemp len2 = newTemp(Ity_I64);
12285
12286 assign(addr1, get_gpr_dw0(r1));
12287 assign(addr2, get_gpr_dw0(r2));
12288 assign(len1, get_gpr_dw0(r1 + 1));
12289 assign(len2, get_gpr_dw0(r2 + 1));
12290
12291 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12292 there are less than 2 bytes left, then the 2nd operand is exhausted
12293 and we're done here. cc = 0 */
12294 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012295 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000012296
12297 /* There are at least two bytes there. Read them. */
12298 IRTemp srcval = newTemp(Ity_I32);
12299 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12300
12301 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12302 inside the interval [0xd800 - 0xdbff] */
12303 IRTemp is_high_surrogate = newTemp(Ity_I32);
12304 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12305 mkU32(1), mkU32(0));
12306 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12307 mkU32(1), mkU32(0));
12308 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12309
12310 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12311 then the 2nd operand is exhausted and we're done here. cc = 0 */
12312 IRExpr *not_enough_bytes =
12313 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12314
florian6820ba52012-07-26 02:01:50 +000012315 next_insn_if(binop(Iop_CmpEQ32,
12316 binop(Iop_And32, mkexpr(is_high_surrogate),
12317 not_enough_bytes),
12318 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012319
12320 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12321 surrogate, read the next two bytes (low surrogate). */
12322 IRTemp low_surrogate = newTemp(Ity_I32);
12323 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12324
12325 assign(low_surrogate,
12326 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12327 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12328 mkU32(0))); // any value is fine; it will not be used
12329
12330 /* Call the helper */
12331 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012332 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12333 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012334
12335 /* Before we can test whether the 1st operand is exhausted we need to
12336 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12337 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12338 IRExpr *invalid_low_surrogate =
12339 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12340
12341 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012342 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012343 }
12344
12345 /* Now test whether the 1st operand is exhausted */
12346 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012347 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012348
12349 /* Extract the bytes to be stored at addr1 */
12350 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12351
12352 store(mkexpr(addr1), data);
12353
12354 /* Update source address and length */
12355 IRTemp num_src_bytes = newTemp(Ity_I64);
12356 assign(num_src_bytes,
12357 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12358 mkU64(4), mkU64(2)));
12359 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12360 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12361
12362 /* Update destination address and length */
12363 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12364 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12365
florian6820ba52012-07-26 02:01:50 +000012366 iterate();
florian2a415a12012-07-21 17:41:36 +000012367
12368 return "cu24";
12369}
floriana4384a32011-08-11 16:58:45 +000012370
florian956194b2012-07-28 22:18:32 +000012371static IRExpr *
12372s390_call_cu42(IRExpr *srcval)
12373{
12374 IRExpr **args, *call;
12375 args = mkIRExprVec_1(srcval);
12376 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12377 "s390_do_cu42", &s390_do_cu42, args);
12378
12379 /* Nothing is excluded from definedness checking. */
12380 call->Iex.CCall.cee->mcx_mask = 0;
12381
12382 return call;
12383}
12384
florian55085f82012-11-21 00:36:55 +000012385static const HChar *
florian956194b2012-07-28 22:18:32 +000012386s390_irgen_CU42(UChar r1, UChar r2)
12387{
12388 IRTemp addr1 = newTemp(Ity_I64);
12389 IRTemp addr2 = newTemp(Ity_I64);
12390 IRTemp len1 = newTemp(Ity_I64);
12391 IRTemp len2 = newTemp(Ity_I64);
12392
12393 assign(addr1, get_gpr_dw0(r1));
12394 assign(addr2, get_gpr_dw0(r2));
12395 assign(len1, get_gpr_dw0(r1 + 1));
12396 assign(len2, get_gpr_dw0(r2 + 1));
12397
12398 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12399 there are less than 4 bytes left, then the 2nd operand is exhausted
12400 and we're done here. cc = 0 */
12401 s390_cc_set(0);
12402 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12403
12404 /* Read the 2nd operand. */
12405 IRTemp srcval = newTemp(Ity_I32);
12406 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12407
12408 /* Call the helper */
12409 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012410 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012411
12412 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12413 cc=2 outranks cc=1 (1st operand exhausted) */
12414 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12415
12416 s390_cc_set(2);
12417 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12418
12419 /* Now test whether the 1st operand is exhausted */
12420 IRTemp num_bytes = newTemp(Ity_I64);
12421 assign(num_bytes, binop(Iop_And64,
12422 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12423 mkU64(0xff)));
12424 s390_cc_set(1);
12425 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12426
12427 /* Extract the bytes to be stored at addr1 */
12428 IRTemp data = newTemp(Ity_I64);
12429 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12430
12431 /* To store the bytes construct 2 dirty helper calls. The helper calls
12432 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12433 that only one of them will be called at runtime. */
12434
12435 Int i;
12436 for (i = 2; i <= 4; ++i) {
12437 IRDirty *d;
12438
12439 if (i == 3) continue; // skip this one
12440
12441 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12442 &s390x_dirtyhelper_CUxy,
12443 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12444 mkexpr(num_bytes)));
12445 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12446 d->mFx = Ifx_Write;
12447 d->mAddr = mkexpr(addr1);
12448 d->mSize = i;
12449 stmt(IRStmt_Dirty(d));
12450 }
12451
12452 /* Update source address and length */
12453 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12454 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12455
12456 /* Update destination address and length */
12457 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12458 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12459
12460 iterate();
12461
12462 return "cu42";
12463}
12464
florian6d9b9b22012-08-03 18:35:39 +000012465static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012466s390_call_cu41(IRExpr *srcval)
12467{
12468 IRExpr **args, *call;
12469 args = mkIRExprVec_1(srcval);
12470 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12471 "s390_do_cu41", &s390_do_cu41, args);
12472
12473 /* Nothing is excluded from definedness checking. */
12474 call->Iex.CCall.cee->mcx_mask = 0;
12475
12476 return call;
12477}
12478
florian55085f82012-11-21 00:36:55 +000012479static const HChar *
florianaf2194f2012-08-06 00:07:54 +000012480s390_irgen_CU41(UChar r1, UChar r2)
12481{
12482 IRTemp addr1 = newTemp(Ity_I64);
12483 IRTemp addr2 = newTemp(Ity_I64);
12484 IRTemp len1 = newTemp(Ity_I64);
12485 IRTemp len2 = newTemp(Ity_I64);
12486
12487 assign(addr1, get_gpr_dw0(r1));
12488 assign(addr2, get_gpr_dw0(r2));
12489 assign(len1, get_gpr_dw0(r1 + 1));
12490 assign(len2, get_gpr_dw0(r2 + 1));
12491
12492 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12493 there are less than 4 bytes left, then the 2nd operand is exhausted
12494 and we're done here. cc = 0 */
12495 s390_cc_set(0);
12496 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12497
12498 /* Read the 2nd operand. */
12499 IRTemp srcval = newTemp(Ity_I32);
12500 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12501
12502 /* Call the helper */
12503 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012504 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012505
12506 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12507 cc=2 outranks cc=1 (1st operand exhausted) */
12508 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12509
12510 s390_cc_set(2);
12511 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12512
12513 /* Now test whether the 1st operand is exhausted */
12514 IRTemp num_bytes = newTemp(Ity_I64);
12515 assign(num_bytes, binop(Iop_And64,
12516 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12517 mkU64(0xff)));
12518 s390_cc_set(1);
12519 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12520
12521 /* Extract the bytes to be stored at addr1 */
12522 IRTemp data = newTemp(Ity_I64);
12523 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12524
12525 /* To store the bytes construct 4 dirty helper calls. The helper calls
12526 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12527 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012528 UInt i;
florianaf2194f2012-08-06 00:07:54 +000012529 for (i = 1; i <= 4; ++i) {
12530 IRDirty *d;
12531
12532 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12533 &s390x_dirtyhelper_CUxy,
12534 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12535 mkexpr(num_bytes)));
12536 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12537 d->mFx = Ifx_Write;
12538 d->mAddr = mkexpr(addr1);
12539 d->mSize = i;
12540 stmt(IRStmt_Dirty(d));
12541 }
12542
12543 /* Update source address and length */
12544 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12545 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12546
12547 /* Update destination address and length */
12548 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12549 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12550
12551 iterate();
12552
12553 return "cu41";
12554}
12555
12556static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012557s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012558{
12559 IRExpr **args, *call;
12560 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012561 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12562 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012563
12564 /* Nothing is excluded from definedness checking. */
12565 call->Iex.CCall.cee->mcx_mask = 0;
12566
12567 return call;
12568}
12569
12570static IRExpr *
12571s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12572 IRExpr *byte4, IRExpr *stuff)
12573{
12574 IRExpr **args, *call;
12575 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12576 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12577 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12578
12579 /* Nothing is excluded from definedness checking. */
12580 call->Iex.CCall.cee->mcx_mask = 0;
12581
12582 return call;
12583}
12584
florian3f8a96a2012-08-05 02:59:55 +000012585static IRExpr *
12586s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12587 IRExpr *byte4, IRExpr *stuff)
12588{
12589 IRExpr **args, *call;
12590 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12591 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12592 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12593
12594 /* Nothing is excluded from definedness checking. */
12595 call->Iex.CCall.cee->mcx_mask = 0;
12596
12597 return call;
12598}
12599
12600static void
12601s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012602{
12603 IRTemp addr1 = newTemp(Ity_I64);
12604 IRTemp addr2 = newTemp(Ity_I64);
12605 IRTemp len1 = newTemp(Ity_I64);
12606 IRTemp len2 = newTemp(Ity_I64);
12607
12608 assign(addr1, get_gpr_dw0(r1));
12609 assign(addr2, get_gpr_dw0(r2));
12610 assign(len1, get_gpr_dw0(r1 + 1));
12611 assign(len2, get_gpr_dw0(r2 + 1));
12612
12613 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12614
12615 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12616 there is less than 1 byte left, then the 2nd operand is exhausted
12617 and we're done here. cc = 0 */
12618 s390_cc_set(0);
12619 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12620
12621 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012622 IRTemp byte1 = newTemp(Ity_I64);
12623 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012624
12625 /* Call the helper to get number of bytes and invalid byte indicator */
12626 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012627 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012628 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012629
12630 /* Check for invalid 1st byte */
12631 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12632 s390_cc_set(2);
12633 next_insn_if(is_invalid);
12634
12635 /* How many bytes do we have to read? */
12636 IRTemp num_src_bytes = newTemp(Ity_I64);
12637 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12638
12639 /* Now test whether the 2nd operand is exhausted */
12640 s390_cc_set(0);
12641 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12642
12643 /* Read the remaining bytes */
12644 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12645
12646 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12647 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012648 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012649 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12650 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012651 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012652 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12653 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012654 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012655
12656 /* Call the helper to get the converted value and invalid byte indicator.
12657 We can pass at most 5 arguments; therefore some encoding is needed
12658 here */
12659 IRExpr *stuff = binop(Iop_Or64,
12660 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12661 mkU64(extended_checking));
12662 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012663
12664 if (is_cu12) {
12665 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12666 byte4, stuff));
12667 } else {
12668 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12669 byte4, stuff));
12670 }
florian6d9b9b22012-08-03 18:35:39 +000012671
12672 /* Check for invalid character */
12673 s390_cc_set(2);
12674 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12675 next_insn_if(is_invalid);
12676
12677 /* Now test whether the 1st operand is exhausted */
12678 IRTemp num_bytes = newTemp(Ity_I64);
12679 assign(num_bytes, binop(Iop_And64,
12680 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12681 mkU64(0xff)));
12682 s390_cc_set(1);
12683 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12684
12685 /* Extract the bytes to be stored at addr1 */
12686 IRTemp data = newTemp(Ity_I64);
12687 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12688
florian3f8a96a2012-08-05 02:59:55 +000012689 if (is_cu12) {
12690 /* To store the bytes construct 2 dirty helper calls. The helper calls
12691 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12692 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012693
florian3f8a96a2012-08-05 02:59:55 +000012694 Int i;
12695 for (i = 2; i <= 4; ++i) {
12696 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012697
florian3f8a96a2012-08-05 02:59:55 +000012698 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012699
florian3f8a96a2012-08-05 02:59:55 +000012700 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12701 &s390x_dirtyhelper_CUxy,
12702 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12703 mkexpr(num_bytes)));
12704 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12705 d->mFx = Ifx_Write;
12706 d->mAddr = mkexpr(addr1);
12707 d->mSize = i;
12708 stmt(IRStmt_Dirty(d));
12709 }
12710 } else {
12711 // cu14
12712 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012713 }
12714
12715 /* Update source address and length */
12716 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12717 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12718
12719 /* Update destination address and length */
12720 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12721 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12722
12723 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012724}
12725
florian55085f82012-11-21 00:36:55 +000012726static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012727s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12728{
12729 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012730
12731 return "cu12";
12732}
12733
florian55085f82012-11-21 00:36:55 +000012734static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012735s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12736{
12737 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12738
12739 return "cu14";
12740}
12741
florian8c88cb62012-08-26 18:58:13 +000012742static IRExpr *
12743s390_call_ecag(IRExpr *op2addr)
12744{
12745 IRExpr **args, *call;
12746
12747 args = mkIRExprVec_1(op2addr);
12748 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12749 "s390_do_ecag", &s390_do_ecag, args);
12750
12751 /* Nothing is excluded from definedness checking. */
12752 call->Iex.CCall.cee->mcx_mask = 0;
12753
12754 return call;
12755}
12756
florian55085f82012-11-21 00:36:55 +000012757static const HChar *
floriand2129202012-09-01 20:01:39 +000012758s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012759{
12760 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012761 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012762 } else {
12763 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12764 }
12765
12766 return "ecag";
12767}
12768
12769
florianb7def222012-12-04 04:45:32 +000012770/* New insns are added here.
12771 If an insn is contingent on a facility being installed also
12772 check whether the list of supported facilities in function
12773 s390x_dirtyhelper_STFLE needs updating */
12774
sewardj2019a972011-03-07 16:04:07 +000012775/*------------------------------------------------------------*/
12776/*--- Build IR for special instructions ---*/
12777/*------------------------------------------------------------*/
12778
florianb4df7682011-07-05 02:09:01 +000012779static void
sewardj2019a972011-03-07 16:04:07 +000012780s390_irgen_client_request(void)
12781{
12782 if (0)
12783 vex_printf("%%R3 = client_request ( %%R2 )\n");
12784
florianf9e1ed72012-04-17 02:41:56 +000012785 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12786 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012787
florianf9e1ed72012-04-17 02:41:56 +000012788 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012789 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012790
12791 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012792}
12793
florianb4df7682011-07-05 02:09:01 +000012794static void
sewardj2019a972011-03-07 16:04:07 +000012795s390_irgen_guest_NRADDR(void)
12796{
12797 if (0)
12798 vex_printf("%%R3 = guest_NRADDR\n");
12799
floriane88b3c92011-07-05 02:48:39 +000012800 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000012801}
12802
florianb4df7682011-07-05 02:09:01 +000012803static void
sewardj2019a972011-03-07 16:04:07 +000012804s390_irgen_call_noredir(void)
12805{
florianf9e1ed72012-04-17 02:41:56 +000012806 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12807 + S390_SPECIAL_OP_SIZE;
12808
sewardj2019a972011-03-07 16:04:07 +000012809 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000012810 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012811
12812 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000012813 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000012814
12815 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012816 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000012817}
12818
12819/* Force proper alignment for the structures below. */
12820#pragma pack(1)
12821
12822
12823static s390_decode_t
12824s390_decode_2byte_and_irgen(UChar *bytes)
12825{
12826 typedef union {
12827 struct {
12828 unsigned int op : 16;
12829 } E;
12830 struct {
12831 unsigned int op : 8;
12832 unsigned int i : 8;
12833 } I;
12834 struct {
12835 unsigned int op : 8;
12836 unsigned int r1 : 4;
12837 unsigned int r2 : 4;
12838 } RR;
12839 } formats;
12840 union {
12841 formats fmt;
12842 UShort value;
12843 } ovl;
12844
12845 vassert(sizeof(formats) == 2);
12846
florianffbd84d2012-12-09 02:06:29 +000012847 ((UChar *)(&ovl.value))[0] = bytes[0];
12848 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000012849
12850 switch (ovl.value & 0xffff) {
12851 case 0x0101: /* PR */ goto unimplemented;
12852 case 0x0102: /* UPT */ goto unimplemented;
12853 case 0x0104: /* PTFF */ goto unimplemented;
12854 case 0x0107: /* SCKPF */ goto unimplemented;
12855 case 0x010a: /* PFPO */ goto unimplemented;
12856 case 0x010b: /* TAM */ goto unimplemented;
12857 case 0x010c: /* SAM24 */ goto unimplemented;
12858 case 0x010d: /* SAM31 */ goto unimplemented;
12859 case 0x010e: /* SAM64 */ goto unimplemented;
12860 case 0x01ff: /* TRAP2 */ goto unimplemented;
12861 }
12862
12863 switch ((ovl.value & 0xff00) >> 8) {
12864 case 0x04: /* SPM */ goto unimplemented;
12865 case 0x05: /* BALR */ goto unimplemented;
12866 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12867 goto ok;
12868 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12869 goto ok;
12870 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
12871 case 0x0b: /* BSM */ goto unimplemented;
12872 case 0x0c: /* BASSM */ goto unimplemented;
12873 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12874 goto ok;
florianb0c9a132011-09-08 15:37:39 +000012875 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12876 goto ok;
12877 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12878 goto ok;
sewardj2019a972011-03-07 16:04:07 +000012879 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12880 goto ok;
12881 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12882 goto ok;
12883 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12884 goto ok;
12885 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12886 goto ok;
12887 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12888 goto ok;
12889 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12890 goto ok;
12891 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12892 goto ok;
12893 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12894 goto ok;
12895 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12896 goto ok;
12897 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12898 goto ok;
12899 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12900 goto ok;
12901 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12902 goto ok;
12903 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12904 goto ok;
12905 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12906 goto ok;
12907 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12908 goto ok;
12909 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12910 goto ok;
12911 case 0x20: /* LPDR */ goto unimplemented;
12912 case 0x21: /* LNDR */ goto unimplemented;
12913 case 0x22: /* LTDR */ goto unimplemented;
12914 case 0x23: /* LCDR */ goto unimplemented;
12915 case 0x24: /* HDR */ goto unimplemented;
12916 case 0x25: /* LDXR */ goto unimplemented;
12917 case 0x26: /* MXR */ goto unimplemented;
12918 case 0x27: /* MXDR */ goto unimplemented;
12919 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12920 goto ok;
12921 case 0x29: /* CDR */ goto unimplemented;
12922 case 0x2a: /* ADR */ goto unimplemented;
12923 case 0x2b: /* SDR */ goto unimplemented;
12924 case 0x2c: /* MDR */ goto unimplemented;
12925 case 0x2d: /* DDR */ goto unimplemented;
12926 case 0x2e: /* AWR */ goto unimplemented;
12927 case 0x2f: /* SWR */ goto unimplemented;
12928 case 0x30: /* LPER */ goto unimplemented;
12929 case 0x31: /* LNER */ goto unimplemented;
12930 case 0x32: /* LTER */ goto unimplemented;
12931 case 0x33: /* LCER */ goto unimplemented;
12932 case 0x34: /* HER */ goto unimplemented;
12933 case 0x35: /* LEDR */ goto unimplemented;
12934 case 0x36: /* AXR */ goto unimplemented;
12935 case 0x37: /* SXR */ goto unimplemented;
12936 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
12937 goto ok;
12938 case 0x39: /* CER */ goto unimplemented;
12939 case 0x3a: /* AER */ goto unimplemented;
12940 case 0x3b: /* SER */ goto unimplemented;
12941 case 0x3c: /* MDER */ goto unimplemented;
12942 case 0x3d: /* DER */ goto unimplemented;
12943 case 0x3e: /* AUR */ goto unimplemented;
12944 case 0x3f: /* SUR */ goto unimplemented;
12945 }
12946
12947 return S390_DECODE_UNKNOWN_INSN;
12948
12949ok:
12950 return S390_DECODE_OK;
12951
12952unimplemented:
12953 return S390_DECODE_UNIMPLEMENTED_INSN;
12954}
12955
12956static s390_decode_t
12957s390_decode_4byte_and_irgen(UChar *bytes)
12958{
12959 typedef union {
12960 struct {
12961 unsigned int op1 : 8;
12962 unsigned int r1 : 4;
12963 unsigned int op2 : 4;
12964 unsigned int i2 : 16;
12965 } RI;
12966 struct {
12967 unsigned int op : 16;
12968 unsigned int : 8;
12969 unsigned int r1 : 4;
12970 unsigned int r2 : 4;
12971 } RRE;
12972 struct {
12973 unsigned int op : 16;
12974 unsigned int r1 : 4;
12975 unsigned int : 4;
12976 unsigned int r3 : 4;
12977 unsigned int r2 : 4;
12978 } RRF;
12979 struct {
12980 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000012981 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000012982 unsigned int m4 : 4;
12983 unsigned int r1 : 4;
12984 unsigned int r2 : 4;
12985 } RRF2;
12986 struct {
12987 unsigned int op : 16;
12988 unsigned int r3 : 4;
12989 unsigned int : 4;
12990 unsigned int r1 : 4;
12991 unsigned int r2 : 4;
12992 } RRF3;
12993 struct {
12994 unsigned int op : 16;
12995 unsigned int r3 : 4;
12996 unsigned int : 4;
12997 unsigned int r1 : 4;
12998 unsigned int r2 : 4;
12999 } RRR;
13000 struct {
13001 unsigned int op : 16;
13002 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013003 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013004 unsigned int r1 : 4;
13005 unsigned int r2 : 4;
13006 } RRF4;
13007 struct {
floriane38f6412012-12-21 17:32:12 +000013008 unsigned int op : 16;
13009 unsigned int : 4;
13010 unsigned int m4 : 4;
13011 unsigned int r1 : 4;
13012 unsigned int r2 : 4;
13013 } RRF5;
13014 struct {
sewardj2019a972011-03-07 16:04:07 +000013015 unsigned int op : 8;
13016 unsigned int r1 : 4;
13017 unsigned int r3 : 4;
13018 unsigned int b2 : 4;
13019 unsigned int d2 : 12;
13020 } RS;
13021 struct {
13022 unsigned int op : 8;
13023 unsigned int r1 : 4;
13024 unsigned int r3 : 4;
13025 unsigned int i2 : 16;
13026 } RSI;
13027 struct {
13028 unsigned int op : 8;
13029 unsigned int r1 : 4;
13030 unsigned int x2 : 4;
13031 unsigned int b2 : 4;
13032 unsigned int d2 : 12;
13033 } RX;
13034 struct {
13035 unsigned int op : 16;
13036 unsigned int b2 : 4;
13037 unsigned int d2 : 12;
13038 } S;
13039 struct {
13040 unsigned int op : 8;
13041 unsigned int i2 : 8;
13042 unsigned int b1 : 4;
13043 unsigned int d1 : 12;
13044 } SI;
13045 } formats;
13046 union {
13047 formats fmt;
13048 UInt value;
13049 } ovl;
13050
13051 vassert(sizeof(formats) == 4);
13052
florianffbd84d2012-12-09 02:06:29 +000013053 ((UChar *)(&ovl.value))[0] = bytes[0];
13054 ((UChar *)(&ovl.value))[1] = bytes[1];
13055 ((UChar *)(&ovl.value))[2] = bytes[2];
13056 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013057
13058 switch ((ovl.value & 0xff0f0000) >> 16) {
13059 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13060 ovl.fmt.RI.i2); goto ok;
13061 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13062 ovl.fmt.RI.i2); goto ok;
13063 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
13064 ovl.fmt.RI.i2); goto ok;
13065 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
13066 ovl.fmt.RI.i2); goto ok;
13067 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
13068 ovl.fmt.RI.i2); goto ok;
13069 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
13070 ovl.fmt.RI.i2); goto ok;
13071 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
13072 ovl.fmt.RI.i2); goto ok;
13073 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
13074 ovl.fmt.RI.i2); goto ok;
13075 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
13076 ovl.fmt.RI.i2); goto ok;
13077 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
13078 ovl.fmt.RI.i2); goto ok;
13079 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
13080 ovl.fmt.RI.i2); goto ok;
13081 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
13082 ovl.fmt.RI.i2); goto ok;
13083 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
13084 ovl.fmt.RI.i2); goto ok;
13085 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
13086 ovl.fmt.RI.i2); goto ok;
13087 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
13088 ovl.fmt.RI.i2); goto ok;
13089 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
13090 ovl.fmt.RI.i2); goto ok;
13091 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
13092 ovl.fmt.RI.i2); goto ok;
13093 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
13094 ovl.fmt.RI.i2); goto ok;
13095 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
13096 ovl.fmt.RI.i2); goto ok;
13097 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
13098 ovl.fmt.RI.i2); goto ok;
13099 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13100 goto ok;
13101 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
13102 ovl.fmt.RI.i2); goto ok;
13103 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
13104 ovl.fmt.RI.i2); goto ok;
13105 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
13106 ovl.fmt.RI.i2); goto ok;
13107 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13108 goto ok;
13109 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
13110 ovl.fmt.RI.i2); goto ok;
13111 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13112 goto ok;
13113 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
13114 ovl.fmt.RI.i2); goto ok;
13115 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13116 goto ok;
13117 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
13118 ovl.fmt.RI.i2); goto ok;
13119 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13120 goto ok;
13121 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
13122 ovl.fmt.RI.i2); goto ok;
13123 }
13124
13125 switch ((ovl.value & 0xffff0000) >> 16) {
13126 case 0x8000: /* SSM */ goto unimplemented;
13127 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013128 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013129 case 0xb202: /* STIDP */ goto unimplemented;
13130 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013131 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
13132 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013133 case 0xb206: /* SCKC */ goto unimplemented;
13134 case 0xb207: /* STCKC */ goto unimplemented;
13135 case 0xb208: /* SPT */ goto unimplemented;
13136 case 0xb209: /* STPT */ goto unimplemented;
13137 case 0xb20a: /* SPKA */ goto unimplemented;
13138 case 0xb20b: /* IPK */ goto unimplemented;
13139 case 0xb20d: /* PTLB */ goto unimplemented;
13140 case 0xb210: /* SPX */ goto unimplemented;
13141 case 0xb211: /* STPX */ goto unimplemented;
13142 case 0xb212: /* STAP */ goto unimplemented;
13143 case 0xb214: /* SIE */ goto unimplemented;
13144 case 0xb218: /* PC */ goto unimplemented;
13145 case 0xb219: /* SAC */ goto unimplemented;
13146 case 0xb21a: /* CFC */ goto unimplemented;
13147 case 0xb221: /* IPTE */ goto unimplemented;
13148 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
13149 case 0xb223: /* IVSK */ goto unimplemented;
13150 case 0xb224: /* IAC */ goto unimplemented;
13151 case 0xb225: /* SSAR */ goto unimplemented;
13152 case 0xb226: /* EPAR */ goto unimplemented;
13153 case 0xb227: /* ESAR */ goto unimplemented;
13154 case 0xb228: /* PT */ goto unimplemented;
13155 case 0xb229: /* ISKE */ goto unimplemented;
13156 case 0xb22a: /* RRBE */ goto unimplemented;
13157 case 0xb22b: /* SSKE */ goto unimplemented;
13158 case 0xb22c: /* TB */ goto unimplemented;
13159 case 0xb22d: /* DXR */ goto unimplemented;
13160 case 0xb22e: /* PGIN */ goto unimplemented;
13161 case 0xb22f: /* PGOUT */ goto unimplemented;
13162 case 0xb230: /* CSCH */ goto unimplemented;
13163 case 0xb231: /* HSCH */ goto unimplemented;
13164 case 0xb232: /* MSCH */ goto unimplemented;
13165 case 0xb233: /* SSCH */ goto unimplemented;
13166 case 0xb234: /* STSCH */ goto unimplemented;
13167 case 0xb235: /* TSCH */ goto unimplemented;
13168 case 0xb236: /* TPI */ goto unimplemented;
13169 case 0xb237: /* SAL */ goto unimplemented;
13170 case 0xb238: /* RSCH */ goto unimplemented;
13171 case 0xb239: /* STCRW */ goto unimplemented;
13172 case 0xb23a: /* STCPS */ goto unimplemented;
13173 case 0xb23b: /* RCHP */ goto unimplemented;
13174 case 0xb23c: /* SCHM */ goto unimplemented;
13175 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000013176 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
13177 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013178 case 0xb244: /* SQDR */ goto unimplemented;
13179 case 0xb245: /* SQER */ goto unimplemented;
13180 case 0xb246: /* STURA */ goto unimplemented;
13181 case 0xb247: /* MSTA */ goto unimplemented;
13182 case 0xb248: /* PALB */ goto unimplemented;
13183 case 0xb249: /* EREG */ goto unimplemented;
13184 case 0xb24a: /* ESTA */ goto unimplemented;
13185 case 0xb24b: /* LURA */ goto unimplemented;
13186 case 0xb24c: /* TAR */ goto unimplemented;
13187 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
13188 ovl.fmt.RRE.r2); goto ok;
13189 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13190 goto ok;
13191 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13192 goto ok;
13193 case 0xb250: /* CSP */ goto unimplemented;
13194 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
13195 ovl.fmt.RRE.r2); goto ok;
13196 case 0xb254: /* MVPG */ goto unimplemented;
13197 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
13198 ovl.fmt.RRE.r2); goto ok;
13199 case 0xb257: /* CUSE */ goto unimplemented;
13200 case 0xb258: /* BSG */ goto unimplemented;
13201 case 0xb25a: /* BSA */ goto unimplemented;
13202 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
13203 ovl.fmt.RRE.r2); goto ok;
13204 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
13205 ovl.fmt.RRE.r2); goto ok;
13206 case 0xb263: /* CMPSC */ goto unimplemented;
13207 case 0xb274: /* SIGA */ goto unimplemented;
13208 case 0xb276: /* XSCH */ goto unimplemented;
13209 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013210 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 +000013211 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013212 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 +000013213 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013214 case 0xb280: /* LPP */ goto unimplemented;
13215 case 0xb284: /* LCCTL */ goto unimplemented;
13216 case 0xb285: /* LPCTL */ goto unimplemented;
13217 case 0xb286: /* QSI */ goto unimplemented;
13218 case 0xb287: /* LSCTL */ goto unimplemented;
13219 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013220 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
13221 goto ok;
13222 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13223 goto ok;
13224 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13225 goto ok;
florian730448f2012-02-04 17:07:07 +000013226 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 +000013227 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
13228 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13229 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000013230 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
13231 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13232 goto ok;
florian933065d2011-07-11 01:48:02 +000013233 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
13234 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013235 case 0xb2b1: /* STFL */ goto unimplemented;
13236 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000013237 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
13238 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013239 case 0xb2b9: /* SRNMT */ goto unimplemented;
13240 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013241 case 0xb2e0: /* SCCTR */ goto unimplemented;
13242 case 0xb2e1: /* SPCTR */ goto unimplemented;
13243 case 0xb2e4: /* ECCTR */ goto unimplemented;
13244 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013245 case 0xb2e8: /* PPA */ goto unimplemented;
13246 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013247 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013248 case 0xb2f8: /* TEND */ goto unimplemented;
13249 case 0xb2fa: /* NIAI */ goto unimplemented;
13250 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013251 case 0xb2ff: /* TRAP4 */ goto unimplemented;
13252 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
13253 ovl.fmt.RRE.r2); goto ok;
13254 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
13255 ovl.fmt.RRE.r2); goto ok;
13256 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
13257 ovl.fmt.RRE.r2); goto ok;
13258 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
13259 ovl.fmt.RRE.r2); goto ok;
13260 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
13261 ovl.fmt.RRE.r2); goto ok;
13262 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
13263 ovl.fmt.RRE.r2); goto ok;
13264 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
13265 ovl.fmt.RRE.r2); goto ok;
13266 case 0xb307: /* MXDBR */ goto unimplemented;
13267 case 0xb308: /* KEBR */ goto unimplemented;
13268 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
13269 ovl.fmt.RRE.r2); goto ok;
13270 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
13271 ovl.fmt.RRE.r2); goto ok;
13272 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
13273 ovl.fmt.RRE.r2); goto ok;
13274 case 0xb30c: /* MDEBR */ goto unimplemented;
13275 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
13276 ovl.fmt.RRE.r2); goto ok;
13277 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
13278 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13279 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
13280 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13281 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
13282 ovl.fmt.RRE.r2); goto ok;
13283 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
13284 ovl.fmt.RRE.r2); goto ok;
13285 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
13286 ovl.fmt.RRE.r2); goto ok;
13287 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
13288 ovl.fmt.RRE.r2); goto ok;
13289 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
13290 ovl.fmt.RRE.r2); goto ok;
13291 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
13292 ovl.fmt.RRE.r2); goto ok;
13293 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
13294 ovl.fmt.RRE.r2); goto ok;
13295 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
13296 ovl.fmt.RRE.r2); goto ok;
13297 case 0xb318: /* KDBR */ goto unimplemented;
13298 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
13299 ovl.fmt.RRE.r2); goto ok;
13300 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
13301 ovl.fmt.RRE.r2); goto ok;
13302 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
13303 ovl.fmt.RRE.r2); goto ok;
13304 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
13305 ovl.fmt.RRE.r2); goto ok;
13306 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
13307 ovl.fmt.RRE.r2); goto ok;
13308 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
13309 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13310 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
13311 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13312 case 0xb324: /* LDER */ goto unimplemented;
13313 case 0xb325: /* LXDR */ goto unimplemented;
13314 case 0xb326: /* LXER */ goto unimplemented;
13315 case 0xb32e: /* MAER */ goto unimplemented;
13316 case 0xb32f: /* MSER */ goto unimplemented;
13317 case 0xb336: /* SQXR */ goto unimplemented;
13318 case 0xb337: /* MEER */ goto unimplemented;
13319 case 0xb338: /* MAYLR */ goto unimplemented;
13320 case 0xb339: /* MYLR */ goto unimplemented;
13321 case 0xb33a: /* MAYR */ goto unimplemented;
13322 case 0xb33b: /* MYR */ goto unimplemented;
13323 case 0xb33c: /* MAYHR */ goto unimplemented;
13324 case 0xb33d: /* MYHR */ goto unimplemented;
13325 case 0xb33e: /* MADR */ goto unimplemented;
13326 case 0xb33f: /* MSDR */ goto unimplemented;
13327 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
13328 ovl.fmt.RRE.r2); goto ok;
13329 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
13330 ovl.fmt.RRE.r2); goto ok;
13331 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
13332 ovl.fmt.RRE.r2); goto ok;
13333 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
13334 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013335 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13336 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13337 ovl.fmt.RRF2.r2); goto ok;
13338 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13339 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13340 ovl.fmt.RRF2.r2); goto ok;
13341 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13342 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13343 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013344 case 0xb347: /* FIXBR */ goto unimplemented;
13345 case 0xb348: /* KXBR */ goto unimplemented;
13346 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13347 ovl.fmt.RRE.r2); goto ok;
13348 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13349 ovl.fmt.RRE.r2); goto ok;
13350 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13351 ovl.fmt.RRE.r2); goto ok;
13352 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13353 ovl.fmt.RRE.r2); goto ok;
13354 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13355 ovl.fmt.RRE.r2); goto ok;
13356 case 0xb350: /* TBEDR */ goto unimplemented;
13357 case 0xb351: /* TBDR */ goto unimplemented;
13358 case 0xb353: /* DIEBR */ goto unimplemented;
13359 case 0xb357: /* FIEBR */ goto unimplemented;
13360 case 0xb358: /* THDER */ goto unimplemented;
13361 case 0xb359: /* THDR */ goto unimplemented;
13362 case 0xb35b: /* DIDBR */ goto unimplemented;
13363 case 0xb35f: /* FIDBR */ goto unimplemented;
13364 case 0xb360: /* LPXR */ goto unimplemented;
13365 case 0xb361: /* LNXR */ goto unimplemented;
13366 case 0xb362: /* LTXR */ goto unimplemented;
13367 case 0xb363: /* LCXR */ goto unimplemented;
13368 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13369 ovl.fmt.RRE.r2); goto ok;
13370 case 0xb366: /* LEXR */ goto unimplemented;
13371 case 0xb367: /* FIXR */ goto unimplemented;
13372 case 0xb369: /* CXR */ goto unimplemented;
13373 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13374 ovl.fmt.RRE.r2); goto ok;
13375 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13376 ovl.fmt.RRE.r2); goto ok;
13377 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13378 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13379 goto ok;
13380 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13381 ovl.fmt.RRE.r2); goto ok;
13382 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13383 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13384 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13385 case 0xb377: /* FIER */ goto unimplemented;
13386 case 0xb37f: /* FIDR */ goto unimplemented;
13387 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13388 case 0xb385: /* SFASR */ goto unimplemented;
13389 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013390 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13391 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13392 ovl.fmt.RRF2.r2); goto ok;
13393 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13394 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13395 ovl.fmt.RRF2.r2); goto ok;
13396 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13397 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13398 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013399 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13400 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13401 ovl.fmt.RRF2.r2); goto ok;
13402 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13403 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13404 ovl.fmt.RRF2.r2); goto ok;
13405 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13406 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13407 ovl.fmt.RRF2.r2); goto ok;
13408 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13409 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13410 ovl.fmt.RRF2.r2); goto ok;
13411 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13412 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13413 ovl.fmt.RRF2.r2); goto ok;
13414 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13415 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13416 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013417 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13418 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13419 ovl.fmt.RRF2.r2); goto ok;
13420 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13421 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13422 ovl.fmt.RRF2.r2); goto ok;
13423 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13424 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13425 ovl.fmt.RRF2.r2); goto ok;
13426 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13427 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13428 ovl.fmt.RRF2.r2); goto ok;
13429 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13430 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13431 ovl.fmt.RRF2.r2); goto ok;
13432 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13433 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13434 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013435 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13436 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13437 ovl.fmt.RRF2.r2); goto ok;
13438 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13439 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13440 ovl.fmt.RRF2.r2); goto ok;
13441 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13442 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13443 ovl.fmt.RRF2.r2); goto ok;
13444 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13445 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13446 ovl.fmt.RRF2.r2); goto ok;
13447 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13448 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13449 ovl.fmt.RRF2.r2); goto ok;
13450 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13451 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13452 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013453 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13454 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13455 ovl.fmt.RRF2.r2); goto ok;
13456 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13457 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13458 ovl.fmt.RRF2.r2); goto ok;
13459 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13460 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13461 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013462 case 0xb3b4: /* CEFR */ goto unimplemented;
13463 case 0xb3b5: /* CDFR */ goto unimplemented;
13464 case 0xb3b6: /* CXFR */ goto unimplemented;
13465 case 0xb3b8: /* CFER */ goto unimplemented;
13466 case 0xb3b9: /* CFDR */ goto unimplemented;
13467 case 0xb3ba: /* CFXR */ goto unimplemented;
13468 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13469 ovl.fmt.RRE.r2); goto ok;
13470 case 0xb3c4: /* CEGR */ goto unimplemented;
13471 case 0xb3c5: /* CDGR */ goto unimplemented;
13472 case 0xb3c6: /* CXGR */ goto unimplemented;
13473 case 0xb3c8: /* CGER */ goto unimplemented;
13474 case 0xb3c9: /* CGDR */ goto unimplemented;
13475 case 0xb3ca: /* CGXR */ goto unimplemented;
13476 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13477 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013478 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13479 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13480 ovl.fmt.RRF4.r2); goto ok;
13481 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13482 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13483 ovl.fmt.RRF4.r2); goto ok;
13484 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13485 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13486 ovl.fmt.RRF4.r2); goto ok;
13487 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13488 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13489 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000013490 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
13491 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13492 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
13493 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13494 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013495 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13496 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013497 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013498 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
13499 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13500 ovl.fmt.RRF4.r2); goto ok;
13501 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
13502 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13503 ovl.fmt.RRF4.r2); goto ok;
13504 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
13505 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13506 ovl.fmt.RRF4.r2); goto ok;
13507 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
13508 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13509 ovl.fmt.RRF4.r2); goto ok;
13510 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
13511 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13512 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
13513 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13514 ovl.fmt.RRF2.r2); goto ok;
13515 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
13516 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013517 case 0xb3df: /* FIXTR */ goto unimplemented;
13518 case 0xb3e0: /* KDTR */ goto unimplemented;
13519 case 0xb3e1: /* CGDTR */ goto unimplemented;
13520 case 0xb3e2: /* CUDTR */ goto unimplemented;
13521 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013522 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
13523 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013524 case 0xb3e5: /* EEDTR */ goto unimplemented;
13525 case 0xb3e7: /* ESDTR */ goto unimplemented;
13526 case 0xb3e8: /* KXTR */ goto unimplemented;
13527 case 0xb3e9: /* CGXTR */ goto unimplemented;
13528 case 0xb3ea: /* CUXTR */ goto unimplemented;
13529 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013530 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
13531 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013532 case 0xb3ed: /* EEXTR */ goto unimplemented;
13533 case 0xb3ef: /* ESXTR */ goto unimplemented;
13534 case 0xb3f1: /* CDGTR */ goto unimplemented;
13535 case 0xb3f2: /* CDUTR */ goto unimplemented;
13536 case 0xb3f3: /* CDSTR */ goto unimplemented;
13537 case 0xb3f4: /* CEDTR */ goto unimplemented;
13538 case 0xb3f5: /* QADTR */ goto unimplemented;
13539 case 0xb3f6: /* IEDTR */ goto unimplemented;
13540 case 0xb3f7: /* RRDTR */ goto unimplemented;
13541 case 0xb3f9: /* CXGTR */ goto unimplemented;
13542 case 0xb3fa: /* CXUTR */ goto unimplemented;
13543 case 0xb3fb: /* CXSTR */ goto unimplemented;
13544 case 0xb3fc: /* CEXTR */ goto unimplemented;
13545 case 0xb3fd: /* QAXTR */ goto unimplemented;
13546 case 0xb3fe: /* IEXTR */ goto unimplemented;
13547 case 0xb3ff: /* RRXTR */ goto unimplemented;
13548 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13549 ovl.fmt.RRE.r2); goto ok;
13550 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13551 ovl.fmt.RRE.r2); goto ok;
13552 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13553 ovl.fmt.RRE.r2); goto ok;
13554 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13555 ovl.fmt.RRE.r2); goto ok;
13556 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13557 ovl.fmt.RRE.r2); goto ok;
13558 case 0xb905: /* LURAG */ goto unimplemented;
13559 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13560 ovl.fmt.RRE.r2); goto ok;
13561 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13562 ovl.fmt.RRE.r2); goto ok;
13563 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13564 ovl.fmt.RRE.r2); goto ok;
13565 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13566 ovl.fmt.RRE.r2); goto ok;
13567 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13568 ovl.fmt.RRE.r2); goto ok;
13569 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13570 ovl.fmt.RRE.r2); goto ok;
13571 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13572 ovl.fmt.RRE.r2); goto ok;
13573 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13574 ovl.fmt.RRE.r2); goto ok;
13575 case 0xb90e: /* EREGG */ goto unimplemented;
13576 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13577 ovl.fmt.RRE.r2); goto ok;
13578 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13579 ovl.fmt.RRE.r2); goto ok;
13580 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13581 ovl.fmt.RRE.r2); goto ok;
13582 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13583 ovl.fmt.RRE.r2); goto ok;
13584 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13585 ovl.fmt.RRE.r2); goto ok;
13586 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13587 ovl.fmt.RRE.r2); goto ok;
13588 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13589 ovl.fmt.RRE.r2); goto ok;
13590 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13591 ovl.fmt.RRE.r2); goto ok;
13592 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13593 ovl.fmt.RRE.r2); goto ok;
13594 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13595 ovl.fmt.RRE.r2); goto ok;
13596 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13597 ovl.fmt.RRE.r2); goto ok;
13598 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13599 ovl.fmt.RRE.r2); goto ok;
13600 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13601 ovl.fmt.RRE.r2); goto ok;
13602 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13603 ovl.fmt.RRE.r2); goto ok;
13604 case 0xb91e: /* KMAC */ goto unimplemented;
13605 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13606 ovl.fmt.RRE.r2); goto ok;
13607 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13608 ovl.fmt.RRE.r2); goto ok;
13609 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13610 ovl.fmt.RRE.r2); goto ok;
13611 case 0xb925: /* STURG */ goto unimplemented;
13612 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13613 ovl.fmt.RRE.r2); goto ok;
13614 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13615 ovl.fmt.RRE.r2); goto ok;
13616 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013617 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013618 case 0xb92b: /* KMO */ goto unimplemented;
13619 case 0xb92c: /* PCC */ goto unimplemented;
13620 case 0xb92d: /* KMCTR */ goto unimplemented;
13621 case 0xb92e: /* KM */ goto unimplemented;
13622 case 0xb92f: /* KMC */ goto unimplemented;
13623 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13624 ovl.fmt.RRE.r2); goto ok;
13625 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13626 ovl.fmt.RRE.r2); goto ok;
13627 case 0xb93e: /* KIMD */ goto unimplemented;
13628 case 0xb93f: /* KLMD */ goto unimplemented;
13629 case 0xb941: /* CFDTR */ goto unimplemented;
13630 case 0xb942: /* CLGDTR */ goto unimplemented;
13631 case 0xb943: /* CLFDTR */ goto unimplemented;
13632 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13633 ovl.fmt.RRE.r2); goto ok;
13634 case 0xb949: /* CFXTR */ goto unimplemented;
13635 case 0xb94a: /* CLGXTR */ goto unimplemented;
13636 case 0xb94b: /* CLFXTR */ goto unimplemented;
13637 case 0xb951: /* CDFTR */ goto unimplemented;
13638 case 0xb952: /* CDLGTR */ goto unimplemented;
13639 case 0xb953: /* CDLFTR */ goto unimplemented;
13640 case 0xb959: /* CXFTR */ goto unimplemented;
13641 case 0xb95a: /* CXLGTR */ goto unimplemented;
13642 case 0xb95b: /* CXLFTR */ goto unimplemented;
13643 case 0xb960: /* CGRT */ goto unimplemented;
13644 case 0xb961: /* CLGRT */ goto unimplemented;
13645 case 0xb972: /* CRT */ goto unimplemented;
13646 case 0xb973: /* CLRT */ goto unimplemented;
13647 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13648 ovl.fmt.RRE.r2); goto ok;
13649 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13650 ovl.fmt.RRE.r2); goto ok;
13651 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13652 ovl.fmt.RRE.r2); goto ok;
13653 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13654 ovl.fmt.RRE.r2); goto ok;
13655 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13656 ovl.fmt.RRE.r2); goto ok;
13657 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13658 ovl.fmt.RRE.r2); goto ok;
13659 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13660 ovl.fmt.RRE.r2); goto ok;
13661 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13662 ovl.fmt.RRE.r2); goto ok;
13663 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13664 ovl.fmt.RRE.r2); goto ok;
13665 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13666 ovl.fmt.RRE.r2); goto ok;
13667 case 0xb98a: /* CSPG */ goto unimplemented;
13668 case 0xb98d: /* EPSW */ goto unimplemented;
13669 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013670 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013671 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13672 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13673 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13674 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13675 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13676 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013677 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13678 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013679 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13680 ovl.fmt.RRE.r2); goto ok;
13681 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13682 ovl.fmt.RRE.r2); goto ok;
13683 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13684 ovl.fmt.RRE.r2); goto ok;
13685 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13686 ovl.fmt.RRE.r2); goto ok;
13687 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13688 ovl.fmt.RRE.r2); goto ok;
13689 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13690 ovl.fmt.RRE.r2); goto ok;
13691 case 0xb99a: /* EPAIR */ goto unimplemented;
13692 case 0xb99b: /* ESAIR */ goto unimplemented;
13693 case 0xb99d: /* ESEA */ goto unimplemented;
13694 case 0xb99e: /* PTI */ goto unimplemented;
13695 case 0xb99f: /* SSAIR */ goto unimplemented;
13696 case 0xb9a2: /* PTF */ goto unimplemented;
13697 case 0xb9aa: /* LPTEA */ goto unimplemented;
13698 case 0xb9ae: /* RRBM */ goto unimplemented;
13699 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013700 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13701 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13702 goto ok;
florian2a415a12012-07-21 17:41:36 +000013703 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13704 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13705 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013706 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13707 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013708 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13709 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013710 case 0xb9bd: /* TRTRE */ goto unimplemented;
13711 case 0xb9be: /* SRSTU */ goto unimplemented;
13712 case 0xb9bf: /* TRTE */ goto unimplemented;
13713 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13714 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13715 goto ok;
13716 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13717 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13718 goto ok;
13719 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13720 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13721 goto ok;
13722 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13723 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13724 goto ok;
13725 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13726 ovl.fmt.RRE.r2); goto ok;
13727 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13728 ovl.fmt.RRE.r2); goto ok;
13729 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13730 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13731 goto ok;
13732 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13733 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13734 goto ok;
13735 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13736 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13737 goto ok;
13738 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13739 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13740 goto ok;
13741 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13742 ovl.fmt.RRE.r2); goto ok;
13743 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13744 ovl.fmt.RRE.r2); goto ok;
13745 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013746 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13747 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13748 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013749 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13750 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13751 goto ok;
13752 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13753 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13754 goto ok;
13755 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13756 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13757 goto ok;
13758 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13759 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13760 goto ok;
13761 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13762 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13763 goto ok;
13764 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13765 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13766 goto ok;
13767 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13768 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13769 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013770 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13771 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13772 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013773 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13774 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13775 goto ok;
13776 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13777 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13778 goto ok;
13779 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13780 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13781 goto ok;
13782 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13783 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13784 goto ok;
13785 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13786 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13787 goto ok;
13788 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13789 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13790 goto ok;
13791 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
13792 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13793 goto ok;
13794 }
13795
13796 switch ((ovl.value & 0xff000000) >> 24) {
13797 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13798 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13799 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13800 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13801 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13802 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13803 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13804 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13805 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13806 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13807 case 0x45: /* BAL */ goto unimplemented;
13808 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13809 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13810 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13811 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13812 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13813 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13814 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13815 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13816 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13817 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13818 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13819 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13820 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13821 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13822 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13823 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13824 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13825 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13826 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13827 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13828 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13829 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13830 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13831 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13832 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13833 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13834 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13835 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13836 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13837 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13838 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13839 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13840 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13841 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13842 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13843 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13844 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13845 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13846 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13847 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13848 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13849 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13850 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13851 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13852 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13853 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13854 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13855 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13856 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13857 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13858 case 0x67: /* MXD */ goto unimplemented;
13859 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13860 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13861 case 0x69: /* CD */ goto unimplemented;
13862 case 0x6a: /* AD */ goto unimplemented;
13863 case 0x6b: /* SD */ goto unimplemented;
13864 case 0x6c: /* MD */ goto unimplemented;
13865 case 0x6d: /* DD */ goto unimplemented;
13866 case 0x6e: /* AW */ goto unimplemented;
13867 case 0x6f: /* SW */ goto unimplemented;
13868 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13869 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13870 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13871 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13872 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
13873 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
13874 case 0x79: /* CE */ goto unimplemented;
13875 case 0x7a: /* AE */ goto unimplemented;
13876 case 0x7b: /* SE */ goto unimplemented;
13877 case 0x7c: /* MDE */ goto unimplemented;
13878 case 0x7d: /* DE */ goto unimplemented;
13879 case 0x7e: /* AU */ goto unimplemented;
13880 case 0x7f: /* SU */ goto unimplemented;
13881 case 0x83: /* DIAG */ goto unimplemented;
13882 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
13883 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13884 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
13885 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
13886 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13887 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13888 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13889 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13890 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13891 ovl.fmt.RS.d2); goto ok;
13892 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13893 ovl.fmt.RS.d2); goto ok;
13894 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13895 ovl.fmt.RS.d2); goto ok;
13896 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13897 ovl.fmt.RS.d2); goto ok;
13898 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13899 ovl.fmt.RS.d2); goto ok;
13900 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13901 ovl.fmt.RS.d2); goto ok;
13902 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13903 ovl.fmt.RS.d2); goto ok;
13904 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
13905 ovl.fmt.RS.d2); goto ok;
13906 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13907 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13908 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13909 ovl.fmt.SI.d1); goto ok;
13910 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13911 ovl.fmt.SI.d1); goto ok;
13912 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13913 ovl.fmt.SI.d1); goto ok;
13914 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13915 ovl.fmt.SI.d1); goto ok;
13916 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13917 ovl.fmt.SI.d1); goto ok;
13918 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
13919 ovl.fmt.SI.d1); goto ok;
13920 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13921 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13922 case 0x99: /* TRACE */ goto unimplemented;
13923 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13924 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13925 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13926 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13927 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
13928 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13929 goto ok;
13930 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
13931 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
13932 goto ok;
13933 case 0xac: /* STNSM */ goto unimplemented;
13934 case 0xad: /* STOSM */ goto unimplemented;
13935 case 0xae: /* SIGP */ goto unimplemented;
13936 case 0xaf: /* MC */ goto unimplemented;
13937 case 0xb1: /* LRA */ goto unimplemented;
13938 case 0xb6: /* STCTL */ goto unimplemented;
13939 case 0xb7: /* LCTL */ goto unimplemented;
13940 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13941 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000013942 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13943 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013944 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13945 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13946 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13947 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13948 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
13949 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
13950 }
13951
13952 return S390_DECODE_UNKNOWN_INSN;
13953
13954ok:
13955 return S390_DECODE_OK;
13956
13957unimplemented:
13958 return S390_DECODE_UNIMPLEMENTED_INSN;
13959}
13960
13961static s390_decode_t
13962s390_decode_6byte_and_irgen(UChar *bytes)
13963{
13964 typedef union {
13965 struct {
13966 unsigned int op1 : 8;
13967 unsigned int r1 : 4;
13968 unsigned int r3 : 4;
13969 unsigned int i2 : 16;
13970 unsigned int : 8;
13971 unsigned int op2 : 8;
13972 } RIE;
13973 struct {
13974 unsigned int op1 : 8;
13975 unsigned int r1 : 4;
13976 unsigned int r2 : 4;
13977 unsigned int i3 : 8;
13978 unsigned int i4 : 8;
13979 unsigned int i5 : 8;
13980 unsigned int op2 : 8;
13981 } RIE_RRUUU;
13982 struct {
13983 unsigned int op1 : 8;
13984 unsigned int r1 : 4;
13985 unsigned int : 4;
13986 unsigned int i2 : 16;
13987 unsigned int m3 : 4;
13988 unsigned int : 4;
13989 unsigned int op2 : 8;
13990 } RIEv1;
13991 struct {
13992 unsigned int op1 : 8;
13993 unsigned int r1 : 4;
13994 unsigned int r2 : 4;
13995 unsigned int i4 : 16;
13996 unsigned int m3 : 4;
13997 unsigned int : 4;
13998 unsigned int op2 : 8;
13999 } RIE_RRPU;
14000 struct {
14001 unsigned int op1 : 8;
14002 unsigned int r1 : 4;
14003 unsigned int m3 : 4;
14004 unsigned int i4 : 16;
14005 unsigned int i2 : 8;
14006 unsigned int op2 : 8;
14007 } RIEv3;
14008 struct {
14009 unsigned int op1 : 8;
14010 unsigned int r1 : 4;
14011 unsigned int op2 : 4;
14012 unsigned int i2 : 32;
14013 } RIL;
14014 struct {
14015 unsigned int op1 : 8;
14016 unsigned int r1 : 4;
14017 unsigned int m3 : 4;
14018 unsigned int b4 : 4;
14019 unsigned int d4 : 12;
14020 unsigned int i2 : 8;
14021 unsigned int op2 : 8;
14022 } RIS;
14023 struct {
14024 unsigned int op1 : 8;
14025 unsigned int r1 : 4;
14026 unsigned int r2 : 4;
14027 unsigned int b4 : 4;
14028 unsigned int d4 : 12;
14029 unsigned int m3 : 4;
14030 unsigned int : 4;
14031 unsigned int op2 : 8;
14032 } RRS;
14033 struct {
14034 unsigned int op1 : 8;
14035 unsigned int l1 : 4;
14036 unsigned int : 4;
14037 unsigned int b1 : 4;
14038 unsigned int d1 : 12;
14039 unsigned int : 8;
14040 unsigned int op2 : 8;
14041 } RSL;
14042 struct {
14043 unsigned int op1 : 8;
14044 unsigned int r1 : 4;
14045 unsigned int r3 : 4;
14046 unsigned int b2 : 4;
14047 unsigned int dl2 : 12;
14048 unsigned int dh2 : 8;
14049 unsigned int op2 : 8;
14050 } RSY;
14051 struct {
14052 unsigned int op1 : 8;
14053 unsigned int r1 : 4;
14054 unsigned int x2 : 4;
14055 unsigned int b2 : 4;
14056 unsigned int d2 : 12;
14057 unsigned int : 8;
14058 unsigned int op2 : 8;
14059 } RXE;
14060 struct {
14061 unsigned int op1 : 8;
14062 unsigned int r3 : 4;
14063 unsigned int x2 : 4;
14064 unsigned int b2 : 4;
14065 unsigned int d2 : 12;
14066 unsigned int r1 : 4;
14067 unsigned int : 4;
14068 unsigned int op2 : 8;
14069 } RXF;
14070 struct {
14071 unsigned int op1 : 8;
14072 unsigned int r1 : 4;
14073 unsigned int x2 : 4;
14074 unsigned int b2 : 4;
14075 unsigned int dl2 : 12;
14076 unsigned int dh2 : 8;
14077 unsigned int op2 : 8;
14078 } RXY;
14079 struct {
14080 unsigned int op1 : 8;
14081 unsigned int i2 : 8;
14082 unsigned int b1 : 4;
14083 unsigned int dl1 : 12;
14084 unsigned int dh1 : 8;
14085 unsigned int op2 : 8;
14086 } SIY;
14087 struct {
14088 unsigned int op : 8;
14089 unsigned int l : 8;
14090 unsigned int b1 : 4;
14091 unsigned int d1 : 12;
14092 unsigned int b2 : 4;
14093 unsigned int d2 : 12;
14094 } SS;
14095 struct {
14096 unsigned int op : 8;
14097 unsigned int l1 : 4;
14098 unsigned int l2 : 4;
14099 unsigned int b1 : 4;
14100 unsigned int d1 : 12;
14101 unsigned int b2 : 4;
14102 unsigned int d2 : 12;
14103 } SS_LLRDRD;
14104 struct {
14105 unsigned int op : 8;
14106 unsigned int r1 : 4;
14107 unsigned int r3 : 4;
14108 unsigned int b2 : 4;
14109 unsigned int d2 : 12;
14110 unsigned int b4 : 4;
14111 unsigned int d4 : 12;
14112 } SS_RRRDRD2;
14113 struct {
14114 unsigned int op : 16;
14115 unsigned int b1 : 4;
14116 unsigned int d1 : 12;
14117 unsigned int b2 : 4;
14118 unsigned int d2 : 12;
14119 } SSE;
14120 struct {
14121 unsigned int op1 : 8;
14122 unsigned int r3 : 4;
14123 unsigned int op2 : 4;
14124 unsigned int b1 : 4;
14125 unsigned int d1 : 12;
14126 unsigned int b2 : 4;
14127 unsigned int d2 : 12;
14128 } SSF;
14129 struct {
14130 unsigned int op : 16;
14131 unsigned int b1 : 4;
14132 unsigned int d1 : 12;
14133 unsigned int i2 : 16;
14134 } SIL;
14135 } formats;
14136 union {
14137 formats fmt;
14138 ULong value;
14139 } ovl;
14140
14141 vassert(sizeof(formats) == 6);
14142
florianffbd84d2012-12-09 02:06:29 +000014143 ((UChar *)(&ovl.value))[0] = bytes[0];
14144 ((UChar *)(&ovl.value))[1] = bytes[1];
14145 ((UChar *)(&ovl.value))[2] = bytes[2];
14146 ((UChar *)(&ovl.value))[3] = bytes[3];
14147 ((UChar *)(&ovl.value))[4] = bytes[4];
14148 ((UChar *)(&ovl.value))[5] = bytes[5];
14149 ((UChar *)(&ovl.value))[6] = 0x0;
14150 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000014151
14152 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
14153 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
14154 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14155 ovl.fmt.RXY.dl2,
14156 ovl.fmt.RXY.dh2); goto ok;
14157 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
14158 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
14159 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14160 ovl.fmt.RXY.dl2,
14161 ovl.fmt.RXY.dh2); goto ok;
14162 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
14163 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14164 ovl.fmt.RXY.dl2,
14165 ovl.fmt.RXY.dh2); goto ok;
14166 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
14167 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14168 ovl.fmt.RXY.dl2,
14169 ovl.fmt.RXY.dh2); goto ok;
14170 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
14171 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14172 ovl.fmt.RXY.dl2,
14173 ovl.fmt.RXY.dh2); goto ok;
14174 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
14175 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14176 ovl.fmt.RXY.dl2,
14177 ovl.fmt.RXY.dh2); goto ok;
14178 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
14179 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14180 ovl.fmt.RXY.dl2,
14181 ovl.fmt.RXY.dh2); goto ok;
14182 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
14183 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14184 ovl.fmt.RXY.dl2,
14185 ovl.fmt.RXY.dh2); goto ok;
14186 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
14187 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14188 ovl.fmt.RXY.dl2,
14189 ovl.fmt.RXY.dh2); goto ok;
14190 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
14191 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
14192 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14193 ovl.fmt.RXY.dl2,
14194 ovl.fmt.RXY.dh2); goto ok;
14195 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
14196 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14197 ovl.fmt.RXY.dl2,
14198 ovl.fmt.RXY.dh2); goto ok;
14199 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
14200 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
14201 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14202 ovl.fmt.RXY.dl2,
14203 ovl.fmt.RXY.dh2); goto ok;
14204 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
14205 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14206 ovl.fmt.RXY.dl2,
14207 ovl.fmt.RXY.dh2); goto ok;
14208 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
14209 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14210 ovl.fmt.RXY.dl2,
14211 ovl.fmt.RXY.dh2); goto ok;
14212 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
14213 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14214 ovl.fmt.RXY.dl2,
14215 ovl.fmt.RXY.dh2); goto ok;
14216 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
14217 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14218 ovl.fmt.RXY.dl2,
14219 ovl.fmt.RXY.dh2); goto ok;
14220 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
14221 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14222 ovl.fmt.RXY.dl2,
14223 ovl.fmt.RXY.dh2); goto ok;
14224 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
14225 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14226 ovl.fmt.RXY.dl2,
14227 ovl.fmt.RXY.dh2); goto ok;
14228 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
14229 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14230 ovl.fmt.RXY.dl2,
14231 ovl.fmt.RXY.dh2); goto ok;
14232 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
14233 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14234 ovl.fmt.RXY.dl2,
14235 ovl.fmt.RXY.dh2); goto ok;
14236 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
14237 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14238 ovl.fmt.RXY.dl2,
14239 ovl.fmt.RXY.dh2); goto ok;
14240 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
14241 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14242 ovl.fmt.RXY.dl2,
14243 ovl.fmt.RXY.dh2); goto ok;
14244 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
14245 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14246 ovl.fmt.RXY.dl2,
14247 ovl.fmt.RXY.dh2); goto ok;
14248 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
14249 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14250 ovl.fmt.RXY.dl2,
14251 ovl.fmt.RXY.dh2); goto ok;
14252 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
14253 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14254 ovl.fmt.RXY.dl2,
14255 ovl.fmt.RXY.dh2); goto ok;
14256 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
14257 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14258 ovl.fmt.RXY.dl2,
14259 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014260 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014261 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
14262 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14263 ovl.fmt.RXY.dl2,
14264 ovl.fmt.RXY.dh2); goto ok;
14265 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
14266 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
14267 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14268 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14269 ovl.fmt.RXY.dh2); goto ok;
14270 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
14271 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14272 ovl.fmt.RXY.dl2,
14273 ovl.fmt.RXY.dh2); goto ok;
14274 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
14275 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14276 ovl.fmt.RXY.dl2,
14277 ovl.fmt.RXY.dh2); goto ok;
14278 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
14279 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14280 ovl.fmt.RXY.dl2,
14281 ovl.fmt.RXY.dh2); goto ok;
14282 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
14283 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14284 ovl.fmt.RXY.dl2,
14285 ovl.fmt.RXY.dh2); goto ok;
14286 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
14287 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14288 ovl.fmt.RXY.dl2,
14289 ovl.fmt.RXY.dh2); goto ok;
14290 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
14291 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14292 ovl.fmt.RXY.dl2,
14293 ovl.fmt.RXY.dh2); goto ok;
14294 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
14295 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14296 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14297 ovl.fmt.RXY.dh2); goto ok;
14298 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
14299 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14300 ovl.fmt.RXY.dl2,
14301 ovl.fmt.RXY.dh2); goto ok;
14302 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
14303 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14304 ovl.fmt.RXY.dl2,
14305 ovl.fmt.RXY.dh2); goto ok;
14306 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
14307 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14308 ovl.fmt.RXY.dl2,
14309 ovl.fmt.RXY.dh2); goto ok;
14310 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
14311 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14312 ovl.fmt.RXY.dl2,
14313 ovl.fmt.RXY.dh2); goto ok;
14314 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
14315 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14316 ovl.fmt.RXY.dl2,
14317 ovl.fmt.RXY.dh2); goto ok;
14318 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
14319 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14320 ovl.fmt.RXY.dl2,
14321 ovl.fmt.RXY.dh2); goto ok;
14322 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
14323 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14324 ovl.fmt.RXY.dl2,
14325 ovl.fmt.RXY.dh2); goto ok;
14326 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
14327 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14328 ovl.fmt.RXY.dl2,
14329 ovl.fmt.RXY.dh2); goto ok;
14330 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
14331 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14332 ovl.fmt.RXY.dl2,
14333 ovl.fmt.RXY.dh2); goto ok;
14334 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
14335 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14336 ovl.fmt.RXY.dl2,
14337 ovl.fmt.RXY.dh2); goto ok;
14338 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
14339 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14340 ovl.fmt.RXY.dl2,
14341 ovl.fmt.RXY.dh2); goto ok;
14342 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
14343 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14344 ovl.fmt.RXY.dl2,
14345 ovl.fmt.RXY.dh2); goto ok;
14346 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
14347 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14348 ovl.fmt.RXY.dl2,
14349 ovl.fmt.RXY.dh2); goto ok;
14350 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
14351 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14352 ovl.fmt.RXY.dl2,
14353 ovl.fmt.RXY.dh2); goto ok;
14354 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, 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 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, 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 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, 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 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, 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 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, 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 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, 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 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, 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 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, 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 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, 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 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, 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 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, 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 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, 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 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, 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 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, 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 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, 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 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014415 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, 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 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14420 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14421 ovl.fmt.RXY.dl2,
14422 ovl.fmt.RXY.dh2); goto ok;
14423 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14424 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14425 ovl.fmt.RXY.dl2,
14426 ovl.fmt.RXY.dh2); goto ok;
14427 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14428 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14429 ovl.fmt.RXY.dl2,
14430 ovl.fmt.RXY.dh2); goto ok;
14431 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14432 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14433 ovl.fmt.RXY.dl2,
14434 ovl.fmt.RXY.dh2); goto ok;
14435 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14436 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14437 ovl.fmt.RXY.dl2,
14438 ovl.fmt.RXY.dh2); goto ok;
14439 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14440 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14441 ovl.fmt.RXY.dl2,
14442 ovl.fmt.RXY.dh2); goto ok;
14443 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
14444 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14445 ovl.fmt.RXY.dl2,
14446 ovl.fmt.RXY.dh2); goto ok;
14447 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
14448 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14449 ovl.fmt.RXY.dl2,
14450 ovl.fmt.RXY.dh2); goto ok;
14451 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
14452 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14453 ovl.fmt.RXY.dl2,
14454 ovl.fmt.RXY.dh2); goto ok;
14455 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
14456 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14457 ovl.fmt.RXY.dl2,
14458 ovl.fmt.RXY.dh2); goto ok;
14459 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
14460 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14461 ovl.fmt.RXY.dl2,
14462 ovl.fmt.RXY.dh2); goto ok;
14463 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
14464 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14465 ovl.fmt.RXY.dl2,
14466 ovl.fmt.RXY.dh2); goto ok;
14467 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
14468 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14469 ovl.fmt.RXY.dl2,
14470 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014471 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
14472 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
14473 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014474 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
14475 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14476 ovl.fmt.RXY.dl2,
14477 ovl.fmt.RXY.dh2); goto ok;
14478 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
14479 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14480 ovl.fmt.RXY.dl2,
14481 ovl.fmt.RXY.dh2); goto ok;
14482 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
14483 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14484 ovl.fmt.RXY.dl2,
14485 ovl.fmt.RXY.dh2); goto ok;
14486 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
14487 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14488 ovl.fmt.RXY.dl2,
14489 ovl.fmt.RXY.dh2); goto ok;
14490 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
14491 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14492 ovl.fmt.RXY.dl2,
14493 ovl.fmt.RXY.dh2); goto ok;
14494 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
14495 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14496 ovl.fmt.RXY.dl2,
14497 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014498 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014499 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
14500 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14501 ovl.fmt.RXY.dl2,
14502 ovl.fmt.RXY.dh2); goto ok;
14503 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
14504 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14505 ovl.fmt.RXY.dl2,
14506 ovl.fmt.RXY.dh2); goto ok;
14507 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
14508 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14509 ovl.fmt.RXY.dl2,
14510 ovl.fmt.RXY.dh2); goto ok;
14511 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
14512 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14513 ovl.fmt.RXY.dl2,
14514 ovl.fmt.RXY.dh2); goto ok;
14515 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14516 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14517 ovl.fmt.RSY.dl2,
14518 ovl.fmt.RSY.dh2); goto ok;
14519 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14520 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14521 ovl.fmt.RSY.dl2,
14522 ovl.fmt.RSY.dh2); goto ok;
14523 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14524 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14525 ovl.fmt.RSY.dl2,
14526 ovl.fmt.RSY.dh2); goto ok;
14527 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14528 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14529 ovl.fmt.RSY.dl2,
14530 ovl.fmt.RSY.dh2); goto ok;
14531 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14532 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14533 ovl.fmt.RSY.dl2,
14534 ovl.fmt.RSY.dh2); goto ok;
14535 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14536 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14537 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14538 ovl.fmt.RSY.dl2,
14539 ovl.fmt.RSY.dh2); goto ok;
14540 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14541 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14542 ovl.fmt.RSY.dl2,
14543 ovl.fmt.RSY.dh2); goto ok;
14544 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14545 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14546 ovl.fmt.RSY.dl2,
14547 ovl.fmt.RSY.dh2); goto ok;
14548 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14549 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14550 ovl.fmt.RSY.dl2,
14551 ovl.fmt.RSY.dh2); goto ok;
14552 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14553 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14554 ovl.fmt.RSY.dl2,
14555 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014556 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014557 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
14558 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14559 ovl.fmt.RSY.dl2,
14560 ovl.fmt.RSY.dh2); goto ok;
14561 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14562 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
14563 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14564 ovl.fmt.RSY.dl2,
14565 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014566 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014567 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14568 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14569 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14570 ovl.fmt.RSY.dh2); goto ok;
14571 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14572 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14573 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14574 ovl.fmt.RSY.dh2); goto ok;
14575 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14576 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14577 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14578 ovl.fmt.RSY.dl2,
14579 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014580 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
14581 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14582 ovl.fmt.RSY.dl2,
14583 ovl.fmt.RSY.dh2); goto ok;
14584 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
14585 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14586 ovl.fmt.RSY.dl2,
14587 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014588 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
14589 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14590 ovl.fmt.RSY.dl2,
14591 ovl.fmt.RSY.dh2); goto ok;
14592 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14593 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14594 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14595 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014596 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
14597 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14598 ovl.fmt.RSY.dl2,
14599 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014600 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14601 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14602 ovl.fmt.SIY.dh1); goto ok;
14603 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14604 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14605 ovl.fmt.SIY.dh1); goto ok;
14606 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14607 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14608 ovl.fmt.SIY.dh1); goto ok;
14609 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14610 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14611 ovl.fmt.SIY.dh1); goto ok;
14612 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14613 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14614 ovl.fmt.SIY.dh1); goto ok;
14615 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14616 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14617 ovl.fmt.SIY.dh1); goto ok;
14618 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14619 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14620 ovl.fmt.SIY.dh1); goto ok;
14621 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14622 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14623 ovl.fmt.SIY.dh1); goto ok;
14624 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14625 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14626 ovl.fmt.SIY.dh1); goto ok;
14627 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14628 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14629 ovl.fmt.SIY.dh1); goto ok;
14630 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14631 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14632 ovl.fmt.RSY.dl2,
14633 ovl.fmt.RSY.dh2); goto ok;
14634 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14635 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14636 ovl.fmt.RSY.dl2,
14637 ovl.fmt.RSY.dh2); goto ok;
14638 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14639 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14640 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14641 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14642 ovl.fmt.RSY.dl2,
14643 ovl.fmt.RSY.dh2); goto ok;
14644 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14645 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14646 ovl.fmt.RSY.dl2,
14647 ovl.fmt.RSY.dh2); goto ok;
14648 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14649 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14650 ovl.fmt.RSY.dl2,
14651 ovl.fmt.RSY.dh2); goto ok;
14652 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14653 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14654 ovl.fmt.RSY.dl2,
14655 ovl.fmt.RSY.dh2); goto ok;
14656 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14657 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14658 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14659 ovl.fmt.RSY.dh2); goto ok;
14660 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14661 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14662 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14663 ovl.fmt.RSY.dl2,
14664 ovl.fmt.RSY.dh2); goto ok;
14665 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14666 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14667 ovl.fmt.RSY.dl2,
14668 ovl.fmt.RSY.dh2); goto ok;
14669 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, 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 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, 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;
sewardjd7bde722011-04-05 13:19:33 +000014677 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14678 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14679 ovl.fmt.RSY.dl2,
14680 ovl.fmt.RSY.dh2,
14681 S390_XMNM_LOCG); goto ok;
14682 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14683 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14684 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14685 ovl.fmt.RSY.dh2,
14686 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014687 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14688 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14689 ovl.fmt.RSY.dl2,
14690 ovl.fmt.RSY.dh2); goto ok;
14691 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14692 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14693 ovl.fmt.RSY.dl2,
14694 ovl.fmt.RSY.dh2); goto ok;
14695 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14696 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14697 ovl.fmt.RSY.dl2,
14698 ovl.fmt.RSY.dh2); goto ok;
14699 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14700 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14701 ovl.fmt.RSY.dl2,
14702 ovl.fmt.RSY.dh2); goto ok;
14703 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14704 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14705 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14706 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014707 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14708 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14709 ovl.fmt.RSY.dl2,
14710 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14711 goto ok;
14712 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14713 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14714 ovl.fmt.RSY.dl2,
14715 ovl.fmt.RSY.dh2,
14716 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014717 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14718 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14719 ovl.fmt.RSY.dl2,
14720 ovl.fmt.RSY.dh2); goto ok;
14721 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14722 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14723 ovl.fmt.RSY.dl2,
14724 ovl.fmt.RSY.dh2); goto ok;
14725 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14726 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14727 ovl.fmt.RSY.dl2,
14728 ovl.fmt.RSY.dh2); goto ok;
14729 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14730 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14731 ovl.fmt.RSY.dl2,
14732 ovl.fmt.RSY.dh2); goto ok;
14733 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14734 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14735 ovl.fmt.RSY.dl2,
14736 ovl.fmt.RSY.dh2); goto ok;
14737 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14738 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14739 goto ok;
14740 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14741 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14742 goto ok;
14743 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14744 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14745 ovl.fmt.RIE_RRUUU.r1,
14746 ovl.fmt.RIE_RRUUU.r2,
14747 ovl.fmt.RIE_RRUUU.i3,
14748 ovl.fmt.RIE_RRUUU.i4,
14749 ovl.fmt.RIE_RRUUU.i5);
14750 goto ok;
14751 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14752 ovl.fmt.RIE_RRUUU.r1,
14753 ovl.fmt.RIE_RRUUU.r2,
14754 ovl.fmt.RIE_RRUUU.i3,
14755 ovl.fmt.RIE_RRUUU.i4,
14756 ovl.fmt.RIE_RRUUU.i5);
14757 goto ok;
14758 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14759 ovl.fmt.RIE_RRUUU.r1,
14760 ovl.fmt.RIE_RRUUU.r2,
14761 ovl.fmt.RIE_RRUUU.i3,
14762 ovl.fmt.RIE_RRUUU.i4,
14763 ovl.fmt.RIE_RRUUU.i5);
14764 goto ok;
14765 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14766 ovl.fmt.RIE_RRUUU.r1,
14767 ovl.fmt.RIE_RRUUU.r2,
14768 ovl.fmt.RIE_RRUUU.i3,
14769 ovl.fmt.RIE_RRUUU.i4,
14770 ovl.fmt.RIE_RRUUU.i5);
14771 goto ok;
florian2289cd42012-12-05 04:23:42 +000014772 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014773 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14774 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14775 ovl.fmt.RIE_RRPU.r1,
14776 ovl.fmt.RIE_RRPU.r2,
14777 ovl.fmt.RIE_RRPU.i4,
14778 ovl.fmt.RIE_RRPU.m3); goto ok;
14779 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14780 ovl.fmt.RIE_RRPU.r1,
14781 ovl.fmt.RIE_RRPU.r2,
14782 ovl.fmt.RIE_RRPU.i4,
14783 ovl.fmt.RIE_RRPU.m3); goto ok;
14784 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14785 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14786 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14787 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14788 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14789 ovl.fmt.RIE_RRPU.r1,
14790 ovl.fmt.RIE_RRPU.r2,
14791 ovl.fmt.RIE_RRPU.i4,
14792 ovl.fmt.RIE_RRPU.m3); goto ok;
14793 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
14794 ovl.fmt.RIE_RRPU.r1,
14795 ovl.fmt.RIE_RRPU.r2,
14796 ovl.fmt.RIE_RRPU.i4,
14797 ovl.fmt.RIE_RRPU.m3); goto ok;
14798 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
14799 ovl.fmt.RIEv3.r1,
14800 ovl.fmt.RIEv3.m3,
14801 ovl.fmt.RIEv3.i4,
14802 ovl.fmt.RIEv3.i2); goto ok;
14803 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
14804 ovl.fmt.RIEv3.r1,
14805 ovl.fmt.RIEv3.m3,
14806 ovl.fmt.RIEv3.i4,
14807 ovl.fmt.RIEv3.i2); goto ok;
14808 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
14809 ovl.fmt.RIEv3.r1,
14810 ovl.fmt.RIEv3.m3,
14811 ovl.fmt.RIEv3.i4,
14812 ovl.fmt.RIEv3.i2); goto ok;
14813 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
14814 ovl.fmt.RIEv3.r1,
14815 ovl.fmt.RIEv3.m3,
14816 ovl.fmt.RIEv3.i4,
14817 ovl.fmt.RIEv3.i2); goto ok;
14818 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
14819 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14820 goto ok;
14821 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
14822 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14823 ovl.fmt.RIE.i2); goto ok;
14824 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
14825 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14826 ovl.fmt.RIE.i2); goto ok;
14827 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
14828 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
14829 ovl.fmt.RIE.i2); goto ok;
14830 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
14831 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14832 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14833 goto ok;
14834 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
14835 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14836 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14837 goto ok;
14838 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
14839 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14840 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14841 goto ok;
14842 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
14843 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
14844 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
14845 goto ok;
14846 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
14847 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14848 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14849 ovl.fmt.RIS.i2); goto ok;
14850 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
14851 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14852 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14853 ovl.fmt.RIS.i2); goto ok;
14854 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
14855 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
14856 ovl.fmt.RIS.d4,
14857 ovl.fmt.RIS.i2); goto ok;
14858 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
14859 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
14860 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
14861 ovl.fmt.RIS.i2); goto ok;
14862 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
14863 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14864 ovl.fmt.RXE.d2); goto ok;
14865 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
14866 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14867 ovl.fmt.RXE.d2); goto ok;
14868 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
14869 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14870 ovl.fmt.RXE.d2); goto ok;
14871 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
14872 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
14873 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
14874 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14875 ovl.fmt.RXE.d2); goto ok;
14876 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
14877 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14878 ovl.fmt.RXE.d2); goto ok;
14879 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
14880 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14881 ovl.fmt.RXE.d2); goto ok;
14882 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
14883 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
14884 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14885 ovl.fmt.RXE.d2); goto ok;
14886 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
14887 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14888 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14889 ovl.fmt.RXF.r1); goto ok;
14890 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
14891 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14892 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14893 ovl.fmt.RXF.r1); goto ok;
14894 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
14895 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14896 ovl.fmt.RXE.d2); goto ok;
14897 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
14898 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14899 ovl.fmt.RXE.d2); goto ok;
14900 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
14901 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14902 ovl.fmt.RXE.d2); goto ok;
14903 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
14904 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14905 ovl.fmt.RXE.d2); goto ok;
14906 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
14907 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14908 ovl.fmt.RXE.d2); goto ok;
14909 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
14910 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14911 ovl.fmt.RXE.d2); goto ok;
14912 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
14913 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
14914 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14915 ovl.fmt.RXE.d2); goto ok;
14916 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
14917 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14918 ovl.fmt.RXE.d2); goto ok;
14919 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
14920 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14921 ovl.fmt.RXE.d2); goto ok;
14922 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
14923 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14924 ovl.fmt.RXE.d2); goto ok;
14925 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
14926 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
14927 ovl.fmt.RXE.d2); goto ok;
14928 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
14929 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14930 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14931 ovl.fmt.RXF.r1); goto ok;
14932 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
14933 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
14934 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
14935 ovl.fmt.RXF.r1); goto ok;
14936 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
14937 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
14938 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
14939 case 0xed000000002eULL: /* MAE */ goto unimplemented;
14940 case 0xed000000002fULL: /* MSE */ goto unimplemented;
14941 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
14942 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
14943 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
14944 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
14945 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
14946 case 0xed000000003aULL: /* MAY */ goto unimplemented;
14947 case 0xed000000003bULL: /* MY */ goto unimplemented;
14948 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
14949 case 0xed000000003dULL: /* MYH */ goto unimplemented;
14950 case 0xed000000003eULL: /* MAD */ goto unimplemented;
14951 case 0xed000000003fULL: /* MSD */ goto unimplemented;
14952 case 0xed0000000040ULL: /* SLDT */ goto unimplemented;
14953 case 0xed0000000041ULL: /* SRDT */ goto unimplemented;
14954 case 0xed0000000048ULL: /* SLXT */ goto unimplemented;
14955 case 0xed0000000049ULL: /* SRXT */ goto unimplemented;
14956 case 0xed0000000050ULL: /* TDCET */ goto unimplemented;
14957 case 0xed0000000051ULL: /* TDGET */ goto unimplemented;
14958 case 0xed0000000054ULL: /* TDCDT */ goto unimplemented;
14959 case 0xed0000000055ULL: /* TDGDT */ goto unimplemented;
14960 case 0xed0000000058ULL: /* TDCXT */ goto unimplemented;
14961 case 0xed0000000059ULL: /* TDGXT */ goto unimplemented;
14962 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
14963 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14964 ovl.fmt.RXY.dl2,
14965 ovl.fmt.RXY.dh2); goto ok;
14966 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
14967 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14968 ovl.fmt.RXY.dl2,
14969 ovl.fmt.RXY.dh2); goto ok;
14970 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
14971 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14972 ovl.fmt.RXY.dl2,
14973 ovl.fmt.RXY.dh2); goto ok;
14974 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
14975 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14976 ovl.fmt.RXY.dl2,
14977 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014978 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
14979 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
14980 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
14981 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014982 }
14983
14984 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
14985 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
14986 ovl.fmt.RIL.i2); goto ok;
14987 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
14988 ovl.fmt.RIL.i2); goto ok;
14989 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
14990 ovl.fmt.RIL.i2); goto ok;
14991 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
14992 ovl.fmt.RIL.i2); goto ok;
14993 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
14994 ovl.fmt.RIL.i2); goto ok;
14995 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
14996 ovl.fmt.RIL.i2); goto ok;
14997 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
14998 ovl.fmt.RIL.i2); goto ok;
14999 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
15000 ovl.fmt.RIL.i2); goto ok;
15001 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
15002 ovl.fmt.RIL.i2); goto ok;
15003 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
15004 ovl.fmt.RIL.i2); goto ok;
15005 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
15006 ovl.fmt.RIL.i2); goto ok;
15007 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
15008 ovl.fmt.RIL.i2); goto ok;
15009 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
15010 ovl.fmt.RIL.i2); goto ok;
15011 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
15012 ovl.fmt.RIL.i2); goto ok;
15013 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
15014 ovl.fmt.RIL.i2); goto ok;
15015 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
15016 ovl.fmt.RIL.i2); goto ok;
15017 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
15018 ovl.fmt.RIL.i2); goto ok;
15019 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
15020 ovl.fmt.RIL.i2); goto ok;
15021 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
15022 ovl.fmt.RIL.i2); goto ok;
15023 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
15024 ovl.fmt.RIL.i2); goto ok;
15025 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
15026 ovl.fmt.RIL.i2); goto ok;
15027 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
15028 ovl.fmt.RIL.i2); goto ok;
15029 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
15030 ovl.fmt.RIL.i2); goto ok;
15031 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
15032 ovl.fmt.RIL.i2); goto ok;
15033 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
15034 ovl.fmt.RIL.i2); goto ok;
15035 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
15036 ovl.fmt.RIL.i2); goto ok;
15037 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
15038 ovl.fmt.RIL.i2); goto ok;
15039 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
15040 ovl.fmt.RIL.i2); goto ok;
15041 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
15042 ovl.fmt.RIL.i2); goto ok;
15043 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
15044 ovl.fmt.RIL.i2); goto ok;
15045 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
15046 ovl.fmt.RIL.i2); goto ok;
15047 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
15048 ovl.fmt.RIL.i2); goto ok;
15049 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
15050 ovl.fmt.RIL.i2); goto ok;
15051 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
15052 ovl.fmt.RIL.i2); goto ok;
15053 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
15054 ovl.fmt.RIL.i2); goto ok;
15055 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
15056 ovl.fmt.RIL.i2); goto ok;
15057 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
15058 ovl.fmt.RIL.i2); goto ok;
15059 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
15060 ovl.fmt.RIL.i2); goto ok;
15061 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
15062 ovl.fmt.RIL.i2); goto ok;
15063 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
15064 ovl.fmt.RIL.i2); goto ok;
15065 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
15066 ovl.fmt.RIL.i2); goto ok;
15067 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
15068 ovl.fmt.RIL.i2); goto ok;
15069 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
15070 ovl.fmt.RIL.i2); goto ok;
15071 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
15072 ovl.fmt.RIL.i2); goto ok;
15073 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
15074 ovl.fmt.RIL.i2); goto ok;
15075 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
15076 ovl.fmt.RIL.i2); goto ok;
15077 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
15078 ovl.fmt.RIL.i2); goto ok;
15079 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
15080 ovl.fmt.RIL.i2); goto ok;
15081 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
15082 ovl.fmt.RIL.i2); goto ok;
15083 case 0xc800ULL: /* MVCOS */ goto unimplemented;
15084 case 0xc801ULL: /* ECTG */ goto unimplemented;
15085 case 0xc802ULL: /* CSST */ goto unimplemented;
15086 case 0xc804ULL: /* LPD */ goto unimplemented;
15087 case 0xc805ULL: /* LPDG */ goto unimplemented;
15088 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
15089 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
15090 ovl.fmt.RIL.i2); goto ok;
15091 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
15092 ovl.fmt.RIL.i2); goto ok;
15093 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
15094 ovl.fmt.RIL.i2); goto ok;
15095 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
15096 ovl.fmt.RIL.i2); goto ok;
15097 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
15098 ovl.fmt.RIL.i2); goto ok;
15099 }
15100
15101 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000015102 case 0xc5ULL: /* BPRP */ goto unimplemented;
15103 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015104 case 0xd0ULL: /* TRTR */ goto unimplemented;
15105 case 0xd1ULL: /* MVN */ goto unimplemented;
15106 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
15107 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15108 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15109 case 0xd3ULL: /* MVZ */ goto unimplemented;
15110 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
15111 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15112 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15113 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
15114 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15115 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15116 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
15117 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15118 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000015119 case 0xd7ULL:
15120 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
15121 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
15122 else
15123 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
15124 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15125 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
15126 goto ok;
sewardj2019a972011-03-07 16:04:07 +000015127 case 0xd9ULL: /* MVCK */ goto unimplemented;
15128 case 0xdaULL: /* MVCP */ goto unimplemented;
15129 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015130 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
15131 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15132 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015133 case 0xddULL: /* TRT */ goto unimplemented;
15134 case 0xdeULL: /* ED */ goto unimplemented;
15135 case 0xdfULL: /* EDMK */ goto unimplemented;
15136 case 0xe1ULL: /* PKU */ goto unimplemented;
15137 case 0xe2ULL: /* UNPKU */ goto unimplemented;
15138 case 0xe8ULL: /* MVCIN */ goto unimplemented;
15139 case 0xe9ULL: /* PKA */ goto unimplemented;
15140 case 0xeaULL: /* UNPKA */ goto unimplemented;
15141 case 0xeeULL: /* PLO */ goto unimplemented;
15142 case 0xefULL: /* LMD */ goto unimplemented;
15143 case 0xf0ULL: /* SRP */ goto unimplemented;
15144 case 0xf1ULL: /* MVO */ goto unimplemented;
15145 case 0xf2ULL: /* PACK */ goto unimplemented;
15146 case 0xf3ULL: /* UNPK */ goto unimplemented;
15147 case 0xf8ULL: /* ZAP */ goto unimplemented;
15148 case 0xf9ULL: /* CP */ goto unimplemented;
15149 case 0xfaULL: /* AP */ goto unimplemented;
15150 case 0xfbULL: /* SP */ goto unimplemented;
15151 case 0xfcULL: /* MP */ goto unimplemented;
15152 case 0xfdULL: /* DP */ goto unimplemented;
15153 }
15154
15155 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
15156 case 0xe500ULL: /* LASP */ goto unimplemented;
15157 case 0xe501ULL: /* TPROT */ goto unimplemented;
15158 case 0xe502ULL: /* STRAG */ goto unimplemented;
15159 case 0xe50eULL: /* MVCSK */ goto unimplemented;
15160 case 0xe50fULL: /* MVCDK */ goto unimplemented;
15161 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
15162 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15163 goto ok;
15164 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
15165 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15166 goto ok;
15167 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
15168 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15169 goto ok;
15170 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
15171 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15172 goto ok;
15173 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
15174 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15175 goto ok;
15176 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
15177 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15178 goto ok;
15179 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
15180 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15181 goto ok;
15182 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
15183 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15184 goto ok;
15185 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
15186 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15187 goto ok;
florian2289cd42012-12-05 04:23:42 +000015188 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
15189 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015190 }
15191
15192 return S390_DECODE_UNKNOWN_INSN;
15193
15194ok:
15195 return S390_DECODE_OK;
15196
15197unimplemented:
15198 return S390_DECODE_UNIMPLEMENTED_INSN;
15199}
15200
15201/* Handle "special" instructions. */
15202static s390_decode_t
15203s390_decode_special_and_irgen(UChar *bytes)
15204{
15205 s390_decode_t status = S390_DECODE_OK;
15206
15207 /* Got a "Special" instruction preamble. Which one is it? */
15208 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
15209 s390_irgen_client_request();
15210 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
15211 s390_irgen_guest_NRADDR();
15212 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
15213 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000015214 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
15215 vex_inject_ir(irsb, Iend_BE);
15216
15217 /* Invalidate the current insn. The reason is that the IRop we're
15218 injecting here can change. In which case the translation has to
15219 be redone. For ease of handling, we simply invalidate all the
15220 time. */
15221 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
15222 mkU64(guest_IA_curr_instr)));
15223 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
15224 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
15225 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
15226 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
15227
15228 put_IA(mkaddr_expr(guest_IA_next_instr));
15229 dis_res->whatNext = Dis_StopHere;
15230 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000015231 } else {
15232 /* We don't know what it is. */
15233 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
15234 }
15235
15236 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15237
15238 return status;
15239}
15240
15241
15242/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000015243static UInt
sewardj2019a972011-03-07 16:04:07 +000015244s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
15245{
15246 s390_decode_t status;
15247
15248 dis_res = dres;
15249
15250 /* Spot the 8-byte preamble: 18ff lr r15,r15
15251 1811 lr r1,r1
15252 1822 lr r2,r2
15253 1833 lr r3,r3 */
15254 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
15255 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
15256 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
15257
15258 /* Handle special instruction that follows that preamble. */
15259 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000015260
15261 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15262 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15263
15264 status =
15265 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000015266 } else {
15267 /* Handle normal instructions. */
15268 switch (insn_length) {
15269 case 2:
15270 status = s390_decode_2byte_and_irgen(bytes);
15271 break;
15272
15273 case 4:
15274 status = s390_decode_4byte_and_irgen(bytes);
15275 break;
15276
15277 case 6:
15278 status = s390_decode_6byte_and_irgen(bytes);
15279 break;
15280
15281 default:
15282 status = S390_DECODE_ERROR;
15283 break;
15284 }
15285 }
florian5fcbba22011-07-27 20:40:22 +000015286 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000015287 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
15288 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000015289 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000015290 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000015291 }
15292
15293 if (status == S390_DECODE_OK) return insn_length; /* OK */
15294
15295 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000015296 if (sigill_diag) {
15297 vex_printf("vex s390->IR: ");
15298 switch (status) {
15299 case S390_DECODE_UNKNOWN_INSN:
15300 vex_printf("unknown insn: ");
15301 break;
sewardj2019a972011-03-07 16:04:07 +000015302
sewardj442e51a2012-12-06 18:08:04 +000015303 case S390_DECODE_UNIMPLEMENTED_INSN:
15304 vex_printf("unimplemented insn: ");
15305 break;
sewardj2019a972011-03-07 16:04:07 +000015306
sewardj442e51a2012-12-06 18:08:04 +000015307 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
15308 vex_printf("unimplemented special insn: ");
15309 break;
sewardj2019a972011-03-07 16:04:07 +000015310
sewardj442e51a2012-12-06 18:08:04 +000015311 default:
15312 case S390_DECODE_ERROR:
15313 vex_printf("decoding error: ");
15314 break;
15315 }
15316
15317 vex_printf("%02x%02x", bytes[0], bytes[1]);
15318 if (insn_length > 2) {
15319 vex_printf(" %02x%02x", bytes[2], bytes[3]);
15320 }
15321 if (insn_length > 4) {
15322 vex_printf(" %02x%02x", bytes[4], bytes[5]);
15323 }
15324 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000015325 }
15326
sewardj2019a972011-03-07 16:04:07 +000015327 return 0; /* Failed */
15328}
15329
15330
sewardj2019a972011-03-07 16:04:07 +000015331/* Disassemble a single instruction INSN into IR. */
15332static DisResult
florian420c5012011-07-22 02:12:28 +000015333disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000015334{
15335 UChar byte;
15336 UInt insn_length;
15337 DisResult dres;
15338
15339 /* ---------------------------------------------------- */
15340 /* --- Compute instruction length -- */
15341 /* ---------------------------------------------------- */
15342
15343 /* Get the first byte of the insn. */
15344 byte = insn[0];
15345
15346 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
15347 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
15348 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
15349
15350 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15351
15352 /* ---------------------------------------------------- */
15353 /* --- Initialise the DisResult data -- */
15354 /* ---------------------------------------------------- */
15355 dres.whatNext = Dis_Continue;
15356 dres.len = insn_length;
15357 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000015358 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000015359
floriana99f20e2011-07-17 14:16:41 +000015360 /* fixs390: consider chasing of conditional jumps */
15361
sewardj2019a972011-03-07 16:04:07 +000015362 /* Normal and special instruction handling starts here. */
15363 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
15364 /* All decode failures end up here. The decoder has already issued an
15365 error message.
15366 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000015367 not been executed, and (is currently) the next to be executed.
15368 The insn address in the guest state needs to be set to
15369 guest_IA_curr_instr, otherwise the complaint will report an
15370 incorrect address. */
15371 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000015372
florian8844a632012-04-13 04:04:06 +000015373 dres.whatNext = Dis_StopHere;
15374 dres.jk_StopHere = Ijk_NoDecode;
15375 dres.continueAt = 0;
15376 dres.len = 0;
15377 } else {
15378 /* Decode success */
15379 switch (dres.whatNext) {
15380 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015381 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015382 break;
15383 case Dis_ResteerU:
15384 case Dis_ResteerC:
15385 put_IA(mkaddr_expr(dres.continueAt));
15386 break;
15387 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000015388 if (dres.jk_StopHere == Ijk_EmWarn ||
15389 dres.jk_StopHere == Ijk_EmFail) {
15390 /* We assume here, that emulation warnings are not given for
15391 insns that transfer control. There is no good way to
15392 do that. */
15393 put_IA(mkaddr_expr(guest_IA_next_instr));
15394 }
florian8844a632012-04-13 04:04:06 +000015395 break;
15396 default:
15397 vassert(0);
15398 }
sewardj2019a972011-03-07 16:04:07 +000015399 }
15400
15401 return dres;
15402}
15403
15404
15405/*------------------------------------------------------------*/
15406/*--- Top-level fn ---*/
15407/*------------------------------------------------------------*/
15408
15409/* Disassemble a single instruction into IR. The instruction
15410 is located in host memory at &guest_code[delta]. */
15411
15412DisResult
15413disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015414 Bool (*resteerOkFn)(void *, Addr64),
15415 Bool resteerCisOk,
15416 void *callback_opaque,
15417 UChar *guest_code,
15418 Long delta,
15419 Addr64 guest_IP,
15420 VexArch guest_arch,
15421 VexArchInfo *archinfo,
15422 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000015423 Bool host_bigendian,
15424 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000015425{
15426 vassert(guest_arch == VexArchS390X);
15427
15428 /* The instruction decoder requires a big-endian machine. */
15429 vassert(host_bigendian == True);
15430
15431 /* Set globals (see top of this file) */
15432 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015433 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015434 resteer_fn = resteerOkFn;
15435 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000015436 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000015437
florian420c5012011-07-22 02:12:28 +000015438 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015439}
15440
15441/*---------------------------------------------------------------*/
15442/*--- end guest_s390_toIR.c ---*/
15443/*---------------------------------------------------------------*/