blob: b013e192bdc6e90a431d2ebf4d23c3c09a51bcae [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
florian99dd03e2013-01-29 03:56:06 +0000243 return IRExpr_ITE(condition, iftrue, iffalse);
sewardj2019a972011-03-07 16:04:07 +0000244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
635 op = mkU64(opc);
636 dep1 = mkexpr(d1);
637 dep2 = mkU64(0);
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, dep1, dep2, ndep);
641}
642
643
644/* Write a floating point value and an integer into the flags thunk. The
645 integer value is zero-extended first. */
646static void
647s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
648{
649 IRExpr *op, *dep1, *dep2, *ndep;
650
651 op = mkU64(opc);
652 dep1 = mkexpr(d1);
653 dep2 = s390_cc_widen(d2, False);
654 ndep = mkU64(0);
655
656 s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a 128-bit floating point value into the flags thunk. This is
661 done by splitting the value into two 64-bits values. */
662static void
663s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
664{
665 IRExpr *op, *hi, *lo, *ndep;
666
667 op = mkU64(opc);
668 hi = unop(Iop_F128HItoF64, mkexpr(d1));
669 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, hi, lo, ndep);
673}
674
675
676/* Write a 128-bit floating point value and an integer into the flags thunk.
677 The integer value is zero-extended first. */
678static void
679s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
680{
681 IRExpr *op, *hi, *lo, *lox, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
686 ndep = s390_cc_widen(nd, False);
687
688 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
689
690 s390_cc_thunk_fill(op, hi, lox, ndep);
691}
692
693
floriane38f6412012-12-21 17:32:12 +0000694/* Write a 128-bit decimal floating point value into the flags thunk.
695 This is done by splitting the value into two 64-bits values. */
696static void
697s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
698{
699 IRExpr *op, *hi, *lo, *ndep;
700
701 op = mkU64(opc);
702 hi = unop(Iop_D128HItoD64, mkexpr(d1));
703 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
704 ndep = mkU64(0);
705
706 s390_cc_thunk_fill(op, hi, lo, ndep);
707}
708
709
floriance9e3db2012-12-27 20:14:03 +0000710/* Write a 128-bit decimal floating point value and an integer into the flags
711 thunk. The integer value is zero-extended first. */
712static void
713s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
714{
715 IRExpr *op, *hi, *lo, *lox, *ndep;
716
717 op = mkU64(opc);
718 hi = unop(Iop_D128HItoD64, mkexpr(d1));
719 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
720 ndep = s390_cc_widen(nd, False);
721
722 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
723
724 s390_cc_thunk_fill(op, hi, lox, ndep);
725}
726
727
sewardj2019a972011-03-07 16:04:07 +0000728static void
729s390_cc_set(UInt val)
730{
731 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
732 mkU64(val), mkU64(0), mkU64(0));
733}
734
735/* Build IR to calculate the condition code from flags thunk.
736 Returns an expression of type Ity_I32 */
737static IRExpr *
738s390_call_calculate_cc(void)
739{
740 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
741
florian428dfdd2012-03-27 03:09:49 +0000742 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
743 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
744 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
745 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000746
747 args = mkIRExprVec_4(op, dep1, dep2, ndep);
748 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
749 "s390_calculate_cc", &s390_calculate_cc, args);
750
751 /* Exclude OP and NDEP from definedness checking. We're only
752 interested in DEP1 and DEP2. */
753 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
754
755 return call;
756}
757
758/* Build IR to calculate the internal condition code for a "compare and branch"
759 insn. Returns an expression of type Ity_I32 */
760static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000761s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000762{
florianff9613f2012-05-12 15:26:44 +0000763 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000764
florianff9613f2012-05-12 15:26:44 +0000765 switch (opc) {
766 case S390_CC_OP_SIGNED_COMPARE:
767 dep1 = s390_cc_widen(op1, True);
768 dep2 = s390_cc_widen(op2, True);
769 break;
770
771 case S390_CC_OP_UNSIGNED_COMPARE:
772 dep1 = s390_cc_widen(op1, False);
773 dep2 = s390_cc_widen(op2, False);
774 break;
775
776 default:
777 vpanic("s390_call_calculate_icc");
778 }
779
780 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000781 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000782
florianff9613f2012-05-12 15:26:44 +0000783 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000784 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000785 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000786
florianff9613f2012-05-12 15:26:44 +0000787 /* Exclude the requested condition, OP and NDEP from definedness
788 checking. We're only interested in DEP1 and DEP2. */
789 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000790
791 return call;
792}
793
794/* Build IR to calculate the condition code from flags thunk.
795 Returns an expression of type Ity_I32 */
796static IRExpr *
797s390_call_calculate_cond(UInt m)
798{
799 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
800
801 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000802 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
803 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
804 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
805 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000806
807 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
808 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
809 "s390_calculate_cond", &s390_calculate_cond, args);
810
811 /* Exclude the requested condition, OP and NDEP from definedness
812 checking. We're only interested in DEP1 and DEP2. */
813 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
814
815 return call;
816}
817
818#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
819#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
820#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
821#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
822#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
823#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
824#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
825 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
826#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
827 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000828
829
sewardj2019a972011-03-07 16:04:07 +0000830
831
832/*------------------------------------------------------------*/
833/*--- Guest register access ---*/
834/*------------------------------------------------------------*/
835
836
837/*------------------------------------------------------------*/
838/*--- ar registers ---*/
839/*------------------------------------------------------------*/
840
841/* Return the guest state offset of a ar register. */
842static UInt
843ar_offset(UInt archreg)
844{
845 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000846 S390X_GUEST_OFFSET(guest_a0),
847 S390X_GUEST_OFFSET(guest_a1),
848 S390X_GUEST_OFFSET(guest_a2),
849 S390X_GUEST_OFFSET(guest_a3),
850 S390X_GUEST_OFFSET(guest_a4),
851 S390X_GUEST_OFFSET(guest_a5),
852 S390X_GUEST_OFFSET(guest_a6),
853 S390X_GUEST_OFFSET(guest_a7),
854 S390X_GUEST_OFFSET(guest_a8),
855 S390X_GUEST_OFFSET(guest_a9),
856 S390X_GUEST_OFFSET(guest_a10),
857 S390X_GUEST_OFFSET(guest_a11),
858 S390X_GUEST_OFFSET(guest_a12),
859 S390X_GUEST_OFFSET(guest_a13),
860 S390X_GUEST_OFFSET(guest_a14),
861 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000862 };
863
864 vassert(archreg < 16);
865
866 return offset[archreg];
867}
868
869
870/* Return the guest state offset of word #0 of a ar register. */
871static __inline__ UInt
872ar_w0_offset(UInt archreg)
873{
874 return ar_offset(archreg) + 0;
875}
876
877/* Write word #0 of a ar to the guest state. */
878static __inline__ void
879put_ar_w0(UInt archreg, IRExpr *expr)
880{
881 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
882
883 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
884}
885
886/* Read word #0 of a ar register. */
887static __inline__ IRExpr *
888get_ar_w0(UInt archreg)
889{
890 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
891}
892
893
894/*------------------------------------------------------------*/
895/*--- fpr registers ---*/
896/*------------------------------------------------------------*/
897
898/* Return the guest state offset of a fpr register. */
899static UInt
900fpr_offset(UInt archreg)
901{
902 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000903 S390X_GUEST_OFFSET(guest_f0),
904 S390X_GUEST_OFFSET(guest_f1),
905 S390X_GUEST_OFFSET(guest_f2),
906 S390X_GUEST_OFFSET(guest_f3),
907 S390X_GUEST_OFFSET(guest_f4),
908 S390X_GUEST_OFFSET(guest_f5),
909 S390X_GUEST_OFFSET(guest_f6),
910 S390X_GUEST_OFFSET(guest_f7),
911 S390X_GUEST_OFFSET(guest_f8),
912 S390X_GUEST_OFFSET(guest_f9),
913 S390X_GUEST_OFFSET(guest_f10),
914 S390X_GUEST_OFFSET(guest_f11),
915 S390X_GUEST_OFFSET(guest_f12),
916 S390X_GUEST_OFFSET(guest_f13),
917 S390X_GUEST_OFFSET(guest_f14),
918 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000919 };
920
921 vassert(archreg < 16);
922
923 return offset[archreg];
924}
925
926
927/* Return the guest state offset of word #0 of a fpr register. */
928static __inline__ UInt
929fpr_w0_offset(UInt archreg)
930{
931 return fpr_offset(archreg) + 0;
932}
933
934/* Write word #0 of a fpr to the guest state. */
935static __inline__ void
936put_fpr_w0(UInt archreg, IRExpr *expr)
937{
938 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
939
940 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
941}
942
943/* Read word #0 of a fpr register. */
944static __inline__ IRExpr *
945get_fpr_w0(UInt archreg)
946{
947 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
948}
949
950/* Return the guest state offset of double word #0 of a fpr register. */
951static __inline__ UInt
952fpr_dw0_offset(UInt archreg)
953{
954 return fpr_offset(archreg) + 0;
955}
956
957/* Write double word #0 of a fpr to the guest state. */
958static __inline__ void
959put_fpr_dw0(UInt archreg, IRExpr *expr)
960{
961 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
962
963 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
964}
965
966/* Read double word #0 of a fpr register. */
967static __inline__ IRExpr *
968get_fpr_dw0(UInt archreg)
969{
970 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
971}
972
floriane38f6412012-12-21 17:32:12 +0000973/* Write word #0 of a dpr to the guest state. */
974static __inline__ void
975put_dpr_w0(UInt archreg, IRExpr *expr)
976{
977 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
978
979 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
980}
981
982/* Read word #0 of a dpr register. */
983static __inline__ IRExpr *
984get_dpr_w0(UInt archreg)
985{
986 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
987}
988
florian12390202012-11-10 22:34:14 +0000989/* Write double word #0 of a fpr containg DFP value to the guest state. */
990static __inline__ void
991put_dpr_dw0(UInt archreg, IRExpr *expr)
992{
993 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
994
995 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
996}
997
998/* Read double word #0 of a fpr register containing DFP value. */
999static __inline__ IRExpr *
1000get_dpr_dw0(UInt archreg)
1001{
1002 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1003}
sewardj2019a972011-03-07 16:04:07 +00001004
1005/*------------------------------------------------------------*/
1006/*--- gpr registers ---*/
1007/*------------------------------------------------------------*/
1008
1009/* Return the guest state offset of a gpr register. */
1010static UInt
1011gpr_offset(UInt archreg)
1012{
1013 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001014 S390X_GUEST_OFFSET(guest_r0),
1015 S390X_GUEST_OFFSET(guest_r1),
1016 S390X_GUEST_OFFSET(guest_r2),
1017 S390X_GUEST_OFFSET(guest_r3),
1018 S390X_GUEST_OFFSET(guest_r4),
1019 S390X_GUEST_OFFSET(guest_r5),
1020 S390X_GUEST_OFFSET(guest_r6),
1021 S390X_GUEST_OFFSET(guest_r7),
1022 S390X_GUEST_OFFSET(guest_r8),
1023 S390X_GUEST_OFFSET(guest_r9),
1024 S390X_GUEST_OFFSET(guest_r10),
1025 S390X_GUEST_OFFSET(guest_r11),
1026 S390X_GUEST_OFFSET(guest_r12),
1027 S390X_GUEST_OFFSET(guest_r13),
1028 S390X_GUEST_OFFSET(guest_r14),
1029 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001030 };
1031
1032 vassert(archreg < 16);
1033
1034 return offset[archreg];
1035}
1036
1037
1038/* Return the guest state offset of word #0 of a gpr register. */
1039static __inline__ UInt
1040gpr_w0_offset(UInt archreg)
1041{
1042 return gpr_offset(archreg) + 0;
1043}
1044
1045/* Write word #0 of a gpr to the guest state. */
1046static __inline__ void
1047put_gpr_w0(UInt archreg, IRExpr *expr)
1048{
1049 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1050
1051 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1052}
1053
1054/* Read word #0 of a gpr register. */
1055static __inline__ IRExpr *
1056get_gpr_w0(UInt archreg)
1057{
1058 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1059}
1060
1061/* Return the guest state offset of double word #0 of a gpr register. */
1062static __inline__ UInt
1063gpr_dw0_offset(UInt archreg)
1064{
1065 return gpr_offset(archreg) + 0;
1066}
1067
1068/* Write double word #0 of a gpr to the guest state. */
1069static __inline__ void
1070put_gpr_dw0(UInt archreg, IRExpr *expr)
1071{
1072 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1073
1074 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1075}
1076
1077/* Read double word #0 of a gpr register. */
1078static __inline__ IRExpr *
1079get_gpr_dw0(UInt archreg)
1080{
1081 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1082}
1083
1084/* Return the guest state offset of half word #1 of a gpr register. */
1085static __inline__ UInt
1086gpr_hw1_offset(UInt archreg)
1087{
1088 return gpr_offset(archreg) + 2;
1089}
1090
1091/* Write half word #1 of a gpr to the guest state. */
1092static __inline__ void
1093put_gpr_hw1(UInt archreg, IRExpr *expr)
1094{
1095 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1096
1097 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1098}
1099
1100/* Read half word #1 of a gpr register. */
1101static __inline__ IRExpr *
1102get_gpr_hw1(UInt archreg)
1103{
1104 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1105}
1106
1107/* Return the guest state offset of byte #6 of a gpr register. */
1108static __inline__ UInt
1109gpr_b6_offset(UInt archreg)
1110{
1111 return gpr_offset(archreg) + 6;
1112}
1113
1114/* Write byte #6 of a gpr to the guest state. */
1115static __inline__ void
1116put_gpr_b6(UInt archreg, IRExpr *expr)
1117{
1118 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1119
1120 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1121}
1122
1123/* Read byte #6 of a gpr register. */
1124static __inline__ IRExpr *
1125get_gpr_b6(UInt archreg)
1126{
1127 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1128}
1129
1130/* Return the guest state offset of byte #3 of a gpr register. */
1131static __inline__ UInt
1132gpr_b3_offset(UInt archreg)
1133{
1134 return gpr_offset(archreg) + 3;
1135}
1136
1137/* Write byte #3 of a gpr to the guest state. */
1138static __inline__ void
1139put_gpr_b3(UInt archreg, IRExpr *expr)
1140{
1141 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1142
1143 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1144}
1145
1146/* Read byte #3 of a gpr register. */
1147static __inline__ IRExpr *
1148get_gpr_b3(UInt archreg)
1149{
1150 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1151}
1152
1153/* Return the guest state offset of byte #0 of a gpr register. */
1154static __inline__ UInt
1155gpr_b0_offset(UInt archreg)
1156{
1157 return gpr_offset(archreg) + 0;
1158}
1159
1160/* Write byte #0 of a gpr to the guest state. */
1161static __inline__ void
1162put_gpr_b0(UInt archreg, IRExpr *expr)
1163{
1164 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1165
1166 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1167}
1168
1169/* Read byte #0 of a gpr register. */
1170static __inline__ IRExpr *
1171get_gpr_b0(UInt archreg)
1172{
1173 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1174}
1175
1176/* Return the guest state offset of word #1 of a gpr register. */
1177static __inline__ UInt
1178gpr_w1_offset(UInt archreg)
1179{
1180 return gpr_offset(archreg) + 4;
1181}
1182
1183/* Write word #1 of a gpr to the guest state. */
1184static __inline__ void
1185put_gpr_w1(UInt archreg, IRExpr *expr)
1186{
1187 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1188
1189 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1190}
1191
1192/* Read word #1 of a gpr register. */
1193static __inline__ IRExpr *
1194get_gpr_w1(UInt archreg)
1195{
1196 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1197}
1198
1199/* Return the guest state offset of half word #3 of a gpr register. */
1200static __inline__ UInt
1201gpr_hw3_offset(UInt archreg)
1202{
1203 return gpr_offset(archreg) + 6;
1204}
1205
1206/* Write half word #3 of a gpr to the guest state. */
1207static __inline__ void
1208put_gpr_hw3(UInt archreg, IRExpr *expr)
1209{
1210 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1211
1212 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1213}
1214
1215/* Read half word #3 of a gpr register. */
1216static __inline__ IRExpr *
1217get_gpr_hw3(UInt archreg)
1218{
1219 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1220}
1221
1222/* Return the guest state offset of byte #7 of a gpr register. */
1223static __inline__ UInt
1224gpr_b7_offset(UInt archreg)
1225{
1226 return gpr_offset(archreg) + 7;
1227}
1228
1229/* Write byte #7 of a gpr to the guest state. */
1230static __inline__ void
1231put_gpr_b7(UInt archreg, IRExpr *expr)
1232{
1233 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1234
1235 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1236}
1237
1238/* Read byte #7 of a gpr register. */
1239static __inline__ IRExpr *
1240get_gpr_b7(UInt archreg)
1241{
1242 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1243}
1244
1245/* Return the guest state offset of half word #0 of a gpr register. */
1246static __inline__ UInt
1247gpr_hw0_offset(UInt archreg)
1248{
1249 return gpr_offset(archreg) + 0;
1250}
1251
1252/* Write half word #0 of a gpr to the guest state. */
1253static __inline__ void
1254put_gpr_hw0(UInt archreg, IRExpr *expr)
1255{
1256 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1257
1258 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1259}
1260
1261/* Read half word #0 of a gpr register. */
1262static __inline__ IRExpr *
1263get_gpr_hw0(UInt archreg)
1264{
1265 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1266}
1267
1268/* Return the guest state offset of byte #4 of a gpr register. */
1269static __inline__ UInt
1270gpr_b4_offset(UInt archreg)
1271{
1272 return gpr_offset(archreg) + 4;
1273}
1274
1275/* Write byte #4 of a gpr to the guest state. */
1276static __inline__ void
1277put_gpr_b4(UInt archreg, IRExpr *expr)
1278{
1279 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1280
1281 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1282}
1283
1284/* Read byte #4 of a gpr register. */
1285static __inline__ IRExpr *
1286get_gpr_b4(UInt archreg)
1287{
1288 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1289}
1290
1291/* Return the guest state offset of byte #1 of a gpr register. */
1292static __inline__ UInt
1293gpr_b1_offset(UInt archreg)
1294{
1295 return gpr_offset(archreg) + 1;
1296}
1297
1298/* Write byte #1 of a gpr to the guest state. */
1299static __inline__ void
1300put_gpr_b1(UInt archreg, IRExpr *expr)
1301{
1302 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1303
1304 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1305}
1306
1307/* Read byte #1 of a gpr register. */
1308static __inline__ IRExpr *
1309get_gpr_b1(UInt archreg)
1310{
1311 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1312}
1313
1314/* Return the guest state offset of half word #2 of a gpr register. */
1315static __inline__ UInt
1316gpr_hw2_offset(UInt archreg)
1317{
1318 return gpr_offset(archreg) + 4;
1319}
1320
1321/* Write half word #2 of a gpr to the guest state. */
1322static __inline__ void
1323put_gpr_hw2(UInt archreg, IRExpr *expr)
1324{
1325 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1326
1327 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1328}
1329
1330/* Read half word #2 of a gpr register. */
1331static __inline__ IRExpr *
1332get_gpr_hw2(UInt archreg)
1333{
1334 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1335}
1336
1337/* Return the guest state offset of byte #5 of a gpr register. */
1338static __inline__ UInt
1339gpr_b5_offset(UInt archreg)
1340{
1341 return gpr_offset(archreg) + 5;
1342}
1343
1344/* Write byte #5 of a gpr to the guest state. */
1345static __inline__ void
1346put_gpr_b5(UInt archreg, IRExpr *expr)
1347{
1348 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1349
1350 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1351}
1352
1353/* Read byte #5 of a gpr register. */
1354static __inline__ IRExpr *
1355get_gpr_b5(UInt archreg)
1356{
1357 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1358}
1359
1360/* Return the guest state offset of byte #2 of a gpr register. */
1361static __inline__ UInt
1362gpr_b2_offset(UInt archreg)
1363{
1364 return gpr_offset(archreg) + 2;
1365}
1366
1367/* Write byte #2 of a gpr to the guest state. */
1368static __inline__ void
1369put_gpr_b2(UInt archreg, IRExpr *expr)
1370{
1371 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1372
1373 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1374}
1375
1376/* Read byte #2 of a gpr register. */
1377static __inline__ IRExpr *
1378get_gpr_b2(UInt archreg)
1379{
1380 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1381}
1382
1383/* Return the guest state offset of the counter register. */
1384static UInt
1385counter_offset(void)
1386{
floriane88b3c92011-07-05 02:48:39 +00001387 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001388}
1389
1390/* Return the guest state offset of double word #0 of the counter register. */
1391static __inline__ UInt
1392counter_dw0_offset(void)
1393{
1394 return counter_offset() + 0;
1395}
1396
1397/* Write double word #0 of the counter to the guest state. */
1398static __inline__ void
1399put_counter_dw0(IRExpr *expr)
1400{
1401 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1402
1403 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1404}
1405
1406/* Read double word #0 of the counter register. */
1407static __inline__ IRExpr *
1408get_counter_dw0(void)
1409{
1410 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1411}
1412
1413/* Return the guest state offset of word #0 of the counter register. */
1414static __inline__ UInt
1415counter_w0_offset(void)
1416{
1417 return counter_offset() + 0;
1418}
1419
1420/* Return the guest state offset of word #1 of the counter register. */
1421static __inline__ UInt
1422counter_w1_offset(void)
1423{
1424 return counter_offset() + 4;
1425}
1426
1427/* Write word #0 of the counter to the guest state. */
1428static __inline__ void
1429put_counter_w0(IRExpr *expr)
1430{
1431 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1432
1433 stmt(IRStmt_Put(counter_w0_offset(), expr));
1434}
1435
1436/* Read word #0 of the counter register. */
1437static __inline__ IRExpr *
1438get_counter_w0(void)
1439{
1440 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1441}
1442
1443/* Write word #1 of the counter to the guest state. */
1444static __inline__ void
1445put_counter_w1(IRExpr *expr)
1446{
1447 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1448
1449 stmt(IRStmt_Put(counter_w1_offset(), expr));
1450}
1451
1452/* Read word #1 of the counter register. */
1453static __inline__ IRExpr *
1454get_counter_w1(void)
1455{
1456 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1457}
1458
1459/* Return the guest state offset of the fpc register. */
1460static UInt
1461fpc_offset(void)
1462{
floriane88b3c92011-07-05 02:48:39 +00001463 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001464}
1465
1466/* Return the guest state offset of word #0 of the fpc register. */
1467static __inline__ UInt
1468fpc_w0_offset(void)
1469{
1470 return fpc_offset() + 0;
1471}
1472
1473/* Write word #0 of the fpc to the guest state. */
1474static __inline__ void
1475put_fpc_w0(IRExpr *expr)
1476{
1477 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1478
1479 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1480}
1481
1482/* Read word #0 of the fpc register. */
1483static __inline__ IRExpr *
1484get_fpc_w0(void)
1485{
1486 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1487}
1488
1489
1490/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001491/*--- Rounding modes ---*/
1492/*------------------------------------------------------------*/
1493
florian125e20d2012-10-07 15:42:37 +00001494/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001495 IRRoundingMode:
1496
1497 rounding mode | s390 | IR
1498 -------------------------
1499 to nearest | 00 | 00
1500 to zero | 01 | 11
1501 to +infinity | 10 | 10
1502 to -infinity | 11 | 01
1503
1504 So: IR = (4 - s390) & 3
1505*/
1506static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001507get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001508{
1509 IRTemp fpc_bits = newTemp(Ity_I32);
1510
1511 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1512 Prior to that bits [30:31] contained the bfp rounding mode with
1513 bit 29 being unused and having a value of 0. So we can always
1514 extract the least significant 3 bits. */
1515 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1516
1517 /* fixs390:
1518
1519
1520 if (! s390_host_has_fpext && rounding_mode > 3) {
1521 emulation warning @ runtime and
1522 set fpc to round nearest
1523 }
1524 */
1525
1526 /* For now silently adjust an unsupported rounding mode to "nearest" */
1527 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1528 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001529 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001530
1531 // rm_IR = (4 - rm_s390) & 3;
1532 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1533}
1534
1535/* Encode the s390 rounding mode as it appears in the m3 field of certain
1536 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1537 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1538 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1539 considers the default rounding mode (4.3.3). */
1540static IRTemp
1541encode_bfp_rounding_mode(UChar mode)
1542{
1543 IRExpr *rm;
1544
1545 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001546 case S390_BFP_ROUND_PER_FPC:
1547 rm = get_bfp_rounding_mode_from_fpc();
1548 break;
1549 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1550 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1551 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1552 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1553 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1554 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001555 default:
1556 vpanic("encode_bfp_rounding_mode");
1557 }
1558
1559 return mktemp(Ity_I32, rm);
1560}
1561
florianc8e4f562012-10-27 16:19:31 +00001562/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1563 IRRoundingMode:
1564
1565 rounding mode | s390 | IR
1566 ------------------------------------------------
1567 to nearest, ties to even | 000 | 000
1568 to zero | 001 | 011
1569 to +infinity | 010 | 010
1570 to -infinity | 011 | 001
1571 to nearest, ties away from 0 | 100 | 100
1572 to nearest, ties toward 0 | 101 | 111
1573 to away from 0 | 110 | 110
1574 to prepare for shorter precision | 111 | 101
1575
1576 So: IR = (s390 ^ ((s390 << 1) & 2))
1577*/
florianc8e4f562012-10-27 16:19:31 +00001578static IRExpr *
1579get_dfp_rounding_mode_from_fpc(void)
1580{
1581 IRTemp fpc_bits = newTemp(Ity_I32);
1582
1583 /* The dfp rounding mode is stored in bits [25:27].
1584 extract the bits at 25:27 and right shift 4 times. */
1585 assign(fpc_bits, binop(Iop_Shr32,
1586 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1587 mkU8(4)));
1588
1589 IRExpr *rm_s390 = mkexpr(fpc_bits);
1590 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1591
1592 return binop(Iop_Xor32, rm_s390,
1593 binop( Iop_And32,
1594 binop(Iop_Shl32, rm_s390, mkU8(1)),
1595 mkU32(2)));
1596}
1597
1598/* Encode the s390 rounding mode as it appears in the m3 field of certain
1599 instructions to VEX's IRRoundingMode. */
1600static IRTemp
1601encode_dfp_rounding_mode(UChar mode)
1602{
1603 IRExpr *rm;
1604
1605 switch (mode) {
1606 case S390_DFP_ROUND_PER_FPC_0:
1607 case S390_DFP_ROUND_PER_FPC_2:
1608 rm = get_dfp_rounding_mode_from_fpc(); break;
1609 case S390_DFP_ROUND_NEAREST_EVEN_4:
1610 case S390_DFP_ROUND_NEAREST_EVEN_8:
1611 rm = mkU32(Irrm_DFP_NEAREST); break;
1612 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1613 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1614 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1615 case S390_DFP_ROUND_PREPARE_SHORT_3:
1616 case S390_DFP_ROUND_PREPARE_SHORT_15:
1617 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1618 case S390_DFP_ROUND_ZERO_5:
1619 case S390_DFP_ROUND_ZERO_9:
1620 rm = mkU32(Irrm_DFP_ZERO ); break;
1621 case S390_DFP_ROUND_POSINF_6:
1622 case S390_DFP_ROUND_POSINF_10:
1623 rm = mkU32(Irrm_DFP_PosINF); break;
1624 case S390_DFP_ROUND_NEGINF_7:
1625 case S390_DFP_ROUND_NEGINF_11:
1626 rm = mkU32(Irrm_DFP_NegINF); break;
1627 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1628 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1629 case S390_DFP_ROUND_AWAY_0:
1630 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1631 default:
1632 vpanic("encode_dfp_rounding_mode");
1633 }
1634
1635 return mktemp(Ity_I32, rm);
1636}
florian12390202012-11-10 22:34:14 +00001637
florianc8e4f562012-10-27 16:19:31 +00001638
florian2c74d242012-09-12 19:38:42 +00001639/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001640/*--- Condition code helpers ---*/
1641/*------------------------------------------------------------*/
1642
1643/* The result of a Iop_CmpFxx operation is a condition code. It is
1644 encoded using the values defined in type IRCmpFxxResult.
1645 Before we can store the condition code into the guest state (or do
1646 anything else with it for that matter) we need to convert it to
1647 the encoding that s390 uses. This is what this function does.
1648
1649 s390 VEX b6 b2 b0 cc.1 cc.0
1650 0 0x40 EQ 1 0 0 0 0
1651 1 0x01 LT 0 0 1 0 1
1652 2 0x00 GT 0 0 0 1 0
1653 3 0x45 Unordered 1 1 1 1 1
1654
1655 The following bits from the VEX encoding are interesting:
1656 b0, b2, b6 with b0 being the LSB. We observe:
1657
1658 cc.0 = b0;
1659 cc.1 = b2 | (~b0 & ~b6)
1660
1661 with cc being the s390 condition code.
1662*/
1663static IRExpr *
1664convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1665{
1666 IRTemp cc0 = newTemp(Ity_I32);
1667 IRTemp cc1 = newTemp(Ity_I32);
1668 IRTemp b0 = newTemp(Ity_I32);
1669 IRTemp b2 = newTemp(Ity_I32);
1670 IRTemp b6 = newTemp(Ity_I32);
1671
1672 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1673 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1674 mkU32(1)));
1675 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1676 mkU32(1)));
1677
1678 assign(cc0, mkexpr(b0));
1679 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1680 binop(Iop_And32,
1681 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1682 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1683 )));
1684
1685 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1686}
1687
1688
1689/* The result of a Iop_CmpDxx operation is a condition code. It is
1690 encoded using the values defined in type IRCmpDxxResult.
1691 Before we can store the condition code into the guest state (or do
1692 anything else with it for that matter) we need to convert it to
1693 the encoding that s390 uses. This is what this function does. */
1694static IRExpr *
1695convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1696{
1697 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1698 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001699 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001700}
1701
1702
1703/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001704/*--- Build IR for formats ---*/
1705/*------------------------------------------------------------*/
1706static void
florian55085f82012-11-21 00:36:55 +00001707s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001708 UChar i)
1709{
florian55085f82012-11-21 00:36:55 +00001710 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001711
sewardj7ee97522011-05-09 21:45:04 +00001712 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001713 s390_disasm(ENC2(MNM, UINT), mnm, i);
1714}
1715
1716static void
florian55085f82012-11-21 00:36:55 +00001717s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001718 UChar r1, UShort i2)
1719{
1720 irgen(r1, i2);
1721}
1722
1723static void
florian55085f82012-11-21 00:36:55 +00001724s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001725 UChar r1, UShort i2)
1726{
florian55085f82012-11-21 00:36:55 +00001727 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001728
sewardj7ee97522011-05-09 21:45:04 +00001729 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001730 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1731}
1732
1733static void
florian55085f82012-11-21 00:36:55 +00001734s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001735 UChar r1, UShort i2)
1736{
florian55085f82012-11-21 00:36:55 +00001737 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001738
sewardj7ee97522011-05-09 21:45:04 +00001739 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001740 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1741}
1742
1743static void
florian55085f82012-11-21 00:36:55 +00001744s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001745 UChar r1, UShort i2)
1746{
florian55085f82012-11-21 00:36:55 +00001747 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001748
sewardj7ee97522011-05-09 21:45:04 +00001749 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001750 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1751}
1752
1753static void
florian55085f82012-11-21 00:36:55 +00001754s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001755 UChar r1, UChar r3, UShort i2)
1756{
florian55085f82012-11-21 00:36:55 +00001757 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001758
sewardj7ee97522011-05-09 21:45:04 +00001759 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001760 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1761}
1762
1763static void
florian55085f82012-11-21 00:36:55 +00001764s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001765 UChar r1, UChar r3, UShort i2)
1766{
florian55085f82012-11-21 00:36:55 +00001767 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001768
sewardj7ee97522011-05-09 21:45:04 +00001769 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001770 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1771}
1772
1773static void
florian55085f82012-11-21 00:36:55 +00001774s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1775 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001776 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1777{
florian55085f82012-11-21 00:36:55 +00001778 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001779
sewardj7ee97522011-05-09 21:45:04 +00001780 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001781 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1782 i5);
1783}
1784
1785static void
florian55085f82012-11-21 00:36:55 +00001786s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1787 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001788 UChar r1, UChar r2, UShort i4, UChar m3)
1789{
florian55085f82012-11-21 00:36:55 +00001790 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001791
sewardj7ee97522011-05-09 21:45:04 +00001792 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001793 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1794 r2, m3, (Int)(Short)i4);
1795}
1796
1797static void
florian55085f82012-11-21 00:36:55 +00001798s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1799 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001800 UChar r1, UChar m3, UShort i4, UChar i2)
1801{
florian55085f82012-11-21 00:36:55 +00001802 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001803
sewardj7ee97522011-05-09 21:45:04 +00001804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001805 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1806 r1, i2, m3, (Int)(Short)i4);
1807}
1808
1809static void
florian55085f82012-11-21 00:36:55 +00001810s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1811 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001812 UChar r1, UChar m3, UShort i4, UChar i2)
1813{
florian55085f82012-11-21 00:36:55 +00001814 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001815
sewardj7ee97522011-05-09 21:45:04 +00001816 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001817 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1818 (Int)(Char)i2, m3, (Int)(Short)i4);
1819}
1820
1821static void
florian55085f82012-11-21 00:36:55 +00001822s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001823 UChar r1, UInt i2)
1824{
1825 irgen(r1, i2);
1826}
1827
1828static void
florian55085f82012-11-21 00:36:55 +00001829s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001830 UChar r1, UInt i2)
1831{
florian55085f82012-11-21 00:36:55 +00001832 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001833
sewardj7ee97522011-05-09 21:45:04 +00001834 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001835 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1836}
1837
1838static void
florian55085f82012-11-21 00:36:55 +00001839s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001840 UChar r1, UInt i2)
1841{
florian55085f82012-11-21 00:36:55 +00001842 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001843
sewardj7ee97522011-05-09 21:45:04 +00001844 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001845 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1846}
1847
1848static void
florian55085f82012-11-21 00:36:55 +00001849s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001850 UChar r1, UInt i2)
1851{
florian55085f82012-11-21 00:36:55 +00001852 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001853
sewardj7ee97522011-05-09 21:45:04 +00001854 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001855 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1856}
1857
1858static void
florian55085f82012-11-21 00:36:55 +00001859s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001860 UChar r1, UInt i2)
1861{
florian55085f82012-11-21 00:36:55 +00001862 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001863
sewardj7ee97522011-05-09 21:45:04 +00001864 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001865 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1866}
1867
1868static void
florian55085f82012-11-21 00:36:55 +00001869s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001870 IRTemp op4addr),
1871 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1872{
florian55085f82012-11-21 00:36:55 +00001873 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001874 IRTemp op4addr = newTemp(Ity_I64);
1875
1876 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1877 mkU64(0)));
1878
1879 mnm = irgen(r1, m3, i2, op4addr);
1880
sewardj7ee97522011-05-09 21:45:04 +00001881 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001882 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1883 (Int)(Char)i2, m3, d4, 0, b4);
1884}
1885
1886static void
florian55085f82012-11-21 00:36:55 +00001887s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001888 IRTemp op4addr),
1889 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1890{
florian55085f82012-11-21 00:36:55 +00001891 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001892 IRTemp op4addr = newTemp(Ity_I64);
1893
1894 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1895 mkU64(0)));
1896
1897 mnm = irgen(r1, m3, i2, op4addr);
1898
sewardj7ee97522011-05-09 21:45:04 +00001899 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001900 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1901 i2, m3, d4, 0, b4);
1902}
1903
1904static void
florian55085f82012-11-21 00:36:55 +00001905s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001906 UChar r1, UChar r2)
1907{
1908 irgen(r1, r2);
1909}
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001913 UChar r1, UChar r2)
1914{
florian55085f82012-11-21 00:36:55 +00001915 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001916
sewardj7ee97522011-05-09 21:45:04 +00001917 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001918 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1919}
1920
1921static void
florian55085f82012-11-21 00:36:55 +00001922s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001923 UChar r1, UChar r2)
1924{
florian55085f82012-11-21 00:36:55 +00001925 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001926
sewardj7ee97522011-05-09 21:45:04 +00001927 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001928 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1929}
1930
1931static void
florian55085f82012-11-21 00:36:55 +00001932s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001933 UChar r1, UChar r2)
1934{
1935 irgen(r1, r2);
1936}
1937
1938static void
florian55085f82012-11-21 00:36:55 +00001939s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001940 UChar r1, UChar r2)
1941{
florian55085f82012-11-21 00:36:55 +00001942 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001943
sewardj7ee97522011-05-09 21:45:04 +00001944 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001945 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1946}
1947
1948static void
florian55085f82012-11-21 00:36:55 +00001949s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001950 UChar r1, UChar r2)
1951{
florian55085f82012-11-21 00:36:55 +00001952 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001953
sewardj7ee97522011-05-09 21:45:04 +00001954 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001955 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1956}
1957
1958static void
florian55085f82012-11-21 00:36:55 +00001959s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001960 UChar r1, UChar r2)
1961{
florian55085f82012-11-21 00:36:55 +00001962 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001963
sewardj7ee97522011-05-09 21:45:04 +00001964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001965 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1966}
1967
1968static void
florian55085f82012-11-21 00:36:55 +00001969s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001970 UChar r1, UChar r2)
1971{
florian55085f82012-11-21 00:36:55 +00001972 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001973
sewardj7ee97522011-05-09 21:45:04 +00001974 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001975 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1976}
1977
1978static void
florian55085f82012-11-21 00:36:55 +00001979s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001980 UChar r1)
1981{
florian55085f82012-11-21 00:36:55 +00001982 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001983
sewardj7ee97522011-05-09 21:45:04 +00001984 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001985 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1986}
1987
1988static void
florian55085f82012-11-21 00:36:55 +00001989s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001990 UChar r1)
1991{
florian55085f82012-11-21 00:36:55 +00001992 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001993
sewardj7ee97522011-05-09 21:45:04 +00001994 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001995 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1996}
1997
1998static void
florian55085f82012-11-21 00:36:55 +00001999s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002000 UChar m3, UChar r1, UChar r2)
2001{
florian55085f82012-11-21 00:36:55 +00002002 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002003
2004 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002005 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002006}
2007
2008static void
florian55085f82012-11-21 00:36:55 +00002009s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002010 UChar r1, UChar r3, UChar r2)
2011{
florian55085f82012-11-21 00:36:55 +00002012 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002013
sewardj7ee97522011-05-09 21:45:04 +00002014 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002015 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2016}
2017
2018static void
florian5c539732013-02-14 14:27:12 +00002019s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2020 UChar r3, UChar r1, UChar r2)
2021{
2022 const HChar *mnm = irgen(r3, r1, r2);
2023
2024 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2025 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2026}
2027
2028static void
florian55085f82012-11-21 00:36:55 +00002029s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2030 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002031 UChar m3, UChar m4, UChar r1, UChar r2)
2032{
florian55085f82012-11-21 00:36:55 +00002033 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002034
2035 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2036 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2037}
2038
2039static void
floriane38f6412012-12-21 17:32:12 +00002040s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2041 UChar m4, UChar r1, UChar r2)
2042{
2043 const HChar *mnm = irgen(m4, r1, r2);
2044
2045 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2046 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2047}
2048
2049static void
florian55085f82012-11-21 00:36:55 +00002050s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2051 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002052 UChar m3, UChar m4, UChar r1, UChar r2)
2053{
florian55085f82012-11-21 00:36:55 +00002054 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002055
2056 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2057 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2058}
2059
2060static void
florian55085f82012-11-21 00:36:55 +00002061s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2062 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002063 UChar m3, UChar m4, UChar r1, UChar r2)
2064{
florian55085f82012-11-21 00:36:55 +00002065 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002066
2067 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2068 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2069}
2070
2071
2072static void
florian55085f82012-11-21 00:36:55 +00002073s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002074 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2075{
2076 irgen(m3, r1, r2);
2077
sewardj7ee97522011-05-09 21:45:04 +00002078 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002079 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2080}
2081
2082static void
florian55085f82012-11-21 00:36:55 +00002083s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002084 UChar r3, UChar r1, UChar r2)
2085{
florian55085f82012-11-21 00:36:55 +00002086 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002087
sewardj7ee97522011-05-09 21:45:04 +00002088 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002089 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2090}
2091
2092static void
florian5c539732013-02-14 14:27:12 +00002093s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2094 UChar r3, UChar m4, UChar r1, UChar r2)
2095{
2096 const HChar *mnm = irgen(r3, m4, r1, r2);
2097
2098 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2099 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2100}
2101
2102static void
2103s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2104 UChar r3, UChar m4, UChar r1, UChar r2)
2105{
2106 const HChar *mnm = irgen(r3, m4, r1, r2);
2107
2108 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2109 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2110}
2111
2112static void
florian55085f82012-11-21 00:36:55 +00002113s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002114 UChar r3, UChar m4, UChar r1, UChar r2)
2115{
florian55085f82012-11-21 00:36:55 +00002116 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002117
2118 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2119 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2120}
2121
2122static void
florian55085f82012-11-21 00:36:55 +00002123s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002124 UChar r3, UChar r1, UChar r2)
2125{
florian55085f82012-11-21 00:36:55 +00002126 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002127
sewardj7ee97522011-05-09 21:45:04 +00002128 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002129 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2130}
2131
2132static void
florian55085f82012-11-21 00:36:55 +00002133s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2134 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002135 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2136{
florian55085f82012-11-21 00:36:55 +00002137 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002138 IRTemp op4addr = newTemp(Ity_I64);
2139
2140 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2141 mkU64(0)));
2142
2143 mnm = irgen(r1, r2, m3, op4addr);
2144
sewardj7ee97522011-05-09 21:45:04 +00002145 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002146 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2147 r2, m3, d4, 0, b4);
2148}
2149
2150static void
florian55085f82012-11-21 00:36:55 +00002151s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002152 UChar r1, 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, 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(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2164}
2165
2166static void
florian55085f82012-11-21 00:36:55 +00002167s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002168 UChar r1, UChar r3, UChar b2, UShort d2)
2169{
florian55085f82012-11-21 00:36:55 +00002170 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002171 IRTemp op2addr = newTemp(Ity_I64);
2172
2173 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2174 mkU64(0)));
2175
2176 mnm = irgen(r1, r3, op2addr);
2177
sewardj7ee97522011-05-09 21:45:04 +00002178 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002179 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2180}
2181
2182static void
florian55085f82012-11-21 00:36:55 +00002183s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002184 UChar r1, UChar r3, UChar b2, UShort d2)
2185{
florian55085f82012-11-21 00:36:55 +00002186 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002187 IRTemp op2addr = newTemp(Ity_I64);
2188
2189 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2190 mkU64(0)));
2191
2192 mnm = irgen(r1, r3, op2addr);
2193
sewardj7ee97522011-05-09 21:45:04 +00002194 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002195 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2196}
2197
2198static void
florian55085f82012-11-21 00:36:55 +00002199s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002200 UChar r1, UChar r3, UChar b2, UShort d2)
2201{
florian55085f82012-11-21 00:36:55 +00002202 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002203 IRTemp op2addr = newTemp(Ity_I64);
2204
2205 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2206 mkU64(0)));
2207
2208 mnm = irgen(r1, r3, op2addr);
2209
sewardj7ee97522011-05-09 21:45:04 +00002210 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002211 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2212}
2213
2214static void
florian55085f82012-11-21 00:36:55 +00002215s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002216 UChar r1, UChar r3, UShort i2)
2217{
florian55085f82012-11-21 00:36:55 +00002218 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002219
sewardj7ee97522011-05-09 21:45:04 +00002220 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002221 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2222}
2223
2224static void
florian55085f82012-11-21 00:36:55 +00002225s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002226 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2227{
florian55085f82012-11-21 00:36:55 +00002228 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002229 IRTemp op2addr = newTemp(Ity_I64);
2230 IRTemp d2 = newTemp(Ity_I64);
2231
2232 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2233 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2234 mkU64(0)));
2235
2236 mnm = irgen(r1, r3, op2addr);
2237
sewardj7ee97522011-05-09 21:45:04 +00002238 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002239 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2240}
2241
2242static void
florian55085f82012-11-21 00:36:55 +00002243s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002244 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2245{
florian55085f82012-11-21 00:36:55 +00002246 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002247 IRTemp op2addr = newTemp(Ity_I64);
2248 IRTemp d2 = newTemp(Ity_I64);
2249
2250 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2251 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2252 mkU64(0)));
2253
2254 mnm = irgen(r1, r3, op2addr);
2255
sewardj7ee97522011-05-09 21:45:04 +00002256 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002257 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2258}
2259
2260static void
florian55085f82012-11-21 00:36:55 +00002261s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002262 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2263{
florian55085f82012-11-21 00:36:55 +00002264 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002265 IRTemp op2addr = newTemp(Ity_I64);
2266 IRTemp d2 = newTemp(Ity_I64);
2267
2268 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2269 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2270 mkU64(0)));
2271
2272 mnm = irgen(r1, r3, op2addr);
2273
sewardj7ee97522011-05-09 21:45:04 +00002274 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002275 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2276}
2277
2278static void
florian55085f82012-11-21 00:36:55 +00002279s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002280 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2281 Int xmnm_kind)
2282{
2283 IRTemp op2addr = newTemp(Ity_I64);
2284 IRTemp d2 = newTemp(Ity_I64);
2285
florian6820ba52012-07-26 02:01:50 +00002286 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2287
sewardjd7bde722011-04-05 13:19:33 +00002288 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2289 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2290 mkU64(0)));
2291
2292 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002293
2294 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002295
sewardj7ee97522011-05-09 21:45:04 +00002296 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002297 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2298}
2299
2300static void
florian55085f82012-11-21 00:36:55 +00002301s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002302 IRTemp op2addr),
2303 UChar r1, UChar x2, UChar b2, UShort d2)
2304{
2305 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 irgen(r1, x2, b2, d2, op2addr);
2312}
2313
2314static void
florian55085f82012-11-21 00:36:55 +00002315s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002316 UChar r1, UChar x2, UChar b2, UShort d2)
2317{
florian55085f82012-11-21 00:36:55 +00002318 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002319 IRTemp op2addr = newTemp(Ity_I64);
2320
2321 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2322 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2323 mkU64(0)));
2324
2325 mnm = irgen(r1, op2addr);
2326
sewardj7ee97522011-05-09 21:45:04 +00002327 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002328 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2329}
2330
2331static void
florian55085f82012-11-21 00:36:55 +00002332s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002333 UChar r1, UChar x2, UChar b2, UShort d2)
2334{
florian55085f82012-11-21 00:36:55 +00002335 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002336 IRTemp op2addr = newTemp(Ity_I64);
2337
2338 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2339 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2340 mkU64(0)));
2341
2342 mnm = irgen(r1, op2addr);
2343
sewardj7ee97522011-05-09 21:45:04 +00002344 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002345 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2346}
2347
2348static void
florian55085f82012-11-21 00:36:55 +00002349s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002350 UChar r1, UChar x2, UChar b2, UShort d2)
2351{
florian55085f82012-11-21 00:36:55 +00002352 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002353 IRTemp op2addr = newTemp(Ity_I64);
2354
2355 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2356 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2357 mkU64(0)));
2358
2359 mnm = irgen(r1, op2addr);
2360
sewardj7ee97522011-05-09 21:45:04 +00002361 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002362 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2363}
2364
2365static void
florian55085f82012-11-21 00:36:55 +00002366s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002367 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2368{
florian55085f82012-11-21 00:36:55 +00002369 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002370 IRTemp op2addr = newTemp(Ity_I64);
2371
2372 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2373 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2374 mkU64(0)));
2375
2376 mnm = irgen(r3, op2addr, r1);
2377
sewardj7ee97522011-05-09 21:45:04 +00002378 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002379 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2380}
2381
2382static void
florian55085f82012-11-21 00:36:55 +00002383s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002384 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2385{
florian55085f82012-11-21 00:36:55 +00002386 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002387 IRTemp op2addr = newTemp(Ity_I64);
2388 IRTemp d2 = newTemp(Ity_I64);
2389
2390 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2391 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2392 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2393 mkU64(0)));
2394
2395 mnm = irgen(r1, op2addr);
2396
sewardj7ee97522011-05-09 21:45:04 +00002397 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002398 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2399}
2400
2401static void
florian55085f82012-11-21 00:36:55 +00002402s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002403 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2404{
florian55085f82012-11-21 00:36:55 +00002405 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002406 IRTemp op2addr = newTemp(Ity_I64);
2407 IRTemp d2 = newTemp(Ity_I64);
2408
2409 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2410 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2411 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2412 mkU64(0)));
2413
2414 mnm = irgen(r1, op2addr);
2415
sewardj7ee97522011-05-09 21:45:04 +00002416 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002417 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2418}
2419
2420static void
florian55085f82012-11-21 00:36:55 +00002421s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002422 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2423{
florian55085f82012-11-21 00:36:55 +00002424 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002425 IRTemp op2addr = newTemp(Ity_I64);
2426 IRTemp d2 = newTemp(Ity_I64);
2427
2428 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2429 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2430 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2431 mkU64(0)));
2432
2433 mnm = irgen();
2434
sewardj7ee97522011-05-09 21:45:04 +00002435 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002436 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2437}
2438
2439static void
florian55085f82012-11-21 00:36:55 +00002440s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002441 UChar b2, UShort d2)
2442{
florian55085f82012-11-21 00:36:55 +00002443 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002444 IRTemp op2addr = newTemp(Ity_I64);
2445
2446 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2447 mkU64(0)));
2448
2449 mnm = irgen(op2addr);
2450
sewardj7ee97522011-05-09 21:45:04 +00002451 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002452 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2453}
2454
2455static void
florian55085f82012-11-21 00:36:55 +00002456s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002457 UChar i2, UChar b1, UShort d1)
2458{
florian55085f82012-11-21 00:36:55 +00002459 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002460 IRTemp op1addr = newTemp(Ity_I64);
2461
2462 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2463 mkU64(0)));
2464
2465 mnm = irgen(i2, op1addr);
2466
sewardj7ee97522011-05-09 21:45:04 +00002467 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002468 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2469}
2470
2471static void
florian55085f82012-11-21 00:36:55 +00002472s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002473 UChar i2, UChar b1, UShort dl1, UChar dh1)
2474{
florian55085f82012-11-21 00:36:55 +00002475 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002476 IRTemp op1addr = newTemp(Ity_I64);
2477 IRTemp d1 = newTemp(Ity_I64);
2478
2479 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2480 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2481 mkU64(0)));
2482
2483 mnm = irgen(i2, op1addr);
2484
sewardj7ee97522011-05-09 21:45:04 +00002485 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002486 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2487}
2488
2489static void
florian55085f82012-11-21 00:36:55 +00002490s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002491 UChar i2, UChar b1, UShort dl1, UChar dh1)
2492{
florian55085f82012-11-21 00:36:55 +00002493 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002494 IRTemp op1addr = newTemp(Ity_I64);
2495 IRTemp d1 = newTemp(Ity_I64);
2496
2497 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2498 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2499 mkU64(0)));
2500
2501 mnm = irgen(i2, op1addr);
2502
sewardj7ee97522011-05-09 21:45:04 +00002503 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002504 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2505}
2506
2507static void
florian55085f82012-11-21 00:36:55 +00002508s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002509 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2510{
florian55085f82012-11-21 00:36:55 +00002511 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002512 IRTemp op1addr = newTemp(Ity_I64);
2513 IRTemp op2addr = newTemp(Ity_I64);
2514
2515 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2516 mkU64(0)));
2517 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2518 mkU64(0)));
2519
2520 mnm = irgen(l, op1addr, op2addr);
2521
sewardj7ee97522011-05-09 21:45:04 +00002522 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002523 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2524}
2525
2526static void
florian55085f82012-11-21 00:36:55 +00002527s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002528 UChar b1, UShort d1, UShort i2)
2529{
florian55085f82012-11-21 00:36:55 +00002530 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002531 IRTemp op1addr = newTemp(Ity_I64);
2532
2533 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2534 mkU64(0)));
2535
2536 mnm = irgen(i2, op1addr);
2537
sewardj7ee97522011-05-09 21:45:04 +00002538 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002539 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2540}
2541
2542static void
florian55085f82012-11-21 00:36:55 +00002543s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002544 UChar b1, UShort d1, UShort i2)
2545{
florian55085f82012-11-21 00:36:55 +00002546 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002547 IRTemp op1addr = newTemp(Ity_I64);
2548
2549 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2550 mkU64(0)));
2551
2552 mnm = irgen(i2, op1addr);
2553
sewardj7ee97522011-05-09 21:45:04 +00002554 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002555 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2556}
2557
2558
2559
2560/*------------------------------------------------------------*/
2561/*--- Build IR for opcodes ---*/
2562/*------------------------------------------------------------*/
2563
florian55085f82012-11-21 00:36:55 +00002564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002565s390_irgen_AR(UChar r1, UChar r2)
2566{
2567 IRTemp op1 = newTemp(Ity_I32);
2568 IRTemp op2 = newTemp(Ity_I32);
2569 IRTemp result = newTemp(Ity_I32);
2570
2571 assign(op1, get_gpr_w1(r1));
2572 assign(op2, get_gpr_w1(r2));
2573 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2574 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2575 put_gpr_w1(r1, mkexpr(result));
2576
2577 return "ar";
2578}
2579
florian55085f82012-11-21 00:36:55 +00002580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002581s390_irgen_AGR(UChar r1, UChar r2)
2582{
2583 IRTemp op1 = newTemp(Ity_I64);
2584 IRTemp op2 = newTemp(Ity_I64);
2585 IRTemp result = newTemp(Ity_I64);
2586
2587 assign(op1, get_gpr_dw0(r1));
2588 assign(op2, get_gpr_dw0(r2));
2589 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2590 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2591 put_gpr_dw0(r1, mkexpr(result));
2592
2593 return "agr";
2594}
2595
florian55085f82012-11-21 00:36:55 +00002596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002597s390_irgen_AGFR(UChar r1, UChar r2)
2598{
2599 IRTemp op1 = newTemp(Ity_I64);
2600 IRTemp op2 = newTemp(Ity_I64);
2601 IRTemp result = newTemp(Ity_I64);
2602
2603 assign(op1, get_gpr_dw0(r1));
2604 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2605 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2606 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2607 put_gpr_dw0(r1, mkexpr(result));
2608
2609 return "agfr";
2610}
2611
florian55085f82012-11-21 00:36:55 +00002612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002613s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2614{
2615 IRTemp op2 = newTemp(Ity_I32);
2616 IRTemp op3 = newTemp(Ity_I32);
2617 IRTemp result = newTemp(Ity_I32);
2618
2619 assign(op2, get_gpr_w1(r2));
2620 assign(op3, get_gpr_w1(r3));
2621 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2622 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2623 put_gpr_w1(r1, mkexpr(result));
2624
2625 return "ark";
2626}
2627
florian55085f82012-11-21 00:36:55 +00002628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002629s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2630{
2631 IRTemp op2 = newTemp(Ity_I64);
2632 IRTemp op3 = newTemp(Ity_I64);
2633 IRTemp result = newTemp(Ity_I64);
2634
2635 assign(op2, get_gpr_dw0(r2));
2636 assign(op3, get_gpr_dw0(r3));
2637 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2638 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2639 put_gpr_dw0(r1, mkexpr(result));
2640
2641 return "agrk";
2642}
2643
florian55085f82012-11-21 00:36:55 +00002644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002645s390_irgen_A(UChar r1, IRTemp op2addr)
2646{
2647 IRTemp op1 = newTemp(Ity_I32);
2648 IRTemp op2 = newTemp(Ity_I32);
2649 IRTemp result = newTemp(Ity_I32);
2650
2651 assign(op1, get_gpr_w1(r1));
2652 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2653 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2654 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2655 put_gpr_w1(r1, mkexpr(result));
2656
2657 return "a";
2658}
2659
florian55085f82012-11-21 00:36:55 +00002660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002661s390_irgen_AY(UChar r1, IRTemp op2addr)
2662{
2663 IRTemp op1 = newTemp(Ity_I32);
2664 IRTemp op2 = newTemp(Ity_I32);
2665 IRTemp result = newTemp(Ity_I32);
2666
2667 assign(op1, get_gpr_w1(r1));
2668 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2669 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2670 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2671 put_gpr_w1(r1, mkexpr(result));
2672
2673 return "ay";
2674}
2675
florian55085f82012-11-21 00:36:55 +00002676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002677s390_irgen_AG(UChar r1, IRTemp op2addr)
2678{
2679 IRTemp op1 = newTemp(Ity_I64);
2680 IRTemp op2 = newTemp(Ity_I64);
2681 IRTemp result = newTemp(Ity_I64);
2682
2683 assign(op1, get_gpr_dw0(r1));
2684 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2685 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2686 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2687 put_gpr_dw0(r1, mkexpr(result));
2688
2689 return "ag";
2690}
2691
florian55085f82012-11-21 00:36:55 +00002692static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002693s390_irgen_AGF(UChar r1, IRTemp op2addr)
2694{
2695 IRTemp op1 = newTemp(Ity_I64);
2696 IRTemp op2 = newTemp(Ity_I64);
2697 IRTemp result = newTemp(Ity_I64);
2698
2699 assign(op1, get_gpr_dw0(r1));
2700 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2701 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2702 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2703 put_gpr_dw0(r1, mkexpr(result));
2704
2705 return "agf";
2706}
2707
florian55085f82012-11-21 00:36:55 +00002708static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002709s390_irgen_AFI(UChar r1, UInt i2)
2710{
2711 IRTemp op1 = newTemp(Ity_I32);
2712 Int op2;
2713 IRTemp result = newTemp(Ity_I32);
2714
2715 assign(op1, get_gpr_w1(r1));
2716 op2 = (Int)i2;
2717 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2718 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2719 mkU32((UInt)op2)));
2720 put_gpr_w1(r1, mkexpr(result));
2721
2722 return "afi";
2723}
2724
florian55085f82012-11-21 00:36:55 +00002725static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002726s390_irgen_AGFI(UChar r1, UInt i2)
2727{
2728 IRTemp op1 = newTemp(Ity_I64);
2729 Long op2;
2730 IRTemp result = newTemp(Ity_I64);
2731
2732 assign(op1, get_gpr_dw0(r1));
2733 op2 = (Long)(Int)i2;
2734 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2735 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2736 mkU64((ULong)op2)));
2737 put_gpr_dw0(r1, mkexpr(result));
2738
2739 return "agfi";
2740}
2741
florian55085f82012-11-21 00:36:55 +00002742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002743s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2744{
2745 Int op2;
2746 IRTemp op3 = newTemp(Ity_I32);
2747 IRTemp result = newTemp(Ity_I32);
2748
2749 op2 = (Int)(Short)i2;
2750 assign(op3, get_gpr_w1(r3));
2751 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2752 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2753 op2)), op3);
2754 put_gpr_w1(r1, mkexpr(result));
2755
2756 return "ahik";
2757}
2758
florian55085f82012-11-21 00:36:55 +00002759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002760s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2761{
2762 Long op2;
2763 IRTemp op3 = newTemp(Ity_I64);
2764 IRTemp result = newTemp(Ity_I64);
2765
2766 op2 = (Long)(Short)i2;
2767 assign(op3, get_gpr_dw0(r3));
2768 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2769 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2770 op2)), op3);
2771 put_gpr_dw0(r1, mkexpr(result));
2772
2773 return "aghik";
2774}
2775
florian55085f82012-11-21 00:36:55 +00002776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002777s390_irgen_ASI(UChar i2, IRTemp op1addr)
2778{
2779 IRTemp op1 = newTemp(Ity_I32);
2780 Int op2;
2781 IRTemp result = newTemp(Ity_I32);
2782
2783 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2784 op2 = (Int)(Char)i2;
2785 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2786 store(mkexpr(op1addr), mkexpr(result));
2787 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2788 mkU32((UInt)op2)));
2789
2790 return "asi";
2791}
2792
florian55085f82012-11-21 00:36:55 +00002793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002794s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2795{
2796 IRTemp op1 = newTemp(Ity_I64);
2797 Long op2;
2798 IRTemp result = newTemp(Ity_I64);
2799
2800 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2801 op2 = (Long)(Char)i2;
2802 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2803 store(mkexpr(op1addr), mkexpr(result));
2804 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2805 mkU64((ULong)op2)));
2806
2807 return "agsi";
2808}
2809
florian55085f82012-11-21 00:36:55 +00002810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002811s390_irgen_AH(UChar r1, IRTemp op2addr)
2812{
2813 IRTemp op1 = newTemp(Ity_I32);
2814 IRTemp op2 = newTemp(Ity_I32);
2815 IRTemp result = newTemp(Ity_I32);
2816
2817 assign(op1, get_gpr_w1(r1));
2818 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2819 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2820 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2821 put_gpr_w1(r1, mkexpr(result));
2822
2823 return "ah";
2824}
2825
florian55085f82012-11-21 00:36:55 +00002826static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002827s390_irgen_AHY(UChar r1, IRTemp op2addr)
2828{
2829 IRTemp op1 = newTemp(Ity_I32);
2830 IRTemp op2 = newTemp(Ity_I32);
2831 IRTemp result = newTemp(Ity_I32);
2832
2833 assign(op1, get_gpr_w1(r1));
2834 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2835 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2836 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2837 put_gpr_w1(r1, mkexpr(result));
2838
2839 return "ahy";
2840}
2841
florian55085f82012-11-21 00:36:55 +00002842static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002843s390_irgen_AHI(UChar r1, UShort i2)
2844{
2845 IRTemp op1 = newTemp(Ity_I32);
2846 Int op2;
2847 IRTemp result = newTemp(Ity_I32);
2848
2849 assign(op1, get_gpr_w1(r1));
2850 op2 = (Int)(Short)i2;
2851 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2852 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2853 mkU32((UInt)op2)));
2854 put_gpr_w1(r1, mkexpr(result));
2855
2856 return "ahi";
2857}
2858
florian55085f82012-11-21 00:36:55 +00002859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002860s390_irgen_AGHI(UChar r1, UShort i2)
2861{
2862 IRTemp op1 = newTemp(Ity_I64);
2863 Long op2;
2864 IRTemp result = newTemp(Ity_I64);
2865
2866 assign(op1, get_gpr_dw0(r1));
2867 op2 = (Long)(Short)i2;
2868 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2869 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2870 mkU64((ULong)op2)));
2871 put_gpr_dw0(r1, mkexpr(result));
2872
2873 return "aghi";
2874}
2875
florian55085f82012-11-21 00:36:55 +00002876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002877s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2878{
2879 IRTemp op2 = newTemp(Ity_I32);
2880 IRTemp op3 = newTemp(Ity_I32);
2881 IRTemp result = newTemp(Ity_I32);
2882
2883 assign(op2, get_gpr_w0(r2));
2884 assign(op3, get_gpr_w0(r3));
2885 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2886 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2887 put_gpr_w0(r1, mkexpr(result));
2888
2889 return "ahhhr";
2890}
2891
florian55085f82012-11-21 00:36:55 +00002892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002893s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2894{
2895 IRTemp op2 = newTemp(Ity_I32);
2896 IRTemp op3 = newTemp(Ity_I32);
2897 IRTemp result = newTemp(Ity_I32);
2898
2899 assign(op2, get_gpr_w0(r2));
2900 assign(op3, get_gpr_w1(r3));
2901 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2902 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2903 put_gpr_w0(r1, mkexpr(result));
2904
2905 return "ahhlr";
2906}
2907
florian55085f82012-11-21 00:36:55 +00002908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002909s390_irgen_AIH(UChar r1, UInt i2)
2910{
2911 IRTemp op1 = newTemp(Ity_I32);
2912 Int op2;
2913 IRTemp result = newTemp(Ity_I32);
2914
2915 assign(op1, get_gpr_w0(r1));
2916 op2 = (Int)i2;
2917 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2918 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2919 mkU32((UInt)op2)));
2920 put_gpr_w0(r1, mkexpr(result));
2921
2922 return "aih";
2923}
2924
florian55085f82012-11-21 00:36:55 +00002925static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002926s390_irgen_ALR(UChar r1, UChar r2)
2927{
2928 IRTemp op1 = newTemp(Ity_I32);
2929 IRTemp op2 = newTemp(Ity_I32);
2930 IRTemp result = newTemp(Ity_I32);
2931
2932 assign(op1, get_gpr_w1(r1));
2933 assign(op2, get_gpr_w1(r2));
2934 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2935 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2936 put_gpr_w1(r1, mkexpr(result));
2937
2938 return "alr";
2939}
2940
florian55085f82012-11-21 00:36:55 +00002941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002942s390_irgen_ALGR(UChar r1, UChar r2)
2943{
2944 IRTemp op1 = newTemp(Ity_I64);
2945 IRTemp op2 = newTemp(Ity_I64);
2946 IRTemp result = newTemp(Ity_I64);
2947
2948 assign(op1, get_gpr_dw0(r1));
2949 assign(op2, get_gpr_dw0(r2));
2950 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2951 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2952 put_gpr_dw0(r1, mkexpr(result));
2953
2954 return "algr";
2955}
2956
florian55085f82012-11-21 00:36:55 +00002957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002958s390_irgen_ALGFR(UChar r1, UChar r2)
2959{
2960 IRTemp op1 = newTemp(Ity_I64);
2961 IRTemp op2 = newTemp(Ity_I64);
2962 IRTemp result = newTemp(Ity_I64);
2963
2964 assign(op1, get_gpr_dw0(r1));
2965 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2966 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2967 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2968 put_gpr_dw0(r1, mkexpr(result));
2969
2970 return "algfr";
2971}
2972
florian55085f82012-11-21 00:36:55 +00002973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002974s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2975{
2976 IRTemp op2 = newTemp(Ity_I32);
2977 IRTemp op3 = newTemp(Ity_I32);
2978 IRTemp result = newTemp(Ity_I32);
2979
2980 assign(op2, get_gpr_w1(r2));
2981 assign(op3, get_gpr_w1(r3));
2982 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2983 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2984 put_gpr_w1(r1, mkexpr(result));
2985
2986 return "alrk";
2987}
2988
florian55085f82012-11-21 00:36:55 +00002989static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002990s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2991{
2992 IRTemp op2 = newTemp(Ity_I64);
2993 IRTemp op3 = newTemp(Ity_I64);
2994 IRTemp result = newTemp(Ity_I64);
2995
2996 assign(op2, get_gpr_dw0(r2));
2997 assign(op3, get_gpr_dw0(r3));
2998 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2999 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3000 put_gpr_dw0(r1, mkexpr(result));
3001
3002 return "algrk";
3003}
3004
florian55085f82012-11-21 00:36:55 +00003005static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003006s390_irgen_AL(UChar r1, IRTemp op2addr)
3007{
3008 IRTemp op1 = newTemp(Ity_I32);
3009 IRTemp op2 = newTemp(Ity_I32);
3010 IRTemp result = newTemp(Ity_I32);
3011
3012 assign(op1, get_gpr_w1(r1));
3013 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3014 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3015 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3016 put_gpr_w1(r1, mkexpr(result));
3017
3018 return "al";
3019}
3020
florian55085f82012-11-21 00:36:55 +00003021static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003022s390_irgen_ALY(UChar r1, IRTemp op2addr)
3023{
3024 IRTemp op1 = newTemp(Ity_I32);
3025 IRTemp op2 = newTemp(Ity_I32);
3026 IRTemp result = newTemp(Ity_I32);
3027
3028 assign(op1, get_gpr_w1(r1));
3029 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3030 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3031 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3032 put_gpr_w1(r1, mkexpr(result));
3033
3034 return "aly";
3035}
3036
florian55085f82012-11-21 00:36:55 +00003037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003038s390_irgen_ALG(UChar r1, IRTemp op2addr)
3039{
3040 IRTemp op1 = newTemp(Ity_I64);
3041 IRTemp op2 = newTemp(Ity_I64);
3042 IRTemp result = newTemp(Ity_I64);
3043
3044 assign(op1, get_gpr_dw0(r1));
3045 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3046 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3047 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3048 put_gpr_dw0(r1, mkexpr(result));
3049
3050 return "alg";
3051}
3052
florian55085f82012-11-21 00:36:55 +00003053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003054s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3055{
3056 IRTemp op1 = newTemp(Ity_I64);
3057 IRTemp op2 = newTemp(Ity_I64);
3058 IRTemp result = newTemp(Ity_I64);
3059
3060 assign(op1, get_gpr_dw0(r1));
3061 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3062 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3063 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3064 put_gpr_dw0(r1, mkexpr(result));
3065
3066 return "algf";
3067}
3068
florian55085f82012-11-21 00:36:55 +00003069static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003070s390_irgen_ALFI(UChar r1, UInt i2)
3071{
3072 IRTemp op1 = newTemp(Ity_I32);
3073 UInt op2;
3074 IRTemp result = newTemp(Ity_I32);
3075
3076 assign(op1, get_gpr_w1(r1));
3077 op2 = i2;
3078 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3079 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3080 mkU32(op2)));
3081 put_gpr_w1(r1, mkexpr(result));
3082
3083 return "alfi";
3084}
3085
florian55085f82012-11-21 00:36:55 +00003086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003087s390_irgen_ALGFI(UChar r1, UInt i2)
3088{
3089 IRTemp op1 = newTemp(Ity_I64);
3090 ULong op2;
3091 IRTemp result = newTemp(Ity_I64);
3092
3093 assign(op1, get_gpr_dw0(r1));
3094 op2 = (ULong)i2;
3095 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3096 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3097 mkU64(op2)));
3098 put_gpr_dw0(r1, mkexpr(result));
3099
3100 return "algfi";
3101}
3102
florian55085f82012-11-21 00:36:55 +00003103static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003104s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3105{
3106 IRTemp op2 = newTemp(Ity_I32);
3107 IRTemp op3 = newTemp(Ity_I32);
3108 IRTemp result = newTemp(Ity_I32);
3109
3110 assign(op2, get_gpr_w0(r2));
3111 assign(op3, get_gpr_w0(r3));
3112 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3113 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3114 put_gpr_w0(r1, mkexpr(result));
3115
3116 return "alhhhr";
3117}
3118
florian55085f82012-11-21 00:36:55 +00003119static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003120s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3121{
3122 IRTemp op2 = newTemp(Ity_I32);
3123 IRTemp op3 = newTemp(Ity_I32);
3124 IRTemp result = newTemp(Ity_I32);
3125
3126 assign(op2, get_gpr_w0(r2));
3127 assign(op3, get_gpr_w1(r3));
3128 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3129 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3130 put_gpr_w0(r1, mkexpr(result));
3131
3132 return "alhhlr";
3133}
3134
florian55085f82012-11-21 00:36:55 +00003135static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003136s390_irgen_ALCR(UChar r1, UChar r2)
3137{
3138 IRTemp op1 = newTemp(Ity_I32);
3139 IRTemp op2 = newTemp(Ity_I32);
3140 IRTemp result = newTemp(Ity_I32);
3141 IRTemp carry_in = newTemp(Ity_I32);
3142
3143 assign(op1, get_gpr_w1(r1));
3144 assign(op2, get_gpr_w1(r2));
3145 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3146 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3147 mkexpr(carry_in)));
3148 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3149 put_gpr_w1(r1, mkexpr(result));
3150
3151 return "alcr";
3152}
3153
florian55085f82012-11-21 00:36:55 +00003154static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003155s390_irgen_ALCGR(UChar r1, UChar r2)
3156{
3157 IRTemp op1 = newTemp(Ity_I64);
3158 IRTemp op2 = newTemp(Ity_I64);
3159 IRTemp result = newTemp(Ity_I64);
3160 IRTemp carry_in = newTemp(Ity_I64);
3161
3162 assign(op1, get_gpr_dw0(r1));
3163 assign(op2, get_gpr_dw0(r2));
3164 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3165 mkU8(1))));
3166 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3167 mkexpr(carry_in)));
3168 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3169 put_gpr_dw0(r1, mkexpr(result));
3170
3171 return "alcgr";
3172}
3173
florian55085f82012-11-21 00:36:55 +00003174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003175s390_irgen_ALC(UChar r1, IRTemp op2addr)
3176{
3177 IRTemp op1 = newTemp(Ity_I32);
3178 IRTemp op2 = newTemp(Ity_I32);
3179 IRTemp result = newTemp(Ity_I32);
3180 IRTemp carry_in = newTemp(Ity_I32);
3181
3182 assign(op1, get_gpr_w1(r1));
3183 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3184 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3185 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3186 mkexpr(carry_in)));
3187 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3188 put_gpr_w1(r1, mkexpr(result));
3189
3190 return "alc";
3191}
3192
florian55085f82012-11-21 00:36:55 +00003193static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003194s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3195{
3196 IRTemp op1 = newTemp(Ity_I64);
3197 IRTemp op2 = newTemp(Ity_I64);
3198 IRTemp result = newTemp(Ity_I64);
3199 IRTemp carry_in = newTemp(Ity_I64);
3200
3201 assign(op1, get_gpr_dw0(r1));
3202 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3203 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3204 mkU8(1))));
3205 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3206 mkexpr(carry_in)));
3207 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3208 put_gpr_dw0(r1, mkexpr(result));
3209
3210 return "alcg";
3211}
3212
florian55085f82012-11-21 00:36:55 +00003213static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003214s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3215{
3216 IRTemp op1 = newTemp(Ity_I32);
3217 UInt op2;
3218 IRTemp result = newTemp(Ity_I32);
3219
3220 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3221 op2 = (UInt)(Int)(Char)i2;
3222 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3223 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3224 mkU32(op2)));
3225 store(mkexpr(op1addr), mkexpr(result));
3226
3227 return "alsi";
3228}
3229
florian55085f82012-11-21 00:36:55 +00003230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003231s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3232{
3233 IRTemp op1 = newTemp(Ity_I64);
3234 ULong op2;
3235 IRTemp result = newTemp(Ity_I64);
3236
3237 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3238 op2 = (ULong)(Long)(Char)i2;
3239 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3240 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3241 mkU64(op2)));
3242 store(mkexpr(op1addr), mkexpr(result));
3243
3244 return "algsi";
3245}
3246
florian55085f82012-11-21 00:36:55 +00003247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003248s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3249{
3250 UInt op2;
3251 IRTemp op3 = newTemp(Ity_I32);
3252 IRTemp result = newTemp(Ity_I32);
3253
3254 op2 = (UInt)(Int)(Short)i2;
3255 assign(op3, get_gpr_w1(r3));
3256 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3257 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3258 op3);
3259 put_gpr_w1(r1, mkexpr(result));
3260
3261 return "alhsik";
3262}
3263
florian55085f82012-11-21 00:36:55 +00003264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003265s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3266{
3267 ULong op2;
3268 IRTemp op3 = newTemp(Ity_I64);
3269 IRTemp result = newTemp(Ity_I64);
3270
3271 op2 = (ULong)(Long)(Short)i2;
3272 assign(op3, get_gpr_dw0(r3));
3273 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3274 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3275 op3);
3276 put_gpr_dw0(r1, mkexpr(result));
3277
3278 return "alghsik";
3279}
3280
florian55085f82012-11-21 00:36:55 +00003281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003282s390_irgen_ALSIH(UChar r1, UInt i2)
3283{
3284 IRTemp op1 = newTemp(Ity_I32);
3285 UInt op2;
3286 IRTemp result = newTemp(Ity_I32);
3287
3288 assign(op1, get_gpr_w0(r1));
3289 op2 = i2;
3290 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3291 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3292 mkU32(op2)));
3293 put_gpr_w0(r1, mkexpr(result));
3294
3295 return "alsih";
3296}
3297
florian55085f82012-11-21 00:36:55 +00003298static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003299s390_irgen_ALSIHN(UChar r1, UInt i2)
3300{
3301 IRTemp op1 = newTemp(Ity_I32);
3302 UInt op2;
3303 IRTemp result = newTemp(Ity_I32);
3304
3305 assign(op1, get_gpr_w0(r1));
3306 op2 = i2;
3307 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3308 put_gpr_w0(r1, mkexpr(result));
3309
3310 return "alsihn";
3311}
3312
florian55085f82012-11-21 00:36:55 +00003313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003314s390_irgen_NR(UChar r1, UChar r2)
3315{
3316 IRTemp op1 = newTemp(Ity_I32);
3317 IRTemp op2 = newTemp(Ity_I32);
3318 IRTemp result = newTemp(Ity_I32);
3319
3320 assign(op1, get_gpr_w1(r1));
3321 assign(op2, get_gpr_w1(r2));
3322 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3323 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3324 put_gpr_w1(r1, mkexpr(result));
3325
3326 return "nr";
3327}
3328
florian55085f82012-11-21 00:36:55 +00003329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003330s390_irgen_NGR(UChar r1, UChar r2)
3331{
3332 IRTemp op1 = newTemp(Ity_I64);
3333 IRTemp op2 = newTemp(Ity_I64);
3334 IRTemp result = newTemp(Ity_I64);
3335
3336 assign(op1, get_gpr_dw0(r1));
3337 assign(op2, get_gpr_dw0(r2));
3338 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3339 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3340 put_gpr_dw0(r1, mkexpr(result));
3341
3342 return "ngr";
3343}
3344
florian55085f82012-11-21 00:36:55 +00003345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003346s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3347{
3348 IRTemp op2 = newTemp(Ity_I32);
3349 IRTemp op3 = newTemp(Ity_I32);
3350 IRTemp result = newTemp(Ity_I32);
3351
3352 assign(op2, get_gpr_w1(r2));
3353 assign(op3, get_gpr_w1(r3));
3354 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3355 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3356 put_gpr_w1(r1, mkexpr(result));
3357
3358 return "nrk";
3359}
3360
florian55085f82012-11-21 00:36:55 +00003361static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003362s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3363{
3364 IRTemp op2 = newTemp(Ity_I64);
3365 IRTemp op3 = newTemp(Ity_I64);
3366 IRTemp result = newTemp(Ity_I64);
3367
3368 assign(op2, get_gpr_dw0(r2));
3369 assign(op3, get_gpr_dw0(r3));
3370 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3371 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3372 put_gpr_dw0(r1, mkexpr(result));
3373
3374 return "ngrk";
3375}
3376
florian55085f82012-11-21 00:36:55 +00003377static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003378s390_irgen_N(UChar r1, IRTemp op2addr)
3379{
3380 IRTemp op1 = newTemp(Ity_I32);
3381 IRTemp op2 = newTemp(Ity_I32);
3382 IRTemp result = newTemp(Ity_I32);
3383
3384 assign(op1, get_gpr_w1(r1));
3385 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3386 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3387 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3388 put_gpr_w1(r1, mkexpr(result));
3389
3390 return "n";
3391}
3392
florian55085f82012-11-21 00:36:55 +00003393static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003394s390_irgen_NY(UChar r1, IRTemp op2addr)
3395{
3396 IRTemp op1 = newTemp(Ity_I32);
3397 IRTemp op2 = newTemp(Ity_I32);
3398 IRTemp result = newTemp(Ity_I32);
3399
3400 assign(op1, get_gpr_w1(r1));
3401 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3402 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3403 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3404 put_gpr_w1(r1, mkexpr(result));
3405
3406 return "ny";
3407}
3408
florian55085f82012-11-21 00:36:55 +00003409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003410s390_irgen_NG(UChar r1, IRTemp op2addr)
3411{
3412 IRTemp op1 = newTemp(Ity_I64);
3413 IRTemp op2 = newTemp(Ity_I64);
3414 IRTemp result = newTemp(Ity_I64);
3415
3416 assign(op1, get_gpr_dw0(r1));
3417 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3418 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3419 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3420 put_gpr_dw0(r1, mkexpr(result));
3421
3422 return "ng";
3423}
3424
florian55085f82012-11-21 00:36:55 +00003425static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003426s390_irgen_NI(UChar i2, IRTemp op1addr)
3427{
3428 IRTemp op1 = newTemp(Ity_I8);
3429 UChar op2;
3430 IRTemp result = newTemp(Ity_I8);
3431
3432 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3433 op2 = i2;
3434 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3435 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3436 store(mkexpr(op1addr), mkexpr(result));
3437
3438 return "ni";
3439}
3440
florian55085f82012-11-21 00:36:55 +00003441static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003442s390_irgen_NIY(UChar i2, IRTemp op1addr)
3443{
3444 IRTemp op1 = newTemp(Ity_I8);
3445 UChar op2;
3446 IRTemp result = newTemp(Ity_I8);
3447
3448 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3449 op2 = i2;
3450 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3451 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3452 store(mkexpr(op1addr), mkexpr(result));
3453
3454 return "niy";
3455}
3456
florian55085f82012-11-21 00:36:55 +00003457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003458s390_irgen_NIHF(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_w0(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_w0(r1, mkexpr(result));
3469
3470 return "nihf";
3471}
3472
florian55085f82012-11-21 00:36:55 +00003473static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003474s390_irgen_NIHH(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_hw0(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_hw0(r1, mkexpr(result));
3485
3486 return "nihh";
3487}
3488
florian55085f82012-11-21 00:36:55 +00003489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003490s390_irgen_NIHL(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_hw1(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_hw1(r1, mkexpr(result));
3501
3502 return "nihl";
3503}
3504
florian55085f82012-11-21 00:36:55 +00003505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003506s390_irgen_NILF(UChar r1, UInt i2)
3507{
3508 IRTemp op1 = newTemp(Ity_I32);
3509 UInt op2;
3510 IRTemp result = newTemp(Ity_I32);
3511
3512 assign(op1, get_gpr_w1(r1));
3513 op2 = i2;
3514 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3515 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3516 put_gpr_w1(r1, mkexpr(result));
3517
3518 return "nilf";
3519}
3520
florian55085f82012-11-21 00:36:55 +00003521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003522s390_irgen_NILH(UChar r1, UShort i2)
3523{
3524 IRTemp op1 = newTemp(Ity_I16);
3525 UShort op2;
3526 IRTemp result = newTemp(Ity_I16);
3527
3528 assign(op1, get_gpr_hw2(r1));
3529 op2 = i2;
3530 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3531 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3532 put_gpr_hw2(r1, mkexpr(result));
3533
3534 return "nilh";
3535}
3536
florian55085f82012-11-21 00:36:55 +00003537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003538s390_irgen_NILL(UChar r1, UShort i2)
3539{
3540 IRTemp op1 = newTemp(Ity_I16);
3541 UShort op2;
3542 IRTemp result = newTemp(Ity_I16);
3543
3544 assign(op1, get_gpr_hw3(r1));
3545 op2 = i2;
3546 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3547 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3548 put_gpr_hw3(r1, mkexpr(result));
3549
3550 return "nill";
3551}
3552
florian55085f82012-11-21 00:36:55 +00003553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003554s390_irgen_BASR(UChar r1, UChar r2)
3555{
3556 IRTemp target = newTemp(Ity_I64);
3557
3558 if (r2 == 0) {
3559 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3560 } else {
3561 if (r1 != r2) {
3562 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3563 call_function(get_gpr_dw0(r2));
3564 } else {
3565 assign(target, get_gpr_dw0(r2));
3566 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3567 call_function(mkexpr(target));
3568 }
3569 }
3570
3571 return "basr";
3572}
3573
florian55085f82012-11-21 00:36:55 +00003574static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003575s390_irgen_BAS(UChar r1, IRTemp op2addr)
3576{
3577 IRTemp target = newTemp(Ity_I64);
3578
3579 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3580 assign(target, mkexpr(op2addr));
3581 call_function(mkexpr(target));
3582
3583 return "bas";
3584}
3585
florian55085f82012-11-21 00:36:55 +00003586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003587s390_irgen_BCR(UChar r1, UChar r2)
3588{
3589 IRTemp cond = newTemp(Ity_I32);
3590
sewardja52e37e2011-04-28 18:48:06 +00003591 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3592 stmt(IRStmt_MBE(Imbe_Fence));
3593 }
3594
sewardj2019a972011-03-07 16:04:07 +00003595 if ((r2 == 0) || (r1 == 0)) {
3596 } else {
3597 if (r1 == 15) {
3598 return_from_function(get_gpr_dw0(r2));
3599 } else {
3600 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003601 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3602 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003603 }
3604 }
sewardj7ee97522011-05-09 21:45:04 +00003605 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003606 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3607
3608 return "bcr";
3609}
3610
florian55085f82012-11-21 00:36:55 +00003611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003612s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3613{
3614 IRTemp cond = newTemp(Ity_I32);
3615
3616 if (r1 == 0) {
3617 } else {
3618 if (r1 == 15) {
3619 always_goto(mkexpr(op2addr));
3620 } else {
3621 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003622 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3623 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003624 }
3625 }
sewardj7ee97522011-05-09 21:45:04 +00003626 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003627 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3628
3629 return "bc";
3630}
3631
florian55085f82012-11-21 00:36:55 +00003632static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003633s390_irgen_BCTR(UChar r1, UChar r2)
3634{
3635 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3636 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003637 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3638 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003639 }
3640
3641 return "bctr";
3642}
3643
florian55085f82012-11-21 00:36:55 +00003644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003645s390_irgen_BCTGR(UChar r1, UChar r2)
3646{
3647 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3648 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003649 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3650 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003651 }
3652
3653 return "bctgr";
3654}
3655
florian55085f82012-11-21 00:36:55 +00003656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003657s390_irgen_BCT(UChar r1, IRTemp op2addr)
3658{
3659 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003660 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3661 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003662
3663 return "bct";
3664}
3665
florian55085f82012-11-21 00:36:55 +00003666static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003667s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3668{
3669 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003670 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3671 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003672
3673 return "bctg";
3674}
3675
florian55085f82012-11-21 00:36:55 +00003676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003677s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3678{
3679 IRTemp value = newTemp(Ity_I32);
3680
3681 assign(value, get_gpr_w1(r3 | 1));
3682 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003683 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3684 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003685
3686 return "bxh";
3687}
3688
florian55085f82012-11-21 00:36:55 +00003689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003690s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3691{
3692 IRTemp value = newTemp(Ity_I64);
3693
3694 assign(value, get_gpr_dw0(r3 | 1));
3695 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003696 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3697 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003698
3699 return "bxhg";
3700}
3701
florian55085f82012-11-21 00:36:55 +00003702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003703s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3704{
3705 IRTemp value = newTemp(Ity_I32);
3706
3707 assign(value, get_gpr_w1(r3 | 1));
3708 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003709 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3710 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003711
3712 return "bxle";
3713}
3714
florian55085f82012-11-21 00:36:55 +00003715static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003716s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3717{
3718 IRTemp value = newTemp(Ity_I64);
3719
3720 assign(value, get_gpr_dw0(r3 | 1));
3721 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003722 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3723 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003724
3725 return "bxleg";
3726}
3727
florian55085f82012-11-21 00:36:55 +00003728static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003729s390_irgen_BRAS(UChar r1, UShort i2)
3730{
3731 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003732 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003733
3734 return "bras";
3735}
3736
florian55085f82012-11-21 00:36:55 +00003737static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003738s390_irgen_BRASL(UChar r1, UInt i2)
3739{
3740 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003741 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003742
3743 return "brasl";
3744}
3745
florian55085f82012-11-21 00:36:55 +00003746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003747s390_irgen_BRC(UChar r1, UShort i2)
3748{
3749 IRTemp cond = newTemp(Ity_I32);
3750
3751 if (r1 == 0) {
3752 } else {
3753 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003754 always_goto_and_chase(
3755 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003756 } else {
3757 assign(cond, s390_call_calculate_cond(r1));
3758 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3759 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3760
3761 }
3762 }
sewardj7ee97522011-05-09 21:45:04 +00003763 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003764 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3765
3766 return "brc";
3767}
3768
florian55085f82012-11-21 00:36:55 +00003769static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003770s390_irgen_BRCL(UChar r1, UInt i2)
3771{
3772 IRTemp cond = newTemp(Ity_I32);
3773
3774 if (r1 == 0) {
3775 } else {
3776 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003777 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003778 } else {
3779 assign(cond, s390_call_calculate_cond(r1));
3780 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3781 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3782 }
3783 }
sewardj7ee97522011-05-09 21:45:04 +00003784 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003785 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3786
3787 return "brcl";
3788}
3789
florian55085f82012-11-21 00:36:55 +00003790static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003791s390_irgen_BRCT(UChar r1, UShort i2)
3792{
3793 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3794 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3795 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3796
3797 return "brct";
3798}
3799
florian55085f82012-11-21 00:36:55 +00003800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003801s390_irgen_BRCTG(UChar r1, UShort i2)
3802{
3803 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3804 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3805 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3806
3807 return "brctg";
3808}
3809
florian55085f82012-11-21 00:36:55 +00003810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003811s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3812{
3813 IRTemp value = newTemp(Ity_I32);
3814
3815 assign(value, get_gpr_w1(r3 | 1));
3816 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3817 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3818 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3819
3820 return "brxh";
3821}
3822
florian55085f82012-11-21 00:36:55 +00003823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003824s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3825{
3826 IRTemp value = newTemp(Ity_I64);
3827
3828 assign(value, get_gpr_dw0(r3 | 1));
3829 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3830 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3831 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3832
3833 return "brxhg";
3834}
3835
florian55085f82012-11-21 00:36:55 +00003836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003837s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3838{
3839 IRTemp value = newTemp(Ity_I32);
3840
3841 assign(value, get_gpr_w1(r3 | 1));
3842 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3843 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3844 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3845
3846 return "brxle";
3847}
3848
florian55085f82012-11-21 00:36:55 +00003849static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003850s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3851{
3852 IRTemp value = newTemp(Ity_I64);
3853
3854 assign(value, get_gpr_dw0(r3 | 1));
3855 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3856 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3857 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3858
3859 return "brxlg";
3860}
3861
florian55085f82012-11-21 00:36:55 +00003862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003863s390_irgen_CR(UChar r1, UChar r2)
3864{
3865 IRTemp op1 = newTemp(Ity_I32);
3866 IRTemp op2 = newTemp(Ity_I32);
3867
3868 assign(op1, get_gpr_w1(r1));
3869 assign(op2, get_gpr_w1(r2));
3870 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3871
3872 return "cr";
3873}
3874
florian55085f82012-11-21 00:36:55 +00003875static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003876s390_irgen_CGR(UChar r1, UChar r2)
3877{
3878 IRTemp op1 = newTemp(Ity_I64);
3879 IRTemp op2 = newTemp(Ity_I64);
3880
3881 assign(op1, get_gpr_dw0(r1));
3882 assign(op2, get_gpr_dw0(r2));
3883 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3884
3885 return "cgr";
3886}
3887
florian55085f82012-11-21 00:36:55 +00003888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003889s390_irgen_CGFR(UChar r1, UChar r2)
3890{
3891 IRTemp op1 = newTemp(Ity_I64);
3892 IRTemp op2 = newTemp(Ity_I64);
3893
3894 assign(op1, get_gpr_dw0(r1));
3895 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3896 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3897
3898 return "cgfr";
3899}
3900
florian55085f82012-11-21 00:36:55 +00003901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003902s390_irgen_C(UChar r1, IRTemp op2addr)
3903{
3904 IRTemp op1 = newTemp(Ity_I32);
3905 IRTemp op2 = newTemp(Ity_I32);
3906
3907 assign(op1, get_gpr_w1(r1));
3908 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3909 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3910
3911 return "c";
3912}
3913
florian55085f82012-11-21 00:36:55 +00003914static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003915s390_irgen_CY(UChar r1, IRTemp op2addr)
3916{
3917 IRTemp op1 = newTemp(Ity_I32);
3918 IRTemp op2 = newTemp(Ity_I32);
3919
3920 assign(op1, get_gpr_w1(r1));
3921 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3922 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3923
3924 return "cy";
3925}
3926
florian55085f82012-11-21 00:36:55 +00003927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003928s390_irgen_CG(UChar r1, IRTemp op2addr)
3929{
3930 IRTemp op1 = newTemp(Ity_I64);
3931 IRTemp op2 = newTemp(Ity_I64);
3932
3933 assign(op1, get_gpr_dw0(r1));
3934 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3935 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3936
3937 return "cg";
3938}
3939
florian55085f82012-11-21 00:36:55 +00003940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003941s390_irgen_CGF(UChar r1, IRTemp op2addr)
3942{
3943 IRTemp op1 = newTemp(Ity_I64);
3944 IRTemp op2 = newTemp(Ity_I64);
3945
3946 assign(op1, get_gpr_dw0(r1));
3947 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3948 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3949
3950 return "cgf";
3951}
3952
florian55085f82012-11-21 00:36:55 +00003953static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003954s390_irgen_CFI(UChar r1, UInt i2)
3955{
3956 IRTemp op1 = newTemp(Ity_I32);
3957 Int op2;
3958
3959 assign(op1, get_gpr_w1(r1));
3960 op2 = (Int)i2;
3961 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3962 mkU32((UInt)op2)));
3963
3964 return "cfi";
3965}
3966
florian55085f82012-11-21 00:36:55 +00003967static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003968s390_irgen_CGFI(UChar r1, UInt i2)
3969{
3970 IRTemp op1 = newTemp(Ity_I64);
3971 Long op2;
3972
3973 assign(op1, get_gpr_dw0(r1));
3974 op2 = (Long)(Int)i2;
3975 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3976 mkU64((ULong)op2)));
3977
3978 return "cgfi";
3979}
3980
florian55085f82012-11-21 00:36:55 +00003981static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003982s390_irgen_CRL(UChar r1, UInt i2)
3983{
3984 IRTemp op1 = newTemp(Ity_I32);
3985 IRTemp op2 = newTemp(Ity_I32);
3986
3987 assign(op1, get_gpr_w1(r1));
3988 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3989 i2 << 1))));
3990 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3991
3992 return "crl";
3993}
3994
florian55085f82012-11-21 00:36:55 +00003995static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003996s390_irgen_CGRL(UChar r1, UInt i2)
3997{
3998 IRTemp op1 = newTemp(Ity_I64);
3999 IRTemp op2 = newTemp(Ity_I64);
4000
4001 assign(op1, get_gpr_dw0(r1));
4002 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4003 i2 << 1))));
4004 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4005
4006 return "cgrl";
4007}
4008
florian55085f82012-11-21 00:36:55 +00004009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004010s390_irgen_CGFRL(UChar r1, UInt i2)
4011{
4012 IRTemp op1 = newTemp(Ity_I64);
4013 IRTemp op2 = newTemp(Ity_I64);
4014
4015 assign(op1, get_gpr_dw0(r1));
4016 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4017 ((ULong)(Long)(Int)i2 << 1)))));
4018 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4019
4020 return "cgfrl";
4021}
4022
florian55085f82012-11-21 00:36:55 +00004023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004024s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
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) {
4033 always_goto(mkexpr(op4addr));
4034 } else {
4035 assign(op1, get_gpr_w1(r1));
4036 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004037 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4038 op1, op2));
florianf321da72012-07-21 20:32:57 +00004039 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4040 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004041 }
4042 }
4043
4044 return "crb";
4045}
4046
florian55085f82012-11-21 00:36:55 +00004047static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004048s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4049{
4050 IRTemp op1 = newTemp(Ity_I64);
4051 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004052 IRTemp cond = newTemp(Ity_I32);
4053
4054 if (m3 == 0) {
4055 } else {
4056 if (m3 == 14) {
4057 always_goto(mkexpr(op4addr));
4058 } else {
4059 assign(op1, get_gpr_dw0(r1));
4060 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004061 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4062 op1, op2));
florianf321da72012-07-21 20:32:57 +00004063 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4064 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004065 }
4066 }
4067
4068 return "cgrb";
4069}
4070
florian55085f82012-11-21 00:36:55 +00004071static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004072s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4073{
4074 IRTemp op1 = newTemp(Ity_I32);
4075 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004076 IRTemp cond = newTemp(Ity_I32);
4077
4078 if (m3 == 0) {
4079 } else {
4080 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004081 always_goto_and_chase(
4082 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004083 } else {
4084 assign(op1, get_gpr_w1(r1));
4085 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004086 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4087 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004088 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4089 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4090
4091 }
4092 }
4093
4094 return "crj";
4095}
4096
florian55085f82012-11-21 00:36:55 +00004097static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004098s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4099{
4100 IRTemp op1 = newTemp(Ity_I64);
4101 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004102 IRTemp cond = newTemp(Ity_I32);
4103
4104 if (m3 == 0) {
4105 } else {
4106 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004107 always_goto_and_chase(
4108 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004109 } else {
4110 assign(op1, get_gpr_dw0(r1));
4111 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004112 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4113 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004114 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4115 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4116
4117 }
4118 }
4119
4120 return "cgrj";
4121}
4122
florian55085f82012-11-21 00:36:55 +00004123static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004124s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
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) {
4133 always_goto(mkexpr(op4addr));
4134 } 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))));
florianf321da72012-07-21 20:32:57 +00004139 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4140 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004141 }
4142 }
4143
4144 return "cib";
4145}
4146
florian55085f82012-11-21 00:36:55 +00004147static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004148s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4149{
4150 IRTemp op1 = newTemp(Ity_I64);
4151 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004152 IRTemp cond = newTemp(Ity_I32);
4153
4154 if (m3 == 0) {
4155 } else {
4156 if (m3 == 14) {
4157 always_goto(mkexpr(op4addr));
4158 } else {
4159 assign(op1, get_gpr_dw0(r1));
4160 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004161 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4162 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004163 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4164 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004165 }
4166 }
4167
4168 return "cgib";
4169}
4170
florian55085f82012-11-21 00:36:55 +00004171static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004172s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4173{
4174 IRTemp op1 = newTemp(Ity_I32);
4175 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004176 IRTemp cond = newTemp(Ity_I32);
4177
4178 if (m3 == 0) {
4179 } else {
4180 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004181 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004182 } else {
4183 assign(op1, get_gpr_w1(r1));
4184 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004185 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4186 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004187 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4188 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4189
4190 }
4191 }
4192
4193 return "cij";
4194}
4195
florian55085f82012-11-21 00:36:55 +00004196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004197s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4198{
4199 IRTemp op1 = newTemp(Ity_I64);
4200 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004201 IRTemp cond = newTemp(Ity_I32);
4202
4203 if (m3 == 0) {
4204 } else {
4205 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004206 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004207 } else {
4208 assign(op1, get_gpr_dw0(r1));
4209 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004210 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4211 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004212 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4213 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4214
4215 }
4216 }
4217
4218 return "cgij";
4219}
4220
florian55085f82012-11-21 00:36:55 +00004221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004222s390_irgen_CH(UChar r1, IRTemp op2addr)
4223{
4224 IRTemp op1 = newTemp(Ity_I32);
4225 IRTemp op2 = newTemp(Ity_I32);
4226
4227 assign(op1, get_gpr_w1(r1));
4228 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4229 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4230
4231 return "ch";
4232}
4233
florian55085f82012-11-21 00:36:55 +00004234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004235s390_irgen_CHY(UChar r1, IRTemp op2addr)
4236{
4237 IRTemp op1 = newTemp(Ity_I32);
4238 IRTemp op2 = newTemp(Ity_I32);
4239
4240 assign(op1, get_gpr_w1(r1));
4241 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4242 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4243
4244 return "chy";
4245}
4246
florian55085f82012-11-21 00:36:55 +00004247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004248s390_irgen_CGH(UChar r1, IRTemp op2addr)
4249{
4250 IRTemp op1 = newTemp(Ity_I64);
4251 IRTemp op2 = newTemp(Ity_I64);
4252
4253 assign(op1, get_gpr_dw0(r1));
4254 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4255 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4256
4257 return "cgh";
4258}
4259
florian55085f82012-11-21 00:36:55 +00004260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004261s390_irgen_CHI(UChar r1, UShort i2)
4262{
4263 IRTemp op1 = newTemp(Ity_I32);
4264 Int op2;
4265
4266 assign(op1, get_gpr_w1(r1));
4267 op2 = (Int)(Short)i2;
4268 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4269 mkU32((UInt)op2)));
4270
4271 return "chi";
4272}
4273
florian55085f82012-11-21 00:36:55 +00004274static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004275s390_irgen_CGHI(UChar r1, UShort i2)
4276{
4277 IRTemp op1 = newTemp(Ity_I64);
4278 Long op2;
4279
4280 assign(op1, get_gpr_dw0(r1));
4281 op2 = (Long)(Short)i2;
4282 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4283 mkU64((ULong)op2)));
4284
4285 return "cghi";
4286}
4287
florian55085f82012-11-21 00:36:55 +00004288static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004289s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4290{
4291 IRTemp op1 = newTemp(Ity_I16);
4292 Short op2;
4293
4294 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4295 op2 = (Short)i2;
4296 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4297 mkU16((UShort)op2)));
4298
4299 return "chhsi";
4300}
4301
florian55085f82012-11-21 00:36:55 +00004302static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004303s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4304{
4305 IRTemp op1 = newTemp(Ity_I32);
4306 Int op2;
4307
4308 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4309 op2 = (Int)(Short)i2;
4310 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4311 mkU32((UInt)op2)));
4312
4313 return "chsi";
4314}
4315
florian55085f82012-11-21 00:36:55 +00004316static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004317s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4318{
4319 IRTemp op1 = newTemp(Ity_I64);
4320 Long op2;
4321
4322 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4323 op2 = (Long)(Short)i2;
4324 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4325 mkU64((ULong)op2)));
4326
4327 return "cghsi";
4328}
4329
florian55085f82012-11-21 00:36:55 +00004330static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004331s390_irgen_CHRL(UChar r1, UInt i2)
4332{
4333 IRTemp op1 = newTemp(Ity_I32);
4334 IRTemp op2 = newTemp(Ity_I32);
4335
4336 assign(op1, get_gpr_w1(r1));
4337 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4338 ((ULong)(Long)(Int)i2 << 1)))));
4339 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4340
4341 return "chrl";
4342}
4343
florian55085f82012-11-21 00:36:55 +00004344static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004345s390_irgen_CGHRL(UChar r1, UInt i2)
4346{
4347 IRTemp op1 = newTemp(Ity_I64);
4348 IRTemp op2 = newTemp(Ity_I64);
4349
4350 assign(op1, get_gpr_dw0(r1));
4351 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4352 ((ULong)(Long)(Int)i2 << 1)))));
4353 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4354
4355 return "cghrl";
4356}
4357
florian55085f82012-11-21 00:36:55 +00004358static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004359s390_irgen_CHHR(UChar r1, UChar r2)
4360{
4361 IRTemp op1 = newTemp(Ity_I32);
4362 IRTemp op2 = newTemp(Ity_I32);
4363
4364 assign(op1, get_gpr_w0(r1));
4365 assign(op2, get_gpr_w0(r2));
4366 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4367
4368 return "chhr";
4369}
4370
florian55085f82012-11-21 00:36:55 +00004371static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004372s390_irgen_CHLR(UChar r1, UChar r2)
4373{
4374 IRTemp op1 = newTemp(Ity_I32);
4375 IRTemp op2 = newTemp(Ity_I32);
4376
4377 assign(op1, get_gpr_w0(r1));
4378 assign(op2, get_gpr_w1(r2));
4379 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4380
4381 return "chlr";
4382}
4383
florian55085f82012-11-21 00:36:55 +00004384static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004385s390_irgen_CHF(UChar r1, IRTemp op2addr)
4386{
4387 IRTemp op1 = newTemp(Ity_I32);
4388 IRTemp op2 = newTemp(Ity_I32);
4389
4390 assign(op1, get_gpr_w0(r1));
4391 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4392 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4393
4394 return "chf";
4395}
4396
florian55085f82012-11-21 00:36:55 +00004397static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004398s390_irgen_CIH(UChar r1, UInt i2)
4399{
4400 IRTemp op1 = newTemp(Ity_I32);
4401 Int op2;
4402
4403 assign(op1, get_gpr_w0(r1));
4404 op2 = (Int)i2;
4405 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4406 mkU32((UInt)op2)));
4407
4408 return "cih";
4409}
4410
florian55085f82012-11-21 00:36:55 +00004411static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004412s390_irgen_CLR(UChar r1, UChar r2)
4413{
4414 IRTemp op1 = newTemp(Ity_I32);
4415 IRTemp op2 = newTemp(Ity_I32);
4416
4417 assign(op1, get_gpr_w1(r1));
4418 assign(op2, get_gpr_w1(r2));
4419 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4420
4421 return "clr";
4422}
4423
florian55085f82012-11-21 00:36:55 +00004424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004425s390_irgen_CLGR(UChar r1, UChar r2)
4426{
4427 IRTemp op1 = newTemp(Ity_I64);
4428 IRTemp op2 = newTemp(Ity_I64);
4429
4430 assign(op1, get_gpr_dw0(r1));
4431 assign(op2, get_gpr_dw0(r2));
4432 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4433
4434 return "clgr";
4435}
4436
florian55085f82012-11-21 00:36:55 +00004437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004438s390_irgen_CLGFR(UChar r1, UChar r2)
4439{
4440 IRTemp op1 = newTemp(Ity_I64);
4441 IRTemp op2 = newTemp(Ity_I64);
4442
4443 assign(op1, get_gpr_dw0(r1));
4444 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4445 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4446
4447 return "clgfr";
4448}
4449
florian55085f82012-11-21 00:36:55 +00004450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004451s390_irgen_CL(UChar r1, IRTemp op2addr)
4452{
4453 IRTemp op1 = newTemp(Ity_I32);
4454 IRTemp op2 = newTemp(Ity_I32);
4455
4456 assign(op1, get_gpr_w1(r1));
4457 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4458 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4459
4460 return "cl";
4461}
4462
florian55085f82012-11-21 00:36:55 +00004463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004464s390_irgen_CLY(UChar r1, IRTemp op2addr)
4465{
4466 IRTemp op1 = newTemp(Ity_I32);
4467 IRTemp op2 = newTemp(Ity_I32);
4468
4469 assign(op1, get_gpr_w1(r1));
4470 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4471 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4472
4473 return "cly";
4474}
4475
florian55085f82012-11-21 00:36:55 +00004476static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004477s390_irgen_CLG(UChar r1, IRTemp op2addr)
4478{
4479 IRTemp op1 = newTemp(Ity_I64);
4480 IRTemp op2 = newTemp(Ity_I64);
4481
4482 assign(op1, get_gpr_dw0(r1));
4483 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4484 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4485
4486 return "clg";
4487}
4488
florian55085f82012-11-21 00:36:55 +00004489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004490s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4491{
4492 IRTemp op1 = newTemp(Ity_I64);
4493 IRTemp op2 = newTemp(Ity_I64);
4494
4495 assign(op1, get_gpr_dw0(r1));
4496 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4497 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4498
4499 return "clgf";
4500}
4501
florian55085f82012-11-21 00:36:55 +00004502static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004503s390_irgen_CLFI(UChar r1, UInt i2)
4504{
4505 IRTemp op1 = newTemp(Ity_I32);
4506 UInt op2;
4507
4508 assign(op1, get_gpr_w1(r1));
4509 op2 = i2;
4510 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4511 mkU32(op2)));
4512
4513 return "clfi";
4514}
4515
florian55085f82012-11-21 00:36:55 +00004516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004517s390_irgen_CLGFI(UChar r1, UInt i2)
4518{
4519 IRTemp op1 = newTemp(Ity_I64);
4520 ULong op2;
4521
4522 assign(op1, get_gpr_dw0(r1));
4523 op2 = (ULong)i2;
4524 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4525 mkU64(op2)));
4526
4527 return "clgfi";
4528}
4529
florian55085f82012-11-21 00:36:55 +00004530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004531s390_irgen_CLI(UChar i2, IRTemp op1addr)
4532{
4533 IRTemp op1 = newTemp(Ity_I8);
4534 UChar op2;
4535
4536 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4537 op2 = i2;
4538 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4539 mkU8(op2)));
4540
4541 return "cli";
4542}
4543
florian55085f82012-11-21 00:36:55 +00004544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004545s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4546{
4547 IRTemp op1 = newTemp(Ity_I8);
4548 UChar op2;
4549
4550 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4551 op2 = i2;
4552 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4553 mkU8(op2)));
4554
4555 return "cliy";
4556}
4557
florian55085f82012-11-21 00:36:55 +00004558static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004559s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4560{
4561 IRTemp op1 = newTemp(Ity_I32);
4562 UInt op2;
4563
4564 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4565 op2 = (UInt)i2;
4566 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4567 mkU32(op2)));
4568
4569 return "clfhsi";
4570}
4571
florian55085f82012-11-21 00:36:55 +00004572static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004573s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4574{
4575 IRTemp op1 = newTemp(Ity_I64);
4576 ULong op2;
4577
4578 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4579 op2 = (ULong)i2;
4580 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4581 mkU64(op2)));
4582
4583 return "clghsi";
4584}
4585
florian55085f82012-11-21 00:36:55 +00004586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004587s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4588{
4589 IRTemp op1 = newTemp(Ity_I16);
4590 UShort op2;
4591
4592 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4593 op2 = i2;
4594 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4595 mkU16(op2)));
4596
4597 return "clhhsi";
4598}
4599
florian55085f82012-11-21 00:36:55 +00004600static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004601s390_irgen_CLRL(UChar r1, UInt i2)
4602{
4603 IRTemp op1 = newTemp(Ity_I32);
4604 IRTemp op2 = newTemp(Ity_I32);
4605
4606 assign(op1, get_gpr_w1(r1));
4607 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4608 i2 << 1))));
4609 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4610
4611 return "clrl";
4612}
4613
florian55085f82012-11-21 00:36:55 +00004614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004615s390_irgen_CLGRL(UChar r1, UInt i2)
4616{
4617 IRTemp op1 = newTemp(Ity_I64);
4618 IRTemp op2 = newTemp(Ity_I64);
4619
4620 assign(op1, get_gpr_dw0(r1));
4621 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4622 i2 << 1))));
4623 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4624
4625 return "clgrl";
4626}
4627
florian55085f82012-11-21 00:36:55 +00004628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004629s390_irgen_CLGFRL(UChar r1, UInt i2)
4630{
4631 IRTemp op1 = newTemp(Ity_I64);
4632 IRTemp op2 = newTemp(Ity_I64);
4633
4634 assign(op1, get_gpr_dw0(r1));
4635 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4636 ((ULong)(Long)(Int)i2 << 1)))));
4637 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4638
4639 return "clgfrl";
4640}
4641
florian55085f82012-11-21 00:36:55 +00004642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004643s390_irgen_CLHRL(UChar r1, UInt i2)
4644{
4645 IRTemp op1 = newTemp(Ity_I32);
4646 IRTemp op2 = newTemp(Ity_I32);
4647
4648 assign(op1, get_gpr_w1(r1));
4649 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4650 ((ULong)(Long)(Int)i2 << 1)))));
4651 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4652
4653 return "clhrl";
4654}
4655
florian55085f82012-11-21 00:36:55 +00004656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004657s390_irgen_CLGHRL(UChar r1, UInt i2)
4658{
4659 IRTemp op1 = newTemp(Ity_I64);
4660 IRTemp op2 = newTemp(Ity_I64);
4661
4662 assign(op1, get_gpr_dw0(r1));
4663 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4664 ((ULong)(Long)(Int)i2 << 1)))));
4665 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4666
4667 return "clghrl";
4668}
4669
florian55085f82012-11-21 00:36:55 +00004670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004671s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
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) {
4680 always_goto(mkexpr(op4addr));
4681 } 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));
florianf321da72012-07-21 20:32:57 +00004686 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4687 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004688 }
4689 }
4690
4691 return "clrb";
4692}
4693
florian55085f82012-11-21 00:36:55 +00004694static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004695s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4696{
4697 IRTemp op1 = newTemp(Ity_I64);
4698 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004699 IRTemp cond = newTemp(Ity_I32);
4700
4701 if (m3 == 0) {
4702 } else {
4703 if (m3 == 14) {
4704 always_goto(mkexpr(op4addr));
4705 } else {
4706 assign(op1, get_gpr_dw0(r1));
4707 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004708 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4709 op1, op2));
florianf321da72012-07-21 20:32:57 +00004710 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4711 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004712 }
4713 }
4714
4715 return "clgrb";
4716}
4717
florian55085f82012-11-21 00:36:55 +00004718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004719s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4720{
4721 IRTemp op1 = newTemp(Ity_I32);
4722 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004723 IRTemp cond = newTemp(Ity_I32);
4724
4725 if (m3 == 0) {
4726 } else {
4727 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004728 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004729 } else {
4730 assign(op1, get_gpr_w1(r1));
4731 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004732 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4733 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004734 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4735 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4736
4737 }
4738 }
4739
4740 return "clrj";
4741}
4742
florian55085f82012-11-21 00:36:55 +00004743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004744s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4745{
4746 IRTemp op1 = newTemp(Ity_I64);
4747 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004748 IRTemp cond = newTemp(Ity_I32);
4749
4750 if (m3 == 0) {
4751 } else {
4752 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004753 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004754 } else {
4755 assign(op1, get_gpr_dw0(r1));
4756 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004757 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4758 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004759 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4760 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4761
4762 }
4763 }
4764
4765 return "clgrj";
4766}
4767
florian55085f82012-11-21 00:36:55 +00004768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004769s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
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) {
4778 always_goto(mkexpr(op4addr));
4779 } 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))));
florianf321da72012-07-21 20:32:57 +00004784 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4785 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004786 }
4787 }
4788
4789 return "clib";
4790}
4791
florian55085f82012-11-21 00:36:55 +00004792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004793s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4794{
4795 IRTemp op1 = newTemp(Ity_I64);
4796 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004797 IRTemp cond = newTemp(Ity_I32);
4798
4799 if (m3 == 0) {
4800 } else {
4801 if (m3 == 14) {
4802 always_goto(mkexpr(op4addr));
4803 } else {
4804 assign(op1, get_gpr_dw0(r1));
4805 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004806 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4807 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004808 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4809 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004810 }
4811 }
4812
4813 return "clgib";
4814}
4815
florian55085f82012-11-21 00:36:55 +00004816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004817s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4818{
4819 IRTemp op1 = newTemp(Ity_I32);
4820 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004821 IRTemp cond = newTemp(Ity_I32);
4822
4823 if (m3 == 0) {
4824 } else {
4825 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004826 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004827 } else {
4828 assign(op1, get_gpr_w1(r1));
4829 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004830 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4831 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004832 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4833 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4834
4835 }
4836 }
4837
4838 return "clij";
4839}
4840
florian55085f82012-11-21 00:36:55 +00004841static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004842s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4843{
4844 IRTemp op1 = newTemp(Ity_I64);
4845 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004846 IRTemp cond = newTemp(Ity_I32);
4847
4848 if (m3 == 0) {
4849 } else {
4850 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004851 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004852 } else {
4853 assign(op1, get_gpr_dw0(r1));
4854 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004855 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4856 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004857 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4858 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4859
4860 }
4861 }
4862
4863 return "clgij";
4864}
4865
florian55085f82012-11-21 00:36:55 +00004866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004867s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4868{
4869 IRTemp op1 = newTemp(Ity_I32);
4870 IRTemp op2 = newTemp(Ity_I32);
4871 IRTemp b0 = newTemp(Ity_I32);
4872 IRTemp b1 = newTemp(Ity_I32);
4873 IRTemp b2 = newTemp(Ity_I32);
4874 IRTemp b3 = newTemp(Ity_I32);
4875 IRTemp c0 = newTemp(Ity_I32);
4876 IRTemp c1 = newTemp(Ity_I32);
4877 IRTemp c2 = newTemp(Ity_I32);
4878 IRTemp c3 = newTemp(Ity_I32);
4879 UChar n;
4880
4881 n = 0;
4882 if ((r3 & 8) != 0) {
4883 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4884 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4885 n = n + 1;
4886 } else {
4887 assign(b0, mkU32(0));
4888 assign(c0, mkU32(0));
4889 }
4890 if ((r3 & 4) != 0) {
4891 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4892 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4893 mkU64(n)))));
4894 n = n + 1;
4895 } else {
4896 assign(b1, mkU32(0));
4897 assign(c1, mkU32(0));
4898 }
4899 if ((r3 & 2) != 0) {
4900 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4901 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4902 mkU64(n)))));
4903 n = n + 1;
4904 } else {
4905 assign(b2, mkU32(0));
4906 assign(c2, mkU32(0));
4907 }
4908 if ((r3 & 1) != 0) {
4909 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4910 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4911 mkU64(n)))));
4912 n = n + 1;
4913 } else {
4914 assign(b3, mkU32(0));
4915 assign(c3, mkU32(0));
4916 }
4917 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4918 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4919 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4920 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4921 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4922 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4923 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4924
4925 return "clm";
4926}
4927
florian55085f82012-11-21 00:36:55 +00004928static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004929s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4930{
4931 IRTemp op1 = newTemp(Ity_I32);
4932 IRTemp op2 = newTemp(Ity_I32);
4933 IRTemp b0 = newTemp(Ity_I32);
4934 IRTemp b1 = newTemp(Ity_I32);
4935 IRTemp b2 = newTemp(Ity_I32);
4936 IRTemp b3 = newTemp(Ity_I32);
4937 IRTemp c0 = newTemp(Ity_I32);
4938 IRTemp c1 = newTemp(Ity_I32);
4939 IRTemp c2 = newTemp(Ity_I32);
4940 IRTemp c3 = newTemp(Ity_I32);
4941 UChar n;
4942
4943 n = 0;
4944 if ((r3 & 8) != 0) {
4945 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4946 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4947 n = n + 1;
4948 } else {
4949 assign(b0, mkU32(0));
4950 assign(c0, mkU32(0));
4951 }
4952 if ((r3 & 4) != 0) {
4953 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4954 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4955 mkU64(n)))));
4956 n = n + 1;
4957 } else {
4958 assign(b1, mkU32(0));
4959 assign(c1, mkU32(0));
4960 }
4961 if ((r3 & 2) != 0) {
4962 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4963 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4964 mkU64(n)))));
4965 n = n + 1;
4966 } else {
4967 assign(b2, mkU32(0));
4968 assign(c2, mkU32(0));
4969 }
4970 if ((r3 & 1) != 0) {
4971 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4972 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4973 mkU64(n)))));
4974 n = n + 1;
4975 } else {
4976 assign(b3, mkU32(0));
4977 assign(c3, mkU32(0));
4978 }
4979 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4980 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4981 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4982 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4983 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4984 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4985 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4986
4987 return "clmy";
4988}
4989
florian55085f82012-11-21 00:36:55 +00004990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004991s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4992{
4993 IRTemp op1 = newTemp(Ity_I32);
4994 IRTemp op2 = newTemp(Ity_I32);
4995 IRTemp b0 = newTemp(Ity_I32);
4996 IRTemp b1 = newTemp(Ity_I32);
4997 IRTemp b2 = newTemp(Ity_I32);
4998 IRTemp b3 = newTemp(Ity_I32);
4999 IRTemp c0 = newTemp(Ity_I32);
5000 IRTemp c1 = newTemp(Ity_I32);
5001 IRTemp c2 = newTemp(Ity_I32);
5002 IRTemp c3 = newTemp(Ity_I32);
5003 UChar n;
5004
5005 n = 0;
5006 if ((r3 & 8) != 0) {
5007 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5008 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5009 n = n + 1;
5010 } else {
5011 assign(b0, mkU32(0));
5012 assign(c0, mkU32(0));
5013 }
5014 if ((r3 & 4) != 0) {
5015 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5016 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5017 mkU64(n)))));
5018 n = n + 1;
5019 } else {
5020 assign(b1, mkU32(0));
5021 assign(c1, mkU32(0));
5022 }
5023 if ((r3 & 2) != 0) {
5024 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5025 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5026 mkU64(n)))));
5027 n = n + 1;
5028 } else {
5029 assign(b2, mkU32(0));
5030 assign(c2, mkU32(0));
5031 }
5032 if ((r3 & 1) != 0) {
5033 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5034 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5035 mkU64(n)))));
5036 n = n + 1;
5037 } else {
5038 assign(b3, mkU32(0));
5039 assign(c3, mkU32(0));
5040 }
5041 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5042 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5043 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5044 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5045 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5046 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5047 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5048
5049 return "clmh";
5050}
5051
florian55085f82012-11-21 00:36:55 +00005052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005053s390_irgen_CLHHR(UChar r1, UChar r2)
5054{
5055 IRTemp op1 = newTemp(Ity_I32);
5056 IRTemp op2 = newTemp(Ity_I32);
5057
5058 assign(op1, get_gpr_w0(r1));
5059 assign(op2, get_gpr_w0(r2));
5060 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5061
5062 return "clhhr";
5063}
5064
florian55085f82012-11-21 00:36:55 +00005065static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005066s390_irgen_CLHLR(UChar r1, UChar r2)
5067{
5068 IRTemp op1 = newTemp(Ity_I32);
5069 IRTemp op2 = newTemp(Ity_I32);
5070
5071 assign(op1, get_gpr_w0(r1));
5072 assign(op2, get_gpr_w1(r2));
5073 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5074
5075 return "clhlr";
5076}
5077
florian55085f82012-11-21 00:36:55 +00005078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005079s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5080{
5081 IRTemp op1 = newTemp(Ity_I32);
5082 IRTemp op2 = newTemp(Ity_I32);
5083
5084 assign(op1, get_gpr_w0(r1));
5085 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5086 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5087
5088 return "clhf";
5089}
5090
florian55085f82012-11-21 00:36:55 +00005091static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005092s390_irgen_CLIH(UChar r1, UInt i2)
5093{
5094 IRTemp op1 = newTemp(Ity_I32);
5095 UInt op2;
5096
5097 assign(op1, get_gpr_w0(r1));
5098 op2 = i2;
5099 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5100 mkU32(op2)));
5101
5102 return "clih";
5103}
5104
florian55085f82012-11-21 00:36:55 +00005105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005106s390_irgen_CPYA(UChar r1, UChar r2)
5107{
5108 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005109 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005110 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5111
5112 return "cpya";
5113}
5114
florian55085f82012-11-21 00:36:55 +00005115static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005116s390_irgen_XR(UChar r1, UChar r2)
5117{
5118 IRTemp op1 = newTemp(Ity_I32);
5119 IRTemp op2 = newTemp(Ity_I32);
5120 IRTemp result = newTemp(Ity_I32);
5121
5122 if (r1 == r2) {
5123 assign(result, mkU32(0));
5124 } else {
5125 assign(op1, get_gpr_w1(r1));
5126 assign(op2, get_gpr_w1(r2));
5127 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5128 }
5129 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5130 put_gpr_w1(r1, mkexpr(result));
5131
5132 return "xr";
5133}
5134
florian55085f82012-11-21 00:36:55 +00005135static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005136s390_irgen_XGR(UChar r1, UChar r2)
5137{
5138 IRTemp op1 = newTemp(Ity_I64);
5139 IRTemp op2 = newTemp(Ity_I64);
5140 IRTemp result = newTemp(Ity_I64);
5141
5142 if (r1 == r2) {
5143 assign(result, mkU64(0));
5144 } else {
5145 assign(op1, get_gpr_dw0(r1));
5146 assign(op2, get_gpr_dw0(r2));
5147 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5148 }
5149 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5150 put_gpr_dw0(r1, mkexpr(result));
5151
5152 return "xgr";
5153}
5154
florian55085f82012-11-21 00:36:55 +00005155static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005156s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5157{
5158 IRTemp op2 = newTemp(Ity_I32);
5159 IRTemp op3 = newTemp(Ity_I32);
5160 IRTemp result = newTemp(Ity_I32);
5161
5162 assign(op2, get_gpr_w1(r2));
5163 assign(op3, get_gpr_w1(r3));
5164 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5165 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5166 put_gpr_w1(r1, mkexpr(result));
5167
5168 return "xrk";
5169}
5170
florian55085f82012-11-21 00:36:55 +00005171static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005172s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5173{
5174 IRTemp op2 = newTemp(Ity_I64);
5175 IRTemp op3 = newTemp(Ity_I64);
5176 IRTemp result = newTemp(Ity_I64);
5177
5178 assign(op2, get_gpr_dw0(r2));
5179 assign(op3, get_gpr_dw0(r3));
5180 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5181 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5182 put_gpr_dw0(r1, mkexpr(result));
5183
5184 return "xgrk";
5185}
5186
florian55085f82012-11-21 00:36:55 +00005187static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005188s390_irgen_X(UChar r1, IRTemp op2addr)
5189{
5190 IRTemp op1 = newTemp(Ity_I32);
5191 IRTemp op2 = newTemp(Ity_I32);
5192 IRTemp result = newTemp(Ity_I32);
5193
5194 assign(op1, get_gpr_w1(r1));
5195 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5196 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5197 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5198 put_gpr_w1(r1, mkexpr(result));
5199
5200 return "x";
5201}
5202
florian55085f82012-11-21 00:36:55 +00005203static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005204s390_irgen_XY(UChar r1, IRTemp op2addr)
5205{
5206 IRTemp op1 = newTemp(Ity_I32);
5207 IRTemp op2 = newTemp(Ity_I32);
5208 IRTemp result = newTemp(Ity_I32);
5209
5210 assign(op1, get_gpr_w1(r1));
5211 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5212 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5213 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5214 put_gpr_w1(r1, mkexpr(result));
5215
5216 return "xy";
5217}
5218
florian55085f82012-11-21 00:36:55 +00005219static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005220s390_irgen_XG(UChar r1, IRTemp op2addr)
5221{
5222 IRTemp op1 = newTemp(Ity_I64);
5223 IRTemp op2 = newTemp(Ity_I64);
5224 IRTemp result = newTemp(Ity_I64);
5225
5226 assign(op1, get_gpr_dw0(r1));
5227 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5228 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5229 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5230 put_gpr_dw0(r1, mkexpr(result));
5231
5232 return "xg";
5233}
5234
florian55085f82012-11-21 00:36:55 +00005235static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005236s390_irgen_XI(UChar i2, IRTemp op1addr)
5237{
5238 IRTemp op1 = newTemp(Ity_I8);
5239 UChar op2;
5240 IRTemp result = newTemp(Ity_I8);
5241
5242 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5243 op2 = i2;
5244 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5245 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5246 store(mkexpr(op1addr), mkexpr(result));
5247
5248 return "xi";
5249}
5250
florian55085f82012-11-21 00:36:55 +00005251static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005252s390_irgen_XIY(UChar i2, IRTemp op1addr)
5253{
5254 IRTemp op1 = newTemp(Ity_I8);
5255 UChar op2;
5256 IRTemp result = newTemp(Ity_I8);
5257
5258 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5259 op2 = i2;
5260 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5261 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5262 store(mkexpr(op1addr), mkexpr(result));
5263
5264 return "xiy";
5265}
5266
florian55085f82012-11-21 00:36:55 +00005267static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005268s390_irgen_XIHF(UChar r1, UInt i2)
5269{
5270 IRTemp op1 = newTemp(Ity_I32);
5271 UInt op2;
5272 IRTemp result = newTemp(Ity_I32);
5273
5274 assign(op1, get_gpr_w0(r1));
5275 op2 = i2;
5276 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5277 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5278 put_gpr_w0(r1, mkexpr(result));
5279
5280 return "xihf";
5281}
5282
florian55085f82012-11-21 00:36:55 +00005283static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005284s390_irgen_XILF(UChar r1, UInt i2)
5285{
5286 IRTemp op1 = newTemp(Ity_I32);
5287 UInt op2;
5288 IRTemp result = newTemp(Ity_I32);
5289
5290 assign(op1, get_gpr_w1(r1));
5291 op2 = i2;
5292 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5293 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5294 put_gpr_w1(r1, mkexpr(result));
5295
5296 return "xilf";
5297}
5298
florian55085f82012-11-21 00:36:55 +00005299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005300s390_irgen_EAR(UChar r1, UChar r2)
5301{
5302 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005303 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005304 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5305
5306 return "ear";
5307}
5308
florian55085f82012-11-21 00:36:55 +00005309static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005310s390_irgen_IC(UChar r1, IRTemp op2addr)
5311{
5312 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5313
5314 return "ic";
5315}
5316
florian55085f82012-11-21 00:36:55 +00005317static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005318s390_irgen_ICY(UChar r1, IRTemp op2addr)
5319{
5320 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5321
5322 return "icy";
5323}
5324
florian55085f82012-11-21 00:36:55 +00005325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005326s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5327{
5328 UChar n;
5329 IRTemp result = newTemp(Ity_I32);
5330 UInt mask;
5331
5332 n = 0;
5333 mask = (UInt)r3;
5334 if ((mask & 8) != 0) {
5335 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5336 n = n + 1;
5337 }
5338 if ((mask & 4) != 0) {
5339 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5340
5341 n = n + 1;
5342 }
5343 if ((mask & 2) != 0) {
5344 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5345
5346 n = n + 1;
5347 }
5348 if ((mask & 1) != 0) {
5349 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5350
5351 n = n + 1;
5352 }
5353 assign(result, get_gpr_w1(r1));
5354 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5355 mkU32(mask)));
5356
5357 return "icm";
5358}
5359
florian55085f82012-11-21 00:36:55 +00005360static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005361s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5362{
5363 UChar n;
5364 IRTemp result = newTemp(Ity_I32);
5365 UInt mask;
5366
5367 n = 0;
5368 mask = (UInt)r3;
5369 if ((mask & 8) != 0) {
5370 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5371 n = n + 1;
5372 }
5373 if ((mask & 4) != 0) {
5374 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5375
5376 n = n + 1;
5377 }
5378 if ((mask & 2) != 0) {
5379 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5380
5381 n = n + 1;
5382 }
5383 if ((mask & 1) != 0) {
5384 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5385
5386 n = n + 1;
5387 }
5388 assign(result, get_gpr_w1(r1));
5389 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5390 mkU32(mask)));
5391
5392 return "icmy";
5393}
5394
florian55085f82012-11-21 00:36:55 +00005395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005396s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5397{
5398 UChar n;
5399 IRTemp result = newTemp(Ity_I32);
5400 UInt mask;
5401
5402 n = 0;
5403 mask = (UInt)r3;
5404 if ((mask & 8) != 0) {
5405 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5406 n = n + 1;
5407 }
5408 if ((mask & 4) != 0) {
5409 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5410
5411 n = n + 1;
5412 }
5413 if ((mask & 2) != 0) {
5414 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5415
5416 n = n + 1;
5417 }
5418 if ((mask & 1) != 0) {
5419 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5420
5421 n = n + 1;
5422 }
5423 assign(result, get_gpr_w0(r1));
5424 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5425 mkU32(mask)));
5426
5427 return "icmh";
5428}
5429
florian55085f82012-11-21 00:36:55 +00005430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005431s390_irgen_IIHF(UChar r1, UInt i2)
5432{
5433 put_gpr_w0(r1, mkU32(i2));
5434
5435 return "iihf";
5436}
5437
florian55085f82012-11-21 00:36:55 +00005438static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005439s390_irgen_IIHH(UChar r1, UShort i2)
5440{
5441 put_gpr_hw0(r1, mkU16(i2));
5442
5443 return "iihh";
5444}
5445
florian55085f82012-11-21 00:36:55 +00005446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005447s390_irgen_IIHL(UChar r1, UShort i2)
5448{
5449 put_gpr_hw1(r1, mkU16(i2));
5450
5451 return "iihl";
5452}
5453
florian55085f82012-11-21 00:36:55 +00005454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005455s390_irgen_IILF(UChar r1, UInt i2)
5456{
5457 put_gpr_w1(r1, mkU32(i2));
5458
5459 return "iilf";
5460}
5461
florian55085f82012-11-21 00:36:55 +00005462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005463s390_irgen_IILH(UChar r1, UShort i2)
5464{
5465 put_gpr_hw2(r1, mkU16(i2));
5466
5467 return "iilh";
5468}
5469
florian55085f82012-11-21 00:36:55 +00005470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005471s390_irgen_IILL(UChar r1, UShort i2)
5472{
5473 put_gpr_hw3(r1, mkU16(i2));
5474
5475 return "iill";
5476}
5477
florian55085f82012-11-21 00:36:55 +00005478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005479s390_irgen_LR(UChar r1, UChar r2)
5480{
5481 put_gpr_w1(r1, get_gpr_w1(r2));
5482
5483 return "lr";
5484}
5485
florian55085f82012-11-21 00:36:55 +00005486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005487s390_irgen_LGR(UChar r1, UChar r2)
5488{
5489 put_gpr_dw0(r1, get_gpr_dw0(r2));
5490
5491 return "lgr";
5492}
5493
florian55085f82012-11-21 00:36:55 +00005494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005495s390_irgen_LGFR(UChar r1, UChar r2)
5496{
5497 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5498
5499 return "lgfr";
5500}
5501
florian55085f82012-11-21 00:36:55 +00005502static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005503s390_irgen_L(UChar r1, IRTemp op2addr)
5504{
5505 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5506
5507 return "l";
5508}
5509
florian55085f82012-11-21 00:36:55 +00005510static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005511s390_irgen_LY(UChar r1, IRTemp op2addr)
5512{
5513 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5514
5515 return "ly";
5516}
5517
florian55085f82012-11-21 00:36:55 +00005518static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005519s390_irgen_LG(UChar r1, IRTemp op2addr)
5520{
5521 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5522
5523 return "lg";
5524}
5525
florian55085f82012-11-21 00:36:55 +00005526static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005527s390_irgen_LGF(UChar r1, IRTemp op2addr)
5528{
5529 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5530
5531 return "lgf";
5532}
5533
florian55085f82012-11-21 00:36:55 +00005534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005535s390_irgen_LGFI(UChar r1, UInt i2)
5536{
5537 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5538
5539 return "lgfi";
5540}
5541
florian55085f82012-11-21 00:36:55 +00005542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005543s390_irgen_LRL(UChar r1, UInt i2)
5544{
5545 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5546 i2 << 1))));
5547
5548 return "lrl";
5549}
5550
florian55085f82012-11-21 00:36:55 +00005551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005552s390_irgen_LGRL(UChar r1, UInt i2)
5553{
5554 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5555 i2 << 1))));
5556
5557 return "lgrl";
5558}
5559
florian55085f82012-11-21 00:36:55 +00005560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005561s390_irgen_LGFRL(UChar r1, UInt i2)
5562{
5563 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5564 ((ULong)(Long)(Int)i2 << 1)))));
5565
5566 return "lgfrl";
5567}
5568
florian55085f82012-11-21 00:36:55 +00005569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005570s390_irgen_LA(UChar r1, IRTemp op2addr)
5571{
5572 put_gpr_dw0(r1, mkexpr(op2addr));
5573
5574 return "la";
5575}
5576
florian55085f82012-11-21 00:36:55 +00005577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005578s390_irgen_LAY(UChar r1, IRTemp op2addr)
5579{
5580 put_gpr_dw0(r1, mkexpr(op2addr));
5581
5582 return "lay";
5583}
5584
florian55085f82012-11-21 00:36:55 +00005585static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005586s390_irgen_LAE(UChar r1, IRTemp op2addr)
5587{
5588 put_gpr_dw0(r1, mkexpr(op2addr));
5589
5590 return "lae";
5591}
5592
florian55085f82012-11-21 00:36:55 +00005593static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005594s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5595{
5596 put_gpr_dw0(r1, mkexpr(op2addr));
5597
5598 return "laey";
5599}
5600
florian55085f82012-11-21 00:36:55 +00005601static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005602s390_irgen_LARL(UChar r1, UInt i2)
5603{
5604 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5605
5606 return "larl";
5607}
5608
floriana265ee72012-12-02 20:58:17 +00005609/* The IR representation of LAA and friends is an approximation of what
5610 happens natively. Essentially a loop containing a compare-and-swap is
5611 constructed which will iterate until the CAS succeeds. As a consequence,
5612 instrumenters may see more memory accesses than happen natively. See also
5613 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005614static void
5615s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005616{
floriana265ee72012-12-02 20:58:17 +00005617 IRCAS *cas;
5618 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005619 IRTemp op2 = newTemp(Ity_I32);
5620 IRTemp op3 = newTemp(Ity_I32);
5621 IRTemp result = newTemp(Ity_I32);
5622
5623 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5624 assign(op3, get_gpr_w1(r3));
5625 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005626
5627 /* Place the addition of second operand and third operand at the
5628 second-operand location everytime */
5629 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5630 Iend_BE, mkexpr(op2addr),
5631 NULL, mkexpr(op2), /* expected value */
5632 NULL, mkexpr(result) /* new value */);
5633 stmt(IRStmt_CAS(cas));
5634
florianffc94012012-12-02 21:31:15 +00005635 /* Set CC according to 32-bit addition */
5636 if (is_signed) {
5637 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5638 } else {
5639 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5640 }
floriana265ee72012-12-02 20:58:17 +00005641
5642 /* If old_mem contains the expected value, then the CAS succeeded.
5643 Otherwise, it did not */
5644 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5645 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005646}
5647
5648static void
5649s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5650{
5651 IRCAS *cas;
5652 IRTemp old_mem = newTemp(Ity_I64);
5653 IRTemp op2 = newTemp(Ity_I64);
5654 IRTemp op3 = newTemp(Ity_I64);
5655 IRTemp result = newTemp(Ity_I64);
5656
5657 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5658 assign(op3, get_gpr_dw0(r3));
5659 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5660
5661 /* Place the addition of second operand and third operand at the
5662 second-operand location everytime */
5663 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5664 Iend_BE, mkexpr(op2addr),
5665 NULL, mkexpr(op2), /* expected value */
5666 NULL, mkexpr(result) /* new value */);
5667 stmt(IRStmt_CAS(cas));
5668
5669 /* Set CC according to 64-bit addition */
5670 if (is_signed) {
5671 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5672 } else {
5673 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5674 }
5675
5676 /* If old_mem contains the expected value, then the CAS succeeded.
5677 Otherwise, it did not */
5678 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5679 put_gpr_dw0(r1, mkexpr(old_mem));
5680}
5681
5682static void
5683s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5684{
5685 IRCAS *cas;
5686 IRTemp old_mem = newTemp(Ity_I32);
5687 IRTemp op2 = newTemp(Ity_I32);
5688 IRTemp op3 = newTemp(Ity_I32);
5689 IRTemp result = newTemp(Ity_I32);
5690
5691 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5692 assign(op3, get_gpr_w1(r3));
5693 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5694
5695 /* Place the addition of second operand and third operand at the
5696 second-operand location everytime */
5697 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5698 Iend_BE, mkexpr(op2addr),
5699 NULL, mkexpr(op2), /* expected value */
5700 NULL, mkexpr(result) /* new value */);
5701 stmt(IRStmt_CAS(cas));
5702
5703 /* Set CC according to bitwise operation */
5704 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5705
5706 /* If old_mem contains the expected value, then the CAS succeeded.
5707 Otherwise, it did not */
5708 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5709 put_gpr_w1(r1, mkexpr(old_mem));
5710}
5711
5712static void
5713s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5714{
5715 IRCAS *cas;
5716 IRTemp old_mem = newTemp(Ity_I64);
5717 IRTemp op2 = newTemp(Ity_I64);
5718 IRTemp op3 = newTemp(Ity_I64);
5719 IRTemp result = newTemp(Ity_I64);
5720
5721 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5722 assign(op3, get_gpr_dw0(r3));
5723 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5724
5725 /* Place the addition of second operand and third operand at the
5726 second-operand location everytime */
5727 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5728 Iend_BE, mkexpr(op2addr),
5729 NULL, mkexpr(op2), /* expected value */
5730 NULL, mkexpr(result) /* new value */);
5731 stmt(IRStmt_CAS(cas));
5732
5733 /* Set CC according to bitwise operation */
5734 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5735
5736 /* If old_mem contains the expected value, then the CAS succeeded.
5737 Otherwise, it did not */
5738 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5739 put_gpr_dw0(r1, mkexpr(old_mem));
5740}
5741
5742static const HChar *
5743s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5744{
5745 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005746
5747 return "laa";
5748}
5749
florian55085f82012-11-21 00:36:55 +00005750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005751s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5752{
florianffc94012012-12-02 21:31:15 +00005753 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005754
5755 return "laag";
5756}
5757
florian55085f82012-11-21 00:36:55 +00005758static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005759s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5760{
florianffc94012012-12-02 21:31:15 +00005761 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005762
5763 return "laal";
5764}
5765
florian55085f82012-11-21 00:36:55 +00005766static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005767s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5768{
florianffc94012012-12-02 21:31:15 +00005769 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005770
5771 return "laalg";
5772}
5773
florian55085f82012-11-21 00:36:55 +00005774static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005775s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5776{
florianffc94012012-12-02 21:31:15 +00005777 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005778
5779 return "lan";
5780}
5781
florian55085f82012-11-21 00:36:55 +00005782static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005783s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5784{
florianffc94012012-12-02 21:31:15 +00005785 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005786
5787 return "lang";
5788}
5789
florian55085f82012-11-21 00:36:55 +00005790static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005791s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5792{
florianffc94012012-12-02 21:31:15 +00005793 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005794
5795 return "lax";
5796}
5797
florian55085f82012-11-21 00:36:55 +00005798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005799s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5800{
florianffc94012012-12-02 21:31:15 +00005801 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005802
5803 return "laxg";
5804}
5805
florian55085f82012-11-21 00:36:55 +00005806static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005807s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5808{
florianffc94012012-12-02 21:31:15 +00005809 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005810
5811 return "lao";
5812}
5813
florian55085f82012-11-21 00:36:55 +00005814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005815s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5816{
florianffc94012012-12-02 21:31:15 +00005817 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005818
5819 return "laog";
5820}
5821
florian55085f82012-11-21 00:36:55 +00005822static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005823s390_irgen_LTR(UChar r1, UChar r2)
5824{
5825 IRTemp op2 = newTemp(Ity_I32);
5826
5827 assign(op2, get_gpr_w1(r2));
5828 put_gpr_w1(r1, mkexpr(op2));
5829 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5830
5831 return "ltr";
5832}
5833
florian55085f82012-11-21 00:36:55 +00005834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005835s390_irgen_LTGR(UChar r1, UChar r2)
5836{
5837 IRTemp op2 = newTemp(Ity_I64);
5838
5839 assign(op2, get_gpr_dw0(r2));
5840 put_gpr_dw0(r1, mkexpr(op2));
5841 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5842
5843 return "ltgr";
5844}
5845
florian55085f82012-11-21 00:36:55 +00005846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005847s390_irgen_LTGFR(UChar r1, UChar r2)
5848{
5849 IRTemp op2 = newTemp(Ity_I64);
5850
5851 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5852 put_gpr_dw0(r1, mkexpr(op2));
5853 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5854
5855 return "ltgfr";
5856}
5857
florian55085f82012-11-21 00:36:55 +00005858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005859s390_irgen_LT(UChar r1, IRTemp op2addr)
5860{
5861 IRTemp op2 = newTemp(Ity_I32);
5862
5863 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5864 put_gpr_w1(r1, mkexpr(op2));
5865 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5866
5867 return "lt";
5868}
5869
florian55085f82012-11-21 00:36:55 +00005870static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005871s390_irgen_LTG(UChar r1, IRTemp op2addr)
5872{
5873 IRTemp op2 = newTemp(Ity_I64);
5874
5875 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5876 put_gpr_dw0(r1, mkexpr(op2));
5877 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5878
5879 return "ltg";
5880}
5881
florian55085f82012-11-21 00:36:55 +00005882static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005883s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5884{
5885 IRTemp op2 = newTemp(Ity_I64);
5886
5887 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5888 put_gpr_dw0(r1, mkexpr(op2));
5889 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5890
5891 return "ltgf";
5892}
5893
florian55085f82012-11-21 00:36:55 +00005894static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005895s390_irgen_LBR(UChar r1, UChar r2)
5896{
5897 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5898
5899 return "lbr";
5900}
5901
florian55085f82012-11-21 00:36:55 +00005902static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005903s390_irgen_LGBR(UChar r1, UChar r2)
5904{
5905 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5906
5907 return "lgbr";
5908}
5909
florian55085f82012-11-21 00:36:55 +00005910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005911s390_irgen_LB(UChar r1, IRTemp op2addr)
5912{
5913 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5914
5915 return "lb";
5916}
5917
florian55085f82012-11-21 00:36:55 +00005918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005919s390_irgen_LGB(UChar r1, IRTemp op2addr)
5920{
5921 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5922
5923 return "lgb";
5924}
5925
florian55085f82012-11-21 00:36:55 +00005926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005927s390_irgen_LBH(UChar r1, IRTemp op2addr)
5928{
5929 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5930
5931 return "lbh";
5932}
5933
florian55085f82012-11-21 00:36:55 +00005934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005935s390_irgen_LCR(UChar r1, UChar r2)
5936{
5937 Int op1;
5938 IRTemp op2 = newTemp(Ity_I32);
5939 IRTemp result = newTemp(Ity_I32);
5940
5941 op1 = 0;
5942 assign(op2, get_gpr_w1(r2));
5943 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5944 put_gpr_w1(r1, mkexpr(result));
5945 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5946 op1)), op2);
5947
5948 return "lcr";
5949}
5950
florian55085f82012-11-21 00:36:55 +00005951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005952s390_irgen_LCGR(UChar r1, UChar r2)
5953{
5954 Long op1;
5955 IRTemp op2 = newTemp(Ity_I64);
5956 IRTemp result = newTemp(Ity_I64);
5957
5958 op1 = 0ULL;
5959 assign(op2, get_gpr_dw0(r2));
5960 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5961 put_gpr_dw0(r1, mkexpr(result));
5962 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5963 op1)), op2);
5964
5965 return "lcgr";
5966}
5967
florian55085f82012-11-21 00:36:55 +00005968static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005969s390_irgen_LCGFR(UChar r1, UChar r2)
5970{
5971 Long op1;
5972 IRTemp op2 = newTemp(Ity_I64);
5973 IRTemp result = newTemp(Ity_I64);
5974
5975 op1 = 0ULL;
5976 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5977 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5978 put_gpr_dw0(r1, mkexpr(result));
5979 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5980 op1)), op2);
5981
5982 return "lcgfr";
5983}
5984
florian55085f82012-11-21 00:36:55 +00005985static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005986s390_irgen_LHR(UChar r1, UChar r2)
5987{
5988 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5989
5990 return "lhr";
5991}
5992
florian55085f82012-11-21 00:36:55 +00005993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005994s390_irgen_LGHR(UChar r1, UChar r2)
5995{
5996 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5997
5998 return "lghr";
5999}
6000
florian55085f82012-11-21 00:36:55 +00006001static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006002s390_irgen_LH(UChar r1, IRTemp op2addr)
6003{
6004 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6005
6006 return "lh";
6007}
6008
florian55085f82012-11-21 00:36:55 +00006009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006010s390_irgen_LHY(UChar r1, IRTemp op2addr)
6011{
6012 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6013
6014 return "lhy";
6015}
6016
florian55085f82012-11-21 00:36:55 +00006017static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006018s390_irgen_LGH(UChar r1, IRTemp op2addr)
6019{
6020 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6021
6022 return "lgh";
6023}
6024
florian55085f82012-11-21 00:36:55 +00006025static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006026s390_irgen_LHI(UChar r1, UShort i2)
6027{
6028 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6029
6030 return "lhi";
6031}
6032
florian55085f82012-11-21 00:36:55 +00006033static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006034s390_irgen_LGHI(UChar r1, UShort i2)
6035{
6036 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6037
6038 return "lghi";
6039}
6040
florian55085f82012-11-21 00:36:55 +00006041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006042s390_irgen_LHRL(UChar r1, UInt i2)
6043{
6044 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6045 ((ULong)(Long)(Int)i2 << 1)))));
6046
6047 return "lhrl";
6048}
6049
florian55085f82012-11-21 00:36:55 +00006050static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006051s390_irgen_LGHRL(UChar r1, UInt i2)
6052{
6053 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6054 ((ULong)(Long)(Int)i2 << 1)))));
6055
6056 return "lghrl";
6057}
6058
florian55085f82012-11-21 00:36:55 +00006059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006060s390_irgen_LHH(UChar r1, IRTemp op2addr)
6061{
6062 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6063
6064 return "lhh";
6065}
6066
florian55085f82012-11-21 00:36:55 +00006067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006068s390_irgen_LFH(UChar r1, IRTemp op2addr)
6069{
6070 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6071
6072 return "lfh";
6073}
6074
florian55085f82012-11-21 00:36:55 +00006075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006076s390_irgen_LLGFR(UChar r1, UChar r2)
6077{
6078 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6079
6080 return "llgfr";
6081}
6082
florian55085f82012-11-21 00:36:55 +00006083static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006084s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6085{
6086 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6087
6088 return "llgf";
6089}
6090
florian55085f82012-11-21 00:36:55 +00006091static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006092s390_irgen_LLGFRL(UChar r1, UInt i2)
6093{
6094 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6095 ((ULong)(Long)(Int)i2 << 1)))));
6096
6097 return "llgfrl";
6098}
6099
florian55085f82012-11-21 00:36:55 +00006100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006101s390_irgen_LLCR(UChar r1, UChar r2)
6102{
6103 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6104
6105 return "llcr";
6106}
6107
florian55085f82012-11-21 00:36:55 +00006108static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006109s390_irgen_LLGCR(UChar r1, UChar r2)
6110{
6111 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6112
6113 return "llgcr";
6114}
6115
florian55085f82012-11-21 00:36:55 +00006116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006117s390_irgen_LLC(UChar r1, IRTemp op2addr)
6118{
6119 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6120
6121 return "llc";
6122}
6123
florian55085f82012-11-21 00:36:55 +00006124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006125s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6126{
6127 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6128
6129 return "llgc";
6130}
6131
florian55085f82012-11-21 00:36:55 +00006132static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006133s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6134{
6135 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6136
6137 return "llch";
6138}
6139
florian55085f82012-11-21 00:36:55 +00006140static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006141s390_irgen_LLHR(UChar r1, UChar r2)
6142{
6143 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6144
6145 return "llhr";
6146}
6147
florian55085f82012-11-21 00:36:55 +00006148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006149s390_irgen_LLGHR(UChar r1, UChar r2)
6150{
6151 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6152
6153 return "llghr";
6154}
6155
florian55085f82012-11-21 00:36:55 +00006156static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006157s390_irgen_LLH(UChar r1, IRTemp op2addr)
6158{
6159 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6160
6161 return "llh";
6162}
6163
florian55085f82012-11-21 00:36:55 +00006164static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006165s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6166{
6167 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6168
6169 return "llgh";
6170}
6171
florian55085f82012-11-21 00:36:55 +00006172static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006173s390_irgen_LLHRL(UChar r1, UInt i2)
6174{
6175 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6176 ((ULong)(Long)(Int)i2 << 1)))));
6177
6178 return "llhrl";
6179}
6180
florian55085f82012-11-21 00:36:55 +00006181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006182s390_irgen_LLGHRL(UChar r1, UInt i2)
6183{
6184 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6185 ((ULong)(Long)(Int)i2 << 1)))));
6186
6187 return "llghrl";
6188}
6189
florian55085f82012-11-21 00:36:55 +00006190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006191s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6192{
6193 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6194
6195 return "llhh";
6196}
6197
florian55085f82012-11-21 00:36:55 +00006198static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006199s390_irgen_LLIHF(UChar r1, UInt i2)
6200{
6201 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6202
6203 return "llihf";
6204}
6205
florian55085f82012-11-21 00:36:55 +00006206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006207s390_irgen_LLIHH(UChar r1, UShort i2)
6208{
6209 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6210
6211 return "llihh";
6212}
6213
florian55085f82012-11-21 00:36:55 +00006214static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006215s390_irgen_LLIHL(UChar r1, UShort i2)
6216{
6217 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6218
6219 return "llihl";
6220}
6221
florian55085f82012-11-21 00:36:55 +00006222static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006223s390_irgen_LLILF(UChar r1, UInt i2)
6224{
6225 put_gpr_dw0(r1, mkU64(i2));
6226
6227 return "llilf";
6228}
6229
florian55085f82012-11-21 00:36:55 +00006230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006231s390_irgen_LLILH(UChar r1, UShort i2)
6232{
6233 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6234
6235 return "llilh";
6236}
6237
florian55085f82012-11-21 00:36:55 +00006238static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006239s390_irgen_LLILL(UChar r1, UShort i2)
6240{
6241 put_gpr_dw0(r1, mkU64(i2));
6242
6243 return "llill";
6244}
6245
florian55085f82012-11-21 00:36:55 +00006246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006247s390_irgen_LLGTR(UChar r1, UChar r2)
6248{
6249 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6250 mkU32(2147483647))));
6251
6252 return "llgtr";
6253}
6254
florian55085f82012-11-21 00:36:55 +00006255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006256s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6257{
6258 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6259 mkexpr(op2addr)), mkU32(2147483647))));
6260
6261 return "llgt";
6262}
6263
florian55085f82012-11-21 00:36:55 +00006264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006265s390_irgen_LNR(UChar r1, UChar r2)
6266{
6267 IRTemp op2 = newTemp(Ity_I32);
6268 IRTemp result = newTemp(Ity_I32);
6269
6270 assign(op2, get_gpr_w1(r2));
6271 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6272 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6273 put_gpr_w1(r1, mkexpr(result));
6274 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6275
6276 return "lnr";
6277}
6278
florian55085f82012-11-21 00:36:55 +00006279static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006280s390_irgen_LNGR(UChar r1, UChar r2)
6281{
6282 IRTemp op2 = newTemp(Ity_I64);
6283 IRTemp result = newTemp(Ity_I64);
6284
6285 assign(op2, get_gpr_dw0(r2));
6286 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6287 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6288 put_gpr_dw0(r1, mkexpr(result));
6289 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6290
6291 return "lngr";
6292}
6293
florian55085f82012-11-21 00:36:55 +00006294static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006295s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6296{
6297 IRTemp op2 = newTemp(Ity_I64);
6298 IRTemp result = newTemp(Ity_I64);
6299
6300 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6301 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6302 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6303 put_gpr_dw0(r1, mkexpr(result));
6304 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6305
6306 return "lngfr";
6307}
6308
florian55085f82012-11-21 00:36:55 +00006309static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006310s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6311{
florian6820ba52012-07-26 02:01:50 +00006312 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006313 put_gpr_w1(r1, get_gpr_w1(r2));
6314
6315 return "locr";
6316}
6317
florian55085f82012-11-21 00:36:55 +00006318static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006319s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6320{
florian6820ba52012-07-26 02:01:50 +00006321 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006322 put_gpr_dw0(r1, get_gpr_dw0(r2));
6323
6324 return "locgr";
6325}
6326
florian55085f82012-11-21 00:36:55 +00006327static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006328s390_irgen_LOC(UChar r1, IRTemp op2addr)
6329{
6330 /* condition is checked in format handler */
6331 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6332
6333 return "loc";
6334}
6335
florian55085f82012-11-21 00:36:55 +00006336static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006337s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6338{
6339 /* condition is checked in format handler */
6340 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6341
6342 return "locg";
6343}
6344
florian55085f82012-11-21 00:36:55 +00006345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006346s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6347{
6348 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6349 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6350 ));
6351
6352 return "lpq";
6353}
6354
florian55085f82012-11-21 00:36:55 +00006355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006356s390_irgen_LPR(UChar r1, UChar r2)
6357{
6358 IRTemp op2 = newTemp(Ity_I32);
6359 IRTemp result = newTemp(Ity_I32);
6360
6361 assign(op2, get_gpr_w1(r2));
6362 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6363 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6364 put_gpr_w1(r1, mkexpr(result));
6365 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6366
6367 return "lpr";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006371s390_irgen_LPGR(UChar r1, UChar r2)
6372{
6373 IRTemp op2 = newTemp(Ity_I64);
6374 IRTemp result = newTemp(Ity_I64);
6375
6376 assign(op2, get_gpr_dw0(r2));
6377 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6378 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6379 put_gpr_dw0(r1, mkexpr(result));
6380 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6381
6382 return "lpgr";
6383}
6384
florian55085f82012-11-21 00:36:55 +00006385static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006386s390_irgen_LPGFR(UChar r1, UChar r2)
6387{
6388 IRTemp op2 = newTemp(Ity_I64);
6389 IRTemp result = newTemp(Ity_I64);
6390
6391 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6392 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6393 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6394 put_gpr_dw0(r1, mkexpr(result));
6395 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6396
6397 return "lpgfr";
6398}
6399
florian55085f82012-11-21 00:36:55 +00006400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006401s390_irgen_LRVR(UChar r1, UChar r2)
6402{
6403 IRTemp b0 = newTemp(Ity_I8);
6404 IRTemp b1 = newTemp(Ity_I8);
6405 IRTemp b2 = newTemp(Ity_I8);
6406 IRTemp b3 = newTemp(Ity_I8);
6407
6408 assign(b3, get_gpr_b7(r2));
6409 assign(b2, get_gpr_b6(r2));
6410 assign(b1, get_gpr_b5(r2));
6411 assign(b0, get_gpr_b4(r2));
6412 put_gpr_b4(r1, mkexpr(b3));
6413 put_gpr_b5(r1, mkexpr(b2));
6414 put_gpr_b6(r1, mkexpr(b1));
6415 put_gpr_b7(r1, mkexpr(b0));
6416
6417 return "lrvr";
6418}
6419
florian55085f82012-11-21 00:36:55 +00006420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006421s390_irgen_LRVGR(UChar r1, UChar r2)
6422{
6423 IRTemp b0 = newTemp(Ity_I8);
6424 IRTemp b1 = newTemp(Ity_I8);
6425 IRTemp b2 = newTemp(Ity_I8);
6426 IRTemp b3 = newTemp(Ity_I8);
6427 IRTemp b4 = newTemp(Ity_I8);
6428 IRTemp b5 = newTemp(Ity_I8);
6429 IRTemp b6 = newTemp(Ity_I8);
6430 IRTemp b7 = newTemp(Ity_I8);
6431
6432 assign(b7, get_gpr_b7(r2));
6433 assign(b6, get_gpr_b6(r2));
6434 assign(b5, get_gpr_b5(r2));
6435 assign(b4, get_gpr_b4(r2));
6436 assign(b3, get_gpr_b3(r2));
6437 assign(b2, get_gpr_b2(r2));
6438 assign(b1, get_gpr_b1(r2));
6439 assign(b0, get_gpr_b0(r2));
6440 put_gpr_b0(r1, mkexpr(b7));
6441 put_gpr_b1(r1, mkexpr(b6));
6442 put_gpr_b2(r1, mkexpr(b5));
6443 put_gpr_b3(r1, mkexpr(b4));
6444 put_gpr_b4(r1, mkexpr(b3));
6445 put_gpr_b5(r1, mkexpr(b2));
6446 put_gpr_b6(r1, mkexpr(b1));
6447 put_gpr_b7(r1, mkexpr(b0));
6448
6449 return "lrvgr";
6450}
6451
florian55085f82012-11-21 00:36:55 +00006452static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006453s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6454{
6455 IRTemp op2 = newTemp(Ity_I16);
6456
6457 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6458 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6459 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6460
6461 return "lrvh";
6462}
6463
florian55085f82012-11-21 00:36:55 +00006464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006465s390_irgen_LRV(UChar r1, IRTemp op2addr)
6466{
6467 IRTemp op2 = newTemp(Ity_I32);
6468
6469 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6470 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6471 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6472 mkU8(8)), mkU32(255))));
6473 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6474 mkU8(16)), mkU32(255))));
6475 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6476 mkU8(24)), mkU32(255))));
6477
6478 return "lrv";
6479}
6480
florian55085f82012-11-21 00:36:55 +00006481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006482s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6483{
6484 IRTemp op2 = newTemp(Ity_I64);
6485
6486 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6487 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6488 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6489 mkU8(8)), mkU64(255))));
6490 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6491 mkU8(16)), mkU64(255))));
6492 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6493 mkU8(24)), mkU64(255))));
6494 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6495 mkU8(32)), mkU64(255))));
6496 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6497 mkU8(40)), mkU64(255))));
6498 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6499 mkU8(48)), mkU64(255))));
6500 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6501 mkU8(56)), mkU64(255))));
6502
6503 return "lrvg";
6504}
6505
florian55085f82012-11-21 00:36:55 +00006506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006507s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6508{
6509 store(mkexpr(op1addr), mkU16(i2));
6510
6511 return "mvhhi";
6512}
6513
florian55085f82012-11-21 00:36:55 +00006514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006515s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6516{
6517 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6518
6519 return "mvhi";
6520}
6521
florian55085f82012-11-21 00:36:55 +00006522static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006523s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6524{
6525 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6526
6527 return "mvghi";
6528}
6529
florian55085f82012-11-21 00:36:55 +00006530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006531s390_irgen_MVI(UChar i2, IRTemp op1addr)
6532{
6533 store(mkexpr(op1addr), mkU8(i2));
6534
6535 return "mvi";
6536}
6537
florian55085f82012-11-21 00:36:55 +00006538static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006539s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6540{
6541 store(mkexpr(op1addr), mkU8(i2));
6542
6543 return "mviy";
6544}
6545
florian55085f82012-11-21 00:36:55 +00006546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006547s390_irgen_MR(UChar r1, UChar r2)
6548{
6549 IRTemp op1 = newTemp(Ity_I32);
6550 IRTemp op2 = newTemp(Ity_I32);
6551 IRTemp result = newTemp(Ity_I64);
6552
6553 assign(op1, get_gpr_w1(r1 + 1));
6554 assign(op2, get_gpr_w1(r2));
6555 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6556 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6557 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6558
6559 return "mr";
6560}
6561
florian55085f82012-11-21 00:36:55 +00006562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006563s390_irgen_M(UChar r1, IRTemp op2addr)
6564{
6565 IRTemp op1 = newTemp(Ity_I32);
6566 IRTemp op2 = newTemp(Ity_I32);
6567 IRTemp result = newTemp(Ity_I64);
6568
6569 assign(op1, get_gpr_w1(r1 + 1));
6570 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6571 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6572 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6573 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6574
6575 return "m";
6576}
6577
florian55085f82012-11-21 00:36:55 +00006578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006579s390_irgen_MFY(UChar r1, IRTemp op2addr)
6580{
6581 IRTemp op1 = newTemp(Ity_I32);
6582 IRTemp op2 = newTemp(Ity_I32);
6583 IRTemp result = newTemp(Ity_I64);
6584
6585 assign(op1, get_gpr_w1(r1 + 1));
6586 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6587 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6588 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6589 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6590
6591 return "mfy";
6592}
6593
florian55085f82012-11-21 00:36:55 +00006594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006595s390_irgen_MH(UChar r1, IRTemp op2addr)
6596{
6597 IRTemp op1 = newTemp(Ity_I32);
6598 IRTemp op2 = newTemp(Ity_I16);
6599 IRTemp result = newTemp(Ity_I64);
6600
6601 assign(op1, get_gpr_w1(r1));
6602 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6603 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6604 ));
6605 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6606
6607 return "mh";
6608}
6609
florian55085f82012-11-21 00:36:55 +00006610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006611s390_irgen_MHY(UChar r1, IRTemp op2addr)
6612{
6613 IRTemp op1 = newTemp(Ity_I32);
6614 IRTemp op2 = newTemp(Ity_I16);
6615 IRTemp result = newTemp(Ity_I64);
6616
6617 assign(op1, get_gpr_w1(r1));
6618 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6619 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6620 ));
6621 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6622
6623 return "mhy";
6624}
6625
florian55085f82012-11-21 00:36:55 +00006626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006627s390_irgen_MHI(UChar r1, UShort i2)
6628{
6629 IRTemp op1 = newTemp(Ity_I32);
6630 Short op2;
6631 IRTemp result = newTemp(Ity_I64);
6632
6633 assign(op1, get_gpr_w1(r1));
6634 op2 = (Short)i2;
6635 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6636 mkU16((UShort)op2))));
6637 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6638
6639 return "mhi";
6640}
6641
florian55085f82012-11-21 00:36:55 +00006642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006643s390_irgen_MGHI(UChar r1, UShort i2)
6644{
6645 IRTemp op1 = newTemp(Ity_I64);
6646 Short op2;
6647 IRTemp result = newTemp(Ity_I128);
6648
6649 assign(op1, get_gpr_dw0(r1));
6650 op2 = (Short)i2;
6651 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6652 mkU16((UShort)op2))));
6653 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6654
6655 return "mghi";
6656}
6657
florian55085f82012-11-21 00:36:55 +00006658static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006659s390_irgen_MLR(UChar r1, UChar r2)
6660{
6661 IRTemp op1 = newTemp(Ity_I32);
6662 IRTemp op2 = newTemp(Ity_I32);
6663 IRTemp result = newTemp(Ity_I64);
6664
6665 assign(op1, get_gpr_w1(r1 + 1));
6666 assign(op2, get_gpr_w1(r2));
6667 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6668 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6669 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6670
6671 return "mlr";
6672}
6673
florian55085f82012-11-21 00:36:55 +00006674static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006675s390_irgen_MLGR(UChar r1, UChar r2)
6676{
6677 IRTemp op1 = newTemp(Ity_I64);
6678 IRTemp op2 = newTemp(Ity_I64);
6679 IRTemp result = newTemp(Ity_I128);
6680
6681 assign(op1, get_gpr_dw0(r1 + 1));
6682 assign(op2, get_gpr_dw0(r2));
6683 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6684 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6685 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6686
6687 return "mlgr";
6688}
6689
florian55085f82012-11-21 00:36:55 +00006690static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006691s390_irgen_ML(UChar r1, IRTemp op2addr)
6692{
6693 IRTemp op1 = newTemp(Ity_I32);
6694 IRTemp op2 = newTemp(Ity_I32);
6695 IRTemp result = newTemp(Ity_I64);
6696
6697 assign(op1, get_gpr_w1(r1 + 1));
6698 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6699 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6700 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6701 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6702
6703 return "ml";
6704}
6705
florian55085f82012-11-21 00:36:55 +00006706static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006707s390_irgen_MLG(UChar r1, IRTemp op2addr)
6708{
6709 IRTemp op1 = newTemp(Ity_I64);
6710 IRTemp op2 = newTemp(Ity_I64);
6711 IRTemp result = newTemp(Ity_I128);
6712
6713 assign(op1, get_gpr_dw0(r1 + 1));
6714 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6715 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6716 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6717 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6718
6719 return "mlg";
6720}
6721
florian55085f82012-11-21 00:36:55 +00006722static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006723s390_irgen_MSR(UChar r1, UChar r2)
6724{
6725 IRTemp op1 = newTemp(Ity_I32);
6726 IRTemp op2 = newTemp(Ity_I32);
6727 IRTemp result = newTemp(Ity_I64);
6728
6729 assign(op1, get_gpr_w1(r1));
6730 assign(op2, get_gpr_w1(r2));
6731 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6732 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6733
6734 return "msr";
6735}
6736
florian55085f82012-11-21 00:36:55 +00006737static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006738s390_irgen_MSGR(UChar r1, UChar r2)
6739{
6740 IRTemp op1 = newTemp(Ity_I64);
6741 IRTemp op2 = newTemp(Ity_I64);
6742 IRTemp result = newTemp(Ity_I128);
6743
6744 assign(op1, get_gpr_dw0(r1));
6745 assign(op2, get_gpr_dw0(r2));
6746 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6747 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6748
6749 return "msgr";
6750}
6751
florian55085f82012-11-21 00:36:55 +00006752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006753s390_irgen_MSGFR(UChar r1, UChar r2)
6754{
6755 IRTemp op1 = newTemp(Ity_I64);
6756 IRTemp op2 = newTemp(Ity_I32);
6757 IRTemp result = newTemp(Ity_I128);
6758
6759 assign(op1, get_gpr_dw0(r1));
6760 assign(op2, get_gpr_w1(r2));
6761 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6762 ));
6763 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6764
6765 return "msgfr";
6766}
6767
florian55085f82012-11-21 00:36:55 +00006768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006769s390_irgen_MS(UChar r1, IRTemp op2addr)
6770{
6771 IRTemp op1 = newTemp(Ity_I32);
6772 IRTemp op2 = newTemp(Ity_I32);
6773 IRTemp result = newTemp(Ity_I64);
6774
6775 assign(op1, get_gpr_w1(r1));
6776 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6777 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6778 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6779
6780 return "ms";
6781}
6782
florian55085f82012-11-21 00:36:55 +00006783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006784s390_irgen_MSY(UChar r1, IRTemp op2addr)
6785{
6786 IRTemp op1 = newTemp(Ity_I32);
6787 IRTemp op2 = newTemp(Ity_I32);
6788 IRTemp result = newTemp(Ity_I64);
6789
6790 assign(op1, get_gpr_w1(r1));
6791 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6792 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6793 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6794
6795 return "msy";
6796}
6797
florian55085f82012-11-21 00:36:55 +00006798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006799s390_irgen_MSG(UChar r1, IRTemp op2addr)
6800{
6801 IRTemp op1 = newTemp(Ity_I64);
6802 IRTemp op2 = newTemp(Ity_I64);
6803 IRTemp result = newTemp(Ity_I128);
6804
6805 assign(op1, get_gpr_dw0(r1));
6806 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6807 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6808 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6809
6810 return "msg";
6811}
6812
florian55085f82012-11-21 00:36:55 +00006813static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006814s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6815{
6816 IRTemp op1 = newTemp(Ity_I64);
6817 IRTemp op2 = newTemp(Ity_I32);
6818 IRTemp result = newTemp(Ity_I128);
6819
6820 assign(op1, get_gpr_dw0(r1));
6821 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6822 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6823 ));
6824 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6825
6826 return "msgf";
6827}
6828
florian55085f82012-11-21 00:36:55 +00006829static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006830s390_irgen_MSFI(UChar r1, UInt i2)
6831{
6832 IRTemp op1 = newTemp(Ity_I32);
6833 Int op2;
6834 IRTemp result = newTemp(Ity_I64);
6835
6836 assign(op1, get_gpr_w1(r1));
6837 op2 = (Int)i2;
6838 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6839 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6840
6841 return "msfi";
6842}
6843
florian55085f82012-11-21 00:36:55 +00006844static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006845s390_irgen_MSGFI(UChar r1, UInt i2)
6846{
6847 IRTemp op1 = newTemp(Ity_I64);
6848 Int op2;
6849 IRTemp result = newTemp(Ity_I128);
6850
6851 assign(op1, get_gpr_dw0(r1));
6852 op2 = (Int)i2;
6853 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6854 op2))));
6855 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6856
6857 return "msgfi";
6858}
6859
florian55085f82012-11-21 00:36:55 +00006860static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006861s390_irgen_OR(UChar r1, UChar r2)
6862{
6863 IRTemp op1 = newTemp(Ity_I32);
6864 IRTemp op2 = newTemp(Ity_I32);
6865 IRTemp result = newTemp(Ity_I32);
6866
6867 assign(op1, get_gpr_w1(r1));
6868 assign(op2, get_gpr_w1(r2));
6869 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6870 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6871 put_gpr_w1(r1, mkexpr(result));
6872
6873 return "or";
6874}
6875
florian55085f82012-11-21 00:36:55 +00006876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006877s390_irgen_OGR(UChar r1, UChar r2)
6878{
6879 IRTemp op1 = newTemp(Ity_I64);
6880 IRTemp op2 = newTemp(Ity_I64);
6881 IRTemp result = newTemp(Ity_I64);
6882
6883 assign(op1, get_gpr_dw0(r1));
6884 assign(op2, get_gpr_dw0(r2));
6885 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6886 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6887 put_gpr_dw0(r1, mkexpr(result));
6888
6889 return "ogr";
6890}
6891
florian55085f82012-11-21 00:36:55 +00006892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006893s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6894{
6895 IRTemp op2 = newTemp(Ity_I32);
6896 IRTemp op3 = newTemp(Ity_I32);
6897 IRTemp result = newTemp(Ity_I32);
6898
6899 assign(op2, get_gpr_w1(r2));
6900 assign(op3, get_gpr_w1(r3));
6901 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6902 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6903 put_gpr_w1(r1, mkexpr(result));
6904
6905 return "ork";
6906}
6907
florian55085f82012-11-21 00:36:55 +00006908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006909s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6910{
6911 IRTemp op2 = newTemp(Ity_I64);
6912 IRTemp op3 = newTemp(Ity_I64);
6913 IRTemp result = newTemp(Ity_I64);
6914
6915 assign(op2, get_gpr_dw0(r2));
6916 assign(op3, get_gpr_dw0(r3));
6917 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6918 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6919 put_gpr_dw0(r1, mkexpr(result));
6920
6921 return "ogrk";
6922}
6923
florian55085f82012-11-21 00:36:55 +00006924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006925s390_irgen_O(UChar r1, IRTemp op2addr)
6926{
6927 IRTemp op1 = newTemp(Ity_I32);
6928 IRTemp op2 = newTemp(Ity_I32);
6929 IRTemp result = newTemp(Ity_I32);
6930
6931 assign(op1, get_gpr_w1(r1));
6932 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6933 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6934 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6935 put_gpr_w1(r1, mkexpr(result));
6936
6937 return "o";
6938}
6939
florian55085f82012-11-21 00:36:55 +00006940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006941s390_irgen_OY(UChar r1, IRTemp op2addr)
6942{
6943 IRTemp op1 = newTemp(Ity_I32);
6944 IRTemp op2 = newTemp(Ity_I32);
6945 IRTemp result = newTemp(Ity_I32);
6946
6947 assign(op1, get_gpr_w1(r1));
6948 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6949 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6950 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6951 put_gpr_w1(r1, mkexpr(result));
6952
6953 return "oy";
6954}
6955
florian55085f82012-11-21 00:36:55 +00006956static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006957s390_irgen_OG(UChar r1, IRTemp op2addr)
6958{
6959 IRTemp op1 = newTemp(Ity_I64);
6960 IRTemp op2 = newTemp(Ity_I64);
6961 IRTemp result = newTemp(Ity_I64);
6962
6963 assign(op1, get_gpr_dw0(r1));
6964 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6965 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6966 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6967 put_gpr_dw0(r1, mkexpr(result));
6968
6969 return "og";
6970}
6971
florian55085f82012-11-21 00:36:55 +00006972static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006973s390_irgen_OI(UChar i2, IRTemp op1addr)
6974{
6975 IRTemp op1 = newTemp(Ity_I8);
6976 UChar op2;
6977 IRTemp result = newTemp(Ity_I8);
6978
6979 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6980 op2 = i2;
6981 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6982 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6983 store(mkexpr(op1addr), mkexpr(result));
6984
6985 return "oi";
6986}
6987
florian55085f82012-11-21 00:36:55 +00006988static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006989s390_irgen_OIY(UChar i2, IRTemp op1addr)
6990{
6991 IRTemp op1 = newTemp(Ity_I8);
6992 UChar op2;
6993 IRTemp result = newTemp(Ity_I8);
6994
6995 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6996 op2 = i2;
6997 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6998 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6999 store(mkexpr(op1addr), mkexpr(result));
7000
7001 return "oiy";
7002}
7003
florian55085f82012-11-21 00:36:55 +00007004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007005s390_irgen_OIHF(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_w0(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_w0(r1, mkexpr(result));
7016
7017 return "oihf";
7018}
7019
florian55085f82012-11-21 00:36:55 +00007020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007021s390_irgen_OIHH(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_hw0(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_hw0(r1, mkexpr(result));
7032
7033 return "oihh";
7034}
7035
florian55085f82012-11-21 00:36:55 +00007036static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007037s390_irgen_OIHL(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_hw1(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_hw1(r1, mkexpr(result));
7048
7049 return "oihl";
7050}
7051
florian55085f82012-11-21 00:36:55 +00007052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007053s390_irgen_OILF(UChar r1, UInt i2)
7054{
7055 IRTemp op1 = newTemp(Ity_I32);
7056 UInt op2;
7057 IRTemp result = newTemp(Ity_I32);
7058
7059 assign(op1, get_gpr_w1(r1));
7060 op2 = i2;
7061 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7062 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7063 put_gpr_w1(r1, mkexpr(result));
7064
7065 return "oilf";
7066}
7067
florian55085f82012-11-21 00:36:55 +00007068static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007069s390_irgen_OILH(UChar r1, UShort i2)
7070{
7071 IRTemp op1 = newTemp(Ity_I16);
7072 UShort op2;
7073 IRTemp result = newTemp(Ity_I16);
7074
7075 assign(op1, get_gpr_hw2(r1));
7076 op2 = i2;
7077 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7078 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7079 put_gpr_hw2(r1, mkexpr(result));
7080
7081 return "oilh";
7082}
7083
florian55085f82012-11-21 00:36:55 +00007084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007085s390_irgen_OILL(UChar r1, UShort i2)
7086{
7087 IRTemp op1 = newTemp(Ity_I16);
7088 UShort op2;
7089 IRTemp result = newTemp(Ity_I16);
7090
7091 assign(op1, get_gpr_hw3(r1));
7092 op2 = i2;
7093 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7094 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7095 put_gpr_hw3(r1, mkexpr(result));
7096
7097 return "oill";
7098}
7099
florian55085f82012-11-21 00:36:55 +00007100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007101s390_irgen_PFD(void)
7102{
7103
7104 return "pfd";
7105}
7106
florian55085f82012-11-21 00:36:55 +00007107static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007108s390_irgen_PFDRL(void)
7109{
7110
7111 return "pfdrl";
7112}
7113
florian55085f82012-11-21 00:36:55 +00007114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007115s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7116{
7117 IRTemp amount = newTemp(Ity_I64);
7118 IRTemp op = newTemp(Ity_I32);
7119
7120 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7121 assign(op, get_gpr_w1(r3));
7122 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7123 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7124 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7125
7126 return "rll";
7127}
7128
florian55085f82012-11-21 00:36:55 +00007129static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007130s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7131{
7132 IRTemp amount = newTemp(Ity_I64);
7133 IRTemp op = newTemp(Ity_I64);
7134
7135 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7136 assign(op, get_gpr_dw0(r3));
7137 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7138 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7139 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7140
7141 return "rllg";
7142}
7143
florian55085f82012-11-21 00:36:55 +00007144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007145s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7146{
7147 UChar from;
7148 UChar to;
7149 UChar rot;
7150 UChar t_bit;
7151 ULong mask;
7152 ULong maskc;
7153 IRTemp result = newTemp(Ity_I64);
7154 IRTemp op2 = newTemp(Ity_I64);
7155
7156 from = i3 & 63;
7157 to = i4 & 63;
7158 rot = i5 & 63;
7159 t_bit = i3 & 128;
7160 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7161 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7162 mkU8(64 - rot))));
7163 if (from <= to) {
7164 mask = ~0ULL;
7165 mask = (mask >> from) & (mask << (63 - to));
7166 maskc = ~mask;
7167 } else {
7168 maskc = ~0ULL;
7169 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7170 mask = ~maskc;
7171 }
7172 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7173 ), mkU64(mask)));
7174 if (t_bit == 0) {
7175 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7176 mkU64(maskc)), mkexpr(result)));
7177 }
7178 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7179
7180 return "rnsbg";
7181}
7182
florian55085f82012-11-21 00:36:55 +00007183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007184s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7185{
7186 UChar from;
7187 UChar to;
7188 UChar rot;
7189 UChar t_bit;
7190 ULong mask;
7191 ULong maskc;
7192 IRTemp result = newTemp(Ity_I64);
7193 IRTemp op2 = newTemp(Ity_I64);
7194
7195 from = i3 & 63;
7196 to = i4 & 63;
7197 rot = i5 & 63;
7198 t_bit = i3 & 128;
7199 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7200 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7201 mkU8(64 - rot))));
7202 if (from <= to) {
7203 mask = ~0ULL;
7204 mask = (mask >> from) & (mask << (63 - to));
7205 maskc = ~mask;
7206 } else {
7207 maskc = ~0ULL;
7208 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7209 mask = ~maskc;
7210 }
7211 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7212 ), mkU64(mask)));
7213 if (t_bit == 0) {
7214 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7215 mkU64(maskc)), mkexpr(result)));
7216 }
7217 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7218
7219 return "rxsbg";
7220}
7221
florian55085f82012-11-21 00:36:55 +00007222static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007223s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7224{
7225 UChar from;
7226 UChar to;
7227 UChar rot;
7228 UChar t_bit;
7229 ULong mask;
7230 ULong maskc;
7231 IRTemp result = newTemp(Ity_I64);
7232 IRTemp op2 = newTemp(Ity_I64);
7233
7234 from = i3 & 63;
7235 to = i4 & 63;
7236 rot = i5 & 63;
7237 t_bit = i3 & 128;
7238 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7239 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7240 mkU8(64 - rot))));
7241 if (from <= to) {
7242 mask = ~0ULL;
7243 mask = (mask >> from) & (mask << (63 - to));
7244 maskc = ~mask;
7245 } else {
7246 maskc = ~0ULL;
7247 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7248 mask = ~maskc;
7249 }
7250 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7251 ), mkU64(mask)));
7252 if (t_bit == 0) {
7253 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7254 mkU64(maskc)), mkexpr(result)));
7255 }
7256 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7257
7258 return "rosbg";
7259}
7260
florian55085f82012-11-21 00:36:55 +00007261static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007262s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7263{
7264 UChar from;
7265 UChar to;
7266 UChar rot;
7267 UChar z_bit;
7268 ULong mask;
7269 ULong maskc;
7270 IRTemp op2 = newTemp(Ity_I64);
7271 IRTemp result = newTemp(Ity_I64);
7272
7273 from = i3 & 63;
7274 to = i4 & 63;
7275 rot = i5 & 63;
7276 z_bit = i4 & 128;
7277 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7278 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7279 mkU8(64 - rot))));
7280 if (from <= to) {
7281 mask = ~0ULL;
7282 mask = (mask >> from) & (mask << (63 - to));
7283 maskc = ~mask;
7284 } else {
7285 maskc = ~0ULL;
7286 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7287 mask = ~maskc;
7288 }
7289 if (z_bit == 0) {
7290 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7291 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7292 } else {
7293 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7294 }
7295 assign(result, get_gpr_dw0(r1));
7296 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7297
7298 return "risbg";
7299}
7300
florian55085f82012-11-21 00:36:55 +00007301static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007302s390_irgen_SAR(UChar r1, UChar r2)
7303{
7304 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007305 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007306 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7307
7308 return "sar";
7309}
7310
florian55085f82012-11-21 00:36:55 +00007311static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007312s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7313{
7314 IRTemp p1 = newTemp(Ity_I64);
7315 IRTemp p2 = newTemp(Ity_I64);
7316 IRTemp op = newTemp(Ity_I64);
7317 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007318 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007319 IRTemp shift_amount = newTemp(Ity_I64);
7320
7321 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7322 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7323 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7324 ));
7325 sign_mask = 1ULL << 63;
7326 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7327 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007328 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7329 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007330 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7331 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7332 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7333
7334 return "slda";
7335}
7336
florian55085f82012-11-21 00:36:55 +00007337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007338s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7339{
7340 IRTemp p1 = newTemp(Ity_I64);
7341 IRTemp p2 = newTemp(Ity_I64);
7342 IRTemp result = newTemp(Ity_I64);
7343
7344 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7345 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7346 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7347 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7348 mkexpr(op2addr), mkU64(63)))));
7349 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7350 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7351
7352 return "sldl";
7353}
7354
florian55085f82012-11-21 00:36:55 +00007355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007356s390_irgen_SLA(UChar r1, IRTemp op2addr)
7357{
7358 IRTemp uop = newTemp(Ity_I32);
7359 IRTemp result = newTemp(Ity_I32);
7360 UInt sign_mask;
7361 IRTemp shift_amount = newTemp(Ity_I64);
7362 IRTemp op = newTemp(Ity_I32);
7363
7364 assign(op, get_gpr_w1(r1));
7365 assign(uop, get_gpr_w1(r1));
7366 sign_mask = 2147483648U;
7367 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7368 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7369 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7370 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7371 put_gpr_w1(r1, mkexpr(result));
7372 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7373
7374 return "sla";
7375}
7376
florian55085f82012-11-21 00:36:55 +00007377static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007378s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7379{
7380 IRTemp uop = newTemp(Ity_I32);
7381 IRTemp result = newTemp(Ity_I32);
7382 UInt sign_mask;
7383 IRTemp shift_amount = newTemp(Ity_I64);
7384 IRTemp op = newTemp(Ity_I32);
7385
7386 assign(op, get_gpr_w1(r3));
7387 assign(uop, get_gpr_w1(r3));
7388 sign_mask = 2147483648U;
7389 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7390 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7391 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7392 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7393 put_gpr_w1(r1, mkexpr(result));
7394 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7395
7396 return "slak";
7397}
7398
florian55085f82012-11-21 00:36:55 +00007399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007400s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7401{
7402 IRTemp uop = newTemp(Ity_I64);
7403 IRTemp result = newTemp(Ity_I64);
7404 ULong sign_mask;
7405 IRTemp shift_amount = newTemp(Ity_I64);
7406 IRTemp op = newTemp(Ity_I64);
7407
7408 assign(op, get_gpr_dw0(r3));
7409 assign(uop, get_gpr_dw0(r3));
7410 sign_mask = 9223372036854775808ULL;
7411 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7412 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7413 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7414 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7415 put_gpr_dw0(r1, mkexpr(result));
7416 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7417
7418 return "slag";
7419}
7420
florian55085f82012-11-21 00:36:55 +00007421static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007422s390_irgen_SLL(UChar r1, IRTemp op2addr)
7423{
7424 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7425 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7426
7427 return "sll";
7428}
7429
florian55085f82012-11-21 00:36:55 +00007430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007431s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7432{
7433 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7434 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7435
7436 return "sllk";
7437}
7438
florian55085f82012-11-21 00:36:55 +00007439static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007440s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7441{
7442 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7443 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7444
7445 return "sllg";
7446}
7447
florian55085f82012-11-21 00:36:55 +00007448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007449s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7450{
7451 IRTemp p1 = newTemp(Ity_I64);
7452 IRTemp p2 = newTemp(Ity_I64);
7453 IRTemp result = newTemp(Ity_I64);
7454
7455 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7456 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7457 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7458 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7459 mkexpr(op2addr), mkU64(63)))));
7460 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7461 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7462 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7463
7464 return "srda";
7465}
7466
florian55085f82012-11-21 00:36:55 +00007467static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007468s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7469{
7470 IRTemp p1 = newTemp(Ity_I64);
7471 IRTemp p2 = newTemp(Ity_I64);
7472 IRTemp result = newTemp(Ity_I64);
7473
7474 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7475 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7476 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7477 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7478 mkexpr(op2addr), mkU64(63)))));
7479 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7480 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7481
7482 return "srdl";
7483}
7484
florian55085f82012-11-21 00:36:55 +00007485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007486s390_irgen_SRA(UChar r1, IRTemp op2addr)
7487{
7488 IRTemp result = newTemp(Ity_I32);
7489 IRTemp op = newTemp(Ity_I32);
7490
7491 assign(op, get_gpr_w1(r1));
7492 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7493 mkexpr(op2addr), mkU64(63)))));
7494 put_gpr_w1(r1, mkexpr(result));
7495 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7496
7497 return "sra";
7498}
7499
florian55085f82012-11-21 00:36:55 +00007500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007501s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7502{
7503 IRTemp result = newTemp(Ity_I32);
7504 IRTemp op = newTemp(Ity_I32);
7505
7506 assign(op, get_gpr_w1(r3));
7507 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7508 mkexpr(op2addr), mkU64(63)))));
7509 put_gpr_w1(r1, mkexpr(result));
7510 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7511
7512 return "srak";
7513}
7514
florian55085f82012-11-21 00:36:55 +00007515static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007516s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7517{
7518 IRTemp result = newTemp(Ity_I64);
7519 IRTemp op = newTemp(Ity_I64);
7520
7521 assign(op, get_gpr_dw0(r3));
7522 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7523 mkexpr(op2addr), mkU64(63)))));
7524 put_gpr_dw0(r1, mkexpr(result));
7525 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7526
7527 return "srag";
7528}
7529
florian55085f82012-11-21 00:36:55 +00007530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007531s390_irgen_SRL(UChar r1, IRTemp op2addr)
7532{
7533 IRTemp op = newTemp(Ity_I32);
7534
7535 assign(op, get_gpr_w1(r1));
7536 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7537 mkexpr(op2addr), mkU64(63)))));
7538
7539 return "srl";
7540}
7541
florian55085f82012-11-21 00:36:55 +00007542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007543s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7544{
7545 IRTemp op = newTemp(Ity_I32);
7546
7547 assign(op, get_gpr_w1(r3));
7548 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7549 mkexpr(op2addr), mkU64(63)))));
7550
7551 return "srlk";
7552}
7553
florian55085f82012-11-21 00:36:55 +00007554static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007555s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7556{
7557 IRTemp op = newTemp(Ity_I64);
7558
7559 assign(op, get_gpr_dw0(r3));
7560 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7561 mkexpr(op2addr), mkU64(63)))));
7562
7563 return "srlg";
7564}
7565
florian55085f82012-11-21 00:36:55 +00007566static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007567s390_irgen_ST(UChar r1, IRTemp op2addr)
7568{
7569 store(mkexpr(op2addr), get_gpr_w1(r1));
7570
7571 return "st";
7572}
7573
florian55085f82012-11-21 00:36:55 +00007574static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007575s390_irgen_STY(UChar r1, IRTemp op2addr)
7576{
7577 store(mkexpr(op2addr), get_gpr_w1(r1));
7578
7579 return "sty";
7580}
7581
florian55085f82012-11-21 00:36:55 +00007582static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007583s390_irgen_STG(UChar r1, IRTemp op2addr)
7584{
7585 store(mkexpr(op2addr), get_gpr_dw0(r1));
7586
7587 return "stg";
7588}
7589
florian55085f82012-11-21 00:36:55 +00007590static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007591s390_irgen_STRL(UChar r1, UInt i2)
7592{
7593 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7594 get_gpr_w1(r1));
7595
7596 return "strl";
7597}
7598
florian55085f82012-11-21 00:36:55 +00007599static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007600s390_irgen_STGRL(UChar r1, UInt i2)
7601{
7602 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7603 get_gpr_dw0(r1));
7604
7605 return "stgrl";
7606}
7607
florian55085f82012-11-21 00:36:55 +00007608static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007609s390_irgen_STC(UChar r1, IRTemp op2addr)
7610{
7611 store(mkexpr(op2addr), get_gpr_b7(r1));
7612
7613 return "stc";
7614}
7615
florian55085f82012-11-21 00:36:55 +00007616static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007617s390_irgen_STCY(UChar r1, IRTemp op2addr)
7618{
7619 store(mkexpr(op2addr), get_gpr_b7(r1));
7620
7621 return "stcy";
7622}
7623
florian55085f82012-11-21 00:36:55 +00007624static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007625s390_irgen_STCH(UChar r1, IRTemp op2addr)
7626{
7627 store(mkexpr(op2addr), get_gpr_b3(r1));
7628
7629 return "stch";
7630}
7631
florian55085f82012-11-21 00:36:55 +00007632static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007633s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7634{
7635 UChar mask;
7636 UChar n;
7637
7638 mask = (UChar)r3;
7639 n = 0;
7640 if ((mask & 8) != 0) {
7641 store(mkexpr(op2addr), get_gpr_b4(r1));
7642 n = n + 1;
7643 }
7644 if ((mask & 4) != 0) {
7645 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7646 n = n + 1;
7647 }
7648 if ((mask & 2) != 0) {
7649 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7650 n = n + 1;
7651 }
7652 if ((mask & 1) != 0) {
7653 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7654 }
7655
7656 return "stcm";
7657}
7658
florian55085f82012-11-21 00:36:55 +00007659static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007660s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7661{
7662 UChar mask;
7663 UChar n;
7664
7665 mask = (UChar)r3;
7666 n = 0;
7667 if ((mask & 8) != 0) {
7668 store(mkexpr(op2addr), get_gpr_b4(r1));
7669 n = n + 1;
7670 }
7671 if ((mask & 4) != 0) {
7672 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7673 n = n + 1;
7674 }
7675 if ((mask & 2) != 0) {
7676 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7677 n = n + 1;
7678 }
7679 if ((mask & 1) != 0) {
7680 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7681 }
7682
7683 return "stcmy";
7684}
7685
florian55085f82012-11-21 00:36:55 +00007686static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007687s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7688{
7689 UChar mask;
7690 UChar n;
7691
7692 mask = (UChar)r3;
7693 n = 0;
7694 if ((mask & 8) != 0) {
7695 store(mkexpr(op2addr), get_gpr_b0(r1));
7696 n = n + 1;
7697 }
7698 if ((mask & 4) != 0) {
7699 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7700 n = n + 1;
7701 }
7702 if ((mask & 2) != 0) {
7703 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7704 n = n + 1;
7705 }
7706 if ((mask & 1) != 0) {
7707 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7708 }
7709
7710 return "stcmh";
7711}
7712
florian55085f82012-11-21 00:36:55 +00007713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007714s390_irgen_STH(UChar r1, IRTemp op2addr)
7715{
7716 store(mkexpr(op2addr), get_gpr_hw3(r1));
7717
7718 return "sth";
7719}
7720
florian55085f82012-11-21 00:36:55 +00007721static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007722s390_irgen_STHY(UChar r1, IRTemp op2addr)
7723{
7724 store(mkexpr(op2addr), get_gpr_hw3(r1));
7725
7726 return "sthy";
7727}
7728
florian55085f82012-11-21 00:36:55 +00007729static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007730s390_irgen_STHRL(UChar r1, UInt i2)
7731{
7732 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7733 get_gpr_hw3(r1));
7734
7735 return "sthrl";
7736}
7737
florian55085f82012-11-21 00:36:55 +00007738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007739s390_irgen_STHH(UChar r1, IRTemp op2addr)
7740{
7741 store(mkexpr(op2addr), get_gpr_hw1(r1));
7742
7743 return "sthh";
7744}
7745
florian55085f82012-11-21 00:36:55 +00007746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007747s390_irgen_STFH(UChar r1, IRTemp op2addr)
7748{
7749 store(mkexpr(op2addr), get_gpr_w0(r1));
7750
7751 return "stfh";
7752}
7753
florian55085f82012-11-21 00:36:55 +00007754static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007755s390_irgen_STOC(UChar r1, IRTemp op2addr)
7756{
7757 /* condition is checked in format handler */
7758 store(mkexpr(op2addr), get_gpr_w1(r1));
7759
7760 return "stoc";
7761}
7762
florian55085f82012-11-21 00:36:55 +00007763static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007764s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7765{
7766 /* condition is checked in format handler */
7767 store(mkexpr(op2addr), get_gpr_dw0(r1));
7768
7769 return "stocg";
7770}
7771
florian55085f82012-11-21 00:36:55 +00007772static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007773s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7774{
7775 store(mkexpr(op2addr), get_gpr_dw0(r1));
7776 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7777
7778 return "stpq";
7779}
7780
florian55085f82012-11-21 00:36:55 +00007781static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007782s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7783{
7784 store(mkexpr(op2addr), get_gpr_b7(r1));
7785 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7786
7787 return "strvh";
7788}
7789
florian55085f82012-11-21 00:36:55 +00007790static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007791s390_irgen_STRV(UChar r1, IRTemp op2addr)
7792{
7793 store(mkexpr(op2addr), get_gpr_b7(r1));
7794 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7795 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7796 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7797
7798 return "strv";
7799}
7800
florian55085f82012-11-21 00:36:55 +00007801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007802s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7803{
7804 store(mkexpr(op2addr), get_gpr_b7(r1));
7805 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7806 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7807 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7808 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7809 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7810 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7811 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7812
7813 return "strvg";
7814}
7815
florian55085f82012-11-21 00:36:55 +00007816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007817s390_irgen_SR(UChar r1, UChar r2)
7818{
7819 IRTemp op1 = newTemp(Ity_I32);
7820 IRTemp op2 = newTemp(Ity_I32);
7821 IRTemp result = newTemp(Ity_I32);
7822
7823 assign(op1, get_gpr_w1(r1));
7824 assign(op2, get_gpr_w1(r2));
7825 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7826 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7827 put_gpr_w1(r1, mkexpr(result));
7828
7829 return "sr";
7830}
7831
florian55085f82012-11-21 00:36:55 +00007832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007833s390_irgen_SGR(UChar r1, UChar r2)
7834{
7835 IRTemp op1 = newTemp(Ity_I64);
7836 IRTemp op2 = newTemp(Ity_I64);
7837 IRTemp result = newTemp(Ity_I64);
7838
7839 assign(op1, get_gpr_dw0(r1));
7840 assign(op2, get_gpr_dw0(r2));
7841 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7842 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7843 put_gpr_dw0(r1, mkexpr(result));
7844
7845 return "sgr";
7846}
7847
florian55085f82012-11-21 00:36:55 +00007848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007849s390_irgen_SGFR(UChar r1, UChar r2)
7850{
7851 IRTemp op1 = newTemp(Ity_I64);
7852 IRTemp op2 = newTemp(Ity_I64);
7853 IRTemp result = newTemp(Ity_I64);
7854
7855 assign(op1, get_gpr_dw0(r1));
7856 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7857 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7858 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7859 put_gpr_dw0(r1, mkexpr(result));
7860
7861 return "sgfr";
7862}
7863
florian55085f82012-11-21 00:36:55 +00007864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007865s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7866{
7867 IRTemp op2 = newTemp(Ity_I32);
7868 IRTemp op3 = newTemp(Ity_I32);
7869 IRTemp result = newTemp(Ity_I32);
7870
7871 assign(op2, get_gpr_w1(r2));
7872 assign(op3, get_gpr_w1(r3));
7873 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7874 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7875 put_gpr_w1(r1, mkexpr(result));
7876
7877 return "srk";
7878}
7879
florian55085f82012-11-21 00:36:55 +00007880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007881s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7882{
7883 IRTemp op2 = newTemp(Ity_I64);
7884 IRTemp op3 = newTemp(Ity_I64);
7885 IRTemp result = newTemp(Ity_I64);
7886
7887 assign(op2, get_gpr_dw0(r2));
7888 assign(op3, get_gpr_dw0(r3));
7889 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7890 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7891 put_gpr_dw0(r1, mkexpr(result));
7892
7893 return "sgrk";
7894}
7895
florian55085f82012-11-21 00:36:55 +00007896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007897s390_irgen_S(UChar r1, IRTemp op2addr)
7898{
7899 IRTemp op1 = newTemp(Ity_I32);
7900 IRTemp op2 = newTemp(Ity_I32);
7901 IRTemp result = newTemp(Ity_I32);
7902
7903 assign(op1, get_gpr_w1(r1));
7904 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7905 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7906 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7907 put_gpr_w1(r1, mkexpr(result));
7908
7909 return "s";
7910}
7911
florian55085f82012-11-21 00:36:55 +00007912static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007913s390_irgen_SY(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, load(Ity_I32, 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 "sy";
7926}
7927
florian55085f82012-11-21 00:36:55 +00007928static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007929s390_irgen_SG(UChar r1, IRTemp op2addr)
7930{
7931 IRTemp op1 = newTemp(Ity_I64);
7932 IRTemp op2 = newTemp(Ity_I64);
7933 IRTemp result = newTemp(Ity_I64);
7934
7935 assign(op1, get_gpr_dw0(r1));
7936 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7937 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7938 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7939 put_gpr_dw0(r1, mkexpr(result));
7940
7941 return "sg";
7942}
7943
florian55085f82012-11-21 00:36:55 +00007944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007945s390_irgen_SGF(UChar r1, IRTemp op2addr)
7946{
7947 IRTemp op1 = newTemp(Ity_I64);
7948 IRTemp op2 = newTemp(Ity_I64);
7949 IRTemp result = newTemp(Ity_I64);
7950
7951 assign(op1, get_gpr_dw0(r1));
7952 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7953 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7954 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7955 put_gpr_dw0(r1, mkexpr(result));
7956
7957 return "sgf";
7958}
7959
florian55085f82012-11-21 00:36:55 +00007960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007961s390_irgen_SH(UChar r1, IRTemp op2addr)
7962{
7963 IRTemp op1 = newTemp(Ity_I32);
7964 IRTemp op2 = newTemp(Ity_I32);
7965 IRTemp result = newTemp(Ity_I32);
7966
7967 assign(op1, get_gpr_w1(r1));
7968 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7969 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7970 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7971 put_gpr_w1(r1, mkexpr(result));
7972
7973 return "sh";
7974}
7975
florian55085f82012-11-21 00:36:55 +00007976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007977s390_irgen_SHY(UChar r1, IRTemp op2addr)
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, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7985 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7986 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7987 put_gpr_w1(r1, mkexpr(result));
7988
7989 return "shy";
7990}
7991
florian55085f82012-11-21 00:36:55 +00007992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007993s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7994{
7995 IRTemp op2 = newTemp(Ity_I32);
7996 IRTemp op3 = newTemp(Ity_I32);
7997 IRTemp result = newTemp(Ity_I32);
7998
7999 assign(op2, get_gpr_w0(r1));
8000 assign(op3, get_gpr_w0(r2));
8001 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8002 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8003 put_gpr_w0(r1, mkexpr(result));
8004
8005 return "shhhr";
8006}
8007
florian55085f82012-11-21 00:36:55 +00008008static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008009s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8010{
8011 IRTemp op2 = newTemp(Ity_I32);
8012 IRTemp op3 = newTemp(Ity_I32);
8013 IRTemp result = newTemp(Ity_I32);
8014
8015 assign(op2, get_gpr_w0(r1));
8016 assign(op3, get_gpr_w1(r2));
8017 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8018 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8019 put_gpr_w0(r1, mkexpr(result));
8020
8021 return "shhlr";
8022}
8023
florian55085f82012-11-21 00:36:55 +00008024static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008025s390_irgen_SLR(UChar r1, UChar r2)
8026{
8027 IRTemp op1 = newTemp(Ity_I32);
8028 IRTemp op2 = newTemp(Ity_I32);
8029 IRTemp result = newTemp(Ity_I32);
8030
8031 assign(op1, get_gpr_w1(r1));
8032 assign(op2, get_gpr_w1(r2));
8033 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8034 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8035 put_gpr_w1(r1, mkexpr(result));
8036
8037 return "slr";
8038}
8039
florian55085f82012-11-21 00:36:55 +00008040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008041s390_irgen_SLGR(UChar r1, UChar r2)
8042{
8043 IRTemp op1 = newTemp(Ity_I64);
8044 IRTemp op2 = newTemp(Ity_I64);
8045 IRTemp result = newTemp(Ity_I64);
8046
8047 assign(op1, get_gpr_dw0(r1));
8048 assign(op2, get_gpr_dw0(r2));
8049 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8050 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8051 put_gpr_dw0(r1, mkexpr(result));
8052
8053 return "slgr";
8054}
8055
florian55085f82012-11-21 00:36:55 +00008056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008057s390_irgen_SLGFR(UChar r1, UChar r2)
8058{
8059 IRTemp op1 = newTemp(Ity_I64);
8060 IRTemp op2 = newTemp(Ity_I64);
8061 IRTemp result = newTemp(Ity_I64);
8062
8063 assign(op1, get_gpr_dw0(r1));
8064 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8065 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8066 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8067 put_gpr_dw0(r1, mkexpr(result));
8068
8069 return "slgfr";
8070}
8071
florian55085f82012-11-21 00:36:55 +00008072static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008073s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8074{
8075 IRTemp op2 = newTemp(Ity_I32);
8076 IRTemp op3 = newTemp(Ity_I32);
8077 IRTemp result = newTemp(Ity_I32);
8078
8079 assign(op2, get_gpr_w1(r2));
8080 assign(op3, get_gpr_w1(r3));
8081 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8082 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8083 put_gpr_w1(r1, mkexpr(result));
8084
8085 return "slrk";
8086}
8087
florian55085f82012-11-21 00:36:55 +00008088static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008089s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8090{
8091 IRTemp op2 = newTemp(Ity_I64);
8092 IRTemp op3 = newTemp(Ity_I64);
8093 IRTemp result = newTemp(Ity_I64);
8094
8095 assign(op2, get_gpr_dw0(r2));
8096 assign(op3, get_gpr_dw0(r3));
8097 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8098 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8099 put_gpr_dw0(r1, mkexpr(result));
8100
8101 return "slgrk";
8102}
8103
florian55085f82012-11-21 00:36:55 +00008104static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008105s390_irgen_SL(UChar r1, IRTemp op2addr)
8106{
8107 IRTemp op1 = newTemp(Ity_I32);
8108 IRTemp op2 = newTemp(Ity_I32);
8109 IRTemp result = newTemp(Ity_I32);
8110
8111 assign(op1, get_gpr_w1(r1));
8112 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8113 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8114 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8115 put_gpr_w1(r1, mkexpr(result));
8116
8117 return "sl";
8118}
8119
florian55085f82012-11-21 00:36:55 +00008120static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008121s390_irgen_SLY(UChar r1, IRTemp op2addr)
8122{
8123 IRTemp op1 = newTemp(Ity_I32);
8124 IRTemp op2 = newTemp(Ity_I32);
8125 IRTemp result = newTemp(Ity_I32);
8126
8127 assign(op1, get_gpr_w1(r1));
8128 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8129 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8130 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8131 put_gpr_w1(r1, mkexpr(result));
8132
8133 return "sly";
8134}
8135
florian55085f82012-11-21 00:36:55 +00008136static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008137s390_irgen_SLG(UChar r1, IRTemp op2addr)
8138{
8139 IRTemp op1 = newTemp(Ity_I64);
8140 IRTemp op2 = newTemp(Ity_I64);
8141 IRTemp result = newTemp(Ity_I64);
8142
8143 assign(op1, get_gpr_dw0(r1));
8144 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8145 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8146 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8147 put_gpr_dw0(r1, mkexpr(result));
8148
8149 return "slg";
8150}
8151
florian55085f82012-11-21 00:36:55 +00008152static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008153s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8154{
8155 IRTemp op1 = newTemp(Ity_I64);
8156 IRTemp op2 = newTemp(Ity_I64);
8157 IRTemp result = newTemp(Ity_I64);
8158
8159 assign(op1, get_gpr_dw0(r1));
8160 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8161 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8162 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8163 put_gpr_dw0(r1, mkexpr(result));
8164
8165 return "slgf";
8166}
8167
florian55085f82012-11-21 00:36:55 +00008168static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008169s390_irgen_SLFI(UChar r1, UInt i2)
8170{
8171 IRTemp op1 = newTemp(Ity_I32);
8172 UInt op2;
8173 IRTemp result = newTemp(Ity_I32);
8174
8175 assign(op1, get_gpr_w1(r1));
8176 op2 = i2;
8177 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8178 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8179 mkU32(op2)));
8180 put_gpr_w1(r1, mkexpr(result));
8181
8182 return "slfi";
8183}
8184
florian55085f82012-11-21 00:36:55 +00008185static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008186s390_irgen_SLGFI(UChar r1, UInt i2)
8187{
8188 IRTemp op1 = newTemp(Ity_I64);
8189 ULong op2;
8190 IRTemp result = newTemp(Ity_I64);
8191
8192 assign(op1, get_gpr_dw0(r1));
8193 op2 = (ULong)i2;
8194 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8195 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8196 mkU64(op2)));
8197 put_gpr_dw0(r1, mkexpr(result));
8198
8199 return "slgfi";
8200}
8201
florian55085f82012-11-21 00:36:55 +00008202static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008203s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8204{
8205 IRTemp op2 = newTemp(Ity_I32);
8206 IRTemp op3 = newTemp(Ity_I32);
8207 IRTemp result = newTemp(Ity_I32);
8208
8209 assign(op2, get_gpr_w0(r1));
8210 assign(op3, get_gpr_w0(r2));
8211 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8212 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8213 put_gpr_w0(r1, mkexpr(result));
8214
8215 return "slhhhr";
8216}
8217
florian55085f82012-11-21 00:36:55 +00008218static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008219s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8220{
8221 IRTemp op2 = newTemp(Ity_I32);
8222 IRTemp op3 = newTemp(Ity_I32);
8223 IRTemp result = newTemp(Ity_I32);
8224
8225 assign(op2, get_gpr_w0(r1));
8226 assign(op3, get_gpr_w1(r2));
8227 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8228 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8229 put_gpr_w0(r1, mkexpr(result));
8230
8231 return "slhhlr";
8232}
8233
florian55085f82012-11-21 00:36:55 +00008234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008235s390_irgen_SLBR(UChar r1, UChar r2)
8236{
8237 IRTemp op1 = newTemp(Ity_I32);
8238 IRTemp op2 = newTemp(Ity_I32);
8239 IRTemp result = newTemp(Ity_I32);
8240 IRTemp borrow_in = newTemp(Ity_I32);
8241
8242 assign(op1, get_gpr_w1(r1));
8243 assign(op2, get_gpr_w1(r2));
8244 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8245 s390_call_calculate_cc(), mkU8(1))));
8246 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8247 mkexpr(borrow_in)));
8248 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8249 put_gpr_w1(r1, mkexpr(result));
8250
8251 return "slbr";
8252}
8253
florian55085f82012-11-21 00:36:55 +00008254static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008255s390_irgen_SLBGR(UChar r1, UChar r2)
8256{
8257 IRTemp op1 = newTemp(Ity_I64);
8258 IRTemp op2 = newTemp(Ity_I64);
8259 IRTemp result = newTemp(Ity_I64);
8260 IRTemp borrow_in = newTemp(Ity_I64);
8261
8262 assign(op1, get_gpr_dw0(r1));
8263 assign(op2, get_gpr_dw0(r2));
8264 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8265 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8266 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8267 mkexpr(borrow_in)));
8268 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8269 put_gpr_dw0(r1, mkexpr(result));
8270
8271 return "slbgr";
8272}
8273
florian55085f82012-11-21 00:36:55 +00008274static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008275s390_irgen_SLB(UChar r1, IRTemp op2addr)
8276{
8277 IRTemp op1 = newTemp(Ity_I32);
8278 IRTemp op2 = newTemp(Ity_I32);
8279 IRTemp result = newTemp(Ity_I32);
8280 IRTemp borrow_in = newTemp(Ity_I32);
8281
8282 assign(op1, get_gpr_w1(r1));
8283 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8284 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8285 s390_call_calculate_cc(), mkU8(1))));
8286 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8287 mkexpr(borrow_in)));
8288 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8289 put_gpr_w1(r1, mkexpr(result));
8290
8291 return "slb";
8292}
8293
florian55085f82012-11-21 00:36:55 +00008294static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008295s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8296{
8297 IRTemp op1 = newTemp(Ity_I64);
8298 IRTemp op2 = newTemp(Ity_I64);
8299 IRTemp result = newTemp(Ity_I64);
8300 IRTemp borrow_in = newTemp(Ity_I64);
8301
8302 assign(op1, get_gpr_dw0(r1));
8303 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8304 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8305 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8306 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8307 mkexpr(borrow_in)));
8308 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8309 put_gpr_dw0(r1, mkexpr(result));
8310
8311 return "slbg";
8312}
8313
florian55085f82012-11-21 00:36:55 +00008314static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008315s390_irgen_SVC(UChar i)
8316{
8317 IRTemp sysno = newTemp(Ity_I64);
8318
8319 if (i != 0) {
8320 assign(sysno, mkU64(i));
8321 } else {
8322 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8323 }
8324 system_call(mkexpr(sysno));
8325
8326 return "svc";
8327}
8328
florian55085f82012-11-21 00:36:55 +00008329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008330s390_irgen_TM(UChar i2, IRTemp op1addr)
8331{
8332 UChar mask;
8333 IRTemp value = newTemp(Ity_I8);
8334
8335 mask = i2;
8336 assign(value, load(Ity_I8, mkexpr(op1addr)));
8337 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8338 mkU8(mask)));
8339
8340 return "tm";
8341}
8342
florian55085f82012-11-21 00:36:55 +00008343static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008344s390_irgen_TMY(UChar i2, IRTemp op1addr)
8345{
8346 UChar mask;
8347 IRTemp value = newTemp(Ity_I8);
8348
8349 mask = i2;
8350 assign(value, load(Ity_I8, mkexpr(op1addr)));
8351 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8352 mkU8(mask)));
8353
8354 return "tmy";
8355}
8356
florian55085f82012-11-21 00:36:55 +00008357static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008358s390_irgen_TMHH(UChar r1, UShort i2)
8359{
8360 UShort mask;
8361 IRTemp value = newTemp(Ity_I16);
8362
8363 mask = i2;
8364 assign(value, get_gpr_hw0(r1));
8365 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8366 mkU16(mask)));
8367
8368 return "tmhh";
8369}
8370
florian55085f82012-11-21 00:36:55 +00008371static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008372s390_irgen_TMHL(UChar r1, UShort i2)
8373{
8374 UShort mask;
8375 IRTemp value = newTemp(Ity_I16);
8376
8377 mask = i2;
8378 assign(value, get_gpr_hw1(r1));
8379 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8380 mkU16(mask)));
8381
8382 return "tmhl";
8383}
8384
florian55085f82012-11-21 00:36:55 +00008385static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008386s390_irgen_TMLH(UChar r1, UShort i2)
8387{
8388 UShort mask;
8389 IRTemp value = newTemp(Ity_I16);
8390
8391 mask = i2;
8392 assign(value, get_gpr_hw2(r1));
8393 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8394 mkU16(mask)));
8395
8396 return "tmlh";
8397}
8398
florian55085f82012-11-21 00:36:55 +00008399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008400s390_irgen_TMLL(UChar r1, UShort i2)
8401{
8402 UShort mask;
8403 IRTemp value = newTemp(Ity_I16);
8404
8405 mask = i2;
8406 assign(value, get_gpr_hw3(r1));
8407 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8408 mkU16(mask)));
8409
8410 return "tmll";
8411}
8412
florian55085f82012-11-21 00:36:55 +00008413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008414s390_irgen_EFPC(UChar r1)
8415{
8416 put_gpr_w1(r1, get_fpc_w0());
8417
8418 return "efpc";
8419}
8420
florian55085f82012-11-21 00:36:55 +00008421static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008422s390_irgen_LER(UChar r1, UChar r2)
8423{
8424 put_fpr_w0(r1, get_fpr_w0(r2));
8425
8426 return "ler";
8427}
8428
florian55085f82012-11-21 00:36:55 +00008429static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008430s390_irgen_LDR(UChar r1, UChar r2)
8431{
8432 put_fpr_dw0(r1, get_fpr_dw0(r2));
8433
8434 return "ldr";
8435}
8436
florian55085f82012-11-21 00:36:55 +00008437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008438s390_irgen_LXR(UChar r1, UChar r2)
8439{
8440 put_fpr_dw0(r1, get_fpr_dw0(r2));
8441 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8442
8443 return "lxr";
8444}
8445
florian55085f82012-11-21 00:36:55 +00008446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008447s390_irgen_LE(UChar r1, IRTemp op2addr)
8448{
8449 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8450
8451 return "le";
8452}
8453
florian55085f82012-11-21 00:36:55 +00008454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008455s390_irgen_LD(UChar r1, IRTemp op2addr)
8456{
8457 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8458
8459 return "ld";
8460}
8461
florian55085f82012-11-21 00:36:55 +00008462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008463s390_irgen_LEY(UChar r1, IRTemp op2addr)
8464{
8465 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8466
8467 return "ley";
8468}
8469
florian55085f82012-11-21 00:36:55 +00008470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008471s390_irgen_LDY(UChar r1, IRTemp op2addr)
8472{
8473 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8474
8475 return "ldy";
8476}
8477
florian55085f82012-11-21 00:36:55 +00008478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008479s390_irgen_LFPC(IRTemp op2addr)
8480{
8481 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8482
8483 return "lfpc";
8484}
8485
florian55085f82012-11-21 00:36:55 +00008486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008487s390_irgen_LZER(UChar r1)
8488{
8489 put_fpr_w0(r1, mkF32i(0x0));
8490
8491 return "lzer";
8492}
8493
florian55085f82012-11-21 00:36:55 +00008494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008495s390_irgen_LZDR(UChar r1)
8496{
8497 put_fpr_dw0(r1, mkF64i(0x0));
8498
8499 return "lzdr";
8500}
8501
florian55085f82012-11-21 00:36:55 +00008502static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008503s390_irgen_LZXR(UChar r1)
8504{
8505 put_fpr_dw0(r1, mkF64i(0x0));
8506 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8507
8508 return "lzxr";
8509}
8510
florian55085f82012-11-21 00:36:55 +00008511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008512s390_irgen_SRNM(IRTemp op2addr)
8513{
florianf0fa1be2012-09-18 20:24:38 +00008514 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008515
florianf0fa1be2012-09-18 20:24:38 +00008516 input_mask = 3;
8517 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008518
florianf0fa1be2012-09-18 20:24:38 +00008519 put_fpc_w0(binop(Iop_Or32,
8520 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8521 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8522 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008523 return "srnm";
8524}
8525
florian55085f82012-11-21 00:36:55 +00008526static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008527s390_irgen_SRNMB(IRTemp op2addr)
8528{
8529 UInt input_mask, fpc_mask;
8530
8531 input_mask = 7;
8532 fpc_mask = 7;
8533
8534 put_fpc_w0(binop(Iop_Or32,
8535 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8536 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8537 mkU32(input_mask))));
8538 return "srnmb";
8539}
8540
florian81a4bfe2012-09-20 01:25:28 +00008541static void
florianf0fa1be2012-09-18 20:24:38 +00008542s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8543{
8544 if (b2 == 0) { /* This is the typical case */
8545 if (d2 > 3) {
8546 if (s390_host_has_fpext && d2 == 7) {
8547 /* ok */
8548 } else {
8549 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008550 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008551 }
8552 }
8553 }
8554
8555 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8556}
8557
8558
florian55085f82012-11-21 00:36:55 +00008559static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008560s390_irgen_SFPC(UChar r1)
8561{
8562 put_fpc_w0(get_gpr_w1(r1));
8563
8564 return "sfpc";
8565}
8566
florian55085f82012-11-21 00:36:55 +00008567static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008568s390_irgen_STE(UChar r1, IRTemp op2addr)
8569{
8570 store(mkexpr(op2addr), get_fpr_w0(r1));
8571
8572 return "ste";
8573}
8574
florian55085f82012-11-21 00:36:55 +00008575static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008576s390_irgen_STD(UChar r1, IRTemp op2addr)
8577{
8578 store(mkexpr(op2addr), get_fpr_dw0(r1));
8579
8580 return "std";
8581}
8582
florian55085f82012-11-21 00:36:55 +00008583static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008584s390_irgen_STEY(UChar r1, IRTemp op2addr)
8585{
8586 store(mkexpr(op2addr), get_fpr_w0(r1));
8587
8588 return "stey";
8589}
8590
florian55085f82012-11-21 00:36:55 +00008591static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008592s390_irgen_STDY(UChar r1, IRTemp op2addr)
8593{
8594 store(mkexpr(op2addr), get_fpr_dw0(r1));
8595
8596 return "stdy";
8597}
8598
florian55085f82012-11-21 00:36:55 +00008599static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008600s390_irgen_STFPC(IRTemp op2addr)
8601{
8602 store(mkexpr(op2addr), get_fpc_w0());
8603
8604 return "stfpc";
8605}
8606
florian55085f82012-11-21 00:36:55 +00008607static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008608s390_irgen_AEBR(UChar r1, UChar r2)
8609{
8610 IRTemp op1 = newTemp(Ity_F32);
8611 IRTemp op2 = newTemp(Ity_F32);
8612 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008613 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008614
8615 assign(op1, get_fpr_w0(r1));
8616 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008617 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008618 mkexpr(op2)));
8619 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8620 put_fpr_w0(r1, mkexpr(result));
8621
8622 return "aebr";
8623}
8624
florian55085f82012-11-21 00:36:55 +00008625static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008626s390_irgen_ADBR(UChar r1, UChar r2)
8627{
8628 IRTemp op1 = newTemp(Ity_F64);
8629 IRTemp op2 = newTemp(Ity_F64);
8630 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008631 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008632
8633 assign(op1, get_fpr_dw0(r1));
8634 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008635 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008636 mkexpr(op2)));
8637 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8638 put_fpr_dw0(r1, mkexpr(result));
8639
8640 return "adbr";
8641}
8642
florian55085f82012-11-21 00:36:55 +00008643static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008644s390_irgen_AEB(UChar r1, IRTemp op2addr)
8645{
8646 IRTemp op1 = newTemp(Ity_F32);
8647 IRTemp op2 = newTemp(Ity_F32);
8648 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008649 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008650
8651 assign(op1, get_fpr_w0(r1));
8652 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008653 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008654 mkexpr(op2)));
8655 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8656 put_fpr_w0(r1, mkexpr(result));
8657
8658 return "aeb";
8659}
8660
florian55085f82012-11-21 00:36:55 +00008661static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008662s390_irgen_ADB(UChar r1, IRTemp op2addr)
8663{
8664 IRTemp op1 = newTemp(Ity_F64);
8665 IRTemp op2 = newTemp(Ity_F64);
8666 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008667 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008668
8669 assign(op1, get_fpr_dw0(r1));
8670 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008671 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008672 mkexpr(op2)));
8673 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8674 put_fpr_dw0(r1, mkexpr(result));
8675
8676 return "adb";
8677}
8678
florian55085f82012-11-21 00:36:55 +00008679static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008680s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8681 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008682{
florian125e20d2012-10-07 15:42:37 +00008683 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008684 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008685 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008686 }
sewardj2019a972011-03-07 16:04:07 +00008687 IRTemp op2 = newTemp(Ity_I32);
8688
8689 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008690 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008691 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008692
8693 return "cefbr";
8694}
8695
florian55085f82012-11-21 00:36:55 +00008696static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008697s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8698 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008699{
8700 IRTemp op2 = newTemp(Ity_I32);
8701
8702 assign(op2, get_gpr_w1(r2));
8703 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8704
8705 return "cdfbr";
8706}
8707
florian55085f82012-11-21 00:36:55 +00008708static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008709s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8710 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008711{
florian125e20d2012-10-07 15:42:37 +00008712 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008713 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008714 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008715 }
sewardj2019a972011-03-07 16:04:07 +00008716 IRTemp op2 = newTemp(Ity_I64);
8717
8718 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008719 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008720 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008721
8722 return "cegbr";
8723}
8724
florian55085f82012-11-21 00:36:55 +00008725static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008726s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8727 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008728{
florian125e20d2012-10-07 15:42:37 +00008729 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008730 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008731 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008732 }
sewardj2019a972011-03-07 16:04:07 +00008733 IRTemp op2 = newTemp(Ity_I64);
8734
8735 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008736 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008737 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008738
8739 return "cdgbr";
8740}
8741
florian55085f82012-11-21 00:36:55 +00008742static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008743s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8744 UChar r1, UChar r2)
8745{
floriane75dafa2012-09-01 17:54:09 +00008746 if (! s390_host_has_fpext) {
8747 emulation_failure(EmFail_S390X_fpext);
8748 } else {
8749 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008750
floriane75dafa2012-09-01 17:54:09 +00008751 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008752 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008753 mkexpr(op2)));
8754 }
florian1c8f7ff2012-09-01 00:12:11 +00008755 return "celfbr";
8756}
8757
florian55085f82012-11-21 00:36:55 +00008758static const HChar *
floriand2129202012-09-01 20:01:39 +00008759s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8760 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008761{
floriane75dafa2012-09-01 17:54:09 +00008762 if (! s390_host_has_fpext) {
8763 emulation_failure(EmFail_S390X_fpext);
8764 } else {
8765 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008766
floriane75dafa2012-09-01 17:54:09 +00008767 assign(op2, get_gpr_w1(r2));
8768 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8769 }
florian1c8f7ff2012-09-01 00:12:11 +00008770 return "cdlfbr";
8771}
8772
florian55085f82012-11-21 00:36:55 +00008773static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008774s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8775 UChar r1, UChar r2)
8776{
floriane75dafa2012-09-01 17:54:09 +00008777 if (! s390_host_has_fpext) {
8778 emulation_failure(EmFail_S390X_fpext);
8779 } else {
8780 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008781
floriane75dafa2012-09-01 17:54:09 +00008782 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008783 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008784 mkexpr(op2)));
8785 }
florian1c8f7ff2012-09-01 00:12:11 +00008786 return "celgbr";
8787}
8788
florian55085f82012-11-21 00:36:55 +00008789static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008790s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8791 UChar r1, UChar r2)
8792{
floriane75dafa2012-09-01 17:54:09 +00008793 if (! s390_host_has_fpext) {
8794 emulation_failure(EmFail_S390X_fpext);
8795 } else {
8796 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008797
floriane75dafa2012-09-01 17:54:09 +00008798 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008799 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8800 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008801 mkexpr(op2)));
8802 }
florian1c8f7ff2012-09-01 00:12:11 +00008803 return "cdlgbr";
8804}
8805
florian55085f82012-11-21 00:36:55 +00008806static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008807s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8808 UChar r1, UChar r2)
8809{
floriane75dafa2012-09-01 17:54:09 +00008810 if (! s390_host_has_fpext) {
8811 emulation_failure(EmFail_S390X_fpext);
8812 } else {
8813 IRTemp op = newTemp(Ity_F32);
8814 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008815 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008816
floriane75dafa2012-09-01 17:54:09 +00008817 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008818 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008819 mkexpr(op)));
8820 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008821 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008822 }
florian1c8f7ff2012-09-01 00:12:11 +00008823 return "clfebr";
8824}
8825
florian55085f82012-11-21 00:36:55 +00008826static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008827s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8828 UChar r1, UChar r2)
8829{
floriane75dafa2012-09-01 17:54:09 +00008830 if (! s390_host_has_fpext) {
8831 emulation_failure(EmFail_S390X_fpext);
8832 } else {
8833 IRTemp op = newTemp(Ity_F64);
8834 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008835 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008836
floriane75dafa2012-09-01 17:54:09 +00008837 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008838 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008839 mkexpr(op)));
8840 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008841 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008842 }
florian1c8f7ff2012-09-01 00:12:11 +00008843 return "clfdbr";
8844}
8845
florian55085f82012-11-21 00:36:55 +00008846static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008847s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8848 UChar r1, UChar r2)
8849{
floriane75dafa2012-09-01 17:54:09 +00008850 if (! s390_host_has_fpext) {
8851 emulation_failure(EmFail_S390X_fpext);
8852 } else {
8853 IRTemp op = newTemp(Ity_F32);
8854 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008855 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008856
floriane75dafa2012-09-01 17:54:09 +00008857 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008858 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008859 mkexpr(op)));
8860 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008861 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008862 }
florian1c8f7ff2012-09-01 00:12:11 +00008863 return "clgebr";
8864}
8865
florian55085f82012-11-21 00:36:55 +00008866static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008867s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8868 UChar r1, UChar r2)
8869{
floriane75dafa2012-09-01 17:54:09 +00008870 if (! s390_host_has_fpext) {
8871 emulation_failure(EmFail_S390X_fpext);
8872 } else {
8873 IRTemp op = newTemp(Ity_F64);
8874 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008875 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008876
floriane75dafa2012-09-01 17:54:09 +00008877 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008878 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008879 mkexpr(op)));
8880 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008881 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008882 }
florian1c8f7ff2012-09-01 00:12:11 +00008883 return "clgdbr";
8884}
8885
florian55085f82012-11-21 00:36:55 +00008886static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008887s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8888 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008889{
8890 IRTemp op = newTemp(Ity_F32);
8891 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008892 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008893
8894 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008895 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008896 mkexpr(op)));
8897 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008898 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008899
8900 return "cfebr";
8901}
8902
florian55085f82012-11-21 00:36:55 +00008903static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008904s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8905 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008906{
8907 IRTemp op = newTemp(Ity_F64);
8908 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008909 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008910
8911 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008912 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008913 mkexpr(op)));
8914 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008915 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008916
8917 return "cfdbr";
8918}
8919
florian55085f82012-11-21 00:36:55 +00008920static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008921s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8922 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008923{
8924 IRTemp op = newTemp(Ity_F32);
8925 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008926 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008927
8928 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008929 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008930 mkexpr(op)));
8931 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008932 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008933
8934 return "cgebr";
8935}
8936
florian55085f82012-11-21 00:36:55 +00008937static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008938s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8939 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008940{
8941 IRTemp op = newTemp(Ity_F64);
8942 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008943 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008944
8945 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008946 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008947 mkexpr(op)));
8948 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008949 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008950
8951 return "cgdbr";
8952}
8953
florian55085f82012-11-21 00:36:55 +00008954static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008955s390_irgen_DEBR(UChar r1, UChar r2)
8956{
8957 IRTemp op1 = newTemp(Ity_F32);
8958 IRTemp op2 = newTemp(Ity_F32);
8959 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008960 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008961
8962 assign(op1, get_fpr_w0(r1));
8963 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008964 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008965 mkexpr(op2)));
8966 put_fpr_w0(r1, mkexpr(result));
8967
8968 return "debr";
8969}
8970
florian55085f82012-11-21 00:36:55 +00008971static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008972s390_irgen_DDBR(UChar r1, UChar r2)
8973{
8974 IRTemp op1 = newTemp(Ity_F64);
8975 IRTemp op2 = newTemp(Ity_F64);
8976 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008977 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008978
8979 assign(op1, get_fpr_dw0(r1));
8980 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008981 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008982 mkexpr(op2)));
8983 put_fpr_dw0(r1, mkexpr(result));
8984
8985 return "ddbr";
8986}
8987
florian55085f82012-11-21 00:36:55 +00008988static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008989s390_irgen_DEB(UChar r1, IRTemp op2addr)
8990{
8991 IRTemp op1 = newTemp(Ity_F32);
8992 IRTemp op2 = newTemp(Ity_F32);
8993 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008994 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008995
8996 assign(op1, get_fpr_w0(r1));
8997 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008998 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008999 mkexpr(op2)));
9000 put_fpr_w0(r1, mkexpr(result));
9001
9002 return "deb";
9003}
9004
florian55085f82012-11-21 00:36:55 +00009005static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009006s390_irgen_DDB(UChar r1, IRTemp op2addr)
9007{
9008 IRTemp op1 = newTemp(Ity_F64);
9009 IRTemp op2 = newTemp(Ity_F64);
9010 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009011 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009012
9013 assign(op1, get_fpr_dw0(r1));
9014 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009015 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009016 mkexpr(op2)));
9017 put_fpr_dw0(r1, mkexpr(result));
9018
9019 return "ddb";
9020}
9021
florian55085f82012-11-21 00:36:55 +00009022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009023s390_irgen_LTEBR(UChar r1, UChar r2)
9024{
9025 IRTemp result = newTemp(Ity_F32);
9026
9027 assign(result, get_fpr_w0(r2));
9028 put_fpr_w0(r1, mkexpr(result));
9029 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9030
9031 return "ltebr";
9032}
9033
florian55085f82012-11-21 00:36:55 +00009034static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009035s390_irgen_LTDBR(UChar r1, UChar r2)
9036{
9037 IRTemp result = newTemp(Ity_F64);
9038
9039 assign(result, get_fpr_dw0(r2));
9040 put_fpr_dw0(r1, mkexpr(result));
9041 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9042
9043 return "ltdbr";
9044}
9045
florian55085f82012-11-21 00:36:55 +00009046static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009047s390_irgen_LCEBR(UChar r1, UChar r2)
9048{
9049 IRTemp result = newTemp(Ity_F32);
9050
9051 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9052 put_fpr_w0(r1, mkexpr(result));
9053 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9054
9055 return "lcebr";
9056}
9057
florian55085f82012-11-21 00:36:55 +00009058static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009059s390_irgen_LCDBR(UChar r1, UChar r2)
9060{
9061 IRTemp result = newTemp(Ity_F64);
9062
9063 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9064 put_fpr_dw0(r1, mkexpr(result));
9065 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9066
9067 return "lcdbr";
9068}
9069
florian55085f82012-11-21 00:36:55 +00009070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009071s390_irgen_LDEBR(UChar r1, UChar r2)
9072{
9073 IRTemp op = newTemp(Ity_F32);
9074
9075 assign(op, get_fpr_w0(r2));
9076 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9077
9078 return "ldebr";
9079}
9080
florian55085f82012-11-21 00:36:55 +00009081static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009082s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9083{
9084 IRTemp op = newTemp(Ity_F32);
9085
9086 assign(op, load(Ity_F32, mkexpr(op2addr)));
9087 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9088
9089 return "ldeb";
9090}
9091
florian55085f82012-11-21 00:36:55 +00009092static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009093s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9094 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009095{
florian125e20d2012-10-07 15:42:37 +00009096 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009097 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009098 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009099 }
sewardj2019a972011-03-07 16:04:07 +00009100 IRTemp op = newTemp(Ity_F64);
9101
9102 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009103 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009104 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009105
9106 return "ledbr";
9107}
9108
florian55085f82012-11-21 00:36:55 +00009109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009110s390_irgen_MEEBR(UChar r1, UChar r2)
9111{
9112 IRTemp op1 = newTemp(Ity_F32);
9113 IRTemp op2 = newTemp(Ity_F32);
9114 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009115 IRRoundingMode rounding_mode =
9116 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009117
9118 assign(op1, get_fpr_w0(r1));
9119 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009120 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009121 mkexpr(op2)));
9122 put_fpr_w0(r1, mkexpr(result));
9123
9124 return "meebr";
9125}
9126
florian55085f82012-11-21 00:36:55 +00009127static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009128s390_irgen_MDBR(UChar r1, UChar r2)
9129{
9130 IRTemp op1 = newTemp(Ity_F64);
9131 IRTemp op2 = newTemp(Ity_F64);
9132 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009133 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009134
9135 assign(op1, get_fpr_dw0(r1));
9136 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009137 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009138 mkexpr(op2)));
9139 put_fpr_dw0(r1, mkexpr(result));
9140
9141 return "mdbr";
9142}
9143
florian55085f82012-11-21 00:36:55 +00009144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009145s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9146{
9147 IRTemp op1 = newTemp(Ity_F32);
9148 IRTemp op2 = newTemp(Ity_F32);
9149 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009150 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009151
9152 assign(op1, get_fpr_w0(r1));
9153 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009154 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009155 mkexpr(op2)));
9156 put_fpr_w0(r1, mkexpr(result));
9157
9158 return "meeb";
9159}
9160
florian55085f82012-11-21 00:36:55 +00009161static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009162s390_irgen_MDB(UChar r1, IRTemp op2addr)
9163{
9164 IRTemp op1 = newTemp(Ity_F64);
9165 IRTemp op2 = newTemp(Ity_F64);
9166 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009167 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009168
9169 assign(op1, get_fpr_dw0(r1));
9170 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009171 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009172 mkexpr(op2)));
9173 put_fpr_dw0(r1, mkexpr(result));
9174
9175 return "mdb";
9176}
9177
florian55085f82012-11-21 00:36:55 +00009178static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009179s390_irgen_SEBR(UChar r1, UChar r2)
9180{
9181 IRTemp op1 = newTemp(Ity_F32);
9182 IRTemp op2 = newTemp(Ity_F32);
9183 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009184 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009185
9186 assign(op1, get_fpr_w0(r1));
9187 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009188 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009189 mkexpr(op2)));
9190 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9191 put_fpr_w0(r1, mkexpr(result));
9192
9193 return "sebr";
9194}
9195
florian55085f82012-11-21 00:36:55 +00009196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009197s390_irgen_SDBR(UChar r1, UChar r2)
9198{
9199 IRTemp op1 = newTemp(Ity_F64);
9200 IRTemp op2 = newTemp(Ity_F64);
9201 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009202 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009203
9204 assign(op1, get_fpr_dw0(r1));
9205 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009206 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009207 mkexpr(op2)));
9208 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9209 put_fpr_dw0(r1, mkexpr(result));
9210
9211 return "sdbr";
9212}
9213
florian55085f82012-11-21 00:36:55 +00009214static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009215s390_irgen_SEB(UChar r1, IRTemp op2addr)
9216{
9217 IRTemp op1 = newTemp(Ity_F32);
9218 IRTemp op2 = newTemp(Ity_F32);
9219 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009220 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009221
9222 assign(op1, get_fpr_w0(r1));
9223 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009224 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009225 mkexpr(op2)));
9226 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9227 put_fpr_w0(r1, mkexpr(result));
9228
9229 return "seb";
9230}
9231
florian55085f82012-11-21 00:36:55 +00009232static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009233s390_irgen_SDB(UChar r1, IRTemp op2addr)
9234{
9235 IRTemp op1 = newTemp(Ity_F64);
9236 IRTemp op2 = newTemp(Ity_F64);
9237 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009238 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009239
9240 assign(op1, get_fpr_dw0(r1));
9241 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009242 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009243 mkexpr(op2)));
9244 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9245 put_fpr_dw0(r1, mkexpr(result));
9246
9247 return "sdb";
9248}
9249
florian55085f82012-11-21 00:36:55 +00009250static const HChar *
florian12390202012-11-10 22:34:14 +00009251s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9252{
9253 IRTemp op1 = newTemp(Ity_D64);
9254 IRTemp op2 = newTemp(Ity_D64);
9255 IRTemp result = newTemp(Ity_D64);
9256 IRTemp rounding_mode;
9257
9258 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009259
9260 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9261 emulation_warning(EmWarn_S390X_fpext_rounding);
9262 m4 = S390_DFP_ROUND_PER_FPC_0;
9263 }
9264
florian12390202012-11-10 22:34:14 +00009265 rounding_mode = encode_dfp_rounding_mode(m4);
9266 assign(op1, get_dpr_dw0(r2));
9267 assign(op2, get_dpr_dw0(r3));
9268 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9269 mkexpr(op2)));
9270 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9271 put_dpr_dw0(r1, mkexpr(result));
9272
9273 return (m4 == 0) ? "adtr" : "adtra";
9274}
9275
florian55085f82012-11-21 00:36:55 +00009276static const HChar *
floriane38f6412012-12-21 17:32:12 +00009277s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9278{
9279 IRTemp op1 = newTemp(Ity_D128);
9280 IRTemp op2 = newTemp(Ity_D128);
9281 IRTemp result = newTemp(Ity_D128);
9282 IRTemp rounding_mode;
9283
9284 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009285
9286 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9287 emulation_warning(EmWarn_S390X_fpext_rounding);
9288 m4 = S390_DFP_ROUND_PER_FPC_0;
9289 }
9290
floriane38f6412012-12-21 17:32:12 +00009291 rounding_mode = encode_dfp_rounding_mode(m4);
9292 assign(op1, get_dpr_pair(r2));
9293 assign(op2, get_dpr_pair(r3));
9294 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9295 mkexpr(op2)));
9296 put_dpr_pair(r1, mkexpr(result));
9297
9298 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9299
9300 return (m4 == 0) ? "axtr" : "axtra";
9301}
9302
9303static const HChar *
9304s390_irgen_CDTR(UChar r1, UChar r2)
9305{
9306 IRTemp op1 = newTemp(Ity_D64);
9307 IRTemp op2 = newTemp(Ity_D64);
9308 IRTemp cc_vex = newTemp(Ity_I32);
9309 IRTemp cc_s390 = newTemp(Ity_I32);
9310
9311 assign(op1, get_dpr_dw0(r1));
9312 assign(op2, get_dpr_dw0(r2));
9313 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9314
florian2d3d87f2012-12-21 21:05:17 +00009315 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009316 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9317
9318 return "cdtr";
9319}
9320
9321static const HChar *
9322s390_irgen_CXTR(UChar r1, UChar r2)
9323{
9324 IRTemp op1 = newTemp(Ity_D128);
9325 IRTemp op2 = newTemp(Ity_D128);
9326 IRTemp cc_vex = newTemp(Ity_I32);
9327 IRTemp cc_s390 = newTemp(Ity_I32);
9328
9329 assign(op1, get_dpr_pair(r1));
9330 assign(op2, get_dpr_pair(r2));
9331 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9332
florian2d3d87f2012-12-21 21:05:17 +00009333 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009334 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9335
9336 return "cxtr";
9337}
9338
9339static const HChar *
florian5f034622013-01-13 02:29:05 +00009340s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9341 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9342{
9343 vassert(s390_host_has_dfp);
9344
9345 if (! s390_host_has_fpext) {
9346 emulation_failure(EmFail_S390X_fpext);
9347 } else {
9348 IRTemp op2 = newTemp(Ity_I32);
9349
9350 assign(op2, get_gpr_w1(r2));
9351 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9352 }
9353 return "cdftr";
9354}
9355
9356static const HChar *
9357s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9358 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9359{
9360 vassert(s390_host_has_dfp);
9361
9362 if (! s390_host_has_fpext) {
9363 emulation_failure(EmFail_S390X_fpext);
9364 } else {
9365 IRTemp op2 = newTemp(Ity_I32);
9366
9367 assign(op2, get_gpr_w1(r2));
9368 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9369 }
9370 return "cxftr";
9371}
9372
9373static const HChar *
floriana887acd2013-02-08 23:32:54 +00009374s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9375 UChar r1, UChar r2)
9376{
9377 IRTemp op2 = newTemp(Ity_I64);
9378
9379 vassert(s390_host_has_dfp);
9380 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9381 emulation_warning(EmWarn_S390X_fpext_rounding);
9382 m3 = S390_DFP_ROUND_PER_FPC_0;
9383 }
9384
9385 assign(op2, get_gpr_dw0(r2));
9386 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9387 mkexpr(op2)));
9388
9389 return (m3 == 0) ? "cdgtr" : "cdgtra";
9390}
9391
9392static const HChar *
9393s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9394 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9395{
9396 IRTemp op2 = newTemp(Ity_I64);
9397
9398 vassert(s390_host_has_dfp);
9399
florian1bb7f6f2013-02-11 00:03:27 +00009400 /* No emulation warning here about an non-zero m3 on hosts without
9401 floating point extension facility. No rounding is performed */
9402
floriana887acd2013-02-08 23:32:54 +00009403 assign(op2, get_gpr_dw0(r2));
9404 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9405
9406 return "cxgtr";
9407}
9408
9409static const HChar *
florian5f034622013-01-13 02:29:05 +00009410s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9411 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9412{
9413 vassert(s390_host_has_dfp);
9414
9415 if (! s390_host_has_fpext) {
9416 emulation_failure(EmFail_S390X_fpext);
9417 } else {
9418 IRTemp op2 = newTemp(Ity_I32);
9419
9420 assign(op2, get_gpr_w1(r2));
9421 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9422 }
9423 return "cdlftr";
9424}
9425
9426static const HChar *
9427s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9428 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9429{
9430 vassert(s390_host_has_dfp);
9431
9432 if (! s390_host_has_fpext) {
9433 emulation_failure(EmFail_S390X_fpext);
9434 } else {
9435 IRTemp op2 = newTemp(Ity_I32);
9436
9437 assign(op2, get_gpr_w1(r2));
9438 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9439 }
9440 return "cxlftr";
9441}
9442
9443static const HChar *
9444s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9445 UChar r1, UChar r2)
9446{
9447 vassert(s390_host_has_dfp);
9448
9449 if (! s390_host_has_fpext) {
9450 emulation_failure(EmFail_S390X_fpext);
9451 } else {
9452 IRTemp op2 = newTemp(Ity_I64);
9453
9454 assign(op2, get_gpr_dw0(r2));
9455 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9456 mkexpr(encode_dfp_rounding_mode(m3)),
9457 mkexpr(op2)));
9458 }
9459 return "cdlgtr";
9460}
9461
9462static const HChar *
9463s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9464 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9465{
9466 vassert(s390_host_has_dfp);
9467
9468 if (! s390_host_has_fpext) {
9469 emulation_failure(EmFail_S390X_fpext);
9470 } else {
9471 IRTemp op2 = newTemp(Ity_I64);
9472
9473 assign(op2, get_gpr_dw0(r2));
9474 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9475 }
9476 return "cxlgtr";
9477}
9478
9479static const HChar *
9480s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9481 UChar r1, UChar r2)
9482{
9483 vassert(s390_host_has_dfp);
9484
9485 if (! s390_host_has_fpext) {
9486 emulation_failure(EmFail_S390X_fpext);
9487 } else {
9488 IRTemp op = newTemp(Ity_D64);
9489 IRTemp result = newTemp(Ity_I32);
9490 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9491
9492 assign(op, get_dpr_dw0(r2));
9493 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9494 mkexpr(op)));
9495 put_gpr_w1(r1, mkexpr(result));
9496 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9497 }
9498 return "cfdtr";
9499}
9500
9501static const HChar *
9502s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9503 UChar r1, UChar r2)
9504{
9505 vassert(s390_host_has_dfp);
9506
9507 if (! s390_host_has_fpext) {
9508 emulation_failure(EmFail_S390X_fpext);
9509 } else {
9510 IRTemp op = newTemp(Ity_D128);
9511 IRTemp result = newTemp(Ity_I32);
9512 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9513
9514 assign(op, get_dpr_pair(r2));
9515 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9516 mkexpr(op)));
9517 put_gpr_w1(r1, mkexpr(result));
9518 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9519 }
9520 return "cfxtr";
9521}
9522
9523static const HChar *
floriana887acd2013-02-08 23:32:54 +00009524s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9525 UChar r1, UChar r2)
9526{
9527 IRTemp op = newTemp(Ity_D64);
9528 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9529
9530 vassert(s390_host_has_dfp);
9531
9532 /* If fpext is not installed and m3 is in 1:7,
9533 rounding mode performed is unpredictable */
9534 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9535 emulation_warning(EmWarn_S390X_fpext_rounding);
9536 m3 = S390_DFP_ROUND_PER_FPC_0;
9537 }
9538
9539 assign(op, get_dpr_dw0(r2));
9540 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9541 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9542
9543 return "cgdtr";
9544}
9545
9546static const HChar *
9547s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9548 UChar r1, UChar r2)
9549{
9550 IRTemp op = newTemp(Ity_D128);
9551 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9552
9553 vassert(s390_host_has_dfp);
9554
9555 /* If fpext is not installed and m3 is in 1:7,
9556 rounding mode performed is unpredictable */
9557 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9558 emulation_warning(EmWarn_S390X_fpext_rounding);
9559 m3 = S390_DFP_ROUND_PER_FPC_0;
9560 }
9561 assign(op, get_dpr_pair(r2));
9562 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9563 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9564
9565 return "cgxtr";
9566}
9567
9568static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009569s390_irgen_CEDTR(UChar r1, UChar r2)
9570{
9571 IRTemp op1 = newTemp(Ity_D64);
9572 IRTemp op2 = newTemp(Ity_D64);
9573 IRTemp cc_vex = newTemp(Ity_I32);
9574 IRTemp cc_s390 = newTemp(Ity_I32);
9575
9576 vassert(s390_host_has_dfp);
9577 assign(op1, get_dpr_dw0(r1));
9578 assign(op2, get_dpr_dw0(r2));
9579 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9580
9581 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9582 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9583
9584 return "cedtr";
9585}
9586
9587static const HChar *
9588s390_irgen_CEXTR(UChar r1, UChar r2)
9589{
9590 IRTemp op1 = newTemp(Ity_D128);
9591 IRTemp op2 = newTemp(Ity_D128);
9592 IRTemp cc_vex = newTemp(Ity_I32);
9593 IRTemp cc_s390 = newTemp(Ity_I32);
9594
9595 vassert(s390_host_has_dfp);
9596 assign(op1, get_dpr_pair(r1));
9597 assign(op2, get_dpr_pair(r2));
9598 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9599
9600 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9601 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9602
9603 return "cextr";
9604}
9605
9606static const HChar *
florian5f034622013-01-13 02:29:05 +00009607s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9608 UChar r1, UChar r2)
9609{
9610 vassert(s390_host_has_dfp);
9611
9612 if (! s390_host_has_fpext) {
9613 emulation_failure(EmFail_S390X_fpext);
9614 } else {
9615 IRTemp op = newTemp(Ity_D64);
9616 IRTemp result = newTemp(Ity_I32);
9617 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9618
9619 assign(op, get_dpr_dw0(r2));
9620 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9621 mkexpr(op)));
9622 put_gpr_w1(r1, mkexpr(result));
9623 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9624 }
9625 return "clfdtr";
9626}
9627
9628static const HChar *
9629s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9630 UChar r1, UChar r2)
9631{
9632 vassert(s390_host_has_dfp);
9633
9634 if (! s390_host_has_fpext) {
9635 emulation_failure(EmFail_S390X_fpext);
9636 } else {
9637 IRTemp op = newTemp(Ity_D128);
9638 IRTemp result = newTemp(Ity_I32);
9639 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9640
9641 assign(op, get_dpr_pair(r2));
9642 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9643 mkexpr(op)));
9644 put_gpr_w1(r1, mkexpr(result));
9645 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9646 }
9647 return "clfxtr";
9648}
9649
9650static const HChar *
9651s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9652 UChar r1, UChar r2)
9653{
9654 vassert(s390_host_has_dfp);
9655
9656 if (! s390_host_has_fpext) {
9657 emulation_failure(EmFail_S390X_fpext);
9658 } else {
9659 IRTemp op = newTemp(Ity_D64);
9660 IRTemp result = newTemp(Ity_I64);
9661 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9662
9663 assign(op, get_dpr_dw0(r2));
9664 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
9665 mkexpr(op)));
9666 put_gpr_dw0(r1, mkexpr(result));
9667 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
9668 }
9669 return "clgdtr";
9670}
9671
9672static const HChar *
9673s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
9674 UChar r1, UChar r2)
9675{
9676 vassert(s390_host_has_dfp);
9677
9678 if (! s390_host_has_fpext) {
9679 emulation_failure(EmFail_S390X_fpext);
9680 } else {
9681 IRTemp op = newTemp(Ity_D128);
9682 IRTemp result = newTemp(Ity_I64);
9683 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9684
9685 assign(op, get_dpr_pair(r2));
9686 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
9687 mkexpr(op)));
9688 put_gpr_dw0(r1, mkexpr(result));
9689 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
9690 rounding_mode);
9691 }
9692 return "clgxtr";
9693}
9694
9695static const HChar *
florian12390202012-11-10 22:34:14 +00009696s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9697{
9698 IRTemp op1 = newTemp(Ity_D64);
9699 IRTemp op2 = newTemp(Ity_D64);
9700 IRTemp result = newTemp(Ity_D64);
9701 IRTemp rounding_mode;
9702
9703 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009704
9705 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9706 emulation_warning(EmWarn_S390X_fpext_rounding);
9707 m4 = S390_DFP_ROUND_PER_FPC_0;
9708 }
9709
florian12390202012-11-10 22:34:14 +00009710 rounding_mode = encode_dfp_rounding_mode(m4);
9711 assign(op1, get_dpr_dw0(r2));
9712 assign(op2, get_dpr_dw0(r3));
9713 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9714 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009715 put_dpr_dw0(r1, mkexpr(result));
9716
9717 return (m4 == 0) ? "ddtr" : "ddtra";
9718}
9719
florian55085f82012-11-21 00:36:55 +00009720static const HChar *
floriane38f6412012-12-21 17:32:12 +00009721s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9722{
9723 IRTemp op1 = newTemp(Ity_D128);
9724 IRTemp op2 = newTemp(Ity_D128);
9725 IRTemp result = newTemp(Ity_D128);
9726 IRTemp rounding_mode;
9727
9728 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009729
9730 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9731 emulation_warning(EmWarn_S390X_fpext_rounding);
9732 m4 = S390_DFP_ROUND_PER_FPC_0;
9733 }
9734
floriane38f6412012-12-21 17:32:12 +00009735 rounding_mode = encode_dfp_rounding_mode(m4);
9736 assign(op1, get_dpr_pair(r2));
9737 assign(op2, get_dpr_pair(r3));
9738 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9739 mkexpr(op2)));
9740 put_dpr_pair(r1, mkexpr(result));
9741
9742 return (m4 == 0) ? "dxtr" : "dxtra";
9743}
9744
9745static const HChar *
florian5c539732013-02-14 14:27:12 +00009746s390_irgen_EEDTR(UChar r1, UChar r2)
9747{
9748 vassert(s390_host_has_dfp);
9749
9750 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
9751 return "eedtr";
9752}
9753
9754static const HChar *
9755s390_irgen_EEXTR(UChar r1, UChar r2)
9756{
9757 vassert(s390_host_has_dfp);
9758
9759 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
9760 return "eextr";
9761}
9762
9763static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009764s390_irgen_ESDTR(UChar r1, UChar r2)
9765{
9766 vassert(s390_host_has_dfp);
9767 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
9768 return "esdtr";
9769}
9770
9771static const HChar *
9772s390_irgen_ESXTR(UChar r1, UChar r2)
9773{
9774 vassert(s390_host_has_dfp);
9775 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
9776 return "esxtr";
9777}
9778
9779static const HChar *
florian5c539732013-02-14 14:27:12 +00009780s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
9781{
9782 IRTemp op1 = newTemp(Ity_I64);
9783 IRTemp op2 = newTemp(Ity_D64);
9784 IRTemp result = newTemp(Ity_D64);
9785
9786 vassert(s390_host_has_dfp);
9787
9788 assign(op1, get_gpr_dw0(r2));
9789 assign(op2, get_dpr_dw0(r3));
9790 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
9791 put_dpr_dw0(r1, mkexpr(result));
9792
9793 return "iedtr";
9794}
9795
9796static const HChar *
9797s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
9798{
9799 IRTemp op1 = newTemp(Ity_I64);
9800 IRTemp op2 = newTemp(Ity_D128);
9801 IRTemp result = newTemp(Ity_D128);
9802
9803 vassert(s390_host_has_dfp);
9804
9805 assign(op1, get_gpr_dw0(r2));
9806 assign(op2, get_dpr_pair(r3));
9807 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
9808 put_dpr_pair(r1, mkexpr(result));
9809
9810 return "iextr";
9811}
9812
9813static const HChar *
floriane38f6412012-12-21 17:32:12 +00009814s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9815{
9816 IRTemp op = newTemp(Ity_D32);
9817
9818 vassert(s390_host_has_dfp);
9819
9820 assign(op, get_dpr_w0(r2));
9821 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
9822
9823 return "ldetr";
9824}
9825
9826static const HChar *
9827s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9828{
9829 IRTemp op = newTemp(Ity_D64);
9830
9831 assign(op, get_dpr_dw0(r2));
9832 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
9833
9834 return "lxdtr";
9835}
9836
9837static const HChar *
9838s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
9839 UChar r1, UChar r2)
9840{
9841 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009842
9843 /* If fpext is not installed and m3 is in 1:7,
9844 rounding mode performed is unpredictable */
9845 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +00009846 emulation_warning(EmWarn_S390X_fpext_rounding);
9847 m3 = S390_DFP_ROUND_PER_FPC_0;
9848 }
9849 IRTemp result = newTemp(Ity_D64);
9850
9851 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
9852 get_dpr_pair(r2)));
9853 put_dpr_dw0(r1, mkexpr(result));
9854
9855 return "ldxtr";
9856}
9857
9858static const HChar *
9859s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
9860 UChar r1, UChar r2)
9861{
9862 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009863
9864 /* If fpext is not installed and m3 is in 1:7,
9865 rounding mode performed is unpredictable */
9866 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +00009867 emulation_warning(EmWarn_S390X_fpext_rounding);
9868 m3 = S390_DFP_ROUND_PER_FPC_0;
9869 }
9870 IRTemp op = newTemp(Ity_D64);
9871
9872 assign(op, get_dpr_dw0(r2));
9873 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
9874 mkexpr(op)));
9875
9876 return "ledtr";
9877}
9878
9879static const HChar *
9880s390_irgen_LTDTR(UChar r1, UChar r2)
9881{
9882 IRTemp result = newTemp(Ity_D64);
9883
9884 assign(result, get_dpr_dw0(r2));
9885 put_dpr_dw0(r1, mkexpr(result));
9886 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9887
9888 return "ltdtr";
9889}
9890
9891static const HChar *
9892s390_irgen_LTXTR(UChar r1, UChar r2)
9893{
9894 IRTemp result = newTemp(Ity_D128);
9895
9896 assign(result, get_dpr_pair(r2));
9897 put_dpr_pair(r1, mkexpr(result));
9898 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9899
9900 return "ltxtr";
9901}
9902
9903static const HChar *
florian12390202012-11-10 22:34:14 +00009904s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9905{
9906 IRTemp op1 = newTemp(Ity_D64);
9907 IRTemp op2 = newTemp(Ity_D64);
9908 IRTemp result = newTemp(Ity_D64);
9909 IRTemp rounding_mode;
9910
9911 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009912
9913 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9914 emulation_warning(EmWarn_S390X_fpext_rounding);
9915 m4 = S390_DFP_ROUND_PER_FPC_0;
9916 }
9917
florian12390202012-11-10 22:34:14 +00009918 rounding_mode = encode_dfp_rounding_mode(m4);
9919 assign(op1, get_dpr_dw0(r2));
9920 assign(op2, get_dpr_dw0(r3));
9921 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9922 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009923 put_dpr_dw0(r1, mkexpr(result));
9924
9925 return (m4 == 0) ? "mdtr" : "mdtra";
9926}
9927
florian55085f82012-11-21 00:36:55 +00009928static const HChar *
floriane38f6412012-12-21 17:32:12 +00009929s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9930{
9931 IRTemp op1 = newTemp(Ity_D128);
9932 IRTemp op2 = newTemp(Ity_D128);
9933 IRTemp result = newTemp(Ity_D128);
9934 IRTemp rounding_mode;
9935
9936 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009937
9938 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9939 emulation_warning(EmWarn_S390X_fpext_rounding);
9940 m4 = S390_DFP_ROUND_PER_FPC_0;
9941 }
9942
floriane38f6412012-12-21 17:32:12 +00009943 rounding_mode = encode_dfp_rounding_mode(m4);
9944 assign(op1, get_dpr_pair(r2));
9945 assign(op2, get_dpr_pair(r3));
9946 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
9947 mkexpr(op2)));
9948 put_dpr_pair(r1, mkexpr(result));
9949
9950 return (m4 == 0) ? "mxtr" : "mxtra";
9951}
9952
9953static const HChar *
florian5c539732013-02-14 14:27:12 +00009954s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
9955{
9956 IRTemp op1 = newTemp(Ity_D64);
9957 IRTemp op2 = newTemp(Ity_D64);
9958 IRTemp result = newTemp(Ity_D64);
9959 IRTemp rounding_mode;
9960
9961 vassert(s390_host_has_dfp);
9962 /* If fpext is not installed and m4 is in 1:7,
9963 rounding mode performed is unpredictable */
9964 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
9965 emulation_warning(EmWarn_S390X_fpext_rounding);
9966 m4 = S390_DFP_ROUND_PER_FPC_0;
9967 }
9968
9969 rounding_mode = encode_dfp_rounding_mode(m4);
9970 assign(op1, get_dpr_dw0(r2));
9971 assign(op2, get_dpr_dw0(r3));
9972 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
9973 mkexpr(op2)));
9974 put_dpr_dw0(r1, mkexpr(result));
9975
9976 return "qadtr";
9977}
9978
9979static const HChar *
9980s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
9981{
9982 IRTemp op1 = newTemp(Ity_D128);
9983 IRTemp op2 = newTemp(Ity_D128);
9984 IRTemp result = newTemp(Ity_D128);
9985 IRTemp rounding_mode;
9986
9987 vassert(s390_host_has_dfp);
9988 /* If fpext is not installed and m4 is in 1:7,
9989 rounding mode performed is unpredictable */
9990 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
9991 emulation_warning(EmWarn_S390X_fpext_rounding);
9992 m4 = S390_DFP_ROUND_PER_FPC_0;
9993 }
9994
9995 rounding_mode = encode_dfp_rounding_mode(m4);
9996 assign(op1, get_dpr_pair(r2));
9997 assign(op2, get_dpr_pair(r3));
9998 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
9999 mkexpr(op2)));
10000 put_dpr_pair(r1, mkexpr(result));
10001
10002 return "qaxtr";
10003}
10004
10005static const HChar *
10006s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10007{
10008 IRTemp op1 = newTemp(Ity_I8);
10009 IRTemp op2 = newTemp(Ity_D64);
10010 IRTemp result = newTemp(Ity_D64);
10011 IRTemp rounding_mode;
10012
10013 vassert(s390_host_has_dfp);
10014 /* If fpext is not installed and m4 is in 1:7,
10015 rounding mode performed is unpredictable */
10016 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10017 emulation_warning(EmWarn_S390X_fpext_rounding);
10018 m4 = S390_DFP_ROUND_PER_FPC_0;
10019 }
10020
10021 rounding_mode = encode_dfp_rounding_mode(m4);
10022 assign(op1, get_gpr_b7(r2));
10023 assign(op2, get_dpr_dw0(r3));
10024 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10025 mkexpr(op1), mkexpr(op2)));
10026 put_dpr_dw0(r1, mkexpr(result));
10027
10028 return "rrdtr";
10029}
10030
10031static const HChar *
10032s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10033{
10034 IRTemp op1 = newTemp(Ity_I8);
10035 IRTemp op2 = newTemp(Ity_D128);
10036 IRTemp result = newTemp(Ity_D128);
10037 IRTemp rounding_mode;
10038
10039 vassert(s390_host_has_dfp);
10040 /* If fpext is not installed and m4 is in 1:7,
10041 rounding mode performed is unpredictable */
10042 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10043 emulation_warning(EmWarn_S390X_fpext_rounding);
10044 m4 = S390_DFP_ROUND_PER_FPC_0;
10045 }
10046
10047 rounding_mode = encode_dfp_rounding_mode(m4);
10048 assign(op1, get_gpr_b7(r2));
10049 assign(op2, get_dpr_pair(r3));
10050 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10051 mkexpr(op1), mkexpr(op2)));
10052 put_dpr_pair(r1, mkexpr(result));
10053
10054 return "rrxtr";
10055}
10056
10057static const HChar *
florian12390202012-11-10 22:34:14 +000010058s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10059{
10060 IRTemp op1 = newTemp(Ity_D64);
10061 IRTemp op2 = newTemp(Ity_D64);
10062 IRTemp result = newTemp(Ity_D64);
10063 IRTemp rounding_mode;
10064
10065 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010066
10067 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10068 emulation_warning(EmWarn_S390X_fpext_rounding);
10069 m4 = S390_DFP_ROUND_PER_FPC_0;
10070 }
10071
florian12390202012-11-10 22:34:14 +000010072 rounding_mode = encode_dfp_rounding_mode(m4);
10073 assign(op1, get_dpr_dw0(r2));
10074 assign(op2, get_dpr_dw0(r3));
10075 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10076 mkexpr(op2)));
10077 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10078 put_dpr_dw0(r1, mkexpr(result));
10079
10080 return (m4 == 0) ? "sdtr" : "sdtra";
10081}
10082
floriane38f6412012-12-21 17:32:12 +000010083static const HChar *
10084s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10085{
10086 IRTemp op1 = newTemp(Ity_D128);
10087 IRTemp op2 = newTemp(Ity_D128);
10088 IRTemp result = newTemp(Ity_D128);
10089 IRTemp rounding_mode;
10090
10091 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010092
10093 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10094 emulation_warning(EmWarn_S390X_fpext_rounding);
10095 m4 = S390_DFP_ROUND_PER_FPC_0;
10096 }
10097
floriane38f6412012-12-21 17:32:12 +000010098 rounding_mode = encode_dfp_rounding_mode(m4);
10099 assign(op1, get_dpr_pair(r2));
10100 assign(op2, get_dpr_pair(r3));
10101 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10102 mkexpr(op2)));
10103 put_dpr_pair(r1, mkexpr(result));
10104
10105 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10106
10107 return (m4 == 0) ? "sxtr" : "sxtra";
10108}
sewardj2019a972011-03-07 16:04:07 +000010109
florian55085f82012-11-21 00:36:55 +000010110static const HChar *
florian1b901d42013-01-01 22:19:24 +000010111s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10112{
10113 IRTemp op = newTemp(Ity_D64);
10114
10115 vassert(s390_host_has_dfp);
10116
10117 assign(op, get_dpr_dw0(r3));
10118 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
10119 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10120
10121 return "sldt";
10122}
10123
10124static const HChar *
10125s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10126{
10127 IRTemp op = newTemp(Ity_D128);
10128
10129 vassert(s390_host_has_dfp);
10130
10131 assign(op, get_dpr_pair(r3));
10132 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
10133 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10134
10135 return "slxt";
10136}
10137
10138static const HChar *
10139s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10140{
10141 IRTemp op = newTemp(Ity_D64);
10142
10143 vassert(s390_host_has_dfp);
10144
10145 assign(op, get_dpr_dw0(r3));
10146 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
10147 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10148
10149 return "srdt";
10150}
10151
10152static const HChar *
10153s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10154{
10155 IRTemp op = newTemp(Ity_D128);
10156
10157 vassert(s390_host_has_dfp);
10158
10159 assign(op, get_dpr_pair(r3));
10160 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
10161 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10162
10163 return "srxt";
10164}
10165
10166static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010167s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10168{
10169 IRTemp value = newTemp(Ity_D32);
10170
10171 vassert(s390_host_has_dfp);
10172 assign(value, get_dpr_w0(r1));
10173
10174 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10175
10176 return "tdcet";
10177}
10178
10179static const HChar *
10180s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10181{
10182 IRTemp value = newTemp(Ity_D64);
10183
10184 vassert(s390_host_has_dfp);
10185 assign(value, get_dpr_dw0(r1));
10186
10187 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10188
10189 return "tdcdt";
10190}
10191
10192static const HChar *
10193s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10194{
10195 IRTemp value = newTemp(Ity_D128);
10196
10197 vassert(s390_host_has_dfp);
10198 assign(value, get_dpr_pair(r1));
10199
10200 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10201
10202 return "tdcxt";
10203}
10204
10205static const HChar *
10206s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10207{
10208 IRTemp value = newTemp(Ity_D32);
10209
10210 vassert(s390_host_has_dfp);
10211 assign(value, get_dpr_w0(r1));
10212
10213 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10214
10215 return "tdget";
10216}
10217
10218static const HChar *
10219s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10220{
10221 IRTemp value = newTemp(Ity_D64);
10222
10223 vassert(s390_host_has_dfp);
10224 assign(value, get_dpr_dw0(r1));
10225
10226 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10227
10228 return "tdgdt";
10229}
10230
10231static const HChar *
10232s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10233{
10234 IRTemp value = newTemp(Ity_D128);
10235
10236 vassert(s390_host_has_dfp);
10237 assign(value, get_dpr_pair(r1));
10238
10239 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10240
10241 return "tdgxt";
10242}
10243
10244static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010245s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10246{
florian79e839e2012-05-05 02:20:30 +000010247 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010248
florian79e839e2012-05-05 02:20:30 +000010249 assign(len, mkU64(length));
10250 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010251
10252 return "clc";
10253}
10254
florian55085f82012-11-21 00:36:55 +000010255static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010256s390_irgen_CLCL(UChar r1, UChar r2)
10257{
10258 IRTemp addr1 = newTemp(Ity_I64);
10259 IRTemp addr2 = newTemp(Ity_I64);
10260 IRTemp addr1_load = newTemp(Ity_I64);
10261 IRTemp addr2_load = newTemp(Ity_I64);
10262 IRTemp len1 = newTemp(Ity_I32);
10263 IRTemp len2 = newTemp(Ity_I32);
10264 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10265 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10266 IRTemp single1 = newTemp(Ity_I8);
10267 IRTemp single2 = newTemp(Ity_I8);
10268 IRTemp pad = newTemp(Ity_I8);
10269
10270 assign(addr1, get_gpr_dw0(r1));
10271 assign(r1p1, get_gpr_w1(r1 + 1));
10272 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10273 assign(addr2, get_gpr_dw0(r2));
10274 assign(r2p1, get_gpr_w1(r2 + 1));
10275 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10276 assign(pad, get_gpr_b4(r2 + 1));
10277
10278 /* len1 == 0 and len2 == 0? Exit */
10279 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010280 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10281 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010282
10283 /* Because mkite evaluates both the then-clause and the else-clause
10284 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10285 may be NULL and loading from there would segfault. So we provide a
10286 valid dummy address in that case. Loading from there does no harm and
10287 the value will be discarded at runtime. */
10288 assign(addr1_load,
10289 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10290 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10291 assign(single1,
10292 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10293 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10294
10295 assign(addr2_load,
10296 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10297 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10298 assign(single2,
10299 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10300 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10301
10302 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10303 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010304 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010305
10306 /* Update len1 and addr1, unless len1 == 0. */
10307 put_gpr_dw0(r1,
10308 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10309 mkexpr(addr1),
10310 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10311
10312 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10313 put_gpr_w1(r1 + 1,
10314 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10315 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10316 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10317
10318 /* Update len2 and addr2, unless len2 == 0. */
10319 put_gpr_dw0(r2,
10320 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10321 mkexpr(addr2),
10322 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10323
10324 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10325 put_gpr_w1(r2 + 1,
10326 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10327 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10328 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10329
florian6820ba52012-07-26 02:01:50 +000010330 iterate();
florianb0c9a132011-09-08 15:37:39 +000010331
10332 return "clcl";
10333}
10334
florian55085f82012-11-21 00:36:55 +000010335static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010336s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10337{
10338 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10339
10340 addr1 = newTemp(Ity_I64);
10341 addr3 = newTemp(Ity_I64);
10342 addr1_load = newTemp(Ity_I64);
10343 addr3_load = newTemp(Ity_I64);
10344 len1 = newTemp(Ity_I64);
10345 len3 = newTemp(Ity_I64);
10346 single1 = newTemp(Ity_I8);
10347 single3 = newTemp(Ity_I8);
10348
10349 assign(addr1, get_gpr_dw0(r1));
10350 assign(len1, get_gpr_dw0(r1 + 1));
10351 assign(addr3, get_gpr_dw0(r3));
10352 assign(len3, get_gpr_dw0(r3 + 1));
10353
10354 /* len1 == 0 and len3 == 0? Exit */
10355 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010356 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10357 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010358
10359 /* A mux requires both ways to be possible. This is a way to prevent clcle
10360 from reading from addr1 if it should read from the pad. Since the pad
10361 has no address, just read from the instruction, we discard that anyway */
10362 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010363 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10364 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010365
10366 /* same for addr3 */
10367 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010368 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10369 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010370
10371 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010372 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10373 unop(Iop_64to8, mkexpr(pad2)),
10374 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010375
10376 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010377 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10378 unop(Iop_64to8, mkexpr(pad2)),
10379 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010380
10381 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10382 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010383 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010384
10385 /* If a length in 0 we must not change this length and the address */
10386 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010387 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10388 mkexpr(addr1),
10389 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010390
10391 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010392 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10393 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010394
10395 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010396 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10397 mkexpr(addr3),
10398 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010399
10400 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010401 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10402 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010403
florian6820ba52012-07-26 02:01:50 +000010404 iterate();
sewardj2019a972011-03-07 16:04:07 +000010405
10406 return "clcle";
10407}
floriana64c2432011-07-16 02:11:50 +000010408
florianb0bf6602012-05-05 00:01:16 +000010409
sewardj2019a972011-03-07 16:04:07 +000010410static void
10411s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10412{
florianb0bf6602012-05-05 00:01:16 +000010413 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10414}
sewardj2019a972011-03-07 16:04:07 +000010415
sewardj2019a972011-03-07 16:04:07 +000010416
florianb0bf6602012-05-05 00:01:16 +000010417static void
10418s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10419{
10420 s390_irgen_xonc(Iop_And8, length, start1, start2);
10421}
sewardj2019a972011-03-07 16:04:07 +000010422
sewardj2019a972011-03-07 16:04:07 +000010423
florianb0bf6602012-05-05 00:01:16 +000010424static void
10425s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10426{
10427 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010428}
10429
10430
10431static void
10432s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10433{
10434 IRTemp current1 = newTemp(Ity_I8);
10435 IRTemp current2 = newTemp(Ity_I8);
10436 IRTemp counter = newTemp(Ity_I64);
10437
10438 assign(counter, get_counter_dw0());
10439 put_counter_dw0(mkU64(0));
10440
10441 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10442 mkexpr(counter))));
10443 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10444 mkexpr(counter))));
10445 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10446 False);
10447
10448 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010449 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010450
10451 /* Check for end of field */
10452 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010453 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010454 put_counter_dw0(mkU64(0));
10455}
10456
10457static void
10458s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10459{
10460 IRTemp counter = newTemp(Ity_I64);
10461
10462 assign(counter, get_counter_dw0());
10463
10464 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10465 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10466
10467 /* Check for end of field */
10468 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010469 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010470 put_counter_dw0(mkU64(0));
10471}
10472
florianf87d4fb2012-05-05 02:55:24 +000010473static void
10474s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10475{
10476 IRTemp op = newTemp(Ity_I8);
10477 IRTemp op1 = newTemp(Ity_I8);
10478 IRTemp result = newTemp(Ity_I64);
10479 IRTemp counter = newTemp(Ity_I64);
10480
10481 assign(counter, get_counter_dw0());
10482
10483 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10484
10485 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10486
10487 assign(op1, load(Ity_I8, mkexpr(result)));
10488 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10489
10490 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010491 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010492 put_counter_dw0(mkU64(0));
10493}
sewardj2019a972011-03-07 16:04:07 +000010494
10495
10496static void
10497s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010498 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010499 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010500{
10501 struct SS {
10502 unsigned int op : 8;
10503 unsigned int l : 8;
10504 unsigned int b1 : 4;
10505 unsigned int d1 : 12;
10506 unsigned int b2 : 4;
10507 unsigned int d2 : 12;
10508 };
10509 union {
10510 struct SS dec;
10511 unsigned long bytes;
10512 } ss;
10513 IRTemp cond;
10514 IRDirty *d;
10515 IRTemp torun;
10516
10517 IRTemp start1 = newTemp(Ity_I64);
10518 IRTemp start2 = newTemp(Ity_I64);
10519 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10520 cond = newTemp(Ity_I1);
10521 torun = newTemp(Ity_I64);
10522
10523 assign(torun, load(Ity_I64, mkexpr(addr2)));
10524 /* Start with a check that the saved code is still correct */
10525 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10526 /* If not, save the new value */
10527 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10528 mkIRExprVec_1(mkexpr(torun)));
10529 d->guard = mkexpr(cond);
10530 stmt(IRStmt_Dirty(d));
10531
10532 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010533 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10534 mkU64(guest_IA_curr_instr)));
10535 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010536 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010537
10538 ss.bytes = last_execute_target;
10539 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10540 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10541 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10542 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10543 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10544 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10545 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010546
sewardj2019a972011-03-07 16:04:07 +000010547 last_execute_target = 0;
10548}
10549
florian55085f82012-11-21 00:36:55 +000010550static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010551s390_irgen_EX(UChar r1, IRTemp addr2)
10552{
10553 switch(last_execute_target & 0xff00000000000000ULL) {
10554 case 0:
10555 {
10556 /* no code information yet */
10557 IRDirty *d;
10558
10559 /* so safe the code... */
10560 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10561 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10562 stmt(IRStmt_Dirty(d));
10563 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010564 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10565 mkU64(guest_IA_curr_instr)));
10566 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010567 restart_if(IRExpr_Const(IRConst_U1(True)));
10568
sewardj2019a972011-03-07 16:04:07 +000010569 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010570 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010571 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000010572 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000010573 break;
10574 }
10575
10576 case 0xd200000000000000ULL:
10577 /* special case MVC */
10578 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010579 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010580
10581 case 0xd500000000000000ULL:
10582 /* special case CLC */
10583 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010584 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010585
10586 case 0xd700000000000000ULL:
10587 /* special case XC */
10588 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010589 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010590
florianb0bf6602012-05-05 00:01:16 +000010591 case 0xd600000000000000ULL:
10592 /* special case OC */
10593 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010594 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010595
10596 case 0xd400000000000000ULL:
10597 /* special case NC */
10598 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010599 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010600
florianf87d4fb2012-05-05 02:55:24 +000010601 case 0xdc00000000000000ULL:
10602 /* special case TR */
10603 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010604 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010605
sewardj2019a972011-03-07 16:04:07 +000010606 default:
10607 {
10608 /* everything else will get a self checking prefix that also checks the
10609 register content */
10610 IRDirty *d;
10611 UChar *bytes;
10612 IRTemp cond;
10613 IRTemp orperand;
10614 IRTemp torun;
10615
10616 cond = newTemp(Ity_I1);
10617 orperand = newTemp(Ity_I64);
10618 torun = newTemp(Ity_I64);
10619
10620 if (r1 == 0)
10621 assign(orperand, mkU64(0));
10622 else
10623 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10624 /* This code is going to be translated */
10625 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10626 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10627
10628 /* Start with a check that saved code is still correct */
10629 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10630 mkU64(last_execute_target)));
10631 /* If not, save the new value */
10632 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10633 mkIRExprVec_1(mkexpr(torun)));
10634 d->guard = mkexpr(cond);
10635 stmt(IRStmt_Dirty(d));
10636
10637 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010638 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10639 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010640 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010641
10642 /* Now comes the actual translation */
10643 bytes = (UChar *) &last_execute_target;
10644 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10645 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010646 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010647 vex_printf(" which was executed by\n");
10648 /* dont make useless translations in the next execute */
10649 last_execute_target = 0;
10650 }
10651 }
10652 return "ex";
10653}
10654
florian55085f82012-11-21 00:36:55 +000010655static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010656s390_irgen_EXRL(UChar r1, UInt offset)
10657{
10658 IRTemp addr = newTemp(Ity_I64);
10659 /* we might save one round trip because we know the target */
10660 if (!last_execute_target)
10661 last_execute_target = *(ULong *)(HWord)
10662 (guest_IA_curr_instr + offset * 2UL);
10663 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10664 s390_irgen_EX(r1, addr);
10665 return "exrl";
10666}
10667
florian55085f82012-11-21 00:36:55 +000010668static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010669s390_irgen_IPM(UChar r1)
10670{
10671 // As long as we dont support SPM, lets just assume 0 as program mask
10672 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
10673 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
10674
10675 return "ipm";
10676}
10677
10678
florian55085f82012-11-21 00:36:55 +000010679static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010680s390_irgen_SRST(UChar r1, UChar r2)
10681{
10682 IRTemp address = newTemp(Ity_I64);
10683 IRTemp next = newTemp(Ity_I64);
10684 IRTemp delim = newTemp(Ity_I8);
10685 IRTemp counter = newTemp(Ity_I64);
10686 IRTemp byte = newTemp(Ity_I8);
10687
10688 assign(address, get_gpr_dw0(r2));
10689 assign(next, get_gpr_dw0(r1));
10690
10691 assign(counter, get_counter_dw0());
10692 put_counter_dw0(mkU64(0));
10693
10694 // start = next? CC=2 and out r1 and r2 unchanged
10695 s390_cc_set(2);
10696 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010697 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000010698
10699 assign(byte, load(Ity_I8, mkexpr(address)));
10700 assign(delim, get_gpr_b7(0));
10701
10702 // byte = delim? CC=1, R1=address
10703 s390_cc_set(1);
10704 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000010705 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010706
10707 // else: all equal, no end yet, loop
10708 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10709 put_gpr_dw0(r1, mkexpr(next));
10710 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010711
florian6820ba52012-07-26 02:01:50 +000010712 iterate();
sewardj2019a972011-03-07 16:04:07 +000010713
10714 return "srst";
10715}
10716
florian55085f82012-11-21 00:36:55 +000010717static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010718s390_irgen_CLST(UChar r1, UChar r2)
10719{
10720 IRTemp address1 = newTemp(Ity_I64);
10721 IRTemp address2 = newTemp(Ity_I64);
10722 IRTemp end = newTemp(Ity_I8);
10723 IRTemp counter = newTemp(Ity_I64);
10724 IRTemp byte1 = newTemp(Ity_I8);
10725 IRTemp byte2 = newTemp(Ity_I8);
10726
10727 assign(address1, get_gpr_dw0(r1));
10728 assign(address2, get_gpr_dw0(r2));
10729 assign(end, get_gpr_b7(0));
10730 assign(counter, get_counter_dw0());
10731 put_counter_dw0(mkU64(0));
10732 assign(byte1, load(Ity_I8, mkexpr(address1)));
10733 assign(byte2, load(Ity_I8, mkexpr(address2)));
10734
10735 // end in both? all equal, reset r1 and r2 to start values
10736 s390_cc_set(0);
10737 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
10738 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010739 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10740 binop(Iop_Or8,
10741 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10742 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010743
10744 put_gpr_dw0(r1, mkexpr(address1));
10745 put_gpr_dw0(r2, mkexpr(address2));
10746
10747 // End found in string1
10748 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010749 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010750
10751 // End found in string2
10752 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010753 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010754
10755 // string1 < string2
10756 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010757 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10758 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010759
10760 // string2 < string1
10761 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010762 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10763 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010764
10765 // else: all equal, no end yet, loop
10766 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10767 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10768 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010769
florian6820ba52012-07-26 02:01:50 +000010770 iterate();
sewardj2019a972011-03-07 16:04:07 +000010771
10772 return "clst";
10773}
10774
10775static void
10776s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10777{
10778 UChar reg;
10779 IRTemp addr = newTemp(Ity_I64);
10780
10781 assign(addr, mkexpr(op2addr));
10782 reg = r1;
10783 do {
10784 IRTemp old = addr;
10785
10786 reg %= 16;
10787 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10788 addr = newTemp(Ity_I64);
10789 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10790 reg++;
10791 } while (reg != (r3 + 1));
10792}
10793
florian55085f82012-11-21 00:36:55 +000010794static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010795s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10796{
10797 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10798
10799 return "lm";
10800}
10801
florian55085f82012-11-21 00:36:55 +000010802static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010803s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
10804{
10805 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10806
10807 return "lmy";
10808}
10809
florian55085f82012-11-21 00:36:55 +000010810static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010811s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
10812{
10813 UChar reg;
10814 IRTemp addr = newTemp(Ity_I64);
10815
10816 assign(addr, mkexpr(op2addr));
10817 reg = r1;
10818 do {
10819 IRTemp old = addr;
10820
10821 reg %= 16;
10822 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
10823 addr = newTemp(Ity_I64);
10824 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10825 reg++;
10826 } while (reg != (r3 + 1));
10827
10828 return "lmh";
10829}
10830
florian55085f82012-11-21 00:36:55 +000010831static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010832s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
10833{
10834 UChar reg;
10835 IRTemp addr = newTemp(Ity_I64);
10836
10837 assign(addr, mkexpr(op2addr));
10838 reg = r1;
10839 do {
10840 IRTemp old = addr;
10841
10842 reg %= 16;
10843 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
10844 addr = newTemp(Ity_I64);
10845 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10846 reg++;
10847 } while (reg != (r3 + 1));
10848
10849 return "lmg";
10850}
10851
10852static void
10853s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10854{
10855 UChar reg;
10856 IRTemp addr = newTemp(Ity_I64);
10857
10858 assign(addr, mkexpr(op2addr));
10859 reg = r1;
10860 do {
10861 IRTemp old = addr;
10862
10863 reg %= 16;
10864 store(mkexpr(addr), get_gpr_w1(reg));
10865 addr = newTemp(Ity_I64);
10866 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10867 reg++;
10868 } while( reg != (r3 + 1));
10869}
10870
florian55085f82012-11-21 00:36:55 +000010871static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010872s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
10873{
10874 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10875
10876 return "stm";
10877}
10878
florian55085f82012-11-21 00:36:55 +000010879static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010880s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
10881{
10882 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10883
10884 return "stmy";
10885}
10886
florian55085f82012-11-21 00:36:55 +000010887static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010888s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
10889{
10890 UChar reg;
10891 IRTemp addr = newTemp(Ity_I64);
10892
10893 assign(addr, mkexpr(op2addr));
10894 reg = r1;
10895 do {
10896 IRTemp old = addr;
10897
10898 reg %= 16;
10899 store(mkexpr(addr), get_gpr_w0(reg));
10900 addr = newTemp(Ity_I64);
10901 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10902 reg++;
10903 } while( reg != (r3 + 1));
10904
10905 return "stmh";
10906}
10907
florian55085f82012-11-21 00:36:55 +000010908static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010909s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
10910{
10911 UChar reg;
10912 IRTemp addr = newTemp(Ity_I64);
10913
10914 assign(addr, mkexpr(op2addr));
10915 reg = r1;
10916 do {
10917 IRTemp old = addr;
10918
10919 reg %= 16;
10920 store(mkexpr(addr), get_gpr_dw0(reg));
10921 addr = newTemp(Ity_I64);
10922 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10923 reg++;
10924 } while( reg != (r3 + 1));
10925
10926 return "stmg";
10927}
10928
10929static void
florianb0bf6602012-05-05 00:01:16 +000010930s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000010931{
10932 IRTemp old1 = newTemp(Ity_I8);
10933 IRTemp old2 = newTemp(Ity_I8);
10934 IRTemp new1 = newTemp(Ity_I8);
10935 IRTemp counter = newTemp(Ity_I32);
10936 IRTemp addr1 = newTemp(Ity_I64);
10937
10938 assign(counter, get_counter_w0());
10939
10940 assign(addr1, binop(Iop_Add64, mkexpr(start1),
10941 unop(Iop_32Uto64, mkexpr(counter))));
10942
10943 assign(old1, load(Ity_I8, mkexpr(addr1)));
10944 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10945 unop(Iop_32Uto64,mkexpr(counter)))));
10946 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
10947
10948 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000010949 if (op == Iop_Xor8) {
10950 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000010951 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
10952 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000010953 } else
10954 store(mkexpr(addr1), mkexpr(new1));
10955 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
10956 get_counter_w1()));
10957
10958 /* Check for end of field */
10959 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010960 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010961 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
10962 False);
10963 put_counter_dw0(mkU64(0));
10964}
10965
florian55085f82012-11-21 00:36:55 +000010966static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010967s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
10968{
florianb0bf6602012-05-05 00:01:16 +000010969 IRTemp len = newTemp(Ity_I32);
10970
10971 assign(len, mkU32(length));
10972 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010973
10974 return "xc";
10975}
10976
sewardjb63967e2011-03-24 08:50:04 +000010977static void
10978s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
10979{
10980 IRTemp counter = newTemp(Ity_I32);
10981 IRTemp start = newTemp(Ity_I64);
10982 IRTemp addr = newTemp(Ity_I64);
10983
10984 assign(start,
10985 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
10986
10987 if (length < 8) {
10988 UInt i;
10989
10990 for (i = 0; i <= length; ++i) {
10991 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
10992 }
10993 } else {
10994 assign(counter, get_counter_w0());
10995
10996 assign(addr, binop(Iop_Add64, mkexpr(start),
10997 unop(Iop_32Uto64, mkexpr(counter))));
10998
10999 store(mkexpr(addr), mkU8(0));
11000
11001 /* Check for end of field */
11002 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011003 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011004
11005 /* Reset counter */
11006 put_counter_dw0(mkU64(0));
11007 }
11008
11009 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11010
sewardj7ee97522011-05-09 21:45:04 +000011011 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011012 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11013}
11014
florian55085f82012-11-21 00:36:55 +000011015static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011016s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11017{
florianb0bf6602012-05-05 00:01:16 +000011018 IRTemp len = newTemp(Ity_I32);
11019
11020 assign(len, mkU32(length));
11021 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011022
11023 return "nc";
11024}
11025
florian55085f82012-11-21 00:36:55 +000011026static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011027s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11028{
florianb0bf6602012-05-05 00:01:16 +000011029 IRTemp len = newTemp(Ity_I32);
11030
11031 assign(len, mkU32(length));
11032 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011033
11034 return "oc";
11035}
11036
11037
florian55085f82012-11-21 00:36:55 +000011038static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011039s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11040{
florian79e839e2012-05-05 02:20:30 +000011041 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011042
florian79e839e2012-05-05 02:20:30 +000011043 assign(len, mkU64(length));
11044 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011045
11046 return "mvc";
11047}
11048
florian55085f82012-11-21 00:36:55 +000011049static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011050s390_irgen_MVCL(UChar r1, UChar r2)
11051{
11052 IRTemp addr1 = newTemp(Ity_I64);
11053 IRTemp addr2 = newTemp(Ity_I64);
11054 IRTemp addr2_load = newTemp(Ity_I64);
11055 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11056 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11057 IRTemp len1 = newTemp(Ity_I32);
11058 IRTemp len2 = newTemp(Ity_I32);
11059 IRTemp pad = newTemp(Ity_I8);
11060 IRTemp single = newTemp(Ity_I8);
11061
11062 assign(addr1, get_gpr_dw0(r1));
11063 assign(r1p1, get_gpr_w1(r1 + 1));
11064 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11065 assign(addr2, get_gpr_dw0(r2));
11066 assign(r2p1, get_gpr_w1(r2 + 1));
11067 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11068 assign(pad, get_gpr_b4(r2 + 1));
11069
11070 /* len1 == 0 ? */
11071 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011072 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011073
11074 /* Check for destructive overlap:
11075 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11076 s390_cc_set(3);
11077 IRTemp cond1 = newTemp(Ity_I32);
11078 assign(cond1, unop(Iop_1Uto32,
11079 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11080 IRTemp cond2 = newTemp(Ity_I32);
11081 assign(cond2, unop(Iop_1Uto32,
11082 binop(Iop_CmpLT64U, mkexpr(addr1),
11083 binop(Iop_Add64, mkexpr(addr2),
11084 unop(Iop_32Uto64, mkexpr(len1))))));
11085 IRTemp cond3 = newTemp(Ity_I32);
11086 assign(cond3, unop(Iop_1Uto32,
11087 binop(Iop_CmpLT64U,
11088 mkexpr(addr1),
11089 binop(Iop_Add64, mkexpr(addr2),
11090 unop(Iop_32Uto64, mkexpr(len2))))));
11091
florian6820ba52012-07-26 02:01:50 +000011092 next_insn_if(binop(Iop_CmpEQ32,
11093 binop(Iop_And32,
11094 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11095 mkexpr(cond3)),
11096 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011097
11098 /* See s390_irgen_CLCL for explanation why we cannot load directly
11099 and need two steps. */
11100 assign(addr2_load,
11101 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11102 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11103 assign(single,
11104 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11105 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11106
11107 store(mkexpr(addr1), mkexpr(single));
11108
11109 /* Update addr1 and len1 */
11110 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11111 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11112
11113 /* Update addr2 and len2 */
11114 put_gpr_dw0(r2,
11115 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11116 mkexpr(addr2),
11117 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11118
11119 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11120 put_gpr_w1(r2 + 1,
11121 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11122 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11123 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11124
11125 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011126 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011127
11128 return "mvcl";
11129}
11130
11131
florian55085f82012-11-21 00:36:55 +000011132static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011133s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11134{
11135 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11136
11137 addr1 = newTemp(Ity_I64);
11138 addr3 = newTemp(Ity_I64);
11139 addr3_load = newTemp(Ity_I64);
11140 len1 = newTemp(Ity_I64);
11141 len3 = newTemp(Ity_I64);
11142 single = newTemp(Ity_I8);
11143
11144 assign(addr1, get_gpr_dw0(r1));
11145 assign(len1, get_gpr_dw0(r1 + 1));
11146 assign(addr3, get_gpr_dw0(r3));
11147 assign(len3, get_gpr_dw0(r3 + 1));
11148
11149 // len1 == 0 ?
11150 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011151 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011152
11153 /* This is a hack to prevent mvcle from reading from addr3 if it
11154 should read from the pad. Since the pad has no address, just
11155 read from the instruction, we discard that anyway */
11156 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011157 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11158 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011159
11160 assign(single,
florian6ad49522011-09-09 02:38:55 +000011161 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11162 unop(Iop_64to8, mkexpr(pad2)),
11163 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011164 store(mkexpr(addr1), mkexpr(single));
11165
11166 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11167
11168 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11169
11170 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011171 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11172 mkexpr(addr3),
11173 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011174
11175 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011176 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11177 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011178
sewardj2019a972011-03-07 16:04:07 +000011179 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011180 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011181
11182 return "mvcle";
11183}
11184
florian55085f82012-11-21 00:36:55 +000011185static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011186s390_irgen_MVST(UChar r1, UChar r2)
11187{
11188 IRTemp addr1 = newTemp(Ity_I64);
11189 IRTemp addr2 = newTemp(Ity_I64);
11190 IRTemp end = newTemp(Ity_I8);
11191 IRTemp byte = newTemp(Ity_I8);
11192 IRTemp counter = newTemp(Ity_I64);
11193
11194 assign(addr1, get_gpr_dw0(r1));
11195 assign(addr2, get_gpr_dw0(r2));
11196 assign(counter, get_counter_dw0());
11197 assign(end, get_gpr_b7(0));
11198 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11199 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11200
11201 // We use unlimited as cpu-determined number
11202 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011203 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011204
11205 // and always set cc=1 at the end + update r1
11206 s390_cc_set(1);
11207 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11208 put_counter_dw0(mkU64(0));
11209
11210 return "mvst";
11211}
11212
11213static void
11214s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11215{
11216 IRTemp op1 = newTemp(Ity_I64);
11217 IRTemp result = newTemp(Ity_I64);
11218
11219 assign(op1, binop(Iop_32HLto64,
11220 get_gpr_w1(r1), // high 32 bits
11221 get_gpr_w1(r1 + 1))); // low 32 bits
11222 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11223 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11224 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11225}
11226
11227static void
11228s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11229{
11230 IRTemp op1 = newTemp(Ity_I128);
11231 IRTemp result = newTemp(Ity_I128);
11232
11233 assign(op1, binop(Iop_64HLto128,
11234 get_gpr_dw0(r1), // high 64 bits
11235 get_gpr_dw0(r1 + 1))); // low 64 bits
11236 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11237 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11238 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11239}
11240
11241static void
11242s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11243{
11244 IRTemp op1 = newTemp(Ity_I64);
11245 IRTemp result = newTemp(Ity_I128);
11246
11247 assign(op1, get_gpr_dw0(r1 + 1));
11248 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11249 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11250 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11251}
11252
florian55085f82012-11-21 00:36:55 +000011253static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011254s390_irgen_DR(UChar r1, UChar r2)
11255{
11256 IRTemp op2 = newTemp(Ity_I32);
11257
11258 assign(op2, get_gpr_w1(r2));
11259
11260 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11261
11262 return "dr";
11263}
11264
florian55085f82012-11-21 00:36:55 +000011265static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011266s390_irgen_D(UChar r1, IRTemp op2addr)
11267{
11268 IRTemp op2 = newTemp(Ity_I32);
11269
11270 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11271
11272 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11273
11274 return "d";
11275}
11276
florian55085f82012-11-21 00:36:55 +000011277static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011278s390_irgen_DLR(UChar r1, UChar r2)
11279{
11280 IRTemp op2 = newTemp(Ity_I32);
11281
11282 assign(op2, get_gpr_w1(r2));
11283
11284 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11285
florian7cd1cde2012-08-16 23:57:43 +000011286 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011287}
11288
florian55085f82012-11-21 00:36:55 +000011289static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011290s390_irgen_DL(UChar r1, IRTemp op2addr)
11291{
11292 IRTemp op2 = newTemp(Ity_I32);
11293
11294 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11295
11296 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11297
11298 return "dl";
11299}
11300
florian55085f82012-11-21 00:36:55 +000011301static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011302s390_irgen_DLG(UChar r1, IRTemp op2addr)
11303{
11304 IRTemp op2 = newTemp(Ity_I64);
11305
11306 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11307
11308 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11309
11310 return "dlg";
11311}
11312
florian55085f82012-11-21 00:36:55 +000011313static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011314s390_irgen_DLGR(UChar r1, UChar r2)
11315{
11316 IRTemp op2 = newTemp(Ity_I64);
11317
11318 assign(op2, get_gpr_dw0(r2));
11319
11320 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11321
11322 return "dlgr";
11323}
11324
florian55085f82012-11-21 00:36:55 +000011325static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011326s390_irgen_DSGR(UChar r1, UChar r2)
11327{
11328 IRTemp op2 = newTemp(Ity_I64);
11329
11330 assign(op2, get_gpr_dw0(r2));
11331
11332 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11333
11334 return "dsgr";
11335}
11336
florian55085f82012-11-21 00:36:55 +000011337static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011338s390_irgen_DSG(UChar r1, IRTemp op2addr)
11339{
11340 IRTemp op2 = newTemp(Ity_I64);
11341
11342 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11343
11344 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11345
11346 return "dsg";
11347}
11348
florian55085f82012-11-21 00:36:55 +000011349static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011350s390_irgen_DSGFR(UChar r1, UChar r2)
11351{
11352 IRTemp op2 = newTemp(Ity_I64);
11353
11354 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11355
11356 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11357
11358 return "dsgfr";
11359}
11360
florian55085f82012-11-21 00:36:55 +000011361static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011362s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11363{
11364 IRTemp op2 = newTemp(Ity_I64);
11365
11366 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11367
11368 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11369
11370 return "dsgf";
11371}
11372
11373static void
11374s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11375{
11376 UChar reg;
11377 IRTemp addr = newTemp(Ity_I64);
11378
11379 assign(addr, mkexpr(op2addr));
11380 reg = r1;
11381 do {
11382 IRTemp old = addr;
11383
11384 reg %= 16;
11385 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11386 addr = newTemp(Ity_I64);
11387 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11388 reg++;
11389 } while (reg != (r3 + 1));
11390}
11391
florian55085f82012-11-21 00:36:55 +000011392static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011393s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11394{
11395 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11396
11397 return "lam";
11398}
11399
florian55085f82012-11-21 00:36:55 +000011400static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011401s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11402{
11403 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11404
11405 return "lamy";
11406}
11407
11408static void
11409s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11410{
11411 UChar reg;
11412 IRTemp addr = newTemp(Ity_I64);
11413
11414 assign(addr, mkexpr(op2addr));
11415 reg = r1;
11416 do {
11417 IRTemp old = addr;
11418
11419 reg %= 16;
11420 store(mkexpr(addr), get_ar_w0(reg));
11421 addr = newTemp(Ity_I64);
11422 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11423 reg++;
11424 } while (reg != (r3 + 1));
11425}
11426
florian55085f82012-11-21 00:36:55 +000011427static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011428s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11429{
11430 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11431
11432 return "stam";
11433}
11434
florian55085f82012-11-21 00:36:55 +000011435static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011436s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11437{
11438 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11439
11440 return "stamy";
11441}
11442
11443
11444/* Implementation for 32-bit compare-and-swap */
11445static void
11446s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11447{
11448 IRCAS *cas;
11449 IRTemp op1 = newTemp(Ity_I32);
11450 IRTemp old_mem = newTemp(Ity_I32);
11451 IRTemp op3 = newTemp(Ity_I32);
11452 IRTemp result = newTemp(Ity_I32);
11453 IRTemp nequal = newTemp(Ity_I1);
11454
11455 assign(op1, get_gpr_w1(r1));
11456 assign(op3, get_gpr_w1(r3));
11457
11458 /* The first and second operands are compared. If they are equal,
11459 the third operand is stored at the second- operand location. */
11460 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11461 Iend_BE, mkexpr(op2addr),
11462 NULL, mkexpr(op1), /* expected value */
11463 NULL, mkexpr(op3) /* new value */);
11464 stmt(IRStmt_CAS(cas));
11465
11466 /* Set CC. Operands compared equal -> 0, else 1. */
11467 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11468 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11469
11470 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11471 Otherwise, store the old_value from memory in r1 and yield. */
11472 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11473 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011474 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011475}
11476
florian55085f82012-11-21 00:36:55 +000011477static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011478s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11479{
11480 s390_irgen_cas_32(r1, r3, op2addr);
11481
11482 return "cs";
11483}
11484
florian55085f82012-11-21 00:36:55 +000011485static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011486s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11487{
11488 s390_irgen_cas_32(r1, r3, op2addr);
11489
11490 return "csy";
11491}
11492
florian55085f82012-11-21 00:36:55 +000011493static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011494s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11495{
11496 IRCAS *cas;
11497 IRTemp op1 = newTemp(Ity_I64);
11498 IRTemp old_mem = newTemp(Ity_I64);
11499 IRTemp op3 = newTemp(Ity_I64);
11500 IRTemp result = newTemp(Ity_I64);
11501 IRTemp nequal = newTemp(Ity_I1);
11502
11503 assign(op1, get_gpr_dw0(r1));
11504 assign(op3, get_gpr_dw0(r3));
11505
11506 /* The first and second operands are compared. If they are equal,
11507 the third operand is stored at the second- operand location. */
11508 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11509 Iend_BE, mkexpr(op2addr),
11510 NULL, mkexpr(op1), /* expected value */
11511 NULL, mkexpr(op3) /* new value */);
11512 stmt(IRStmt_CAS(cas));
11513
11514 /* Set CC. Operands compared equal -> 0, else 1. */
11515 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11516 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11517
11518 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11519 Otherwise, store the old_value from memory in r1 and yield. */
11520 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11521 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011522 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011523
11524 return "csg";
11525}
11526
florian448cbba2012-06-06 02:26:01 +000011527/* Implementation for 32-bit compare-double-and-swap */
11528static void
11529s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11530{
11531 IRCAS *cas;
11532 IRTemp op1_high = newTemp(Ity_I32);
11533 IRTemp op1_low = newTemp(Ity_I32);
11534 IRTemp old_mem_high = newTemp(Ity_I32);
11535 IRTemp old_mem_low = newTemp(Ity_I32);
11536 IRTemp op3_high = newTemp(Ity_I32);
11537 IRTemp op3_low = newTemp(Ity_I32);
11538 IRTemp result = newTemp(Ity_I32);
11539 IRTemp nequal = newTemp(Ity_I1);
11540
11541 assign(op1_high, get_gpr_w1(r1));
11542 assign(op1_low, get_gpr_w1(r1+1));
11543 assign(op3_high, get_gpr_w1(r3));
11544 assign(op3_low, get_gpr_w1(r3+1));
11545
11546 /* The first and second operands are compared. If they are equal,
11547 the third operand is stored at the second-operand location. */
11548 cas = mkIRCAS(old_mem_high, old_mem_low,
11549 Iend_BE, mkexpr(op2addr),
11550 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11551 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11552 stmt(IRStmt_CAS(cas));
11553
11554 /* Set CC. Operands compared equal -> 0, else 1. */
11555 assign(result, unop(Iop_1Uto32,
11556 binop(Iop_CmpNE32,
11557 binop(Iop_Or32,
11558 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11559 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11560 mkU32(0))));
11561
11562 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11563
11564 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11565 Otherwise, store the old_value from memory in r1 and yield. */
11566 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11567 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11568 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011569 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011570}
11571
florian55085f82012-11-21 00:36:55 +000011572static const HChar *
florian448cbba2012-06-06 02:26:01 +000011573s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11574{
11575 s390_irgen_cdas_32(r1, r3, op2addr);
11576
11577 return "cds";
11578}
11579
florian55085f82012-11-21 00:36:55 +000011580static const HChar *
florian448cbba2012-06-06 02:26:01 +000011581s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11582{
11583 s390_irgen_cdas_32(r1, r3, op2addr);
11584
11585 return "cdsy";
11586}
11587
florian55085f82012-11-21 00:36:55 +000011588static const HChar *
florian448cbba2012-06-06 02:26:01 +000011589s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11590{
11591 IRCAS *cas;
11592 IRTemp op1_high = newTemp(Ity_I64);
11593 IRTemp op1_low = newTemp(Ity_I64);
11594 IRTemp old_mem_high = newTemp(Ity_I64);
11595 IRTemp old_mem_low = newTemp(Ity_I64);
11596 IRTemp op3_high = newTemp(Ity_I64);
11597 IRTemp op3_low = newTemp(Ity_I64);
11598 IRTemp result = newTemp(Ity_I64);
11599 IRTemp nequal = newTemp(Ity_I1);
11600
11601 assign(op1_high, get_gpr_dw0(r1));
11602 assign(op1_low, get_gpr_dw0(r1+1));
11603 assign(op3_high, get_gpr_dw0(r3));
11604 assign(op3_low, get_gpr_dw0(r3+1));
11605
11606 /* The first and second operands are compared. If they are equal,
11607 the third operand is stored at the second-operand location. */
11608 cas = mkIRCAS(old_mem_high, old_mem_low,
11609 Iend_BE, mkexpr(op2addr),
11610 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11611 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11612 stmt(IRStmt_CAS(cas));
11613
11614 /* Set CC. Operands compared equal -> 0, else 1. */
11615 assign(result, unop(Iop_1Uto64,
11616 binop(Iop_CmpNE64,
11617 binop(Iop_Or64,
11618 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11619 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11620 mkU64(0))));
11621
11622 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11623
11624 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11625 Otherwise, store the old_value from memory in r1 and yield. */
11626 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11627 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11628 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011629 yield_if(mkexpr(nequal));
11630
florian448cbba2012-06-06 02:26:01 +000011631 return "cdsg";
11632}
11633
sewardj2019a972011-03-07 16:04:07 +000011634
11635/* Binary floating point */
11636
florian55085f82012-11-21 00:36:55 +000011637static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011638s390_irgen_AXBR(UChar r1, UChar r2)
11639{
11640 IRTemp op1 = newTemp(Ity_F128);
11641 IRTemp op2 = newTemp(Ity_F128);
11642 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011643 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011644
11645 assign(op1, get_fpr_pair(r1));
11646 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011647 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011648 mkexpr(op2)));
11649 put_fpr_pair(r1, mkexpr(result));
11650
11651 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11652
11653 return "axbr";
11654}
11655
florian55085f82012-11-21 00:36:55 +000011656static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011657s390_irgen_CEBR(UChar r1, UChar r2)
11658{
11659 IRTemp op1 = newTemp(Ity_F32);
11660 IRTemp op2 = newTemp(Ity_F32);
11661 IRTemp cc_vex = newTemp(Ity_I32);
11662 IRTemp cc_s390 = newTemp(Ity_I32);
11663
11664 assign(op1, get_fpr_w0(r1));
11665 assign(op2, get_fpr_w0(r2));
11666 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11667
florian2d3d87f2012-12-21 21:05:17 +000011668 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011669 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11670
11671 return "cebr";
11672}
11673
florian55085f82012-11-21 00:36:55 +000011674static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011675s390_irgen_CDBR(UChar r1, UChar r2)
11676{
11677 IRTemp op1 = newTemp(Ity_F64);
11678 IRTemp op2 = newTemp(Ity_F64);
11679 IRTemp cc_vex = newTemp(Ity_I32);
11680 IRTemp cc_s390 = newTemp(Ity_I32);
11681
11682 assign(op1, get_fpr_dw0(r1));
11683 assign(op2, get_fpr_dw0(r2));
11684 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11685
florian2d3d87f2012-12-21 21:05:17 +000011686 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011687 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11688
11689 return "cdbr";
11690}
11691
florian55085f82012-11-21 00:36:55 +000011692static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011693s390_irgen_CXBR(UChar r1, UChar r2)
11694{
11695 IRTemp op1 = newTemp(Ity_F128);
11696 IRTemp op2 = newTemp(Ity_F128);
11697 IRTemp cc_vex = newTemp(Ity_I32);
11698 IRTemp cc_s390 = newTemp(Ity_I32);
11699
11700 assign(op1, get_fpr_pair(r1));
11701 assign(op2, get_fpr_pair(r2));
11702 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
11703
florian2d3d87f2012-12-21 21:05:17 +000011704 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011705 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11706
11707 return "cxbr";
11708}
11709
florian55085f82012-11-21 00:36:55 +000011710static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011711s390_irgen_CEB(UChar r1, IRTemp op2addr)
11712{
11713 IRTemp op1 = newTemp(Ity_F32);
11714 IRTemp op2 = newTemp(Ity_F32);
11715 IRTemp cc_vex = newTemp(Ity_I32);
11716 IRTemp cc_s390 = newTemp(Ity_I32);
11717
11718 assign(op1, get_fpr_w0(r1));
11719 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11720 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11721
florian2d3d87f2012-12-21 21:05:17 +000011722 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011723 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11724
11725 return "ceb";
11726}
11727
florian55085f82012-11-21 00:36:55 +000011728static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011729s390_irgen_CDB(UChar r1, IRTemp op2addr)
11730{
11731 IRTemp op1 = newTemp(Ity_F64);
11732 IRTemp op2 = newTemp(Ity_F64);
11733 IRTemp cc_vex = newTemp(Ity_I32);
11734 IRTemp cc_s390 = newTemp(Ity_I32);
11735
11736 assign(op1, get_fpr_dw0(r1));
11737 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11738 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11739
florian2d3d87f2012-12-21 21:05:17 +000011740 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011741 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11742
11743 return "cdb";
11744}
11745
florian55085f82012-11-21 00:36:55 +000011746static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011747s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11748 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011749{
11750 IRTemp op2 = newTemp(Ity_I32);
11751
11752 assign(op2, get_gpr_w1(r2));
11753 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11754
11755 return "cxfbr";
11756}
11757
florian55085f82012-11-21 00:36:55 +000011758static const HChar *
floriand2129202012-09-01 20:01:39 +000011759s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11760 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011761{
floriane75dafa2012-09-01 17:54:09 +000011762 if (! s390_host_has_fpext) {
11763 emulation_failure(EmFail_S390X_fpext);
11764 } else {
11765 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011766
floriane75dafa2012-09-01 17:54:09 +000011767 assign(op2, get_gpr_w1(r2));
11768 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11769 }
florian1c8f7ff2012-09-01 00:12:11 +000011770 return "cxlfbr";
11771}
11772
11773
florian55085f82012-11-21 00:36:55 +000011774static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011775s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11776 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011777{
11778 IRTemp op2 = newTemp(Ity_I64);
11779
11780 assign(op2, get_gpr_dw0(r2));
11781 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11782
11783 return "cxgbr";
11784}
11785
florian55085f82012-11-21 00:36:55 +000011786static const HChar *
floriand2129202012-09-01 20:01:39 +000011787s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11788 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011789{
floriane75dafa2012-09-01 17:54:09 +000011790 if (! s390_host_has_fpext) {
11791 emulation_failure(EmFail_S390X_fpext);
11792 } else {
11793 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011794
floriane75dafa2012-09-01 17:54:09 +000011795 assign(op2, get_gpr_dw0(r2));
11796 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11797 }
florian1c8f7ff2012-09-01 00:12:11 +000011798 return "cxlgbr";
11799}
11800
florian55085f82012-11-21 00:36:55 +000011801static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011802s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11803 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011804{
11805 IRTemp op = newTemp(Ity_F128);
11806 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011807 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011808
11809 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011810 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011811 mkexpr(op)));
11812 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011813 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011814
11815 return "cfxbr";
11816}
11817
florian55085f82012-11-21 00:36:55 +000011818static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011819s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
11820 UChar r1, UChar r2)
11821{
floriane75dafa2012-09-01 17:54:09 +000011822 if (! s390_host_has_fpext) {
11823 emulation_failure(EmFail_S390X_fpext);
11824 } else {
11825 IRTemp op = newTemp(Ity_F128);
11826 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011827 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011828
floriane75dafa2012-09-01 17:54:09 +000011829 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011830 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011831 mkexpr(op)));
11832 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011833 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011834 }
florian1c8f7ff2012-09-01 00:12:11 +000011835 return "clfxbr";
11836}
11837
11838
florian55085f82012-11-21 00:36:55 +000011839static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011840s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
11841 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011842{
11843 IRTemp op = newTemp(Ity_F128);
11844 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011845 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011846
11847 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011848 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011849 mkexpr(op)));
11850 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011851 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011852
11853 return "cgxbr";
11854}
11855
florian55085f82012-11-21 00:36:55 +000011856static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011857s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
11858 UChar r1, UChar r2)
11859{
floriane75dafa2012-09-01 17:54:09 +000011860 if (! s390_host_has_fpext) {
11861 emulation_failure(EmFail_S390X_fpext);
11862 } else {
11863 IRTemp op = newTemp(Ity_F128);
11864 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011865 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011866
floriane75dafa2012-09-01 17:54:09 +000011867 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011868 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011869 mkexpr(op)));
11870 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011871 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
11872 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011873 }
florian1c8f7ff2012-09-01 00:12:11 +000011874 return "clgxbr";
11875}
11876
florian55085f82012-11-21 00:36:55 +000011877static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011878s390_irgen_DXBR(UChar r1, UChar r2)
11879{
11880 IRTemp op1 = newTemp(Ity_F128);
11881 IRTemp op2 = newTemp(Ity_F128);
11882 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011883 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011884
11885 assign(op1, get_fpr_pair(r1));
11886 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011887 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011888 mkexpr(op2)));
11889 put_fpr_pair(r1, mkexpr(result));
11890
11891 return "dxbr";
11892}
11893
florian55085f82012-11-21 00:36:55 +000011894static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011895s390_irgen_LTXBR(UChar r1, UChar r2)
11896{
11897 IRTemp result = newTemp(Ity_F128);
11898
11899 assign(result, get_fpr_pair(r2));
11900 put_fpr_pair(r1, mkexpr(result));
11901 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11902
11903 return "ltxbr";
11904}
11905
florian55085f82012-11-21 00:36:55 +000011906static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011907s390_irgen_LCXBR(UChar r1, UChar r2)
11908{
11909 IRTemp result = newTemp(Ity_F128);
11910
11911 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
11912 put_fpr_pair(r1, mkexpr(result));
11913 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11914
11915 return "lcxbr";
11916}
11917
florian55085f82012-11-21 00:36:55 +000011918static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011919s390_irgen_LXDBR(UChar r1, UChar r2)
11920{
11921 IRTemp op = newTemp(Ity_F64);
11922
11923 assign(op, get_fpr_dw0(r2));
11924 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11925
11926 return "lxdbr";
11927}
11928
florian55085f82012-11-21 00:36:55 +000011929static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011930s390_irgen_LXEBR(UChar r1, UChar r2)
11931{
11932 IRTemp op = newTemp(Ity_F32);
11933
11934 assign(op, get_fpr_w0(r2));
11935 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11936
11937 return "lxebr";
11938}
11939
florian55085f82012-11-21 00:36:55 +000011940static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011941s390_irgen_LXDB(UChar r1, IRTemp op2addr)
11942{
11943 IRTemp op = newTemp(Ity_F64);
11944
11945 assign(op, load(Ity_F64, mkexpr(op2addr)));
11946 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11947
11948 return "lxdb";
11949}
11950
florian55085f82012-11-21 00:36:55 +000011951static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011952s390_irgen_LXEB(UChar r1, IRTemp op2addr)
11953{
11954 IRTemp op = newTemp(Ity_F32);
11955
11956 assign(op, load(Ity_F32, mkexpr(op2addr)));
11957 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11958
11959 return "lxeb";
11960}
11961
florian55085f82012-11-21 00:36:55 +000011962static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011963s390_irgen_LNEBR(UChar r1, UChar r2)
11964{
11965 IRTemp result = newTemp(Ity_F32);
11966
11967 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
11968 put_fpr_w0(r1, mkexpr(result));
11969 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11970
11971 return "lnebr";
11972}
11973
florian55085f82012-11-21 00:36:55 +000011974static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011975s390_irgen_LNDBR(UChar r1, UChar r2)
11976{
11977 IRTemp result = newTemp(Ity_F64);
11978
11979 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11980 put_fpr_dw0(r1, mkexpr(result));
11981 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11982
11983 return "lndbr";
11984}
11985
florian55085f82012-11-21 00:36:55 +000011986static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011987s390_irgen_LNXBR(UChar r1, UChar r2)
11988{
11989 IRTemp result = newTemp(Ity_F128);
11990
11991 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
11992 put_fpr_pair(r1, mkexpr(result));
11993 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11994
11995 return "lnxbr";
11996}
11997
florian55085f82012-11-21 00:36:55 +000011998static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011999s390_irgen_LPEBR(UChar r1, UChar r2)
12000{
12001 IRTemp result = newTemp(Ity_F32);
12002
12003 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12004 put_fpr_w0(r1, mkexpr(result));
12005 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12006
12007 return "lpebr";
12008}
12009
florian55085f82012-11-21 00:36:55 +000012010static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012011s390_irgen_LPDBR(UChar r1, UChar r2)
12012{
12013 IRTemp result = newTemp(Ity_F64);
12014
12015 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12016 put_fpr_dw0(r1, mkexpr(result));
12017 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12018
12019 return "lpdbr";
12020}
12021
florian55085f82012-11-21 00:36:55 +000012022static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012023s390_irgen_LPXBR(UChar r1, UChar r2)
12024{
12025 IRTemp result = newTemp(Ity_F128);
12026
12027 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12028 put_fpr_pair(r1, mkexpr(result));
12029 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12030
12031 return "lpxbr";
12032}
12033
florian55085f82012-11-21 00:36:55 +000012034static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012035s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12036 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012037{
florian125e20d2012-10-07 15:42:37 +000012038 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012039 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012040 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012041 }
sewardj2019a972011-03-07 16:04:07 +000012042 IRTemp result = newTemp(Ity_F64);
12043
floriandb4fcaa2012-09-05 19:54:08 +000012044 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012045 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012046 put_fpr_dw0(r1, mkexpr(result));
12047
12048 return "ldxbr";
12049}
12050
florian55085f82012-11-21 00:36:55 +000012051static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012052s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12053 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012054{
florian125e20d2012-10-07 15:42:37 +000012055 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012056 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012057 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012058 }
sewardj2019a972011-03-07 16:04:07 +000012059 IRTemp result = newTemp(Ity_F32);
12060
floriandb4fcaa2012-09-05 19:54:08 +000012061 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012062 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012063 put_fpr_w0(r1, mkexpr(result));
12064
12065 return "lexbr";
12066}
12067
florian55085f82012-11-21 00:36:55 +000012068static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012069s390_irgen_MXBR(UChar r1, UChar r2)
12070{
12071 IRTemp op1 = newTemp(Ity_F128);
12072 IRTemp op2 = newTemp(Ity_F128);
12073 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012074 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012075
12076 assign(op1, get_fpr_pair(r1));
12077 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012078 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012079 mkexpr(op2)));
12080 put_fpr_pair(r1, mkexpr(result));
12081
12082 return "mxbr";
12083}
12084
florian55085f82012-11-21 00:36:55 +000012085static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012086s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12087{
florian125e20d2012-10-07 15:42:37 +000012088 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012089
floriandb4fcaa2012-09-05 19:54:08 +000012090 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012091 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012092
12093 return "maebr";
12094}
12095
florian55085f82012-11-21 00:36:55 +000012096static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012097s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12098{
florian125e20d2012-10-07 15:42:37 +000012099 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012100
floriandb4fcaa2012-09-05 19:54:08 +000012101 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012102 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012103
12104 return "madbr";
12105}
12106
florian55085f82012-11-21 00:36:55 +000012107static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012108s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12109{
12110 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012111 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012112
floriandb4fcaa2012-09-05 19:54:08 +000012113 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012114 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012115
12116 return "maeb";
12117}
12118
florian55085f82012-11-21 00:36:55 +000012119static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012120s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12121{
12122 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012123 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012124
floriandb4fcaa2012-09-05 19:54:08 +000012125 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012126 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012127
12128 return "madb";
12129}
12130
florian55085f82012-11-21 00:36:55 +000012131static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012132s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12133{
florian125e20d2012-10-07 15:42:37 +000012134 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012135
floriandb4fcaa2012-09-05 19:54:08 +000012136 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012137 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012138
12139 return "msebr";
12140}
12141
florian55085f82012-11-21 00:36:55 +000012142static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012143s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12144{
florian125e20d2012-10-07 15:42:37 +000012145 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012146
floriandb4fcaa2012-09-05 19:54:08 +000012147 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012148 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012149
12150 return "msdbr";
12151}
12152
florian55085f82012-11-21 00:36:55 +000012153static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012154s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12155{
12156 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012157 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012158
floriandb4fcaa2012-09-05 19:54:08 +000012159 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012160 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012161
12162 return "mseb";
12163}
12164
florian55085f82012-11-21 00:36:55 +000012165static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012166s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12167{
12168 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012169 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012170
floriandb4fcaa2012-09-05 19:54:08 +000012171 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012172 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012173
12174 return "msdb";
12175}
12176
florian55085f82012-11-21 00:36:55 +000012177static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012178s390_irgen_SQEBR(UChar r1, UChar r2)
12179{
12180 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012181 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012182
floriandb4fcaa2012-09-05 19:54:08 +000012183 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012184 put_fpr_w0(r1, mkexpr(result));
12185
12186 return "sqebr";
12187}
12188
florian55085f82012-11-21 00:36:55 +000012189static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012190s390_irgen_SQDBR(UChar r1, UChar r2)
12191{
12192 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012193 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012194
floriandb4fcaa2012-09-05 19:54:08 +000012195 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012196 put_fpr_dw0(r1, mkexpr(result));
12197
12198 return "sqdbr";
12199}
12200
florian55085f82012-11-21 00:36:55 +000012201static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012202s390_irgen_SQXBR(UChar r1, UChar r2)
12203{
12204 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012205 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012206
floriandb4fcaa2012-09-05 19:54:08 +000012207 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12208 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012209 put_fpr_pair(r1, mkexpr(result));
12210
12211 return "sqxbr";
12212}
12213
florian55085f82012-11-21 00:36:55 +000012214static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012215s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12216{
12217 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012218 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012219
12220 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012221 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012222
12223 return "sqeb";
12224}
12225
florian55085f82012-11-21 00:36:55 +000012226static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012227s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12228{
12229 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012230 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012231
12232 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012233 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012234
12235 return "sqdb";
12236}
12237
florian55085f82012-11-21 00:36:55 +000012238static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012239s390_irgen_SXBR(UChar r1, UChar r2)
12240{
12241 IRTemp op1 = newTemp(Ity_F128);
12242 IRTemp op2 = newTemp(Ity_F128);
12243 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012244 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012245
12246 assign(op1, get_fpr_pair(r1));
12247 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012248 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012249 mkexpr(op2)));
12250 put_fpr_pair(r1, mkexpr(result));
12251 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12252
12253 return "sxbr";
12254}
12255
florian55085f82012-11-21 00:36:55 +000012256static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012257s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12258{
12259 IRTemp value = newTemp(Ity_F32);
12260
12261 assign(value, get_fpr_w0(r1));
12262
12263 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12264
12265 return "tceb";
12266}
12267
florian55085f82012-11-21 00:36:55 +000012268static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012269s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12270{
12271 IRTemp value = newTemp(Ity_F64);
12272
12273 assign(value, get_fpr_dw0(r1));
12274
12275 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12276
12277 return "tcdb";
12278}
12279
florian55085f82012-11-21 00:36:55 +000012280static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012281s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12282{
12283 IRTemp value = newTemp(Ity_F128);
12284
12285 assign(value, get_fpr_pair(r1));
12286
12287 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12288
12289 return "tcxb";
12290}
12291
florian55085f82012-11-21 00:36:55 +000012292static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012293s390_irgen_LCDFR(UChar r1, UChar r2)
12294{
12295 IRTemp result = newTemp(Ity_F64);
12296
12297 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12298 put_fpr_dw0(r1, mkexpr(result));
12299
12300 return "lcdfr";
12301}
12302
florian55085f82012-11-21 00:36:55 +000012303static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012304s390_irgen_LNDFR(UChar r1, UChar r2)
12305{
12306 IRTemp result = newTemp(Ity_F64);
12307
12308 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12309 put_fpr_dw0(r1, mkexpr(result));
12310
12311 return "lndfr";
12312}
12313
florian55085f82012-11-21 00:36:55 +000012314static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012315s390_irgen_LPDFR(UChar r1, UChar r2)
12316{
12317 IRTemp result = newTemp(Ity_F64);
12318
12319 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12320 put_fpr_dw0(r1, mkexpr(result));
12321
12322 return "lpdfr";
12323}
12324
florian55085f82012-11-21 00:36:55 +000012325static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012326s390_irgen_LDGR(UChar r1, UChar r2)
12327{
12328 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12329
12330 return "ldgr";
12331}
12332
florian55085f82012-11-21 00:36:55 +000012333static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012334s390_irgen_LGDR(UChar r1, UChar r2)
12335{
12336 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12337
12338 return "lgdr";
12339}
12340
12341
florian55085f82012-11-21 00:36:55 +000012342static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012343s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12344{
12345 IRTemp sign = newTemp(Ity_I64);
12346 IRTemp value = newTemp(Ity_I64);
12347
12348 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12349 mkU64(1ULL << 63)));
12350 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12351 mkU64((1ULL << 63) - 1)));
12352 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12353 mkexpr(sign))));
12354
12355 return "cpsdr";
12356}
12357
12358
sewardj2019a972011-03-07 16:04:07 +000012359static IRExpr *
12360s390_call_cvb(IRExpr *in)
12361{
12362 IRExpr **args, *call;
12363
12364 args = mkIRExprVec_1(in);
12365 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12366 "s390_do_cvb", &s390_do_cvb, args);
12367
12368 /* Nothing is excluded from definedness checking. */
12369 call->Iex.CCall.cee->mcx_mask = 0;
12370
12371 return call;
12372}
12373
florian55085f82012-11-21 00:36:55 +000012374static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012375s390_irgen_CVB(UChar r1, IRTemp op2addr)
12376{
12377 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12378
12379 return "cvb";
12380}
12381
florian55085f82012-11-21 00:36:55 +000012382static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012383s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12384{
12385 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12386
12387 return "cvby";
12388}
12389
12390
sewardj2019a972011-03-07 16:04:07 +000012391static IRExpr *
12392s390_call_cvd(IRExpr *in)
12393{
12394 IRExpr **args, *call;
12395
12396 args = mkIRExprVec_1(in);
12397 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12398 "s390_do_cvd", &s390_do_cvd, args);
12399
12400 /* Nothing is excluded from definedness checking. */
12401 call->Iex.CCall.cee->mcx_mask = 0;
12402
12403 return call;
12404}
12405
florian55085f82012-11-21 00:36:55 +000012406static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012407s390_irgen_CVD(UChar r1, IRTemp op2addr)
12408{
florian11b8ee82012-08-06 13:35:33 +000012409 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012410
12411 return "cvd";
12412}
12413
florian55085f82012-11-21 00:36:55 +000012414static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012415s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12416{
12417 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12418
12419 return "cvdy";
12420}
12421
florian55085f82012-11-21 00:36:55 +000012422static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012423s390_irgen_FLOGR(UChar r1, UChar r2)
12424{
12425 IRTemp input = newTemp(Ity_I64);
12426 IRTemp not_zero = newTemp(Ity_I64);
12427 IRTemp tmpnum = newTemp(Ity_I64);
12428 IRTemp num = newTemp(Ity_I64);
12429 IRTemp shift_amount = newTemp(Ity_I8);
12430
12431 /* We use the "count leading zeroes" operator because the number of
12432 leading zeroes is identical with the bit position of the first '1' bit.
12433 However, that operator does not work when the input value is zero.
12434 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12435 the modified value. If input == 0, then the result is 64. Otherwise,
12436 the result of Clz64 is what we want. */
12437
12438 assign(input, get_gpr_dw0(r2));
12439 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12440 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12441
12442 /* num = (input == 0) ? 64 : tmpnum */
12443 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12444 /* == 0 */ mkU64(64),
12445 /* != 0 */ mkexpr(tmpnum)));
12446
12447 put_gpr_dw0(r1, mkexpr(num));
12448
12449 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12450 is to first shift the input value by NUM + 1 bits to the left which
12451 causes the leftmost '1' bit to disappear. Then we shift logically to
12452 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12453 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12454 the width of the value-to-be-shifted, we need to special case
12455 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12456 For both such INPUT values the result will be 0. */
12457
12458 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12459 mkU64(1))));
12460
12461 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012462 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12463 /* == 0 || == 1*/ mkU64(0),
12464 /* otherwise */
12465 binop(Iop_Shr64,
12466 binop(Iop_Shl64, mkexpr(input),
12467 mkexpr(shift_amount)),
12468 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012469
12470 /* Compare the original value as an unsigned integer with 0. */
12471 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12472 mktemp(Ity_I64, mkU64(0)), False);
12473
12474 return "flogr";
12475}
12476
florian55085f82012-11-21 00:36:55 +000012477static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012478s390_irgen_STCK(IRTemp op2addr)
12479{
12480 IRDirty *d;
12481 IRTemp cc = newTemp(Ity_I64);
12482
12483 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12484 &s390x_dirtyhelper_STCK,
12485 mkIRExprVec_1(mkexpr(op2addr)));
12486 d->mFx = Ifx_Write;
12487 d->mAddr = mkexpr(op2addr);
12488 d->mSize = 8;
12489 stmt(IRStmt_Dirty(d));
12490 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12491 mkexpr(cc), mkU64(0), mkU64(0));
12492 return "stck";
12493}
12494
florian55085f82012-11-21 00:36:55 +000012495static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012496s390_irgen_STCKF(IRTemp op2addr)
12497{
florianc5c669b2012-08-26 14:32:28 +000012498 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012499 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012500 } else {
12501 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012502
florianc5c669b2012-08-26 14:32:28 +000012503 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12504 &s390x_dirtyhelper_STCKF,
12505 mkIRExprVec_1(mkexpr(op2addr)));
12506 d->mFx = Ifx_Write;
12507 d->mAddr = mkexpr(op2addr);
12508 d->mSize = 8;
12509 stmt(IRStmt_Dirty(d));
12510 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12511 mkexpr(cc), mkU64(0), mkU64(0));
12512 }
sewardj1e5fea62011-05-17 16:18:36 +000012513 return "stckf";
12514}
12515
florian55085f82012-11-21 00:36:55 +000012516static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012517s390_irgen_STCKE(IRTemp op2addr)
12518{
12519 IRDirty *d;
12520 IRTemp cc = newTemp(Ity_I64);
12521
12522 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12523 &s390x_dirtyhelper_STCKE,
12524 mkIRExprVec_1(mkexpr(op2addr)));
12525 d->mFx = Ifx_Write;
12526 d->mAddr = mkexpr(op2addr);
12527 d->mSize = 16;
12528 stmt(IRStmt_Dirty(d));
12529 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12530 mkexpr(cc), mkU64(0), mkU64(0));
12531 return "stcke";
12532}
12533
florian55085f82012-11-21 00:36:55 +000012534static const HChar *
florian933065d2011-07-11 01:48:02 +000012535s390_irgen_STFLE(IRTemp op2addr)
12536{
florian4e0083e2012-08-26 03:41:56 +000012537 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012538 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012539 return "stfle";
12540 }
12541
florian933065d2011-07-11 01:48:02 +000012542 IRDirty *d;
12543 IRTemp cc = newTemp(Ity_I64);
12544
12545 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12546 &s390x_dirtyhelper_STFLE,
12547 mkIRExprVec_1(mkexpr(op2addr)));
12548
12549 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
12550
sewardjc9069f22012-06-01 16:09:50 +000012551 d->nFxState = 1;
12552 vex_bzero(&d->fxState, sizeof(d->fxState));
12553
florian933065d2011-07-11 01:48:02 +000012554 d->fxState[0].fx = Ifx_Modify; /* read then write */
12555 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12556 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012557
12558 d->mAddr = mkexpr(op2addr);
12559 /* Pretend all double words are written */
12560 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12561 d->mFx = Ifx_Write;
12562
12563 stmt(IRStmt_Dirty(d));
12564
12565 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12566
12567 return "stfle";
12568}
12569
florian55085f82012-11-21 00:36:55 +000012570static const HChar *
floriana4384a32011-08-11 16:58:45 +000012571s390_irgen_CKSM(UChar r1,UChar r2)
12572{
12573 IRTemp addr = newTemp(Ity_I64);
12574 IRTemp op = newTemp(Ity_I32);
12575 IRTemp len = newTemp(Ity_I64);
12576 IRTemp oldval = newTemp(Ity_I32);
12577 IRTemp mask = newTemp(Ity_I32);
12578 IRTemp newop = newTemp(Ity_I32);
12579 IRTemp result = newTemp(Ity_I32);
12580 IRTemp result1 = newTemp(Ity_I32);
12581 IRTemp inc = newTemp(Ity_I64);
12582
12583 assign(oldval, get_gpr_w1(r1));
12584 assign(addr, get_gpr_dw0(r2));
12585 assign(len, get_gpr_dw0(r2+1));
12586
12587 /* Condition code is always zero. */
12588 s390_cc_set(0);
12589
12590 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012591 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012592
12593 /* Assiging the increment variable to adjust address and length
12594 later on. */
12595 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12596 mkexpr(len), mkU64(4)));
12597
12598 /* If length < 4 the final 4-byte 2nd operand value is computed by
12599 appending the remaining bytes to the right with 0. This is done
12600 by AND'ing the 4 bytes loaded from memory with an appropriate
12601 mask. If length >= 4, that mask is simply 0xffffffff. */
12602
12603 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12604 /* Mask computation when len < 4:
12605 0xffffffff << (32 - (len % 4)*8) */
12606 binop(Iop_Shl32, mkU32(0xffffffff),
12607 unop(Iop_32to8,
12608 binop(Iop_Sub32, mkU32(32),
12609 binop(Iop_Shl32,
12610 unop(Iop_64to32,
12611 binop(Iop_And64,
12612 mkexpr(len), mkU64(3))),
12613 mkU8(3))))),
12614 mkU32(0xffffffff)));
12615
12616 assign(op, load(Ity_I32, mkexpr(addr)));
12617 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12618 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12619
12620 /* Checking for carry */
12621 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12622 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12623 mkexpr(result)));
12624
12625 put_gpr_w1(r1, mkexpr(result1));
12626 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12627 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12628
florian6820ba52012-07-26 02:01:50 +000012629 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012630
12631 return "cksm";
12632}
12633
florian55085f82012-11-21 00:36:55 +000012634static const HChar *
florian9af37692012-01-15 21:01:16 +000012635s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12636{
12637 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12638 src_addr = newTemp(Ity_I64);
12639 des_addr = newTemp(Ity_I64);
12640 tab_addr = newTemp(Ity_I64);
12641 test_byte = newTemp(Ity_I8);
12642 src_len = newTemp(Ity_I64);
12643
12644 assign(src_addr, get_gpr_dw0(r2));
12645 assign(des_addr, get_gpr_dw0(r1));
12646 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012647 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012648 assign(test_byte, get_gpr_b7(0));
12649
12650 IRTemp op = newTemp(Ity_I8);
12651 IRTemp op1 = newTemp(Ity_I8);
12652 IRTemp result = newTemp(Ity_I64);
12653
12654 /* End of source string? We're done; proceed to next insn */
12655 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012656 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012657
12658 /* Load character from source string, index translation table and
12659 store translated character in op1. */
12660 assign(op, load(Ity_I8, mkexpr(src_addr)));
12661
12662 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12663 mkexpr(tab_addr)));
12664 assign(op1, load(Ity_I8, mkexpr(result)));
12665
12666 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12667 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012668 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000012669 }
12670 store(get_gpr_dw0(r1), mkexpr(op1));
12671
12672 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12673 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12674 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12675
florian6820ba52012-07-26 02:01:50 +000012676 iterate();
florian9af37692012-01-15 21:01:16 +000012677
12678 return "troo";
12679}
12680
florian55085f82012-11-21 00:36:55 +000012681static const HChar *
florian730448f2012-02-04 17:07:07 +000012682s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
12683{
12684 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12685 src_addr = newTemp(Ity_I64);
12686 des_addr = newTemp(Ity_I64);
12687 tab_addr = newTemp(Ity_I64);
12688 test_byte = newTemp(Ity_I8);
12689 src_len = newTemp(Ity_I64);
12690
12691 assign(src_addr, get_gpr_dw0(r2));
12692 assign(des_addr, get_gpr_dw0(r1));
12693 assign(tab_addr, get_gpr_dw0(1));
12694 assign(src_len, get_gpr_dw0(r1+1));
12695 assign(test_byte, get_gpr_b7(0));
12696
12697 IRTemp op = newTemp(Ity_I16);
12698 IRTemp op1 = newTemp(Ity_I8);
12699 IRTemp result = newTemp(Ity_I64);
12700
12701 /* End of source string? We're done; proceed to next insn */
12702 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012703 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012704
12705 /* Load character from source string, index translation table and
12706 store translated character in op1. */
12707 assign(op, load(Ity_I16, mkexpr(src_addr)));
12708
12709 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12710 mkexpr(tab_addr)));
12711
12712 assign(op1, load(Ity_I8, mkexpr(result)));
12713
12714 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12715 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012716 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012717 }
12718 store(get_gpr_dw0(r1), mkexpr(op1));
12719
12720 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12721 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12722 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12723
florian6820ba52012-07-26 02:01:50 +000012724 iterate();
florian730448f2012-02-04 17:07:07 +000012725
12726 return "trto";
12727}
12728
florian55085f82012-11-21 00:36:55 +000012729static const HChar *
florian730448f2012-02-04 17:07:07 +000012730s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
12731{
12732 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12733 src_addr = newTemp(Ity_I64);
12734 des_addr = newTemp(Ity_I64);
12735 tab_addr = newTemp(Ity_I64);
12736 test_byte = newTemp(Ity_I16);
12737 src_len = newTemp(Ity_I64);
12738
12739 assign(src_addr, get_gpr_dw0(r2));
12740 assign(des_addr, get_gpr_dw0(r1));
12741 assign(tab_addr, get_gpr_dw0(1));
12742 assign(src_len, get_gpr_dw0(r1+1));
12743 assign(test_byte, get_gpr_hw3(0));
12744
12745 IRTemp op = newTemp(Ity_I8);
12746 IRTemp op1 = newTemp(Ity_I16);
12747 IRTemp result = newTemp(Ity_I64);
12748
12749 /* End of source string? We're done; proceed to next insn */
12750 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012751 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012752
12753 /* Load character from source string, index translation table and
12754 store translated character in op1. */
12755 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12756
12757 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12758 mkexpr(tab_addr)));
12759 assign(op1, load(Ity_I16, mkexpr(result)));
12760
12761 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12762 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012763 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012764 }
12765 store(get_gpr_dw0(r1), mkexpr(op1));
12766
12767 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12768 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12769 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12770
florian6820ba52012-07-26 02:01:50 +000012771 iterate();
florian730448f2012-02-04 17:07:07 +000012772
12773 return "trot";
12774}
12775
florian55085f82012-11-21 00:36:55 +000012776static const HChar *
florian730448f2012-02-04 17:07:07 +000012777s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12778{
12779 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12780 src_addr = newTemp(Ity_I64);
12781 des_addr = newTemp(Ity_I64);
12782 tab_addr = newTemp(Ity_I64);
12783 test_byte = newTemp(Ity_I16);
12784 src_len = newTemp(Ity_I64);
12785
12786 assign(src_addr, get_gpr_dw0(r2));
12787 assign(des_addr, get_gpr_dw0(r1));
12788 assign(tab_addr, get_gpr_dw0(1));
12789 assign(src_len, get_gpr_dw0(r1+1));
12790 assign(test_byte, get_gpr_hw3(0));
12791
12792 IRTemp op = newTemp(Ity_I16);
12793 IRTemp op1 = newTemp(Ity_I16);
12794 IRTemp result = newTemp(Ity_I64);
12795
12796 /* End of source string? We're done; proceed to next insn */
12797 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012798 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012799
12800 /* Load character from source string, index translation table and
12801 store translated character in op1. */
12802 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12803
12804 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12805 mkexpr(tab_addr)));
12806 assign(op1, load(Ity_I16, mkexpr(result)));
12807
12808 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12809 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012810 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012811 }
12812
12813 store(get_gpr_dw0(r1), mkexpr(op1));
12814
12815 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12816 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12817 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12818
florian6820ba52012-07-26 02:01:50 +000012819 iterate();
florian730448f2012-02-04 17:07:07 +000012820
12821 return "trtt";
12822}
12823
florian55085f82012-11-21 00:36:55 +000012824static const HChar *
florian730448f2012-02-04 17:07:07 +000012825s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
12826{
florianf87d4fb2012-05-05 02:55:24 +000012827 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000012828
florianf87d4fb2012-05-05 02:55:24 +000012829 assign(len, mkU64(length));
12830 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000012831
12832 return "tr";
12833}
12834
florian55085f82012-11-21 00:36:55 +000012835static const HChar *
florian730448f2012-02-04 17:07:07 +000012836s390_irgen_TRE(UChar r1,UChar r2)
12837{
12838 IRTemp src_addr, tab_addr, src_len, test_byte;
12839 src_addr = newTemp(Ity_I64);
12840 tab_addr = newTemp(Ity_I64);
12841 src_len = newTemp(Ity_I64);
12842 test_byte = newTemp(Ity_I8);
12843
12844 assign(src_addr, get_gpr_dw0(r1));
12845 assign(src_len, get_gpr_dw0(r1+1));
12846 assign(tab_addr, get_gpr_dw0(r2));
12847 assign(test_byte, get_gpr_b7(0));
12848
12849 IRTemp op = newTemp(Ity_I8);
12850 IRTemp op1 = newTemp(Ity_I8);
12851 IRTemp result = newTemp(Ity_I64);
12852
12853 /* End of source string? We're done; proceed to next insn */
12854 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012855 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012856
12857 /* Load character from source string and compare with test byte */
12858 assign(op, load(Ity_I8, mkexpr(src_addr)));
12859
12860 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012861 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012862
12863 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12864 mkexpr(tab_addr)));
12865
12866 assign(op1, load(Ity_I8, mkexpr(result)));
12867
12868 store(get_gpr_dw0(r1), mkexpr(op1));
12869 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12870 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12871
florian6820ba52012-07-26 02:01:50 +000012872 iterate();
florian730448f2012-02-04 17:07:07 +000012873
12874 return "tre";
12875}
12876
floriana0100c92012-07-20 00:06:35 +000012877static IRExpr *
12878s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
12879{
12880 IRExpr **args, *call;
12881 args = mkIRExprVec_2(srcval, low_surrogate);
12882 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12883 "s390_do_cu21", &s390_do_cu21, args);
12884
12885 /* Nothing is excluded from definedness checking. */
12886 call->Iex.CCall.cee->mcx_mask = 0;
12887
12888 return call;
12889}
12890
florian55085f82012-11-21 00:36:55 +000012891static const HChar *
floriana0100c92012-07-20 00:06:35 +000012892s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
12893{
12894 IRTemp addr1 = newTemp(Ity_I64);
12895 IRTemp addr2 = newTemp(Ity_I64);
12896 IRTemp len1 = newTemp(Ity_I64);
12897 IRTemp len2 = newTemp(Ity_I64);
12898
12899 assign(addr1, get_gpr_dw0(r1));
12900 assign(addr2, get_gpr_dw0(r2));
12901 assign(len1, get_gpr_dw0(r1 + 1));
12902 assign(len2, get_gpr_dw0(r2 + 1));
12903
12904 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12905 there are less than 2 bytes left, then the 2nd operand is exhausted
12906 and we're done here. cc = 0 */
12907 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012908 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000012909
12910 /* There are at least two bytes there. Read them. */
12911 IRTemp srcval = newTemp(Ity_I32);
12912 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12913
12914 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12915 inside the interval [0xd800 - 0xdbff] */
12916 IRTemp is_high_surrogate = newTemp(Ity_I32);
12917 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12918 mkU32(1), mkU32(0));
12919 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12920 mkU32(1), mkU32(0));
12921 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12922
12923 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12924 then the 2nd operand is exhausted and we're done here. cc = 0 */
12925 IRExpr *not_enough_bytes =
12926 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12927
florian6820ba52012-07-26 02:01:50 +000012928 next_insn_if(binop(Iop_CmpEQ32,
12929 binop(Iop_And32, mkexpr(is_high_surrogate),
12930 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000012931
12932 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12933 surrogate, read the next two bytes (low surrogate). */
12934 IRTemp low_surrogate = newTemp(Ity_I32);
12935 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12936
12937 assign(low_surrogate,
12938 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12939 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12940 mkU32(0))); // any value is fine; it will not be used
12941
12942 /* Call the helper */
12943 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012944 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
12945 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000012946
12947 /* Before we can test whether the 1st operand is exhausted we need to
12948 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12949 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12950 IRExpr *invalid_low_surrogate =
12951 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12952
12953 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012954 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000012955 }
12956
12957 /* Now test whether the 1st operand is exhausted */
12958 IRTemp num_bytes = newTemp(Ity_I64);
12959 assign(num_bytes, binop(Iop_And64,
12960 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12961 mkU64(0xff)));
12962 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012963 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000012964
12965 /* Extract the bytes to be stored at addr1 */
12966 IRTemp data = newTemp(Ity_I64);
12967 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12968
12969 /* To store the bytes construct 4 dirty helper calls. The helper calls
12970 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12971 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012972 UInt i;
floriana0100c92012-07-20 00:06:35 +000012973 for (i = 1; i <= 4; ++i) {
12974 IRDirty *d;
12975
12976 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12977 &s390x_dirtyhelper_CUxy,
12978 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12979 mkexpr(num_bytes)));
12980 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12981 d->mFx = Ifx_Write;
12982 d->mAddr = mkexpr(addr1);
12983 d->mSize = i;
12984 stmt(IRStmt_Dirty(d));
12985 }
12986
12987 /* Update source address and length */
12988 IRTemp num_src_bytes = newTemp(Ity_I64);
12989 assign(num_src_bytes,
12990 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12991 mkU64(4), mkU64(2)));
12992 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12993 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12994
12995 /* Update destination address and length */
12996 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12997 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12998
florian6820ba52012-07-26 02:01:50 +000012999 iterate();
floriana0100c92012-07-20 00:06:35 +000013000
13001 return "cu21";
13002}
13003
florian2a415a12012-07-21 17:41:36 +000013004static IRExpr *
13005s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13006{
13007 IRExpr **args, *call;
13008 args = mkIRExprVec_2(srcval, low_surrogate);
13009 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13010 "s390_do_cu24", &s390_do_cu24, args);
13011
13012 /* Nothing is excluded from definedness checking. */
13013 call->Iex.CCall.cee->mcx_mask = 0;
13014
13015 return call;
13016}
13017
florian55085f82012-11-21 00:36:55 +000013018static const HChar *
florian2a415a12012-07-21 17:41:36 +000013019s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13020{
13021 IRTemp addr1 = newTemp(Ity_I64);
13022 IRTemp addr2 = newTemp(Ity_I64);
13023 IRTemp len1 = newTemp(Ity_I64);
13024 IRTemp len2 = newTemp(Ity_I64);
13025
13026 assign(addr1, get_gpr_dw0(r1));
13027 assign(addr2, get_gpr_dw0(r2));
13028 assign(len1, get_gpr_dw0(r1 + 1));
13029 assign(len2, get_gpr_dw0(r2 + 1));
13030
13031 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13032 there are less than 2 bytes left, then the 2nd operand is exhausted
13033 and we're done here. cc = 0 */
13034 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013035 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013036
13037 /* There are at least two bytes there. Read them. */
13038 IRTemp srcval = newTemp(Ity_I32);
13039 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13040
13041 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13042 inside the interval [0xd800 - 0xdbff] */
13043 IRTemp is_high_surrogate = newTemp(Ity_I32);
13044 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13045 mkU32(1), mkU32(0));
13046 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13047 mkU32(1), mkU32(0));
13048 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13049
13050 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13051 then the 2nd operand is exhausted and we're done here. cc = 0 */
13052 IRExpr *not_enough_bytes =
13053 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13054
florian6820ba52012-07-26 02:01:50 +000013055 next_insn_if(binop(Iop_CmpEQ32,
13056 binop(Iop_And32, mkexpr(is_high_surrogate),
13057 not_enough_bytes),
13058 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013059
13060 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13061 surrogate, read the next two bytes (low surrogate). */
13062 IRTemp low_surrogate = newTemp(Ity_I32);
13063 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13064
13065 assign(low_surrogate,
13066 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13067 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13068 mkU32(0))); // any value is fine; it will not be used
13069
13070 /* Call the helper */
13071 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013072 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13073 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013074
13075 /* Before we can test whether the 1st operand is exhausted we need to
13076 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13077 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13078 IRExpr *invalid_low_surrogate =
13079 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13080
13081 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013082 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013083 }
13084
13085 /* Now test whether the 1st operand is exhausted */
13086 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013087 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013088
13089 /* Extract the bytes to be stored at addr1 */
13090 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13091
13092 store(mkexpr(addr1), data);
13093
13094 /* Update source address and length */
13095 IRTemp num_src_bytes = newTemp(Ity_I64);
13096 assign(num_src_bytes,
13097 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13098 mkU64(4), mkU64(2)));
13099 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13100 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13101
13102 /* Update destination address and length */
13103 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13104 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13105
florian6820ba52012-07-26 02:01:50 +000013106 iterate();
florian2a415a12012-07-21 17:41:36 +000013107
13108 return "cu24";
13109}
floriana4384a32011-08-11 16:58:45 +000013110
florian956194b2012-07-28 22:18:32 +000013111static IRExpr *
13112s390_call_cu42(IRExpr *srcval)
13113{
13114 IRExpr **args, *call;
13115 args = mkIRExprVec_1(srcval);
13116 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13117 "s390_do_cu42", &s390_do_cu42, args);
13118
13119 /* Nothing is excluded from definedness checking. */
13120 call->Iex.CCall.cee->mcx_mask = 0;
13121
13122 return call;
13123}
13124
florian55085f82012-11-21 00:36:55 +000013125static const HChar *
florian956194b2012-07-28 22:18:32 +000013126s390_irgen_CU42(UChar r1, UChar r2)
13127{
13128 IRTemp addr1 = newTemp(Ity_I64);
13129 IRTemp addr2 = newTemp(Ity_I64);
13130 IRTemp len1 = newTemp(Ity_I64);
13131 IRTemp len2 = newTemp(Ity_I64);
13132
13133 assign(addr1, get_gpr_dw0(r1));
13134 assign(addr2, get_gpr_dw0(r2));
13135 assign(len1, get_gpr_dw0(r1 + 1));
13136 assign(len2, get_gpr_dw0(r2 + 1));
13137
13138 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13139 there are less than 4 bytes left, then the 2nd operand is exhausted
13140 and we're done here. cc = 0 */
13141 s390_cc_set(0);
13142 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13143
13144 /* Read the 2nd operand. */
13145 IRTemp srcval = newTemp(Ity_I32);
13146 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13147
13148 /* Call the helper */
13149 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013150 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013151
13152 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13153 cc=2 outranks cc=1 (1st operand exhausted) */
13154 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13155
13156 s390_cc_set(2);
13157 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13158
13159 /* Now test whether the 1st operand is exhausted */
13160 IRTemp num_bytes = newTemp(Ity_I64);
13161 assign(num_bytes, binop(Iop_And64,
13162 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13163 mkU64(0xff)));
13164 s390_cc_set(1);
13165 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13166
13167 /* Extract the bytes to be stored at addr1 */
13168 IRTemp data = newTemp(Ity_I64);
13169 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13170
13171 /* To store the bytes construct 2 dirty helper calls. The helper calls
13172 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13173 that only one of them will be called at runtime. */
13174
13175 Int i;
13176 for (i = 2; i <= 4; ++i) {
13177 IRDirty *d;
13178
13179 if (i == 3) continue; // skip this one
13180
13181 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13182 &s390x_dirtyhelper_CUxy,
13183 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13184 mkexpr(num_bytes)));
13185 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13186 d->mFx = Ifx_Write;
13187 d->mAddr = mkexpr(addr1);
13188 d->mSize = i;
13189 stmt(IRStmt_Dirty(d));
13190 }
13191
13192 /* Update source address and length */
13193 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13194 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13195
13196 /* Update destination address and length */
13197 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13198 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13199
13200 iterate();
13201
13202 return "cu42";
13203}
13204
florian6d9b9b22012-08-03 18:35:39 +000013205static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013206s390_call_cu41(IRExpr *srcval)
13207{
13208 IRExpr **args, *call;
13209 args = mkIRExprVec_1(srcval);
13210 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13211 "s390_do_cu41", &s390_do_cu41, args);
13212
13213 /* Nothing is excluded from definedness checking. */
13214 call->Iex.CCall.cee->mcx_mask = 0;
13215
13216 return call;
13217}
13218
florian55085f82012-11-21 00:36:55 +000013219static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013220s390_irgen_CU41(UChar r1, UChar r2)
13221{
13222 IRTemp addr1 = newTemp(Ity_I64);
13223 IRTemp addr2 = newTemp(Ity_I64);
13224 IRTemp len1 = newTemp(Ity_I64);
13225 IRTemp len2 = newTemp(Ity_I64);
13226
13227 assign(addr1, get_gpr_dw0(r1));
13228 assign(addr2, get_gpr_dw0(r2));
13229 assign(len1, get_gpr_dw0(r1 + 1));
13230 assign(len2, get_gpr_dw0(r2 + 1));
13231
13232 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13233 there are less than 4 bytes left, then the 2nd operand is exhausted
13234 and we're done here. cc = 0 */
13235 s390_cc_set(0);
13236 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13237
13238 /* Read the 2nd operand. */
13239 IRTemp srcval = newTemp(Ity_I32);
13240 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13241
13242 /* Call the helper */
13243 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013244 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013245
13246 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13247 cc=2 outranks cc=1 (1st operand exhausted) */
13248 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13249
13250 s390_cc_set(2);
13251 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13252
13253 /* Now test whether the 1st operand is exhausted */
13254 IRTemp num_bytes = newTemp(Ity_I64);
13255 assign(num_bytes, binop(Iop_And64,
13256 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13257 mkU64(0xff)));
13258 s390_cc_set(1);
13259 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13260
13261 /* Extract the bytes to be stored at addr1 */
13262 IRTemp data = newTemp(Ity_I64);
13263 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13264
13265 /* To store the bytes construct 4 dirty helper calls. The helper calls
13266 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13267 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013268 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013269 for (i = 1; i <= 4; ++i) {
13270 IRDirty *d;
13271
13272 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13273 &s390x_dirtyhelper_CUxy,
13274 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13275 mkexpr(num_bytes)));
13276 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13277 d->mFx = Ifx_Write;
13278 d->mAddr = mkexpr(addr1);
13279 d->mSize = i;
13280 stmt(IRStmt_Dirty(d));
13281 }
13282
13283 /* Update source address and length */
13284 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13285 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13286
13287 /* Update destination address and length */
13288 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13289 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13290
13291 iterate();
13292
13293 return "cu41";
13294}
13295
13296static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013297s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013298{
13299 IRExpr **args, *call;
13300 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013301 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13302 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013303
13304 /* Nothing is excluded from definedness checking. */
13305 call->Iex.CCall.cee->mcx_mask = 0;
13306
13307 return call;
13308}
13309
13310static IRExpr *
13311s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13312 IRExpr *byte4, IRExpr *stuff)
13313{
13314 IRExpr **args, *call;
13315 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13316 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13317 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13318
13319 /* Nothing is excluded from definedness checking. */
13320 call->Iex.CCall.cee->mcx_mask = 0;
13321
13322 return call;
13323}
13324
florian3f8a96a2012-08-05 02:59:55 +000013325static IRExpr *
13326s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13327 IRExpr *byte4, IRExpr *stuff)
13328{
13329 IRExpr **args, *call;
13330 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13331 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13332 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13333
13334 /* Nothing is excluded from definedness checking. */
13335 call->Iex.CCall.cee->mcx_mask = 0;
13336
13337 return call;
13338}
13339
13340static void
13341s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013342{
13343 IRTemp addr1 = newTemp(Ity_I64);
13344 IRTemp addr2 = newTemp(Ity_I64);
13345 IRTemp len1 = newTemp(Ity_I64);
13346 IRTemp len2 = newTemp(Ity_I64);
13347
13348 assign(addr1, get_gpr_dw0(r1));
13349 assign(addr2, get_gpr_dw0(r2));
13350 assign(len1, get_gpr_dw0(r1 + 1));
13351 assign(len2, get_gpr_dw0(r2 + 1));
13352
13353 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13354
13355 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13356 there is less than 1 byte left, then the 2nd operand is exhausted
13357 and we're done here. cc = 0 */
13358 s390_cc_set(0);
13359 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13360
13361 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013362 IRTemp byte1 = newTemp(Ity_I64);
13363 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013364
13365 /* Call the helper to get number of bytes and invalid byte indicator */
13366 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013367 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013368 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013369
13370 /* Check for invalid 1st byte */
13371 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13372 s390_cc_set(2);
13373 next_insn_if(is_invalid);
13374
13375 /* How many bytes do we have to read? */
13376 IRTemp num_src_bytes = newTemp(Ity_I64);
13377 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13378
13379 /* Now test whether the 2nd operand is exhausted */
13380 s390_cc_set(0);
13381 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13382
13383 /* Read the remaining bytes */
13384 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13385
13386 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13387 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013388 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013389 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13390 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013391 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013392 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13393 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013394 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013395
13396 /* Call the helper to get the converted value and invalid byte indicator.
13397 We can pass at most 5 arguments; therefore some encoding is needed
13398 here */
13399 IRExpr *stuff = binop(Iop_Or64,
13400 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13401 mkU64(extended_checking));
13402 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013403
13404 if (is_cu12) {
13405 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13406 byte4, stuff));
13407 } else {
13408 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13409 byte4, stuff));
13410 }
florian6d9b9b22012-08-03 18:35:39 +000013411
13412 /* Check for invalid character */
13413 s390_cc_set(2);
13414 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13415 next_insn_if(is_invalid);
13416
13417 /* Now test whether the 1st operand is exhausted */
13418 IRTemp num_bytes = newTemp(Ity_I64);
13419 assign(num_bytes, binop(Iop_And64,
13420 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13421 mkU64(0xff)));
13422 s390_cc_set(1);
13423 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13424
13425 /* Extract the bytes to be stored at addr1 */
13426 IRTemp data = newTemp(Ity_I64);
13427 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13428
florian3f8a96a2012-08-05 02:59:55 +000013429 if (is_cu12) {
13430 /* To store the bytes construct 2 dirty helper calls. The helper calls
13431 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13432 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013433
florian3f8a96a2012-08-05 02:59:55 +000013434 Int i;
13435 for (i = 2; i <= 4; ++i) {
13436 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013437
florian3f8a96a2012-08-05 02:59:55 +000013438 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013439
florian3f8a96a2012-08-05 02:59:55 +000013440 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13441 &s390x_dirtyhelper_CUxy,
13442 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13443 mkexpr(num_bytes)));
13444 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13445 d->mFx = Ifx_Write;
13446 d->mAddr = mkexpr(addr1);
13447 d->mSize = i;
13448 stmt(IRStmt_Dirty(d));
13449 }
13450 } else {
13451 // cu14
13452 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013453 }
13454
13455 /* Update source address and length */
13456 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13457 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13458
13459 /* Update destination address and length */
13460 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13461 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13462
13463 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013464}
13465
florian55085f82012-11-21 00:36:55 +000013466static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013467s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13468{
13469 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013470
13471 return "cu12";
13472}
13473
florian55085f82012-11-21 00:36:55 +000013474static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013475s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13476{
13477 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13478
13479 return "cu14";
13480}
13481
florian8c88cb62012-08-26 18:58:13 +000013482static IRExpr *
13483s390_call_ecag(IRExpr *op2addr)
13484{
13485 IRExpr **args, *call;
13486
13487 args = mkIRExprVec_1(op2addr);
13488 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13489 "s390_do_ecag", &s390_do_ecag, args);
13490
13491 /* Nothing is excluded from definedness checking. */
13492 call->Iex.CCall.cee->mcx_mask = 0;
13493
13494 return call;
13495}
13496
florian55085f82012-11-21 00:36:55 +000013497static const HChar *
floriand2129202012-09-01 20:01:39 +000013498s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013499{
13500 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013501 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013502 } else {
13503 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13504 }
13505
13506 return "ecag";
13507}
13508
13509
florianb7def222012-12-04 04:45:32 +000013510/* New insns are added here.
13511 If an insn is contingent on a facility being installed also
13512 check whether the list of supported facilities in function
13513 s390x_dirtyhelper_STFLE needs updating */
13514
sewardj2019a972011-03-07 16:04:07 +000013515/*------------------------------------------------------------*/
13516/*--- Build IR for special instructions ---*/
13517/*------------------------------------------------------------*/
13518
florianb4df7682011-07-05 02:09:01 +000013519static void
sewardj2019a972011-03-07 16:04:07 +000013520s390_irgen_client_request(void)
13521{
13522 if (0)
13523 vex_printf("%%R3 = client_request ( %%R2 )\n");
13524
florianf9e1ed72012-04-17 02:41:56 +000013525 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13526 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013527
florianf9e1ed72012-04-17 02:41:56 +000013528 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013529 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013530
13531 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013532}
13533
florianb4df7682011-07-05 02:09:01 +000013534static void
sewardj2019a972011-03-07 16:04:07 +000013535s390_irgen_guest_NRADDR(void)
13536{
13537 if (0)
13538 vex_printf("%%R3 = guest_NRADDR\n");
13539
floriane88b3c92011-07-05 02:48:39 +000013540 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013541}
13542
florianb4df7682011-07-05 02:09:01 +000013543static void
sewardj2019a972011-03-07 16:04:07 +000013544s390_irgen_call_noredir(void)
13545{
florianf9e1ed72012-04-17 02:41:56 +000013546 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13547 + S390_SPECIAL_OP_SIZE;
13548
sewardj2019a972011-03-07 16:04:07 +000013549 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013550 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013551
13552 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013553 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013554
13555 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013556 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013557}
13558
13559/* Force proper alignment for the structures below. */
13560#pragma pack(1)
13561
13562
13563static s390_decode_t
13564s390_decode_2byte_and_irgen(UChar *bytes)
13565{
13566 typedef union {
13567 struct {
13568 unsigned int op : 16;
13569 } E;
13570 struct {
13571 unsigned int op : 8;
13572 unsigned int i : 8;
13573 } I;
13574 struct {
13575 unsigned int op : 8;
13576 unsigned int r1 : 4;
13577 unsigned int r2 : 4;
13578 } RR;
13579 } formats;
13580 union {
13581 formats fmt;
13582 UShort value;
13583 } ovl;
13584
13585 vassert(sizeof(formats) == 2);
13586
florianffbd84d2012-12-09 02:06:29 +000013587 ((UChar *)(&ovl.value))[0] = bytes[0];
13588 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013589
13590 switch (ovl.value & 0xffff) {
13591 case 0x0101: /* PR */ goto unimplemented;
13592 case 0x0102: /* UPT */ goto unimplemented;
13593 case 0x0104: /* PTFF */ goto unimplemented;
13594 case 0x0107: /* SCKPF */ goto unimplemented;
13595 case 0x010a: /* PFPO */ goto unimplemented;
13596 case 0x010b: /* TAM */ goto unimplemented;
13597 case 0x010c: /* SAM24 */ goto unimplemented;
13598 case 0x010d: /* SAM31 */ goto unimplemented;
13599 case 0x010e: /* SAM64 */ goto unimplemented;
13600 case 0x01ff: /* TRAP2 */ goto unimplemented;
13601 }
13602
13603 switch ((ovl.value & 0xff00) >> 8) {
13604 case 0x04: /* SPM */ goto unimplemented;
13605 case 0x05: /* BALR */ goto unimplemented;
13606 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13607 goto ok;
13608 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13609 goto ok;
13610 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13611 case 0x0b: /* BSM */ goto unimplemented;
13612 case 0x0c: /* BASSM */ goto unimplemented;
13613 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13614 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013615 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13616 goto ok;
13617 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13618 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013619 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13620 goto ok;
13621 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13622 goto ok;
13623 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13624 goto ok;
13625 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13626 goto ok;
13627 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13628 goto ok;
13629 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13630 goto ok;
13631 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13632 goto ok;
13633 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13634 goto ok;
13635 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13636 goto ok;
13637 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13638 goto ok;
13639 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13640 goto ok;
13641 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13642 goto ok;
13643 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13644 goto ok;
13645 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13646 goto ok;
13647 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13648 goto ok;
13649 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13650 goto ok;
13651 case 0x20: /* LPDR */ goto unimplemented;
13652 case 0x21: /* LNDR */ goto unimplemented;
13653 case 0x22: /* LTDR */ goto unimplemented;
13654 case 0x23: /* LCDR */ goto unimplemented;
13655 case 0x24: /* HDR */ goto unimplemented;
13656 case 0x25: /* LDXR */ goto unimplemented;
13657 case 0x26: /* MXR */ goto unimplemented;
13658 case 0x27: /* MXDR */ goto unimplemented;
13659 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13660 goto ok;
13661 case 0x29: /* CDR */ goto unimplemented;
13662 case 0x2a: /* ADR */ goto unimplemented;
13663 case 0x2b: /* SDR */ goto unimplemented;
13664 case 0x2c: /* MDR */ goto unimplemented;
13665 case 0x2d: /* DDR */ goto unimplemented;
13666 case 0x2e: /* AWR */ goto unimplemented;
13667 case 0x2f: /* SWR */ goto unimplemented;
13668 case 0x30: /* LPER */ goto unimplemented;
13669 case 0x31: /* LNER */ goto unimplemented;
13670 case 0x32: /* LTER */ goto unimplemented;
13671 case 0x33: /* LCER */ goto unimplemented;
13672 case 0x34: /* HER */ goto unimplemented;
13673 case 0x35: /* LEDR */ goto unimplemented;
13674 case 0x36: /* AXR */ goto unimplemented;
13675 case 0x37: /* SXR */ goto unimplemented;
13676 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13677 goto ok;
13678 case 0x39: /* CER */ goto unimplemented;
13679 case 0x3a: /* AER */ goto unimplemented;
13680 case 0x3b: /* SER */ goto unimplemented;
13681 case 0x3c: /* MDER */ goto unimplemented;
13682 case 0x3d: /* DER */ goto unimplemented;
13683 case 0x3e: /* AUR */ goto unimplemented;
13684 case 0x3f: /* SUR */ goto unimplemented;
13685 }
13686
13687 return S390_DECODE_UNKNOWN_INSN;
13688
13689ok:
13690 return S390_DECODE_OK;
13691
13692unimplemented:
13693 return S390_DECODE_UNIMPLEMENTED_INSN;
13694}
13695
13696static s390_decode_t
13697s390_decode_4byte_and_irgen(UChar *bytes)
13698{
13699 typedef union {
13700 struct {
13701 unsigned int op1 : 8;
13702 unsigned int r1 : 4;
13703 unsigned int op2 : 4;
13704 unsigned int i2 : 16;
13705 } RI;
13706 struct {
13707 unsigned int op : 16;
13708 unsigned int : 8;
13709 unsigned int r1 : 4;
13710 unsigned int r2 : 4;
13711 } RRE;
13712 struct {
13713 unsigned int op : 16;
13714 unsigned int r1 : 4;
13715 unsigned int : 4;
13716 unsigned int r3 : 4;
13717 unsigned int r2 : 4;
13718 } RRF;
13719 struct {
13720 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000013721 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000013722 unsigned int m4 : 4;
13723 unsigned int r1 : 4;
13724 unsigned int r2 : 4;
13725 } RRF2;
13726 struct {
13727 unsigned int op : 16;
13728 unsigned int r3 : 4;
13729 unsigned int : 4;
13730 unsigned int r1 : 4;
13731 unsigned int r2 : 4;
13732 } RRF3;
13733 struct {
13734 unsigned int op : 16;
13735 unsigned int r3 : 4;
13736 unsigned int : 4;
13737 unsigned int r1 : 4;
13738 unsigned int r2 : 4;
13739 } RRR;
13740 struct {
13741 unsigned int op : 16;
13742 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013743 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013744 unsigned int r1 : 4;
13745 unsigned int r2 : 4;
13746 } RRF4;
13747 struct {
floriane38f6412012-12-21 17:32:12 +000013748 unsigned int op : 16;
13749 unsigned int : 4;
13750 unsigned int m4 : 4;
13751 unsigned int r1 : 4;
13752 unsigned int r2 : 4;
13753 } RRF5;
13754 struct {
sewardj2019a972011-03-07 16:04:07 +000013755 unsigned int op : 8;
13756 unsigned int r1 : 4;
13757 unsigned int r3 : 4;
13758 unsigned int b2 : 4;
13759 unsigned int d2 : 12;
13760 } RS;
13761 struct {
13762 unsigned int op : 8;
13763 unsigned int r1 : 4;
13764 unsigned int r3 : 4;
13765 unsigned int i2 : 16;
13766 } RSI;
13767 struct {
13768 unsigned int op : 8;
13769 unsigned int r1 : 4;
13770 unsigned int x2 : 4;
13771 unsigned int b2 : 4;
13772 unsigned int d2 : 12;
13773 } RX;
13774 struct {
13775 unsigned int op : 16;
13776 unsigned int b2 : 4;
13777 unsigned int d2 : 12;
13778 } S;
13779 struct {
13780 unsigned int op : 8;
13781 unsigned int i2 : 8;
13782 unsigned int b1 : 4;
13783 unsigned int d1 : 12;
13784 } SI;
13785 } formats;
13786 union {
13787 formats fmt;
13788 UInt value;
13789 } ovl;
13790
13791 vassert(sizeof(formats) == 4);
13792
florianffbd84d2012-12-09 02:06:29 +000013793 ((UChar *)(&ovl.value))[0] = bytes[0];
13794 ((UChar *)(&ovl.value))[1] = bytes[1];
13795 ((UChar *)(&ovl.value))[2] = bytes[2];
13796 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013797
13798 switch ((ovl.value & 0xff0f0000) >> 16) {
13799 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13800 ovl.fmt.RI.i2); goto ok;
13801 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13802 ovl.fmt.RI.i2); goto ok;
13803 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
13804 ovl.fmt.RI.i2); goto ok;
13805 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
13806 ovl.fmt.RI.i2); goto ok;
13807 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
13808 ovl.fmt.RI.i2); goto ok;
13809 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
13810 ovl.fmt.RI.i2); goto ok;
13811 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
13812 ovl.fmt.RI.i2); goto ok;
13813 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
13814 ovl.fmt.RI.i2); goto ok;
13815 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
13816 ovl.fmt.RI.i2); goto ok;
13817 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
13818 ovl.fmt.RI.i2); goto ok;
13819 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
13820 ovl.fmt.RI.i2); goto ok;
13821 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
13822 ovl.fmt.RI.i2); goto ok;
13823 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
13824 ovl.fmt.RI.i2); goto ok;
13825 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
13826 ovl.fmt.RI.i2); goto ok;
13827 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
13828 ovl.fmt.RI.i2); goto ok;
13829 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
13830 ovl.fmt.RI.i2); goto ok;
13831 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
13832 ovl.fmt.RI.i2); goto ok;
13833 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
13834 ovl.fmt.RI.i2); goto ok;
13835 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
13836 ovl.fmt.RI.i2); goto ok;
13837 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
13838 ovl.fmt.RI.i2); goto ok;
13839 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13840 goto ok;
13841 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
13842 ovl.fmt.RI.i2); goto ok;
13843 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
13844 ovl.fmt.RI.i2); goto ok;
13845 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
13846 ovl.fmt.RI.i2); goto ok;
13847 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13848 goto ok;
13849 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
13850 ovl.fmt.RI.i2); goto ok;
13851 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13852 goto ok;
13853 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
13854 ovl.fmt.RI.i2); goto ok;
13855 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13856 goto ok;
13857 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
13858 ovl.fmt.RI.i2); goto ok;
13859 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13860 goto ok;
13861 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
13862 ovl.fmt.RI.i2); goto ok;
13863 }
13864
13865 switch ((ovl.value & 0xffff0000) >> 16) {
13866 case 0x8000: /* SSM */ goto unimplemented;
13867 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013868 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013869 case 0xb202: /* STIDP */ goto unimplemented;
13870 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013871 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
13872 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013873 case 0xb206: /* SCKC */ goto unimplemented;
13874 case 0xb207: /* STCKC */ goto unimplemented;
13875 case 0xb208: /* SPT */ goto unimplemented;
13876 case 0xb209: /* STPT */ goto unimplemented;
13877 case 0xb20a: /* SPKA */ goto unimplemented;
13878 case 0xb20b: /* IPK */ goto unimplemented;
13879 case 0xb20d: /* PTLB */ goto unimplemented;
13880 case 0xb210: /* SPX */ goto unimplemented;
13881 case 0xb211: /* STPX */ goto unimplemented;
13882 case 0xb212: /* STAP */ goto unimplemented;
13883 case 0xb214: /* SIE */ goto unimplemented;
13884 case 0xb218: /* PC */ goto unimplemented;
13885 case 0xb219: /* SAC */ goto unimplemented;
13886 case 0xb21a: /* CFC */ goto unimplemented;
13887 case 0xb221: /* IPTE */ goto unimplemented;
13888 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
13889 case 0xb223: /* IVSK */ goto unimplemented;
13890 case 0xb224: /* IAC */ goto unimplemented;
13891 case 0xb225: /* SSAR */ goto unimplemented;
13892 case 0xb226: /* EPAR */ goto unimplemented;
13893 case 0xb227: /* ESAR */ goto unimplemented;
13894 case 0xb228: /* PT */ goto unimplemented;
13895 case 0xb229: /* ISKE */ goto unimplemented;
13896 case 0xb22a: /* RRBE */ goto unimplemented;
13897 case 0xb22b: /* SSKE */ goto unimplemented;
13898 case 0xb22c: /* TB */ goto unimplemented;
13899 case 0xb22d: /* DXR */ goto unimplemented;
13900 case 0xb22e: /* PGIN */ goto unimplemented;
13901 case 0xb22f: /* PGOUT */ goto unimplemented;
13902 case 0xb230: /* CSCH */ goto unimplemented;
13903 case 0xb231: /* HSCH */ goto unimplemented;
13904 case 0xb232: /* MSCH */ goto unimplemented;
13905 case 0xb233: /* SSCH */ goto unimplemented;
13906 case 0xb234: /* STSCH */ goto unimplemented;
13907 case 0xb235: /* TSCH */ goto unimplemented;
13908 case 0xb236: /* TPI */ goto unimplemented;
13909 case 0xb237: /* SAL */ goto unimplemented;
13910 case 0xb238: /* RSCH */ goto unimplemented;
13911 case 0xb239: /* STCRW */ goto unimplemented;
13912 case 0xb23a: /* STCPS */ goto unimplemented;
13913 case 0xb23b: /* RCHP */ goto unimplemented;
13914 case 0xb23c: /* SCHM */ goto unimplemented;
13915 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000013916 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
13917 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013918 case 0xb244: /* SQDR */ goto unimplemented;
13919 case 0xb245: /* SQER */ goto unimplemented;
13920 case 0xb246: /* STURA */ goto unimplemented;
13921 case 0xb247: /* MSTA */ goto unimplemented;
13922 case 0xb248: /* PALB */ goto unimplemented;
13923 case 0xb249: /* EREG */ goto unimplemented;
13924 case 0xb24a: /* ESTA */ goto unimplemented;
13925 case 0xb24b: /* LURA */ goto unimplemented;
13926 case 0xb24c: /* TAR */ goto unimplemented;
13927 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
13928 ovl.fmt.RRE.r2); goto ok;
13929 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13930 goto ok;
13931 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13932 goto ok;
13933 case 0xb250: /* CSP */ goto unimplemented;
13934 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
13935 ovl.fmt.RRE.r2); goto ok;
13936 case 0xb254: /* MVPG */ goto unimplemented;
13937 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
13938 ovl.fmt.RRE.r2); goto ok;
13939 case 0xb257: /* CUSE */ goto unimplemented;
13940 case 0xb258: /* BSG */ goto unimplemented;
13941 case 0xb25a: /* BSA */ goto unimplemented;
13942 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
13943 ovl.fmt.RRE.r2); goto ok;
13944 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
13945 ovl.fmt.RRE.r2); goto ok;
13946 case 0xb263: /* CMPSC */ goto unimplemented;
13947 case 0xb274: /* SIGA */ goto unimplemented;
13948 case 0xb276: /* XSCH */ goto unimplemented;
13949 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013950 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 +000013951 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013952 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 +000013953 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013954 case 0xb280: /* LPP */ goto unimplemented;
13955 case 0xb284: /* LCCTL */ goto unimplemented;
13956 case 0xb285: /* LPCTL */ goto unimplemented;
13957 case 0xb286: /* QSI */ goto unimplemented;
13958 case 0xb287: /* LSCTL */ goto unimplemented;
13959 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013960 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
13961 goto ok;
13962 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13963 goto ok;
13964 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13965 goto ok;
florian730448f2012-02-04 17:07:07 +000013966 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 +000013967 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
13968 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13969 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000013970 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
13971 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13972 goto ok;
florian933065d2011-07-11 01:48:02 +000013973 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
13974 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013975 case 0xb2b1: /* STFL */ goto unimplemented;
13976 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000013977 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
13978 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013979 case 0xb2b9: /* SRNMT */ goto unimplemented;
13980 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013981 case 0xb2e0: /* SCCTR */ goto unimplemented;
13982 case 0xb2e1: /* SPCTR */ goto unimplemented;
13983 case 0xb2e4: /* ECCTR */ goto unimplemented;
13984 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013985 case 0xb2e8: /* PPA */ goto unimplemented;
13986 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013987 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013988 case 0xb2f8: /* TEND */ goto unimplemented;
13989 case 0xb2fa: /* NIAI */ goto unimplemented;
13990 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013991 case 0xb2ff: /* TRAP4 */ goto unimplemented;
13992 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
13993 ovl.fmt.RRE.r2); goto ok;
13994 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
13995 ovl.fmt.RRE.r2); goto ok;
13996 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
13997 ovl.fmt.RRE.r2); goto ok;
13998 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
13999 ovl.fmt.RRE.r2); goto ok;
14000 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14001 ovl.fmt.RRE.r2); goto ok;
14002 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14003 ovl.fmt.RRE.r2); goto ok;
14004 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14005 ovl.fmt.RRE.r2); goto ok;
14006 case 0xb307: /* MXDBR */ goto unimplemented;
14007 case 0xb308: /* KEBR */ goto unimplemented;
14008 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14009 ovl.fmt.RRE.r2); goto ok;
14010 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14011 ovl.fmt.RRE.r2); goto ok;
14012 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14013 ovl.fmt.RRE.r2); goto ok;
14014 case 0xb30c: /* MDEBR */ goto unimplemented;
14015 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14016 ovl.fmt.RRE.r2); goto ok;
14017 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14018 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14019 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14020 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14021 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14022 ovl.fmt.RRE.r2); goto ok;
14023 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14024 ovl.fmt.RRE.r2); goto ok;
14025 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14026 ovl.fmt.RRE.r2); goto ok;
14027 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14028 ovl.fmt.RRE.r2); goto ok;
14029 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14030 ovl.fmt.RRE.r2); goto ok;
14031 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14032 ovl.fmt.RRE.r2); goto ok;
14033 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14034 ovl.fmt.RRE.r2); goto ok;
14035 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14036 ovl.fmt.RRE.r2); goto ok;
14037 case 0xb318: /* KDBR */ goto unimplemented;
14038 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14039 ovl.fmt.RRE.r2); goto ok;
14040 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14041 ovl.fmt.RRE.r2); goto ok;
14042 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14043 ovl.fmt.RRE.r2); goto ok;
14044 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14045 ovl.fmt.RRE.r2); goto ok;
14046 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14047 ovl.fmt.RRE.r2); goto ok;
14048 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14049 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14050 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14051 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14052 case 0xb324: /* LDER */ goto unimplemented;
14053 case 0xb325: /* LXDR */ goto unimplemented;
14054 case 0xb326: /* LXER */ goto unimplemented;
14055 case 0xb32e: /* MAER */ goto unimplemented;
14056 case 0xb32f: /* MSER */ goto unimplemented;
14057 case 0xb336: /* SQXR */ goto unimplemented;
14058 case 0xb337: /* MEER */ goto unimplemented;
14059 case 0xb338: /* MAYLR */ goto unimplemented;
14060 case 0xb339: /* MYLR */ goto unimplemented;
14061 case 0xb33a: /* MAYR */ goto unimplemented;
14062 case 0xb33b: /* MYR */ goto unimplemented;
14063 case 0xb33c: /* MAYHR */ goto unimplemented;
14064 case 0xb33d: /* MYHR */ goto unimplemented;
14065 case 0xb33e: /* MADR */ goto unimplemented;
14066 case 0xb33f: /* MSDR */ goto unimplemented;
14067 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14068 ovl.fmt.RRE.r2); goto ok;
14069 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14070 ovl.fmt.RRE.r2); goto ok;
14071 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14072 ovl.fmt.RRE.r2); goto ok;
14073 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14074 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014075 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14076 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14077 ovl.fmt.RRF2.r2); goto ok;
14078 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14079 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14080 ovl.fmt.RRF2.r2); goto ok;
14081 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14082 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14083 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014084 case 0xb347: /* FIXBR */ goto unimplemented;
14085 case 0xb348: /* KXBR */ goto unimplemented;
14086 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14087 ovl.fmt.RRE.r2); goto ok;
14088 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14089 ovl.fmt.RRE.r2); goto ok;
14090 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14091 ovl.fmt.RRE.r2); goto ok;
14092 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14093 ovl.fmt.RRE.r2); goto ok;
14094 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14095 ovl.fmt.RRE.r2); goto ok;
14096 case 0xb350: /* TBEDR */ goto unimplemented;
14097 case 0xb351: /* TBDR */ goto unimplemented;
14098 case 0xb353: /* DIEBR */ goto unimplemented;
14099 case 0xb357: /* FIEBR */ goto unimplemented;
14100 case 0xb358: /* THDER */ goto unimplemented;
14101 case 0xb359: /* THDR */ goto unimplemented;
14102 case 0xb35b: /* DIDBR */ goto unimplemented;
14103 case 0xb35f: /* FIDBR */ goto unimplemented;
14104 case 0xb360: /* LPXR */ goto unimplemented;
14105 case 0xb361: /* LNXR */ goto unimplemented;
14106 case 0xb362: /* LTXR */ goto unimplemented;
14107 case 0xb363: /* LCXR */ goto unimplemented;
14108 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14109 ovl.fmt.RRE.r2); goto ok;
14110 case 0xb366: /* LEXR */ goto unimplemented;
14111 case 0xb367: /* FIXR */ goto unimplemented;
14112 case 0xb369: /* CXR */ goto unimplemented;
14113 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14114 ovl.fmt.RRE.r2); goto ok;
14115 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14116 ovl.fmt.RRE.r2); goto ok;
14117 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14118 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14119 goto ok;
14120 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14121 ovl.fmt.RRE.r2); goto ok;
14122 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14123 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14124 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14125 case 0xb377: /* FIER */ goto unimplemented;
14126 case 0xb37f: /* FIDR */ goto unimplemented;
14127 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14128 case 0xb385: /* SFASR */ goto unimplemented;
14129 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014130 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14131 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14132 ovl.fmt.RRF2.r2); goto ok;
14133 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14134 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14135 ovl.fmt.RRF2.r2); goto ok;
14136 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14137 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14138 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014139 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14140 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14141 ovl.fmt.RRF2.r2); goto ok;
14142 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14143 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14144 ovl.fmt.RRF2.r2); goto ok;
14145 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14146 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14147 ovl.fmt.RRF2.r2); goto ok;
14148 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14149 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14150 ovl.fmt.RRF2.r2); goto ok;
14151 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14152 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14153 ovl.fmt.RRF2.r2); goto ok;
14154 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14155 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14156 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014157 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14158 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14159 ovl.fmt.RRF2.r2); goto ok;
14160 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14161 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14162 ovl.fmt.RRF2.r2); goto ok;
14163 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14164 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14165 ovl.fmt.RRF2.r2); goto ok;
14166 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14167 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14168 ovl.fmt.RRF2.r2); goto ok;
14169 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14170 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14171 ovl.fmt.RRF2.r2); goto ok;
14172 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14173 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14174 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014175 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14176 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14177 ovl.fmt.RRF2.r2); goto ok;
14178 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14179 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14180 ovl.fmt.RRF2.r2); goto ok;
14181 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14182 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14183 ovl.fmt.RRF2.r2); goto ok;
14184 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14185 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14186 ovl.fmt.RRF2.r2); goto ok;
14187 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14188 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14189 ovl.fmt.RRF2.r2); goto ok;
14190 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14191 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14192 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014193 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14194 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14195 ovl.fmt.RRF2.r2); goto ok;
14196 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14197 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14198 ovl.fmt.RRF2.r2); goto ok;
14199 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14200 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14201 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014202 case 0xb3b4: /* CEFR */ goto unimplemented;
14203 case 0xb3b5: /* CDFR */ goto unimplemented;
14204 case 0xb3b6: /* CXFR */ goto unimplemented;
14205 case 0xb3b8: /* CFER */ goto unimplemented;
14206 case 0xb3b9: /* CFDR */ goto unimplemented;
14207 case 0xb3ba: /* CFXR */ goto unimplemented;
14208 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14209 ovl.fmt.RRE.r2); goto ok;
14210 case 0xb3c4: /* CEGR */ goto unimplemented;
14211 case 0xb3c5: /* CDGR */ goto unimplemented;
14212 case 0xb3c6: /* CXGR */ goto unimplemented;
14213 case 0xb3c8: /* CGER */ goto unimplemented;
14214 case 0xb3c9: /* CGDR */ goto unimplemented;
14215 case 0xb3ca: /* CGXR */ goto unimplemented;
14216 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14217 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014218 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14219 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14220 ovl.fmt.RRF4.r2); goto ok;
14221 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14222 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14223 ovl.fmt.RRF4.r2); goto ok;
14224 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14225 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14226 ovl.fmt.RRF4.r2); goto ok;
14227 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14228 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14229 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014230 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14231 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14232 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14233 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14234 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014235 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14236 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014237 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014238 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14239 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14240 ovl.fmt.RRF4.r2); goto ok;
14241 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14242 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14243 ovl.fmt.RRF4.r2); goto ok;
14244 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14245 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14246 ovl.fmt.RRF4.r2); goto ok;
14247 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14248 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14249 ovl.fmt.RRF4.r2); goto ok;
14250 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14251 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14252 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14253 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14254 ovl.fmt.RRF2.r2); goto ok;
14255 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14256 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014257 case 0xb3df: /* FIXTR */ goto unimplemented;
14258 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014259 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14260 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14261 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014262 case 0xb3e2: /* CUDTR */ goto unimplemented;
14263 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014264 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14265 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014266 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14267 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014268 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14269 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014270 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014271 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14272 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14273 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014274 case 0xb3ea: /* CUXTR */ goto unimplemented;
14275 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014276 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14277 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014278 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14279 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014280 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14281 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014282 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14283 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14284 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014285 case 0xb3f2: /* CDUTR */ goto unimplemented;
14286 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014287 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14288 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014289 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14290 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14291 ovl.fmt.RRF4.r2); goto ok;
14292 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14293 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14294 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14295 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14296 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014297 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14298 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14299 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014300 case 0xb3fa: /* CXUTR */ goto unimplemented;
14301 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014302 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14303 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014304 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14305 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14306 ovl.fmt.RRF4.r2); goto ok;
14307 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14308 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14309 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14310 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14311 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014312 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14313 ovl.fmt.RRE.r2); goto ok;
14314 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14315 ovl.fmt.RRE.r2); goto ok;
14316 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14317 ovl.fmt.RRE.r2); goto ok;
14318 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14319 ovl.fmt.RRE.r2); goto ok;
14320 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14321 ovl.fmt.RRE.r2); goto ok;
14322 case 0xb905: /* LURAG */ goto unimplemented;
14323 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14324 ovl.fmt.RRE.r2); goto ok;
14325 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14326 ovl.fmt.RRE.r2); goto ok;
14327 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14328 ovl.fmt.RRE.r2); goto ok;
14329 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14330 ovl.fmt.RRE.r2); goto ok;
14331 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14332 ovl.fmt.RRE.r2); goto ok;
14333 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14334 ovl.fmt.RRE.r2); goto ok;
14335 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14336 ovl.fmt.RRE.r2); goto ok;
14337 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14338 ovl.fmt.RRE.r2); goto ok;
14339 case 0xb90e: /* EREGG */ goto unimplemented;
14340 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14341 ovl.fmt.RRE.r2); goto ok;
14342 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14343 ovl.fmt.RRE.r2); goto ok;
14344 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14345 ovl.fmt.RRE.r2); goto ok;
14346 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14347 ovl.fmt.RRE.r2); goto ok;
14348 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14349 ovl.fmt.RRE.r2); goto ok;
14350 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14351 ovl.fmt.RRE.r2); goto ok;
14352 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14353 ovl.fmt.RRE.r2); goto ok;
14354 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14355 ovl.fmt.RRE.r2); goto ok;
14356 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14357 ovl.fmt.RRE.r2); goto ok;
14358 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14359 ovl.fmt.RRE.r2); goto ok;
14360 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14361 ovl.fmt.RRE.r2); goto ok;
14362 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14363 ovl.fmt.RRE.r2); goto ok;
14364 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14365 ovl.fmt.RRE.r2); goto ok;
14366 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14367 ovl.fmt.RRE.r2); goto ok;
14368 case 0xb91e: /* KMAC */ goto unimplemented;
14369 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14370 ovl.fmt.RRE.r2); goto ok;
14371 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14372 ovl.fmt.RRE.r2); goto ok;
14373 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14374 ovl.fmt.RRE.r2); goto ok;
14375 case 0xb925: /* STURG */ goto unimplemented;
14376 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14377 ovl.fmt.RRE.r2); goto ok;
14378 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14379 ovl.fmt.RRE.r2); goto ok;
14380 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014381 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014382 case 0xb92b: /* KMO */ goto unimplemented;
14383 case 0xb92c: /* PCC */ goto unimplemented;
14384 case 0xb92d: /* KMCTR */ goto unimplemented;
14385 case 0xb92e: /* KM */ goto unimplemented;
14386 case 0xb92f: /* KMC */ goto unimplemented;
14387 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14388 ovl.fmt.RRE.r2); goto ok;
14389 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14390 ovl.fmt.RRE.r2); goto ok;
14391 case 0xb93e: /* KIMD */ goto unimplemented;
14392 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014393 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14394 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14395 ovl.fmt.RRF2.r2); goto ok;
14396 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14397 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14398 ovl.fmt.RRF2.r2); goto ok;
14399 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14400 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14401 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014402 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14403 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014404 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14405 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14406 ovl.fmt.RRF2.r2); goto ok;
14407 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14408 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14409 ovl.fmt.RRF2.r2); goto ok;
14410 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14411 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14412 ovl.fmt.RRF2.r2); goto ok;
14413 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14414 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14415 ovl.fmt.RRF2.r2); goto ok;
14416 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14417 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14418 ovl.fmt.RRF2.r2); goto ok;
14419 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14420 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14421 ovl.fmt.RRF2.r2); goto ok;
14422 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14423 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14424 ovl.fmt.RRF2.r2); goto ok;
14425 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14426 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14427 ovl.fmt.RRF2.r2); goto ok;
14428 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14429 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14430 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014431 case 0xb960: /* CGRT */ goto unimplemented;
14432 case 0xb961: /* CLGRT */ goto unimplemented;
14433 case 0xb972: /* CRT */ goto unimplemented;
14434 case 0xb973: /* CLRT */ goto unimplemented;
14435 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14436 ovl.fmt.RRE.r2); goto ok;
14437 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14438 ovl.fmt.RRE.r2); goto ok;
14439 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14440 ovl.fmt.RRE.r2); goto ok;
14441 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14442 ovl.fmt.RRE.r2); goto ok;
14443 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14444 ovl.fmt.RRE.r2); goto ok;
14445 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14446 ovl.fmt.RRE.r2); goto ok;
14447 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14448 ovl.fmt.RRE.r2); goto ok;
14449 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14450 ovl.fmt.RRE.r2); goto ok;
14451 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14452 ovl.fmt.RRE.r2); goto ok;
14453 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14454 ovl.fmt.RRE.r2); goto ok;
14455 case 0xb98a: /* CSPG */ goto unimplemented;
14456 case 0xb98d: /* EPSW */ goto unimplemented;
14457 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014458 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014459 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14460 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14461 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14462 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14463 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14464 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014465 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14466 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014467 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14468 ovl.fmt.RRE.r2); goto ok;
14469 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14470 ovl.fmt.RRE.r2); goto ok;
14471 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14472 ovl.fmt.RRE.r2); goto ok;
14473 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14474 ovl.fmt.RRE.r2); goto ok;
14475 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14476 ovl.fmt.RRE.r2); goto ok;
14477 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14478 ovl.fmt.RRE.r2); goto ok;
14479 case 0xb99a: /* EPAIR */ goto unimplemented;
14480 case 0xb99b: /* ESAIR */ goto unimplemented;
14481 case 0xb99d: /* ESEA */ goto unimplemented;
14482 case 0xb99e: /* PTI */ goto unimplemented;
14483 case 0xb99f: /* SSAIR */ goto unimplemented;
14484 case 0xb9a2: /* PTF */ goto unimplemented;
14485 case 0xb9aa: /* LPTEA */ goto unimplemented;
14486 case 0xb9ae: /* RRBM */ goto unimplemented;
14487 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014488 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14489 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14490 goto ok;
florian2a415a12012-07-21 17:41:36 +000014491 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14492 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14493 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014494 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14495 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014496 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14497 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014498 case 0xb9bd: /* TRTRE */ goto unimplemented;
14499 case 0xb9be: /* SRSTU */ goto unimplemented;
14500 case 0xb9bf: /* TRTE */ goto unimplemented;
14501 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14502 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14503 goto ok;
14504 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14505 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14506 goto ok;
14507 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14508 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14509 goto ok;
14510 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14511 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14512 goto ok;
14513 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14514 ovl.fmt.RRE.r2); goto ok;
14515 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14516 ovl.fmt.RRE.r2); goto ok;
14517 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14518 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14519 goto ok;
14520 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14521 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14522 goto ok;
14523 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14524 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14525 goto ok;
14526 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14527 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14528 goto ok;
14529 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14530 ovl.fmt.RRE.r2); goto ok;
14531 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14532 ovl.fmt.RRE.r2); goto ok;
14533 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014534 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14535 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14536 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014537 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14538 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14539 goto ok;
14540 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14541 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14542 goto ok;
14543 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14544 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14545 goto ok;
14546 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14547 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14548 goto ok;
14549 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14550 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14551 goto ok;
14552 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14553 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14554 goto ok;
14555 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14556 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14557 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014558 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14559 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14560 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014561 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14562 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14563 goto ok;
14564 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14565 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14566 goto ok;
14567 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14568 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14569 goto ok;
14570 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14571 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14572 goto ok;
14573 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14574 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14575 goto ok;
14576 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14577 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14578 goto ok;
14579 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14580 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14581 goto ok;
14582 }
14583
14584 switch ((ovl.value & 0xff000000) >> 24) {
14585 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14586 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14587 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14588 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14589 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14590 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14591 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14592 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14593 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14594 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14595 case 0x45: /* BAL */ goto unimplemented;
14596 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14597 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14598 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14599 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14600 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14601 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14602 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14603 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14604 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14605 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14606 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14607 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14608 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14609 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14610 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14611 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14612 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14613 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14614 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14615 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14616 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14617 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14618 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14619 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14620 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14621 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14622 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14623 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14624 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14625 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14626 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14627 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14628 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14629 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14630 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14631 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14632 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14633 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14634 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14635 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14636 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14637 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14638 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14639 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14640 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14641 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14642 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14643 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14644 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14645 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14646 case 0x67: /* MXD */ goto unimplemented;
14647 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14648 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14649 case 0x69: /* CD */ goto unimplemented;
14650 case 0x6a: /* AD */ goto unimplemented;
14651 case 0x6b: /* SD */ goto unimplemented;
14652 case 0x6c: /* MD */ goto unimplemented;
14653 case 0x6d: /* DD */ goto unimplemented;
14654 case 0x6e: /* AW */ goto unimplemented;
14655 case 0x6f: /* SW */ goto unimplemented;
14656 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14657 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14658 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14659 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14660 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14661 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14662 case 0x79: /* CE */ goto unimplemented;
14663 case 0x7a: /* AE */ goto unimplemented;
14664 case 0x7b: /* SE */ goto unimplemented;
14665 case 0x7c: /* MDE */ goto unimplemented;
14666 case 0x7d: /* DE */ goto unimplemented;
14667 case 0x7e: /* AU */ goto unimplemented;
14668 case 0x7f: /* SU */ goto unimplemented;
14669 case 0x83: /* DIAG */ goto unimplemented;
14670 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
14671 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14672 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
14673 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14674 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14675 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14676 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14677 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14678 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14679 ovl.fmt.RS.d2); goto ok;
14680 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14681 ovl.fmt.RS.d2); goto ok;
14682 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14683 ovl.fmt.RS.d2); goto ok;
14684 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14685 ovl.fmt.RS.d2); goto ok;
14686 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14687 ovl.fmt.RS.d2); goto ok;
14688 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14689 ovl.fmt.RS.d2); goto ok;
14690 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14691 ovl.fmt.RS.d2); goto ok;
14692 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14693 ovl.fmt.RS.d2); goto ok;
14694 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14695 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14696 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14697 ovl.fmt.SI.d1); goto ok;
14698 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14699 ovl.fmt.SI.d1); goto ok;
14700 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14701 ovl.fmt.SI.d1); goto ok;
14702 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14703 ovl.fmt.SI.d1); goto ok;
14704 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14705 ovl.fmt.SI.d1); goto ok;
14706 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14707 ovl.fmt.SI.d1); goto ok;
14708 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14709 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14710 case 0x99: /* TRACE */ goto unimplemented;
14711 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14712 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14713 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14714 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14715 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
14716 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14717 goto ok;
14718 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
14719 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14720 goto ok;
14721 case 0xac: /* STNSM */ goto unimplemented;
14722 case 0xad: /* STOSM */ goto unimplemented;
14723 case 0xae: /* SIGP */ goto unimplemented;
14724 case 0xaf: /* MC */ goto unimplemented;
14725 case 0xb1: /* LRA */ goto unimplemented;
14726 case 0xb6: /* STCTL */ goto unimplemented;
14727 case 0xb7: /* LCTL */ goto unimplemented;
14728 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14729 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014730 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14731 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014732 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14733 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14734 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14735 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14736 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14737 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14738 }
14739
14740 return S390_DECODE_UNKNOWN_INSN;
14741
14742ok:
14743 return S390_DECODE_OK;
14744
14745unimplemented:
14746 return S390_DECODE_UNIMPLEMENTED_INSN;
14747}
14748
14749static s390_decode_t
14750s390_decode_6byte_and_irgen(UChar *bytes)
14751{
14752 typedef union {
14753 struct {
14754 unsigned int op1 : 8;
14755 unsigned int r1 : 4;
14756 unsigned int r3 : 4;
14757 unsigned int i2 : 16;
14758 unsigned int : 8;
14759 unsigned int op2 : 8;
14760 } RIE;
14761 struct {
14762 unsigned int op1 : 8;
14763 unsigned int r1 : 4;
14764 unsigned int r2 : 4;
14765 unsigned int i3 : 8;
14766 unsigned int i4 : 8;
14767 unsigned int i5 : 8;
14768 unsigned int op2 : 8;
14769 } RIE_RRUUU;
14770 struct {
14771 unsigned int op1 : 8;
14772 unsigned int r1 : 4;
14773 unsigned int : 4;
14774 unsigned int i2 : 16;
14775 unsigned int m3 : 4;
14776 unsigned int : 4;
14777 unsigned int op2 : 8;
14778 } RIEv1;
14779 struct {
14780 unsigned int op1 : 8;
14781 unsigned int r1 : 4;
14782 unsigned int r2 : 4;
14783 unsigned int i4 : 16;
14784 unsigned int m3 : 4;
14785 unsigned int : 4;
14786 unsigned int op2 : 8;
14787 } RIE_RRPU;
14788 struct {
14789 unsigned int op1 : 8;
14790 unsigned int r1 : 4;
14791 unsigned int m3 : 4;
14792 unsigned int i4 : 16;
14793 unsigned int i2 : 8;
14794 unsigned int op2 : 8;
14795 } RIEv3;
14796 struct {
14797 unsigned int op1 : 8;
14798 unsigned int r1 : 4;
14799 unsigned int op2 : 4;
14800 unsigned int i2 : 32;
14801 } RIL;
14802 struct {
14803 unsigned int op1 : 8;
14804 unsigned int r1 : 4;
14805 unsigned int m3 : 4;
14806 unsigned int b4 : 4;
14807 unsigned int d4 : 12;
14808 unsigned int i2 : 8;
14809 unsigned int op2 : 8;
14810 } RIS;
14811 struct {
14812 unsigned int op1 : 8;
14813 unsigned int r1 : 4;
14814 unsigned int r2 : 4;
14815 unsigned int b4 : 4;
14816 unsigned int d4 : 12;
14817 unsigned int m3 : 4;
14818 unsigned int : 4;
14819 unsigned int op2 : 8;
14820 } RRS;
14821 struct {
14822 unsigned int op1 : 8;
14823 unsigned int l1 : 4;
14824 unsigned int : 4;
14825 unsigned int b1 : 4;
14826 unsigned int d1 : 12;
14827 unsigned int : 8;
14828 unsigned int op2 : 8;
14829 } RSL;
14830 struct {
14831 unsigned int op1 : 8;
14832 unsigned int r1 : 4;
14833 unsigned int r3 : 4;
14834 unsigned int b2 : 4;
14835 unsigned int dl2 : 12;
14836 unsigned int dh2 : 8;
14837 unsigned int op2 : 8;
14838 } RSY;
14839 struct {
14840 unsigned int op1 : 8;
14841 unsigned int r1 : 4;
14842 unsigned int x2 : 4;
14843 unsigned int b2 : 4;
14844 unsigned int d2 : 12;
14845 unsigned int : 8;
14846 unsigned int op2 : 8;
14847 } RXE;
14848 struct {
14849 unsigned int op1 : 8;
14850 unsigned int r3 : 4;
14851 unsigned int x2 : 4;
14852 unsigned int b2 : 4;
14853 unsigned int d2 : 12;
14854 unsigned int r1 : 4;
14855 unsigned int : 4;
14856 unsigned int op2 : 8;
14857 } RXF;
14858 struct {
14859 unsigned int op1 : 8;
14860 unsigned int r1 : 4;
14861 unsigned int x2 : 4;
14862 unsigned int b2 : 4;
14863 unsigned int dl2 : 12;
14864 unsigned int dh2 : 8;
14865 unsigned int op2 : 8;
14866 } RXY;
14867 struct {
14868 unsigned int op1 : 8;
14869 unsigned int i2 : 8;
14870 unsigned int b1 : 4;
14871 unsigned int dl1 : 12;
14872 unsigned int dh1 : 8;
14873 unsigned int op2 : 8;
14874 } SIY;
14875 struct {
14876 unsigned int op : 8;
14877 unsigned int l : 8;
14878 unsigned int b1 : 4;
14879 unsigned int d1 : 12;
14880 unsigned int b2 : 4;
14881 unsigned int d2 : 12;
14882 } SS;
14883 struct {
14884 unsigned int op : 8;
14885 unsigned int l1 : 4;
14886 unsigned int l2 : 4;
14887 unsigned int b1 : 4;
14888 unsigned int d1 : 12;
14889 unsigned int b2 : 4;
14890 unsigned int d2 : 12;
14891 } SS_LLRDRD;
14892 struct {
14893 unsigned int op : 8;
14894 unsigned int r1 : 4;
14895 unsigned int r3 : 4;
14896 unsigned int b2 : 4;
14897 unsigned int d2 : 12;
14898 unsigned int b4 : 4;
14899 unsigned int d4 : 12;
14900 } SS_RRRDRD2;
14901 struct {
14902 unsigned int op : 16;
14903 unsigned int b1 : 4;
14904 unsigned int d1 : 12;
14905 unsigned int b2 : 4;
14906 unsigned int d2 : 12;
14907 } SSE;
14908 struct {
14909 unsigned int op1 : 8;
14910 unsigned int r3 : 4;
14911 unsigned int op2 : 4;
14912 unsigned int b1 : 4;
14913 unsigned int d1 : 12;
14914 unsigned int b2 : 4;
14915 unsigned int d2 : 12;
14916 } SSF;
14917 struct {
14918 unsigned int op : 16;
14919 unsigned int b1 : 4;
14920 unsigned int d1 : 12;
14921 unsigned int i2 : 16;
14922 } SIL;
14923 } formats;
14924 union {
14925 formats fmt;
14926 ULong value;
14927 } ovl;
14928
14929 vassert(sizeof(formats) == 6);
14930
florianffbd84d2012-12-09 02:06:29 +000014931 ((UChar *)(&ovl.value))[0] = bytes[0];
14932 ((UChar *)(&ovl.value))[1] = bytes[1];
14933 ((UChar *)(&ovl.value))[2] = bytes[2];
14934 ((UChar *)(&ovl.value))[3] = bytes[3];
14935 ((UChar *)(&ovl.value))[4] = bytes[4];
14936 ((UChar *)(&ovl.value))[5] = bytes[5];
14937 ((UChar *)(&ovl.value))[6] = 0x0;
14938 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000014939
14940 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
14941 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
14942 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14943 ovl.fmt.RXY.dl2,
14944 ovl.fmt.RXY.dh2); goto ok;
14945 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
14946 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
14947 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14948 ovl.fmt.RXY.dl2,
14949 ovl.fmt.RXY.dh2); goto ok;
14950 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
14951 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14952 ovl.fmt.RXY.dl2,
14953 ovl.fmt.RXY.dh2); goto ok;
14954 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
14955 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14956 ovl.fmt.RXY.dl2,
14957 ovl.fmt.RXY.dh2); goto ok;
14958 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
14959 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14960 ovl.fmt.RXY.dl2,
14961 ovl.fmt.RXY.dh2); goto ok;
14962 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, 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 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, 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 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, 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 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, 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;
14978 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
14979 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
14980 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14981 ovl.fmt.RXY.dl2,
14982 ovl.fmt.RXY.dh2); goto ok;
14983 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
14984 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14985 ovl.fmt.RXY.dl2,
14986 ovl.fmt.RXY.dh2); goto ok;
14987 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
14988 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
14989 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14990 ovl.fmt.RXY.dl2,
14991 ovl.fmt.RXY.dh2); goto ok;
14992 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
14993 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14994 ovl.fmt.RXY.dl2,
14995 ovl.fmt.RXY.dh2); goto ok;
14996 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
14997 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14998 ovl.fmt.RXY.dl2,
14999 ovl.fmt.RXY.dh2); goto ok;
15000 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15001 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15002 ovl.fmt.RXY.dl2,
15003 ovl.fmt.RXY.dh2); goto ok;
15004 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15005 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15006 ovl.fmt.RXY.dl2,
15007 ovl.fmt.RXY.dh2); goto ok;
15008 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15009 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15010 ovl.fmt.RXY.dl2,
15011 ovl.fmt.RXY.dh2); goto ok;
15012 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15013 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15014 ovl.fmt.RXY.dl2,
15015 ovl.fmt.RXY.dh2); goto ok;
15016 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15017 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15018 ovl.fmt.RXY.dl2,
15019 ovl.fmt.RXY.dh2); goto ok;
15020 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15021 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15022 ovl.fmt.RXY.dl2,
15023 ovl.fmt.RXY.dh2); goto ok;
15024 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15025 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15026 ovl.fmt.RXY.dl2,
15027 ovl.fmt.RXY.dh2); goto ok;
15028 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15029 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15030 ovl.fmt.RXY.dl2,
15031 ovl.fmt.RXY.dh2); goto ok;
15032 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15033 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15034 ovl.fmt.RXY.dl2,
15035 ovl.fmt.RXY.dh2); goto ok;
15036 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15037 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15038 ovl.fmt.RXY.dl2,
15039 ovl.fmt.RXY.dh2); goto ok;
15040 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15041 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15042 ovl.fmt.RXY.dl2,
15043 ovl.fmt.RXY.dh2); goto ok;
15044 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15045 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15046 ovl.fmt.RXY.dl2,
15047 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015048 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015049 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15050 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15051 ovl.fmt.RXY.dl2,
15052 ovl.fmt.RXY.dh2); goto ok;
15053 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15054 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15055 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15056 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15057 ovl.fmt.RXY.dh2); goto ok;
15058 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15059 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15060 ovl.fmt.RXY.dl2,
15061 ovl.fmt.RXY.dh2); goto ok;
15062 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15063 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15064 ovl.fmt.RXY.dl2,
15065 ovl.fmt.RXY.dh2); goto ok;
15066 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15067 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15068 ovl.fmt.RXY.dl2,
15069 ovl.fmt.RXY.dh2); goto ok;
15070 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15071 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15072 ovl.fmt.RXY.dl2,
15073 ovl.fmt.RXY.dh2); goto ok;
15074 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15075 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15076 ovl.fmt.RXY.dl2,
15077 ovl.fmt.RXY.dh2); goto ok;
15078 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15079 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15080 ovl.fmt.RXY.dl2,
15081 ovl.fmt.RXY.dh2); goto ok;
15082 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15083 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15084 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15085 ovl.fmt.RXY.dh2); goto ok;
15086 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15087 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15088 ovl.fmt.RXY.dl2,
15089 ovl.fmt.RXY.dh2); goto ok;
15090 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15091 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15092 ovl.fmt.RXY.dl2,
15093 ovl.fmt.RXY.dh2); goto ok;
15094 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15095 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15096 ovl.fmt.RXY.dl2,
15097 ovl.fmt.RXY.dh2); goto ok;
15098 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15099 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15100 ovl.fmt.RXY.dl2,
15101 ovl.fmt.RXY.dh2); goto ok;
15102 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15103 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15104 ovl.fmt.RXY.dl2,
15105 ovl.fmt.RXY.dh2); goto ok;
15106 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15107 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15108 ovl.fmt.RXY.dl2,
15109 ovl.fmt.RXY.dh2); goto ok;
15110 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15111 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15112 ovl.fmt.RXY.dl2,
15113 ovl.fmt.RXY.dh2); goto ok;
15114 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15115 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15116 ovl.fmt.RXY.dl2,
15117 ovl.fmt.RXY.dh2); goto ok;
15118 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15119 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15120 ovl.fmt.RXY.dl2,
15121 ovl.fmt.RXY.dh2); goto ok;
15122 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15123 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15124 ovl.fmt.RXY.dl2,
15125 ovl.fmt.RXY.dh2); goto ok;
15126 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15127 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15128 ovl.fmt.RXY.dl2,
15129 ovl.fmt.RXY.dh2); goto ok;
15130 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15131 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15132 ovl.fmt.RXY.dl2,
15133 ovl.fmt.RXY.dh2); goto ok;
15134 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15135 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15136 ovl.fmt.RXY.dl2,
15137 ovl.fmt.RXY.dh2); goto ok;
15138 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15139 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15140 ovl.fmt.RXY.dl2,
15141 ovl.fmt.RXY.dh2); goto ok;
15142 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15143 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15144 ovl.fmt.RXY.dl2,
15145 ovl.fmt.RXY.dh2); goto ok;
15146 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15147 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15148 ovl.fmt.RXY.dl2,
15149 ovl.fmt.RXY.dh2); goto ok;
15150 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15151 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15152 ovl.fmt.RXY.dl2,
15153 ovl.fmt.RXY.dh2); goto ok;
15154 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15155 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15156 ovl.fmt.RXY.dl2,
15157 ovl.fmt.RXY.dh2); goto ok;
15158 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15159 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15160 ovl.fmt.RXY.dl2,
15161 ovl.fmt.RXY.dh2); goto ok;
15162 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15163 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15164 ovl.fmt.RXY.dl2,
15165 ovl.fmt.RXY.dh2); goto ok;
15166 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15167 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15168 ovl.fmt.RXY.dl2,
15169 ovl.fmt.RXY.dh2); goto ok;
15170 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15171 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15172 ovl.fmt.RXY.dl2,
15173 ovl.fmt.RXY.dh2); goto ok;
15174 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15175 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15176 ovl.fmt.RXY.dl2,
15177 ovl.fmt.RXY.dh2); goto ok;
15178 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15179 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15180 ovl.fmt.RXY.dl2,
15181 ovl.fmt.RXY.dh2); goto ok;
15182 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15183 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15184 ovl.fmt.RXY.dl2,
15185 ovl.fmt.RXY.dh2); goto ok;
15186 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15187 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15188 ovl.fmt.RXY.dl2,
15189 ovl.fmt.RXY.dh2); goto ok;
15190 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15191 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15192 ovl.fmt.RXY.dl2,
15193 ovl.fmt.RXY.dh2); goto ok;
15194 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15195 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15196 ovl.fmt.RXY.dl2,
15197 ovl.fmt.RXY.dh2); goto ok;
15198 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15199 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15200 ovl.fmt.RXY.dl2,
15201 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015202 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015203 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15204 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15205 ovl.fmt.RXY.dl2,
15206 ovl.fmt.RXY.dh2); goto ok;
15207 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15208 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15209 ovl.fmt.RXY.dl2,
15210 ovl.fmt.RXY.dh2); goto ok;
15211 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15212 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15213 ovl.fmt.RXY.dl2,
15214 ovl.fmt.RXY.dh2); goto ok;
15215 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15216 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15217 ovl.fmt.RXY.dl2,
15218 ovl.fmt.RXY.dh2); goto ok;
15219 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15220 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15221 ovl.fmt.RXY.dl2,
15222 ovl.fmt.RXY.dh2); goto ok;
15223 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15224 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15225 ovl.fmt.RXY.dl2,
15226 ovl.fmt.RXY.dh2); goto ok;
15227 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15228 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15229 ovl.fmt.RXY.dl2,
15230 ovl.fmt.RXY.dh2); goto ok;
15231 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15232 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15233 ovl.fmt.RXY.dl2,
15234 ovl.fmt.RXY.dh2); goto ok;
15235 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15236 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15237 ovl.fmt.RXY.dl2,
15238 ovl.fmt.RXY.dh2); goto ok;
15239 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15240 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15241 ovl.fmt.RXY.dl2,
15242 ovl.fmt.RXY.dh2); goto ok;
15243 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15244 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15245 ovl.fmt.RXY.dl2,
15246 ovl.fmt.RXY.dh2); goto ok;
15247 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15248 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15249 ovl.fmt.RXY.dl2,
15250 ovl.fmt.RXY.dh2); goto ok;
15251 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15252 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15253 ovl.fmt.RXY.dl2,
15254 ovl.fmt.RXY.dh2); goto ok;
15255 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15256 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15257 ovl.fmt.RXY.dl2,
15258 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015259 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15260 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15261 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015262 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15263 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15264 ovl.fmt.RXY.dl2,
15265 ovl.fmt.RXY.dh2); goto ok;
15266 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15267 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15268 ovl.fmt.RXY.dl2,
15269 ovl.fmt.RXY.dh2); goto ok;
15270 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15271 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15272 ovl.fmt.RXY.dl2,
15273 ovl.fmt.RXY.dh2); goto ok;
15274 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15275 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15276 ovl.fmt.RXY.dl2,
15277 ovl.fmt.RXY.dh2); goto ok;
15278 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15279 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15280 ovl.fmt.RXY.dl2,
15281 ovl.fmt.RXY.dh2); goto ok;
15282 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15283 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15284 ovl.fmt.RXY.dl2,
15285 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015286 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015287 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15288 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15289 ovl.fmt.RXY.dl2,
15290 ovl.fmt.RXY.dh2); goto ok;
15291 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15292 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15293 ovl.fmt.RXY.dl2,
15294 ovl.fmt.RXY.dh2); goto ok;
15295 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15296 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15297 ovl.fmt.RXY.dl2,
15298 ovl.fmt.RXY.dh2); goto ok;
15299 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15300 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15301 ovl.fmt.RXY.dl2,
15302 ovl.fmt.RXY.dh2); goto ok;
15303 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15304 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15305 ovl.fmt.RSY.dl2,
15306 ovl.fmt.RSY.dh2); goto ok;
15307 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15308 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15309 ovl.fmt.RSY.dl2,
15310 ovl.fmt.RSY.dh2); goto ok;
15311 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15312 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15313 ovl.fmt.RSY.dl2,
15314 ovl.fmt.RSY.dh2); goto ok;
15315 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15316 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15317 ovl.fmt.RSY.dl2,
15318 ovl.fmt.RSY.dh2); goto ok;
15319 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15320 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15321 ovl.fmt.RSY.dl2,
15322 ovl.fmt.RSY.dh2); goto ok;
15323 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15324 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15325 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15326 ovl.fmt.RSY.dl2,
15327 ovl.fmt.RSY.dh2); goto ok;
15328 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15329 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15330 ovl.fmt.RSY.dl2,
15331 ovl.fmt.RSY.dh2); goto ok;
15332 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15333 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15334 ovl.fmt.RSY.dl2,
15335 ovl.fmt.RSY.dh2); goto ok;
15336 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15337 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15338 ovl.fmt.RSY.dl2,
15339 ovl.fmt.RSY.dh2); goto ok;
15340 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15341 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15342 ovl.fmt.RSY.dl2,
15343 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015344 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015345 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15346 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15347 ovl.fmt.RSY.dl2,
15348 ovl.fmt.RSY.dh2); goto ok;
15349 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15350 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15351 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15352 ovl.fmt.RSY.dl2,
15353 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015354 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015355 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15356 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15357 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15358 ovl.fmt.RSY.dh2); goto ok;
15359 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15360 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15361 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15362 ovl.fmt.RSY.dh2); goto ok;
15363 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15364 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15365 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15366 ovl.fmt.RSY.dl2,
15367 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015368 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15369 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15370 ovl.fmt.RSY.dl2,
15371 ovl.fmt.RSY.dh2); goto ok;
15372 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15373 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15374 ovl.fmt.RSY.dl2,
15375 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015376 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15377 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15378 ovl.fmt.RSY.dl2,
15379 ovl.fmt.RSY.dh2); goto ok;
15380 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15381 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15382 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15383 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015384 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15385 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15386 ovl.fmt.RSY.dl2,
15387 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015388 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15389 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15390 ovl.fmt.SIY.dh1); goto ok;
15391 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15392 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15393 ovl.fmt.SIY.dh1); goto ok;
15394 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15395 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15396 ovl.fmt.SIY.dh1); goto ok;
15397 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15398 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15399 ovl.fmt.SIY.dh1); goto ok;
15400 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15401 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15402 ovl.fmt.SIY.dh1); goto ok;
15403 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15404 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15405 ovl.fmt.SIY.dh1); goto ok;
15406 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15407 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15408 ovl.fmt.SIY.dh1); goto ok;
15409 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15410 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15411 ovl.fmt.SIY.dh1); goto ok;
15412 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15413 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15414 ovl.fmt.SIY.dh1); goto ok;
15415 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15416 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15417 ovl.fmt.SIY.dh1); goto ok;
15418 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15419 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15420 ovl.fmt.RSY.dl2,
15421 ovl.fmt.RSY.dh2); goto ok;
15422 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15423 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15424 ovl.fmt.RSY.dl2,
15425 ovl.fmt.RSY.dh2); goto ok;
15426 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15427 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15428 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15429 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15430 ovl.fmt.RSY.dl2,
15431 ovl.fmt.RSY.dh2); goto ok;
15432 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15433 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15434 ovl.fmt.RSY.dl2,
15435 ovl.fmt.RSY.dh2); goto ok;
15436 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15437 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15438 ovl.fmt.RSY.dl2,
15439 ovl.fmt.RSY.dh2); goto ok;
15440 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15441 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15442 ovl.fmt.RSY.dl2,
15443 ovl.fmt.RSY.dh2); goto ok;
15444 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15445 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15446 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15447 ovl.fmt.RSY.dh2); goto ok;
15448 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15449 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15450 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15451 ovl.fmt.RSY.dl2,
15452 ovl.fmt.RSY.dh2); goto ok;
15453 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15454 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15455 ovl.fmt.RSY.dl2,
15456 ovl.fmt.RSY.dh2); goto ok;
15457 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15458 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15459 ovl.fmt.RSY.dl2,
15460 ovl.fmt.RSY.dh2); goto ok;
15461 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15462 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15463 ovl.fmt.RSY.dl2,
15464 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015465 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15466 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15467 ovl.fmt.RSY.dl2,
15468 ovl.fmt.RSY.dh2,
15469 S390_XMNM_LOCG); goto ok;
15470 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15471 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15472 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15473 ovl.fmt.RSY.dh2,
15474 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015475 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15476 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15477 ovl.fmt.RSY.dl2,
15478 ovl.fmt.RSY.dh2); goto ok;
15479 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15480 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15481 ovl.fmt.RSY.dl2,
15482 ovl.fmt.RSY.dh2); goto ok;
15483 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15484 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15485 ovl.fmt.RSY.dl2,
15486 ovl.fmt.RSY.dh2); goto ok;
15487 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15488 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15489 ovl.fmt.RSY.dl2,
15490 ovl.fmt.RSY.dh2); goto ok;
15491 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15492 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15493 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15494 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015495 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15496 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15497 ovl.fmt.RSY.dl2,
15498 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15499 goto ok;
15500 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15501 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15502 ovl.fmt.RSY.dl2,
15503 ovl.fmt.RSY.dh2,
15504 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015505 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15506 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15507 ovl.fmt.RSY.dl2,
15508 ovl.fmt.RSY.dh2); goto ok;
15509 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15510 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15511 ovl.fmt.RSY.dl2,
15512 ovl.fmt.RSY.dh2); goto ok;
15513 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15514 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15515 ovl.fmt.RSY.dl2,
15516 ovl.fmt.RSY.dh2); goto ok;
15517 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15518 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15519 ovl.fmt.RSY.dl2,
15520 ovl.fmt.RSY.dh2); goto ok;
15521 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15522 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15523 ovl.fmt.RSY.dl2,
15524 ovl.fmt.RSY.dh2); goto ok;
15525 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15526 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15527 goto ok;
15528 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15529 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15530 goto ok;
15531 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15532 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15533 ovl.fmt.RIE_RRUUU.r1,
15534 ovl.fmt.RIE_RRUUU.r2,
15535 ovl.fmt.RIE_RRUUU.i3,
15536 ovl.fmt.RIE_RRUUU.i4,
15537 ovl.fmt.RIE_RRUUU.i5);
15538 goto ok;
15539 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15540 ovl.fmt.RIE_RRUUU.r1,
15541 ovl.fmt.RIE_RRUUU.r2,
15542 ovl.fmt.RIE_RRUUU.i3,
15543 ovl.fmt.RIE_RRUUU.i4,
15544 ovl.fmt.RIE_RRUUU.i5);
15545 goto ok;
15546 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15547 ovl.fmt.RIE_RRUUU.r1,
15548 ovl.fmt.RIE_RRUUU.r2,
15549 ovl.fmt.RIE_RRUUU.i3,
15550 ovl.fmt.RIE_RRUUU.i4,
15551 ovl.fmt.RIE_RRUUU.i5);
15552 goto ok;
15553 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15554 ovl.fmt.RIE_RRUUU.r1,
15555 ovl.fmt.RIE_RRUUU.r2,
15556 ovl.fmt.RIE_RRUUU.i3,
15557 ovl.fmt.RIE_RRUUU.i4,
15558 ovl.fmt.RIE_RRUUU.i5);
15559 goto ok;
florian2289cd42012-12-05 04:23:42 +000015560 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015561 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15562 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15563 ovl.fmt.RIE_RRPU.r1,
15564 ovl.fmt.RIE_RRPU.r2,
15565 ovl.fmt.RIE_RRPU.i4,
15566 ovl.fmt.RIE_RRPU.m3); goto ok;
15567 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15568 ovl.fmt.RIE_RRPU.r1,
15569 ovl.fmt.RIE_RRPU.r2,
15570 ovl.fmt.RIE_RRPU.i4,
15571 ovl.fmt.RIE_RRPU.m3); goto ok;
15572 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15573 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15574 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15575 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15576 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15577 ovl.fmt.RIE_RRPU.r1,
15578 ovl.fmt.RIE_RRPU.r2,
15579 ovl.fmt.RIE_RRPU.i4,
15580 ovl.fmt.RIE_RRPU.m3); goto ok;
15581 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15582 ovl.fmt.RIE_RRPU.r1,
15583 ovl.fmt.RIE_RRPU.r2,
15584 ovl.fmt.RIE_RRPU.i4,
15585 ovl.fmt.RIE_RRPU.m3); goto ok;
15586 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15587 ovl.fmt.RIEv3.r1,
15588 ovl.fmt.RIEv3.m3,
15589 ovl.fmt.RIEv3.i4,
15590 ovl.fmt.RIEv3.i2); goto ok;
15591 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15592 ovl.fmt.RIEv3.r1,
15593 ovl.fmt.RIEv3.m3,
15594 ovl.fmt.RIEv3.i4,
15595 ovl.fmt.RIEv3.i2); goto ok;
15596 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15597 ovl.fmt.RIEv3.r1,
15598 ovl.fmt.RIEv3.m3,
15599 ovl.fmt.RIEv3.i4,
15600 ovl.fmt.RIEv3.i2); goto ok;
15601 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15602 ovl.fmt.RIEv3.r1,
15603 ovl.fmt.RIEv3.m3,
15604 ovl.fmt.RIEv3.i4,
15605 ovl.fmt.RIEv3.i2); goto ok;
15606 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15607 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15608 goto ok;
15609 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15610 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15611 ovl.fmt.RIE.i2); goto ok;
15612 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15613 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15614 ovl.fmt.RIE.i2); goto ok;
15615 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15616 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15617 ovl.fmt.RIE.i2); goto ok;
15618 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15619 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15620 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15621 goto ok;
15622 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15623 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15624 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15625 goto ok;
15626 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15627 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15628 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15629 goto ok;
15630 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15631 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15632 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15633 goto ok;
15634 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15635 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15636 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15637 ovl.fmt.RIS.i2); goto ok;
15638 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15639 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15640 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15641 ovl.fmt.RIS.i2); goto ok;
15642 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15643 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15644 ovl.fmt.RIS.d4,
15645 ovl.fmt.RIS.i2); goto ok;
15646 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15647 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15648 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15649 ovl.fmt.RIS.i2); goto ok;
15650 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15651 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15652 ovl.fmt.RXE.d2); goto ok;
15653 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15654 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15655 ovl.fmt.RXE.d2); goto ok;
15656 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15657 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15658 ovl.fmt.RXE.d2); goto ok;
15659 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15660 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15661 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15662 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15663 ovl.fmt.RXE.d2); goto ok;
15664 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15665 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15666 ovl.fmt.RXE.d2); goto ok;
15667 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
15668 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15669 ovl.fmt.RXE.d2); goto ok;
15670 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
15671 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
15672 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15673 ovl.fmt.RXE.d2); goto ok;
15674 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
15675 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15676 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15677 ovl.fmt.RXF.r1); goto ok;
15678 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
15679 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15680 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15681 ovl.fmt.RXF.r1); goto ok;
15682 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
15683 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15684 ovl.fmt.RXE.d2); goto ok;
15685 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
15686 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15687 ovl.fmt.RXE.d2); goto ok;
15688 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
15689 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15690 ovl.fmt.RXE.d2); goto ok;
15691 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
15692 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15693 ovl.fmt.RXE.d2); goto ok;
15694 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
15695 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15696 ovl.fmt.RXE.d2); goto ok;
15697 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
15698 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15699 ovl.fmt.RXE.d2); goto ok;
15700 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
15701 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
15702 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15703 ovl.fmt.RXE.d2); goto ok;
15704 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
15705 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15706 ovl.fmt.RXE.d2); goto ok;
15707 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
15708 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15709 ovl.fmt.RXE.d2); goto ok;
15710 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
15711 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15712 ovl.fmt.RXE.d2); goto ok;
15713 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
15714 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15715 ovl.fmt.RXE.d2); goto ok;
15716 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
15717 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15718 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15719 ovl.fmt.RXF.r1); goto ok;
15720 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
15721 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15722 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15723 ovl.fmt.RXF.r1); goto ok;
15724 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
15725 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
15726 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
15727 case 0xed000000002eULL: /* MAE */ goto unimplemented;
15728 case 0xed000000002fULL: /* MSE */ goto unimplemented;
15729 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
15730 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
15731 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
15732 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
15733 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
15734 case 0xed000000003aULL: /* MAY */ goto unimplemented;
15735 case 0xed000000003bULL: /* MY */ goto unimplemented;
15736 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
15737 case 0xed000000003dULL: /* MYH */ goto unimplemented;
15738 case 0xed000000003eULL: /* MAD */ goto unimplemented;
15739 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000015740 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
15741 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15742 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15743 ovl.fmt.RXF.r1); goto ok;
15744 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
15745 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15746 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15747 ovl.fmt.RXF.r1); goto ok;
15748 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
15749 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15750 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15751 ovl.fmt.RXF.r1); goto ok;
15752 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
15753 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15754 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15755 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000015756 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
15757 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15758 ovl.fmt.RXE.d2); goto ok;
15759 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
15760 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15761 ovl.fmt.RXE.d2); goto ok;
15762 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
15763 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15764 ovl.fmt.RXE.d2); goto ok;
15765 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
15766 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15767 ovl.fmt.RXE.d2); goto ok;
15768 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
15769 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15770 ovl.fmt.RXE.d2); goto ok;
15771 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
15772 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15773 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015774 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
15775 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15776 ovl.fmt.RXY.dl2,
15777 ovl.fmt.RXY.dh2); goto ok;
15778 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
15779 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15780 ovl.fmt.RXY.dl2,
15781 ovl.fmt.RXY.dh2); goto ok;
15782 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
15783 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15784 ovl.fmt.RXY.dl2,
15785 ovl.fmt.RXY.dh2); goto ok;
15786 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
15787 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15788 ovl.fmt.RXY.dl2,
15789 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015790 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
15791 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
15792 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
15793 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015794 }
15795
15796 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
15797 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
15798 ovl.fmt.RIL.i2); goto ok;
15799 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
15800 ovl.fmt.RIL.i2); goto ok;
15801 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
15802 ovl.fmt.RIL.i2); goto ok;
15803 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
15804 ovl.fmt.RIL.i2); goto ok;
15805 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
15806 ovl.fmt.RIL.i2); goto ok;
15807 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
15808 ovl.fmt.RIL.i2); goto ok;
15809 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
15810 ovl.fmt.RIL.i2); goto ok;
15811 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
15812 ovl.fmt.RIL.i2); goto ok;
15813 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
15814 ovl.fmt.RIL.i2); goto ok;
15815 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
15816 ovl.fmt.RIL.i2); goto ok;
15817 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
15818 ovl.fmt.RIL.i2); goto ok;
15819 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
15820 ovl.fmt.RIL.i2); goto ok;
15821 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
15822 ovl.fmt.RIL.i2); goto ok;
15823 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
15824 ovl.fmt.RIL.i2); goto ok;
15825 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
15826 ovl.fmt.RIL.i2); goto ok;
15827 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
15828 ovl.fmt.RIL.i2); goto ok;
15829 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
15830 ovl.fmt.RIL.i2); goto ok;
15831 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
15832 ovl.fmt.RIL.i2); goto ok;
15833 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
15834 ovl.fmt.RIL.i2); goto ok;
15835 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
15836 ovl.fmt.RIL.i2); goto ok;
15837 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
15838 ovl.fmt.RIL.i2); goto ok;
15839 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
15840 ovl.fmt.RIL.i2); goto ok;
15841 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
15842 ovl.fmt.RIL.i2); goto ok;
15843 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
15844 ovl.fmt.RIL.i2); goto ok;
15845 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
15846 ovl.fmt.RIL.i2); goto ok;
15847 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
15848 ovl.fmt.RIL.i2); goto ok;
15849 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
15850 ovl.fmt.RIL.i2); goto ok;
15851 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
15852 ovl.fmt.RIL.i2); goto ok;
15853 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
15854 ovl.fmt.RIL.i2); goto ok;
15855 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
15856 ovl.fmt.RIL.i2); goto ok;
15857 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
15858 ovl.fmt.RIL.i2); goto ok;
15859 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
15860 ovl.fmt.RIL.i2); goto ok;
15861 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
15862 ovl.fmt.RIL.i2); goto ok;
15863 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
15864 ovl.fmt.RIL.i2); goto ok;
15865 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
15866 ovl.fmt.RIL.i2); goto ok;
15867 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
15868 ovl.fmt.RIL.i2); goto ok;
15869 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
15870 ovl.fmt.RIL.i2); goto ok;
15871 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
15872 ovl.fmt.RIL.i2); goto ok;
15873 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
15874 ovl.fmt.RIL.i2); goto ok;
15875 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
15876 ovl.fmt.RIL.i2); goto ok;
15877 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
15878 ovl.fmt.RIL.i2); goto ok;
15879 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
15880 ovl.fmt.RIL.i2); goto ok;
15881 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
15882 ovl.fmt.RIL.i2); goto ok;
15883 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
15884 ovl.fmt.RIL.i2); goto ok;
15885 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
15886 ovl.fmt.RIL.i2); goto ok;
15887 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
15888 ovl.fmt.RIL.i2); goto ok;
15889 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
15890 ovl.fmt.RIL.i2); goto ok;
15891 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
15892 ovl.fmt.RIL.i2); goto ok;
15893 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
15894 ovl.fmt.RIL.i2); goto ok;
15895 case 0xc800ULL: /* MVCOS */ goto unimplemented;
15896 case 0xc801ULL: /* ECTG */ goto unimplemented;
15897 case 0xc802ULL: /* CSST */ goto unimplemented;
15898 case 0xc804ULL: /* LPD */ goto unimplemented;
15899 case 0xc805ULL: /* LPDG */ goto unimplemented;
15900 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
15901 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
15902 ovl.fmt.RIL.i2); goto ok;
15903 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
15904 ovl.fmt.RIL.i2); goto ok;
15905 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
15906 ovl.fmt.RIL.i2); goto ok;
15907 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
15908 ovl.fmt.RIL.i2); goto ok;
15909 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
15910 ovl.fmt.RIL.i2); goto ok;
15911 }
15912
15913 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000015914 case 0xc5ULL: /* BPRP */ goto unimplemented;
15915 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015916 case 0xd0ULL: /* TRTR */ goto unimplemented;
15917 case 0xd1ULL: /* MVN */ goto unimplemented;
15918 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
15919 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15920 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15921 case 0xd3ULL: /* MVZ */ goto unimplemented;
15922 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
15923 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15924 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15925 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
15926 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15927 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15928 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
15929 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15930 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000015931 case 0xd7ULL:
15932 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
15933 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
15934 else
15935 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
15936 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15937 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
15938 goto ok;
sewardj2019a972011-03-07 16:04:07 +000015939 case 0xd9ULL: /* MVCK */ goto unimplemented;
15940 case 0xdaULL: /* MVCP */ goto unimplemented;
15941 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015942 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
15943 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15944 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015945 case 0xddULL: /* TRT */ goto unimplemented;
15946 case 0xdeULL: /* ED */ goto unimplemented;
15947 case 0xdfULL: /* EDMK */ goto unimplemented;
15948 case 0xe1ULL: /* PKU */ goto unimplemented;
15949 case 0xe2ULL: /* UNPKU */ goto unimplemented;
15950 case 0xe8ULL: /* MVCIN */ goto unimplemented;
15951 case 0xe9ULL: /* PKA */ goto unimplemented;
15952 case 0xeaULL: /* UNPKA */ goto unimplemented;
15953 case 0xeeULL: /* PLO */ goto unimplemented;
15954 case 0xefULL: /* LMD */ goto unimplemented;
15955 case 0xf0ULL: /* SRP */ goto unimplemented;
15956 case 0xf1ULL: /* MVO */ goto unimplemented;
15957 case 0xf2ULL: /* PACK */ goto unimplemented;
15958 case 0xf3ULL: /* UNPK */ goto unimplemented;
15959 case 0xf8ULL: /* ZAP */ goto unimplemented;
15960 case 0xf9ULL: /* CP */ goto unimplemented;
15961 case 0xfaULL: /* AP */ goto unimplemented;
15962 case 0xfbULL: /* SP */ goto unimplemented;
15963 case 0xfcULL: /* MP */ goto unimplemented;
15964 case 0xfdULL: /* DP */ goto unimplemented;
15965 }
15966
15967 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
15968 case 0xe500ULL: /* LASP */ goto unimplemented;
15969 case 0xe501ULL: /* TPROT */ goto unimplemented;
15970 case 0xe502ULL: /* STRAG */ goto unimplemented;
15971 case 0xe50eULL: /* MVCSK */ goto unimplemented;
15972 case 0xe50fULL: /* MVCDK */ goto unimplemented;
15973 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
15974 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15975 goto ok;
15976 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
15977 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15978 goto ok;
15979 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
15980 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15981 goto ok;
15982 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
15983 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15984 goto ok;
15985 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
15986 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15987 goto ok;
15988 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
15989 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15990 goto ok;
15991 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
15992 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15993 goto ok;
15994 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
15995 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15996 goto ok;
15997 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
15998 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15999 goto ok;
florian2289cd42012-12-05 04:23:42 +000016000 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16001 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016002 }
16003
16004 return S390_DECODE_UNKNOWN_INSN;
16005
16006ok:
16007 return S390_DECODE_OK;
16008
16009unimplemented:
16010 return S390_DECODE_UNIMPLEMENTED_INSN;
16011}
16012
16013/* Handle "special" instructions. */
16014static s390_decode_t
16015s390_decode_special_and_irgen(UChar *bytes)
16016{
16017 s390_decode_t status = S390_DECODE_OK;
16018
16019 /* Got a "Special" instruction preamble. Which one is it? */
16020 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16021 s390_irgen_client_request();
16022 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16023 s390_irgen_guest_NRADDR();
16024 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16025 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016026 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16027 vex_inject_ir(irsb, Iend_BE);
16028
16029 /* Invalidate the current insn. The reason is that the IRop we're
16030 injecting here can change. In which case the translation has to
16031 be redone. For ease of handling, we simply invalidate all the
16032 time. */
16033 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
16034 mkU64(guest_IA_curr_instr)));
16035 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
16036 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16037 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16038 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16039
16040 put_IA(mkaddr_expr(guest_IA_next_instr));
16041 dis_res->whatNext = Dis_StopHere;
16042 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000016043 } else {
16044 /* We don't know what it is. */
16045 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16046 }
16047
16048 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16049
16050 return status;
16051}
16052
16053
16054/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016055static UInt
sewardj2019a972011-03-07 16:04:07 +000016056s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
16057{
16058 s390_decode_t status;
16059
16060 dis_res = dres;
16061
16062 /* Spot the 8-byte preamble: 18ff lr r15,r15
16063 1811 lr r1,r1
16064 1822 lr r2,r2
16065 1833 lr r3,r3 */
16066 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16067 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16068 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16069
16070 /* Handle special instruction that follows that preamble. */
16071 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016072
16073 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16074 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16075
16076 status =
16077 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016078 } else {
16079 /* Handle normal instructions. */
16080 switch (insn_length) {
16081 case 2:
16082 status = s390_decode_2byte_and_irgen(bytes);
16083 break;
16084
16085 case 4:
16086 status = s390_decode_4byte_and_irgen(bytes);
16087 break;
16088
16089 case 6:
16090 status = s390_decode_6byte_and_irgen(bytes);
16091 break;
16092
16093 default:
16094 status = S390_DECODE_ERROR;
16095 break;
16096 }
16097 }
florian5fcbba22011-07-27 20:40:22 +000016098 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016099 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16100 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016101 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016102 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016103 }
16104
16105 if (status == S390_DECODE_OK) return insn_length; /* OK */
16106
16107 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016108 if (sigill_diag) {
16109 vex_printf("vex s390->IR: ");
16110 switch (status) {
16111 case S390_DECODE_UNKNOWN_INSN:
16112 vex_printf("unknown insn: ");
16113 break;
sewardj2019a972011-03-07 16:04:07 +000016114
sewardj442e51a2012-12-06 18:08:04 +000016115 case S390_DECODE_UNIMPLEMENTED_INSN:
16116 vex_printf("unimplemented insn: ");
16117 break;
sewardj2019a972011-03-07 16:04:07 +000016118
sewardj442e51a2012-12-06 18:08:04 +000016119 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16120 vex_printf("unimplemented special insn: ");
16121 break;
sewardj2019a972011-03-07 16:04:07 +000016122
sewardj442e51a2012-12-06 18:08:04 +000016123 default:
16124 case S390_DECODE_ERROR:
16125 vex_printf("decoding error: ");
16126 break;
16127 }
16128
16129 vex_printf("%02x%02x", bytes[0], bytes[1]);
16130 if (insn_length > 2) {
16131 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16132 }
16133 if (insn_length > 4) {
16134 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16135 }
16136 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016137 }
16138
sewardj2019a972011-03-07 16:04:07 +000016139 return 0; /* Failed */
16140}
16141
16142
sewardj2019a972011-03-07 16:04:07 +000016143/* Disassemble a single instruction INSN into IR. */
16144static DisResult
florian420c5012011-07-22 02:12:28 +000016145disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016146{
16147 UChar byte;
16148 UInt insn_length;
16149 DisResult dres;
16150
16151 /* ---------------------------------------------------- */
16152 /* --- Compute instruction length -- */
16153 /* ---------------------------------------------------- */
16154
16155 /* Get the first byte of the insn. */
16156 byte = insn[0];
16157
16158 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16159 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16160 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16161
16162 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16163
16164 /* ---------------------------------------------------- */
16165 /* --- Initialise the DisResult data -- */
16166 /* ---------------------------------------------------- */
16167 dres.whatNext = Dis_Continue;
16168 dres.len = insn_length;
16169 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016170 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000016171
floriana99f20e2011-07-17 14:16:41 +000016172 /* fixs390: consider chasing of conditional jumps */
16173
sewardj2019a972011-03-07 16:04:07 +000016174 /* Normal and special instruction handling starts here. */
16175 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16176 /* All decode failures end up here. The decoder has already issued an
16177 error message.
16178 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016179 not been executed, and (is currently) the next to be executed.
16180 The insn address in the guest state needs to be set to
16181 guest_IA_curr_instr, otherwise the complaint will report an
16182 incorrect address. */
16183 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016184
florian8844a632012-04-13 04:04:06 +000016185 dres.whatNext = Dis_StopHere;
16186 dres.jk_StopHere = Ijk_NoDecode;
16187 dres.continueAt = 0;
16188 dres.len = 0;
16189 } else {
16190 /* Decode success */
16191 switch (dres.whatNext) {
16192 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016193 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016194 break;
16195 case Dis_ResteerU:
16196 case Dis_ResteerC:
16197 put_IA(mkaddr_expr(dres.continueAt));
16198 break;
16199 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016200 if (dres.jk_StopHere == Ijk_EmWarn ||
16201 dres.jk_StopHere == Ijk_EmFail) {
16202 /* We assume here, that emulation warnings are not given for
16203 insns that transfer control. There is no good way to
16204 do that. */
16205 put_IA(mkaddr_expr(guest_IA_next_instr));
16206 }
florian8844a632012-04-13 04:04:06 +000016207 break;
16208 default:
16209 vassert(0);
16210 }
sewardj2019a972011-03-07 16:04:07 +000016211 }
16212
16213 return dres;
16214}
16215
16216
16217/*------------------------------------------------------------*/
16218/*--- Top-level fn ---*/
16219/*------------------------------------------------------------*/
16220
16221/* Disassemble a single instruction into IR. The instruction
16222 is located in host memory at &guest_code[delta]. */
16223
16224DisResult
16225disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000016226 Bool (*resteerOkFn)(void *, Addr64),
16227 Bool resteerCisOk,
16228 void *callback_opaque,
16229 UChar *guest_code,
16230 Long delta,
16231 Addr64 guest_IP,
16232 VexArch guest_arch,
16233 VexArchInfo *archinfo,
16234 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000016235 Bool host_bigendian,
16236 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016237{
16238 vassert(guest_arch == VexArchS390X);
16239
16240 /* The instruction decoder requires a big-endian machine. */
16241 vassert(host_bigendian == True);
16242
16243 /* Set globals (see top of this file) */
16244 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016245 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016246 resteer_fn = resteerOkFn;
16247 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016248 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016249
florian420c5012011-07-22 02:12:28 +000016250 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016251}
16252
16253/*---------------------------------------------------------------*/
16254/*--- end guest_s390_toIR.c ---*/
16255/*---------------------------------------------------------------*/