blob: 750250b935dad08d9e833b5d5ce9f855b917ebdb [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
243 return IRExpr_Mux0X(unop(Iop_1Uto8, condition), iffalse, iftrue);
244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
635 op = mkU64(opc);
636 dep1 = mkexpr(d1);
637 dep2 = mkU64(0);
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, dep1, dep2, ndep);
641}
642
643
644/* Write a floating point value and an integer into the flags thunk. The
645 integer value is zero-extended first. */
646static void
647s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
648{
649 IRExpr *op, *dep1, *dep2, *ndep;
650
651 op = mkU64(opc);
652 dep1 = mkexpr(d1);
653 dep2 = s390_cc_widen(d2, False);
654 ndep = mkU64(0);
655
656 s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a 128-bit floating point value into the flags thunk. This is
661 done by splitting the value into two 64-bits values. */
662static void
663s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
664{
665 IRExpr *op, *hi, *lo, *ndep;
666
667 op = mkU64(opc);
668 hi = unop(Iop_F128HItoF64, mkexpr(d1));
669 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, hi, lo, ndep);
673}
674
675
676/* Write a 128-bit floating point value and an integer into the flags thunk.
677 The integer value is zero-extended first. */
678static void
679s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
680{
681 IRExpr *op, *hi, *lo, *lox, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
686 ndep = s390_cc_widen(nd, False);
687
688 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
689
690 s390_cc_thunk_fill(op, hi, lox, ndep);
691}
692
693
floriane38f6412012-12-21 17:32:12 +0000694/* Write a 128-bit decimal floating point value into the flags thunk.
695 This is done by splitting the value into two 64-bits values. */
696static void
697s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
698{
699 IRExpr *op, *hi, *lo, *ndep;
700
701 op = mkU64(opc);
702 hi = unop(Iop_D128HItoD64, mkexpr(d1));
703 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
704 ndep = mkU64(0);
705
706 s390_cc_thunk_fill(op, hi, lo, ndep);
707}
708
709
floriance9e3db2012-12-27 20:14:03 +0000710/* Write a 128-bit decimal floating point value and an integer into the flags
711 thunk. The integer value is zero-extended first. */
712static void
713s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
714{
715 IRExpr *op, *hi, *lo, *lox, *ndep;
716
717 op = mkU64(opc);
718 hi = unop(Iop_D128HItoD64, mkexpr(d1));
719 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
720 ndep = s390_cc_widen(nd, False);
721
722 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
723
724 s390_cc_thunk_fill(op, hi, lox, ndep);
725}
726
727
sewardj2019a972011-03-07 16:04:07 +0000728static void
729s390_cc_set(UInt val)
730{
731 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
732 mkU64(val), mkU64(0), mkU64(0));
733}
734
735/* Build IR to calculate the condition code from flags thunk.
736 Returns an expression of type Ity_I32 */
737static IRExpr *
738s390_call_calculate_cc(void)
739{
740 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
741
florian428dfdd2012-03-27 03:09:49 +0000742 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
743 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
744 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
745 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000746
747 args = mkIRExprVec_4(op, dep1, dep2, ndep);
748 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
749 "s390_calculate_cc", &s390_calculate_cc, args);
750
751 /* Exclude OP and NDEP from definedness checking. We're only
752 interested in DEP1 and DEP2. */
753 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
754
755 return call;
756}
757
758/* Build IR to calculate the internal condition code for a "compare and branch"
759 insn. Returns an expression of type Ity_I32 */
760static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000761s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000762{
florianff9613f2012-05-12 15:26:44 +0000763 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000764
florianff9613f2012-05-12 15:26:44 +0000765 switch (opc) {
766 case S390_CC_OP_SIGNED_COMPARE:
767 dep1 = s390_cc_widen(op1, True);
768 dep2 = s390_cc_widen(op2, True);
769 break;
770
771 case S390_CC_OP_UNSIGNED_COMPARE:
772 dep1 = s390_cc_widen(op1, False);
773 dep2 = s390_cc_widen(op2, False);
774 break;
775
776 default:
777 vpanic("s390_call_calculate_icc");
778 }
779
780 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000781 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000782
florianff9613f2012-05-12 15:26:44 +0000783 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000784 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000785 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000786
florianff9613f2012-05-12 15:26:44 +0000787 /* Exclude the requested condition, OP and NDEP from definedness
788 checking. We're only interested in DEP1 and DEP2. */
789 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000790
791 return call;
792}
793
794/* Build IR to calculate the condition code from flags thunk.
795 Returns an expression of type Ity_I32 */
796static IRExpr *
797s390_call_calculate_cond(UInt m)
798{
799 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
800
801 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000802 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
803 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
804 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
805 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000806
807 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
808 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
809 "s390_calculate_cond", &s390_calculate_cond, args);
810
811 /* Exclude the requested condition, OP and NDEP from definedness
812 checking. We're only interested in DEP1 and DEP2. */
813 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
814
815 return call;
816}
817
818#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
819#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
820#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
821#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
822#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
823#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
824#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
825 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
826#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
827 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000828
829
sewardj2019a972011-03-07 16:04:07 +0000830
831
832/*------------------------------------------------------------*/
833/*--- Guest register access ---*/
834/*------------------------------------------------------------*/
835
836
837/*------------------------------------------------------------*/
838/*--- ar registers ---*/
839/*------------------------------------------------------------*/
840
841/* Return the guest state offset of a ar register. */
842static UInt
843ar_offset(UInt archreg)
844{
845 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000846 S390X_GUEST_OFFSET(guest_a0),
847 S390X_GUEST_OFFSET(guest_a1),
848 S390X_GUEST_OFFSET(guest_a2),
849 S390X_GUEST_OFFSET(guest_a3),
850 S390X_GUEST_OFFSET(guest_a4),
851 S390X_GUEST_OFFSET(guest_a5),
852 S390X_GUEST_OFFSET(guest_a6),
853 S390X_GUEST_OFFSET(guest_a7),
854 S390X_GUEST_OFFSET(guest_a8),
855 S390X_GUEST_OFFSET(guest_a9),
856 S390X_GUEST_OFFSET(guest_a10),
857 S390X_GUEST_OFFSET(guest_a11),
858 S390X_GUEST_OFFSET(guest_a12),
859 S390X_GUEST_OFFSET(guest_a13),
860 S390X_GUEST_OFFSET(guest_a14),
861 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000862 };
863
864 vassert(archreg < 16);
865
866 return offset[archreg];
867}
868
869
870/* Return the guest state offset of word #0 of a ar register. */
871static __inline__ UInt
872ar_w0_offset(UInt archreg)
873{
874 return ar_offset(archreg) + 0;
875}
876
877/* Write word #0 of a ar to the guest state. */
878static __inline__ void
879put_ar_w0(UInt archreg, IRExpr *expr)
880{
881 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
882
883 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
884}
885
886/* Read word #0 of a ar register. */
887static __inline__ IRExpr *
888get_ar_w0(UInt archreg)
889{
890 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
891}
892
893
894/*------------------------------------------------------------*/
895/*--- fpr registers ---*/
896/*------------------------------------------------------------*/
897
898/* Return the guest state offset of a fpr register. */
899static UInt
900fpr_offset(UInt archreg)
901{
902 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000903 S390X_GUEST_OFFSET(guest_f0),
904 S390X_GUEST_OFFSET(guest_f1),
905 S390X_GUEST_OFFSET(guest_f2),
906 S390X_GUEST_OFFSET(guest_f3),
907 S390X_GUEST_OFFSET(guest_f4),
908 S390X_GUEST_OFFSET(guest_f5),
909 S390X_GUEST_OFFSET(guest_f6),
910 S390X_GUEST_OFFSET(guest_f7),
911 S390X_GUEST_OFFSET(guest_f8),
912 S390X_GUEST_OFFSET(guest_f9),
913 S390X_GUEST_OFFSET(guest_f10),
914 S390X_GUEST_OFFSET(guest_f11),
915 S390X_GUEST_OFFSET(guest_f12),
916 S390X_GUEST_OFFSET(guest_f13),
917 S390X_GUEST_OFFSET(guest_f14),
918 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000919 };
920
921 vassert(archreg < 16);
922
923 return offset[archreg];
924}
925
926
927/* Return the guest state offset of word #0 of a fpr register. */
928static __inline__ UInt
929fpr_w0_offset(UInt archreg)
930{
931 return fpr_offset(archreg) + 0;
932}
933
934/* Write word #0 of a fpr to the guest state. */
935static __inline__ void
936put_fpr_w0(UInt archreg, IRExpr *expr)
937{
938 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
939
940 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
941}
942
943/* Read word #0 of a fpr register. */
944static __inline__ IRExpr *
945get_fpr_w0(UInt archreg)
946{
947 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
948}
949
950/* Return the guest state offset of double word #0 of a fpr register. */
951static __inline__ UInt
952fpr_dw0_offset(UInt archreg)
953{
954 return fpr_offset(archreg) + 0;
955}
956
957/* Write double word #0 of a fpr to the guest state. */
958static __inline__ void
959put_fpr_dw0(UInt archreg, IRExpr *expr)
960{
961 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
962
963 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
964}
965
966/* Read double word #0 of a fpr register. */
967static __inline__ IRExpr *
968get_fpr_dw0(UInt archreg)
969{
970 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
971}
972
floriane38f6412012-12-21 17:32:12 +0000973/* Write word #0 of a dpr to the guest state. */
974static __inline__ void
975put_dpr_w0(UInt archreg, IRExpr *expr)
976{
977 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
978
979 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
980}
981
982/* Read word #0 of a dpr register. */
983static __inline__ IRExpr *
984get_dpr_w0(UInt archreg)
985{
986 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
987}
988
florian12390202012-11-10 22:34:14 +0000989/* Write double word #0 of a fpr containg DFP value to the guest state. */
990static __inline__ void
991put_dpr_dw0(UInt archreg, IRExpr *expr)
992{
993 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
994
995 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
996}
997
998/* Read double word #0 of a fpr register containing DFP value. */
999static __inline__ IRExpr *
1000get_dpr_dw0(UInt archreg)
1001{
1002 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1003}
sewardj2019a972011-03-07 16:04:07 +00001004
1005/*------------------------------------------------------------*/
1006/*--- gpr registers ---*/
1007/*------------------------------------------------------------*/
1008
1009/* Return the guest state offset of a gpr register. */
1010static UInt
1011gpr_offset(UInt archreg)
1012{
1013 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001014 S390X_GUEST_OFFSET(guest_r0),
1015 S390X_GUEST_OFFSET(guest_r1),
1016 S390X_GUEST_OFFSET(guest_r2),
1017 S390X_GUEST_OFFSET(guest_r3),
1018 S390X_GUEST_OFFSET(guest_r4),
1019 S390X_GUEST_OFFSET(guest_r5),
1020 S390X_GUEST_OFFSET(guest_r6),
1021 S390X_GUEST_OFFSET(guest_r7),
1022 S390X_GUEST_OFFSET(guest_r8),
1023 S390X_GUEST_OFFSET(guest_r9),
1024 S390X_GUEST_OFFSET(guest_r10),
1025 S390X_GUEST_OFFSET(guest_r11),
1026 S390X_GUEST_OFFSET(guest_r12),
1027 S390X_GUEST_OFFSET(guest_r13),
1028 S390X_GUEST_OFFSET(guest_r14),
1029 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001030 };
1031
1032 vassert(archreg < 16);
1033
1034 return offset[archreg];
1035}
1036
1037
1038/* Return the guest state offset of word #0 of a gpr register. */
1039static __inline__ UInt
1040gpr_w0_offset(UInt archreg)
1041{
1042 return gpr_offset(archreg) + 0;
1043}
1044
1045/* Write word #0 of a gpr to the guest state. */
1046static __inline__ void
1047put_gpr_w0(UInt archreg, IRExpr *expr)
1048{
1049 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1050
1051 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1052}
1053
1054/* Read word #0 of a gpr register. */
1055static __inline__ IRExpr *
1056get_gpr_w0(UInt archreg)
1057{
1058 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1059}
1060
1061/* Return the guest state offset of double word #0 of a gpr register. */
1062static __inline__ UInt
1063gpr_dw0_offset(UInt archreg)
1064{
1065 return gpr_offset(archreg) + 0;
1066}
1067
1068/* Write double word #0 of a gpr to the guest state. */
1069static __inline__ void
1070put_gpr_dw0(UInt archreg, IRExpr *expr)
1071{
1072 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1073
1074 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1075}
1076
1077/* Read double word #0 of a gpr register. */
1078static __inline__ IRExpr *
1079get_gpr_dw0(UInt archreg)
1080{
1081 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1082}
1083
1084/* Return the guest state offset of half word #1 of a gpr register. */
1085static __inline__ UInt
1086gpr_hw1_offset(UInt archreg)
1087{
1088 return gpr_offset(archreg) + 2;
1089}
1090
1091/* Write half word #1 of a gpr to the guest state. */
1092static __inline__ void
1093put_gpr_hw1(UInt archreg, IRExpr *expr)
1094{
1095 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1096
1097 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1098}
1099
1100/* Read half word #1 of a gpr register. */
1101static __inline__ IRExpr *
1102get_gpr_hw1(UInt archreg)
1103{
1104 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1105}
1106
1107/* Return the guest state offset of byte #6 of a gpr register. */
1108static __inline__ UInt
1109gpr_b6_offset(UInt archreg)
1110{
1111 return gpr_offset(archreg) + 6;
1112}
1113
1114/* Write byte #6 of a gpr to the guest state. */
1115static __inline__ void
1116put_gpr_b6(UInt archreg, IRExpr *expr)
1117{
1118 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1119
1120 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1121}
1122
1123/* Read byte #6 of a gpr register. */
1124static __inline__ IRExpr *
1125get_gpr_b6(UInt archreg)
1126{
1127 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1128}
1129
1130/* Return the guest state offset of byte #3 of a gpr register. */
1131static __inline__ UInt
1132gpr_b3_offset(UInt archreg)
1133{
1134 return gpr_offset(archreg) + 3;
1135}
1136
1137/* Write byte #3 of a gpr to the guest state. */
1138static __inline__ void
1139put_gpr_b3(UInt archreg, IRExpr *expr)
1140{
1141 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1142
1143 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1144}
1145
1146/* Read byte #3 of a gpr register. */
1147static __inline__ IRExpr *
1148get_gpr_b3(UInt archreg)
1149{
1150 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1151}
1152
1153/* Return the guest state offset of byte #0 of a gpr register. */
1154static __inline__ UInt
1155gpr_b0_offset(UInt archreg)
1156{
1157 return gpr_offset(archreg) + 0;
1158}
1159
1160/* Write byte #0 of a gpr to the guest state. */
1161static __inline__ void
1162put_gpr_b0(UInt archreg, IRExpr *expr)
1163{
1164 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1165
1166 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1167}
1168
1169/* Read byte #0 of a gpr register. */
1170static __inline__ IRExpr *
1171get_gpr_b0(UInt archreg)
1172{
1173 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1174}
1175
1176/* Return the guest state offset of word #1 of a gpr register. */
1177static __inline__ UInt
1178gpr_w1_offset(UInt archreg)
1179{
1180 return gpr_offset(archreg) + 4;
1181}
1182
1183/* Write word #1 of a gpr to the guest state. */
1184static __inline__ void
1185put_gpr_w1(UInt archreg, IRExpr *expr)
1186{
1187 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1188
1189 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1190}
1191
1192/* Read word #1 of a gpr register. */
1193static __inline__ IRExpr *
1194get_gpr_w1(UInt archreg)
1195{
1196 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1197}
1198
1199/* Return the guest state offset of half word #3 of a gpr register. */
1200static __inline__ UInt
1201gpr_hw3_offset(UInt archreg)
1202{
1203 return gpr_offset(archreg) + 6;
1204}
1205
1206/* Write half word #3 of a gpr to the guest state. */
1207static __inline__ void
1208put_gpr_hw3(UInt archreg, IRExpr *expr)
1209{
1210 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1211
1212 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1213}
1214
1215/* Read half word #3 of a gpr register. */
1216static __inline__ IRExpr *
1217get_gpr_hw3(UInt archreg)
1218{
1219 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1220}
1221
1222/* Return the guest state offset of byte #7 of a gpr register. */
1223static __inline__ UInt
1224gpr_b7_offset(UInt archreg)
1225{
1226 return gpr_offset(archreg) + 7;
1227}
1228
1229/* Write byte #7 of a gpr to the guest state. */
1230static __inline__ void
1231put_gpr_b7(UInt archreg, IRExpr *expr)
1232{
1233 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1234
1235 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1236}
1237
1238/* Read byte #7 of a gpr register. */
1239static __inline__ IRExpr *
1240get_gpr_b7(UInt archreg)
1241{
1242 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1243}
1244
1245/* Return the guest state offset of half word #0 of a gpr register. */
1246static __inline__ UInt
1247gpr_hw0_offset(UInt archreg)
1248{
1249 return gpr_offset(archreg) + 0;
1250}
1251
1252/* Write half word #0 of a gpr to the guest state. */
1253static __inline__ void
1254put_gpr_hw0(UInt archreg, IRExpr *expr)
1255{
1256 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1257
1258 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1259}
1260
1261/* Read half word #0 of a gpr register. */
1262static __inline__ IRExpr *
1263get_gpr_hw0(UInt archreg)
1264{
1265 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1266}
1267
1268/* Return the guest state offset of byte #4 of a gpr register. */
1269static __inline__ UInt
1270gpr_b4_offset(UInt archreg)
1271{
1272 return gpr_offset(archreg) + 4;
1273}
1274
1275/* Write byte #4 of a gpr to the guest state. */
1276static __inline__ void
1277put_gpr_b4(UInt archreg, IRExpr *expr)
1278{
1279 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1280
1281 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1282}
1283
1284/* Read byte #4 of a gpr register. */
1285static __inline__ IRExpr *
1286get_gpr_b4(UInt archreg)
1287{
1288 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1289}
1290
1291/* Return the guest state offset of byte #1 of a gpr register. */
1292static __inline__ UInt
1293gpr_b1_offset(UInt archreg)
1294{
1295 return gpr_offset(archreg) + 1;
1296}
1297
1298/* Write byte #1 of a gpr to the guest state. */
1299static __inline__ void
1300put_gpr_b1(UInt archreg, IRExpr *expr)
1301{
1302 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1303
1304 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1305}
1306
1307/* Read byte #1 of a gpr register. */
1308static __inline__ IRExpr *
1309get_gpr_b1(UInt archreg)
1310{
1311 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1312}
1313
1314/* Return the guest state offset of half word #2 of a gpr register. */
1315static __inline__ UInt
1316gpr_hw2_offset(UInt archreg)
1317{
1318 return gpr_offset(archreg) + 4;
1319}
1320
1321/* Write half word #2 of a gpr to the guest state. */
1322static __inline__ void
1323put_gpr_hw2(UInt archreg, IRExpr *expr)
1324{
1325 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1326
1327 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1328}
1329
1330/* Read half word #2 of a gpr register. */
1331static __inline__ IRExpr *
1332get_gpr_hw2(UInt archreg)
1333{
1334 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1335}
1336
1337/* Return the guest state offset of byte #5 of a gpr register. */
1338static __inline__ UInt
1339gpr_b5_offset(UInt archreg)
1340{
1341 return gpr_offset(archreg) + 5;
1342}
1343
1344/* Write byte #5 of a gpr to the guest state. */
1345static __inline__ void
1346put_gpr_b5(UInt archreg, IRExpr *expr)
1347{
1348 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1349
1350 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1351}
1352
1353/* Read byte #5 of a gpr register. */
1354static __inline__ IRExpr *
1355get_gpr_b5(UInt archreg)
1356{
1357 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1358}
1359
1360/* Return the guest state offset of byte #2 of a gpr register. */
1361static __inline__ UInt
1362gpr_b2_offset(UInt archreg)
1363{
1364 return gpr_offset(archreg) + 2;
1365}
1366
1367/* Write byte #2 of a gpr to the guest state. */
1368static __inline__ void
1369put_gpr_b2(UInt archreg, IRExpr *expr)
1370{
1371 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1372
1373 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1374}
1375
1376/* Read byte #2 of a gpr register. */
1377static __inline__ IRExpr *
1378get_gpr_b2(UInt archreg)
1379{
1380 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1381}
1382
1383/* Return the guest state offset of the counter register. */
1384static UInt
1385counter_offset(void)
1386{
floriane88b3c92011-07-05 02:48:39 +00001387 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001388}
1389
1390/* Return the guest state offset of double word #0 of the counter register. */
1391static __inline__ UInt
1392counter_dw0_offset(void)
1393{
1394 return counter_offset() + 0;
1395}
1396
1397/* Write double word #0 of the counter to the guest state. */
1398static __inline__ void
1399put_counter_dw0(IRExpr *expr)
1400{
1401 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1402
1403 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1404}
1405
1406/* Read double word #0 of the counter register. */
1407static __inline__ IRExpr *
1408get_counter_dw0(void)
1409{
1410 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1411}
1412
1413/* Return the guest state offset of word #0 of the counter register. */
1414static __inline__ UInt
1415counter_w0_offset(void)
1416{
1417 return counter_offset() + 0;
1418}
1419
1420/* Return the guest state offset of word #1 of the counter register. */
1421static __inline__ UInt
1422counter_w1_offset(void)
1423{
1424 return counter_offset() + 4;
1425}
1426
1427/* Write word #0 of the counter to the guest state. */
1428static __inline__ void
1429put_counter_w0(IRExpr *expr)
1430{
1431 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1432
1433 stmt(IRStmt_Put(counter_w0_offset(), expr));
1434}
1435
1436/* Read word #0 of the counter register. */
1437static __inline__ IRExpr *
1438get_counter_w0(void)
1439{
1440 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1441}
1442
1443/* Write word #1 of the counter to the guest state. */
1444static __inline__ void
1445put_counter_w1(IRExpr *expr)
1446{
1447 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1448
1449 stmt(IRStmt_Put(counter_w1_offset(), expr));
1450}
1451
1452/* Read word #1 of the counter register. */
1453static __inline__ IRExpr *
1454get_counter_w1(void)
1455{
1456 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1457}
1458
1459/* Return the guest state offset of the fpc register. */
1460static UInt
1461fpc_offset(void)
1462{
floriane88b3c92011-07-05 02:48:39 +00001463 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001464}
1465
1466/* Return the guest state offset of word #0 of the fpc register. */
1467static __inline__ UInt
1468fpc_w0_offset(void)
1469{
1470 return fpc_offset() + 0;
1471}
1472
1473/* Write word #0 of the fpc to the guest state. */
1474static __inline__ void
1475put_fpc_w0(IRExpr *expr)
1476{
1477 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1478
1479 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1480}
1481
1482/* Read word #0 of the fpc register. */
1483static __inline__ IRExpr *
1484get_fpc_w0(void)
1485{
1486 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1487}
1488
1489
1490/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001491/*--- Rounding modes ---*/
1492/*------------------------------------------------------------*/
1493
florian125e20d2012-10-07 15:42:37 +00001494/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001495 IRRoundingMode:
1496
1497 rounding mode | s390 | IR
1498 -------------------------
1499 to nearest | 00 | 00
1500 to zero | 01 | 11
1501 to +infinity | 10 | 10
1502 to -infinity | 11 | 01
1503
1504 So: IR = (4 - s390) & 3
1505*/
1506static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001507get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001508{
1509 IRTemp fpc_bits = newTemp(Ity_I32);
1510
1511 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1512 Prior to that bits [30:31] contained the bfp rounding mode with
1513 bit 29 being unused and having a value of 0. So we can always
1514 extract the least significant 3 bits. */
1515 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1516
1517 /* fixs390:
1518
1519
1520 if (! s390_host_has_fpext && rounding_mode > 3) {
1521 emulation warning @ runtime and
1522 set fpc to round nearest
1523 }
1524 */
1525
1526 /* For now silently adjust an unsupported rounding mode to "nearest" */
1527 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1528 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001529 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001530
1531 // rm_IR = (4 - rm_s390) & 3;
1532 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1533}
1534
1535/* Encode the s390 rounding mode as it appears in the m3 field of certain
1536 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1537 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1538 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1539 considers the default rounding mode (4.3.3). */
1540static IRTemp
1541encode_bfp_rounding_mode(UChar mode)
1542{
1543 IRExpr *rm;
1544
1545 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001546 case S390_BFP_ROUND_PER_FPC:
1547 rm = get_bfp_rounding_mode_from_fpc();
1548 break;
1549 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1550 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1551 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1552 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1553 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1554 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001555 default:
1556 vpanic("encode_bfp_rounding_mode");
1557 }
1558
1559 return mktemp(Ity_I32, rm);
1560}
1561
florianc8e4f562012-10-27 16:19:31 +00001562/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1563 IRRoundingMode:
1564
1565 rounding mode | s390 | IR
1566 ------------------------------------------------
1567 to nearest, ties to even | 000 | 000
1568 to zero | 001 | 011
1569 to +infinity | 010 | 010
1570 to -infinity | 011 | 001
1571 to nearest, ties away from 0 | 100 | 100
1572 to nearest, ties toward 0 | 101 | 111
1573 to away from 0 | 110 | 110
1574 to prepare for shorter precision | 111 | 101
1575
1576 So: IR = (s390 ^ ((s390 << 1) & 2))
1577*/
florianc8e4f562012-10-27 16:19:31 +00001578static IRExpr *
1579get_dfp_rounding_mode_from_fpc(void)
1580{
1581 IRTemp fpc_bits = newTemp(Ity_I32);
1582
1583 /* The dfp rounding mode is stored in bits [25:27].
1584 extract the bits at 25:27 and right shift 4 times. */
1585 assign(fpc_bits, binop(Iop_Shr32,
1586 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1587 mkU8(4)));
1588
1589 IRExpr *rm_s390 = mkexpr(fpc_bits);
1590 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1591
1592 return binop(Iop_Xor32, rm_s390,
1593 binop( Iop_And32,
1594 binop(Iop_Shl32, rm_s390, mkU8(1)),
1595 mkU32(2)));
1596}
1597
1598/* Encode the s390 rounding mode as it appears in the m3 field of certain
1599 instructions to VEX's IRRoundingMode. */
1600static IRTemp
1601encode_dfp_rounding_mode(UChar mode)
1602{
1603 IRExpr *rm;
1604
1605 switch (mode) {
1606 case S390_DFP_ROUND_PER_FPC_0:
1607 case S390_DFP_ROUND_PER_FPC_2:
1608 rm = get_dfp_rounding_mode_from_fpc(); break;
1609 case S390_DFP_ROUND_NEAREST_EVEN_4:
1610 case S390_DFP_ROUND_NEAREST_EVEN_8:
1611 rm = mkU32(Irrm_DFP_NEAREST); break;
1612 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1613 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1614 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1615 case S390_DFP_ROUND_PREPARE_SHORT_3:
1616 case S390_DFP_ROUND_PREPARE_SHORT_15:
1617 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1618 case S390_DFP_ROUND_ZERO_5:
1619 case S390_DFP_ROUND_ZERO_9:
1620 rm = mkU32(Irrm_DFP_ZERO ); break;
1621 case S390_DFP_ROUND_POSINF_6:
1622 case S390_DFP_ROUND_POSINF_10:
1623 rm = mkU32(Irrm_DFP_PosINF); break;
1624 case S390_DFP_ROUND_NEGINF_7:
1625 case S390_DFP_ROUND_NEGINF_11:
1626 rm = mkU32(Irrm_DFP_NegINF); break;
1627 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1628 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1629 case S390_DFP_ROUND_AWAY_0:
1630 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1631 default:
1632 vpanic("encode_dfp_rounding_mode");
1633 }
1634
1635 return mktemp(Ity_I32, rm);
1636}
florian12390202012-11-10 22:34:14 +00001637
florianc8e4f562012-10-27 16:19:31 +00001638
florian2c74d242012-09-12 19:38:42 +00001639/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001640/*--- Condition code helpers ---*/
1641/*------------------------------------------------------------*/
1642
1643/* The result of a Iop_CmpFxx operation is a condition code. It is
1644 encoded using the values defined in type IRCmpFxxResult.
1645 Before we can store the condition code into the guest state (or do
1646 anything else with it for that matter) we need to convert it to
1647 the encoding that s390 uses. This is what this function does.
1648
1649 s390 VEX b6 b2 b0 cc.1 cc.0
1650 0 0x40 EQ 1 0 0 0 0
1651 1 0x01 LT 0 0 1 0 1
1652 2 0x00 GT 0 0 0 1 0
1653 3 0x45 Unordered 1 1 1 1 1
1654
1655 The following bits from the VEX encoding are interesting:
1656 b0, b2, b6 with b0 being the LSB. We observe:
1657
1658 cc.0 = b0;
1659 cc.1 = b2 | (~b0 & ~b6)
1660
1661 with cc being the s390 condition code.
1662*/
1663static IRExpr *
1664convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1665{
1666 IRTemp cc0 = newTemp(Ity_I32);
1667 IRTemp cc1 = newTemp(Ity_I32);
1668 IRTemp b0 = newTemp(Ity_I32);
1669 IRTemp b2 = newTemp(Ity_I32);
1670 IRTemp b6 = newTemp(Ity_I32);
1671
1672 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1673 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1674 mkU32(1)));
1675 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1676 mkU32(1)));
1677
1678 assign(cc0, mkexpr(b0));
1679 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1680 binop(Iop_And32,
1681 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1682 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1683 )));
1684
1685 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1686}
1687
1688
1689/* The result of a Iop_CmpDxx operation is a condition code. It is
1690 encoded using the values defined in type IRCmpDxxResult.
1691 Before we can store the condition code into the guest state (or do
1692 anything else with it for that matter) we need to convert it to
1693 the encoding that s390 uses. This is what this function does. */
1694static IRExpr *
1695convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1696{
1697 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1698 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001699 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001700}
1701
1702
1703/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001704/*--- Build IR for formats ---*/
1705/*------------------------------------------------------------*/
1706static void
florian55085f82012-11-21 00:36:55 +00001707s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001708 UChar i)
1709{
florian55085f82012-11-21 00:36:55 +00001710 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001711
sewardj7ee97522011-05-09 21:45:04 +00001712 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001713 s390_disasm(ENC2(MNM, UINT), mnm, i);
1714}
1715
1716static void
florian55085f82012-11-21 00:36:55 +00001717s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001718 UChar r1, UShort i2)
1719{
1720 irgen(r1, i2);
1721}
1722
1723static void
florian55085f82012-11-21 00:36:55 +00001724s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001725 UChar r1, UShort i2)
1726{
florian55085f82012-11-21 00:36:55 +00001727 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001728
sewardj7ee97522011-05-09 21:45:04 +00001729 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001730 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1731}
1732
1733static void
florian55085f82012-11-21 00:36:55 +00001734s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001735 UChar r1, UShort i2)
1736{
florian55085f82012-11-21 00:36:55 +00001737 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001738
sewardj7ee97522011-05-09 21:45:04 +00001739 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001740 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1741}
1742
1743static void
florian55085f82012-11-21 00:36:55 +00001744s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001745 UChar r1, UShort i2)
1746{
florian55085f82012-11-21 00:36:55 +00001747 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001748
sewardj7ee97522011-05-09 21:45:04 +00001749 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001750 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1751}
1752
1753static void
florian55085f82012-11-21 00:36:55 +00001754s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001755 UChar r1, UChar r3, UShort i2)
1756{
florian55085f82012-11-21 00:36:55 +00001757 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001758
sewardj7ee97522011-05-09 21:45:04 +00001759 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001760 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1761}
1762
1763static void
florian55085f82012-11-21 00:36:55 +00001764s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001765 UChar r1, UChar r3, UShort i2)
1766{
florian55085f82012-11-21 00:36:55 +00001767 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001768
sewardj7ee97522011-05-09 21:45:04 +00001769 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001770 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1771}
1772
1773static void
florian55085f82012-11-21 00:36:55 +00001774s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1775 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001776 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1777{
florian55085f82012-11-21 00:36:55 +00001778 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001779
sewardj7ee97522011-05-09 21:45:04 +00001780 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001781 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1782 i5);
1783}
1784
1785static void
florian55085f82012-11-21 00:36:55 +00001786s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1787 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001788 UChar r1, UChar r2, UShort i4, UChar m3)
1789{
florian55085f82012-11-21 00:36:55 +00001790 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001791
sewardj7ee97522011-05-09 21:45:04 +00001792 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001793 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1794 r2, m3, (Int)(Short)i4);
1795}
1796
1797static void
florian55085f82012-11-21 00:36:55 +00001798s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1799 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001800 UChar r1, UChar m3, UShort i4, UChar i2)
1801{
florian55085f82012-11-21 00:36:55 +00001802 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001803
sewardj7ee97522011-05-09 21:45:04 +00001804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001805 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1806 r1, i2, m3, (Int)(Short)i4);
1807}
1808
1809static void
florian55085f82012-11-21 00:36:55 +00001810s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1811 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001812 UChar r1, UChar m3, UShort i4, UChar i2)
1813{
florian55085f82012-11-21 00:36:55 +00001814 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001815
sewardj7ee97522011-05-09 21:45:04 +00001816 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001817 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1818 (Int)(Char)i2, m3, (Int)(Short)i4);
1819}
1820
1821static void
florian55085f82012-11-21 00:36:55 +00001822s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001823 UChar r1, UInt i2)
1824{
1825 irgen(r1, i2);
1826}
1827
1828static void
florian55085f82012-11-21 00:36:55 +00001829s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001830 UChar r1, UInt i2)
1831{
florian55085f82012-11-21 00:36:55 +00001832 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001833
sewardj7ee97522011-05-09 21:45:04 +00001834 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001835 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1836}
1837
1838static void
florian55085f82012-11-21 00:36:55 +00001839s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001840 UChar r1, UInt i2)
1841{
florian55085f82012-11-21 00:36:55 +00001842 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001843
sewardj7ee97522011-05-09 21:45:04 +00001844 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001845 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1846}
1847
1848static void
florian55085f82012-11-21 00:36:55 +00001849s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001850 UChar r1, UInt i2)
1851{
florian55085f82012-11-21 00:36:55 +00001852 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001853
sewardj7ee97522011-05-09 21:45:04 +00001854 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001855 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1856}
1857
1858static void
florian55085f82012-11-21 00:36:55 +00001859s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001860 UChar r1, UInt i2)
1861{
florian55085f82012-11-21 00:36:55 +00001862 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001863
sewardj7ee97522011-05-09 21:45:04 +00001864 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001865 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1866}
1867
1868static void
florian55085f82012-11-21 00:36:55 +00001869s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001870 IRTemp op4addr),
1871 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1872{
florian55085f82012-11-21 00:36:55 +00001873 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001874 IRTemp op4addr = newTemp(Ity_I64);
1875
1876 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1877 mkU64(0)));
1878
1879 mnm = irgen(r1, m3, i2, op4addr);
1880
sewardj7ee97522011-05-09 21:45:04 +00001881 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001882 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1883 (Int)(Char)i2, m3, d4, 0, b4);
1884}
1885
1886static void
florian55085f82012-11-21 00:36:55 +00001887s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001888 IRTemp op4addr),
1889 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1890{
florian55085f82012-11-21 00:36:55 +00001891 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001892 IRTemp op4addr = newTemp(Ity_I64);
1893
1894 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1895 mkU64(0)));
1896
1897 mnm = irgen(r1, m3, i2, op4addr);
1898
sewardj7ee97522011-05-09 21:45:04 +00001899 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001900 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1901 i2, m3, d4, 0, b4);
1902}
1903
1904static void
florian55085f82012-11-21 00:36:55 +00001905s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001906 UChar r1, UChar r2)
1907{
1908 irgen(r1, r2);
1909}
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001913 UChar r1, UChar r2)
1914{
florian55085f82012-11-21 00:36:55 +00001915 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001916
sewardj7ee97522011-05-09 21:45:04 +00001917 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001918 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1919}
1920
1921static void
florian55085f82012-11-21 00:36:55 +00001922s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001923 UChar r1, UChar r2)
1924{
florian55085f82012-11-21 00:36:55 +00001925 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001926
sewardj7ee97522011-05-09 21:45:04 +00001927 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001928 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1929}
1930
1931static void
florian55085f82012-11-21 00:36:55 +00001932s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001933 UChar r1, UChar r2)
1934{
1935 irgen(r1, r2);
1936}
1937
1938static void
florian55085f82012-11-21 00:36:55 +00001939s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001940 UChar r1, UChar r2)
1941{
florian55085f82012-11-21 00:36:55 +00001942 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001943
sewardj7ee97522011-05-09 21:45:04 +00001944 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001945 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1946}
1947
1948static void
florian55085f82012-11-21 00:36:55 +00001949s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001950 UChar r1, UChar r2)
1951{
florian55085f82012-11-21 00:36:55 +00001952 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001953
sewardj7ee97522011-05-09 21:45:04 +00001954 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001955 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1956}
1957
1958static void
florian55085f82012-11-21 00:36:55 +00001959s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001960 UChar r1, UChar r2)
1961{
florian55085f82012-11-21 00:36:55 +00001962 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001963
sewardj7ee97522011-05-09 21:45:04 +00001964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001965 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1966}
1967
1968static void
florian55085f82012-11-21 00:36:55 +00001969s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001970 UChar r1, UChar r2)
1971{
florian55085f82012-11-21 00:36:55 +00001972 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001973
sewardj7ee97522011-05-09 21:45:04 +00001974 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001975 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1976}
1977
1978static void
florian55085f82012-11-21 00:36:55 +00001979s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001980 UChar r1)
1981{
florian55085f82012-11-21 00:36:55 +00001982 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001983
sewardj7ee97522011-05-09 21:45:04 +00001984 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001985 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1986}
1987
1988static void
florian55085f82012-11-21 00:36:55 +00001989s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001990 UChar r1)
1991{
florian55085f82012-11-21 00:36:55 +00001992 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001993
sewardj7ee97522011-05-09 21:45:04 +00001994 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001995 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1996}
1997
1998static void
florian55085f82012-11-21 00:36:55 +00001999s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002000 UChar m3, UChar r1, UChar r2)
2001{
florian55085f82012-11-21 00:36:55 +00002002 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002003
2004 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002005 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002006}
2007
2008static void
florian55085f82012-11-21 00:36:55 +00002009s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002010 UChar r1, UChar r3, UChar r2)
2011{
florian55085f82012-11-21 00:36:55 +00002012 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002013
sewardj7ee97522011-05-09 21:45:04 +00002014 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002015 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2016}
2017
2018static void
florian55085f82012-11-21 00:36:55 +00002019s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2020 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002021 UChar m3, UChar m4, UChar r1, UChar r2)
2022{
florian55085f82012-11-21 00:36:55 +00002023 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002024
2025 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2026 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2027}
2028
2029static void
floriane38f6412012-12-21 17:32:12 +00002030s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2031 UChar m4, UChar r1, UChar r2)
2032{
2033 const HChar *mnm = irgen(m4, r1, r2);
2034
2035 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2036 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2037}
2038
2039static void
florian55085f82012-11-21 00:36:55 +00002040s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2041 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002042 UChar m3, UChar m4, UChar r1, UChar r2)
2043{
florian55085f82012-11-21 00:36:55 +00002044 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002045
2046 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2047 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2048}
2049
2050static void
florian55085f82012-11-21 00:36:55 +00002051s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2052 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002053 UChar m3, UChar m4, UChar r1, UChar r2)
2054{
florian55085f82012-11-21 00:36:55 +00002055 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002056
2057 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2058 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2059}
2060
2061
2062static void
florian55085f82012-11-21 00:36:55 +00002063s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002064 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2065{
2066 irgen(m3, r1, r2);
2067
sewardj7ee97522011-05-09 21:45:04 +00002068 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002069 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2070}
2071
2072static void
florian55085f82012-11-21 00:36:55 +00002073s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002074 UChar r3, UChar r1, UChar r2)
2075{
florian55085f82012-11-21 00:36:55 +00002076 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002077
sewardj7ee97522011-05-09 21:45:04 +00002078 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002079 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2080}
2081
2082static void
florian55085f82012-11-21 00:36:55 +00002083s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002084 UChar r3, UChar m4, UChar r1, UChar r2)
2085{
florian55085f82012-11-21 00:36:55 +00002086 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002087
2088 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2089 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2090}
2091
2092static void
florian55085f82012-11-21 00:36:55 +00002093s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002094 UChar r3, UChar r1, UChar r2)
2095{
florian55085f82012-11-21 00:36:55 +00002096 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002097
sewardj7ee97522011-05-09 21:45:04 +00002098 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002099 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2100}
2101
2102static void
florian55085f82012-11-21 00:36:55 +00002103s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2104 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002105 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2106{
florian55085f82012-11-21 00:36:55 +00002107 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002108 IRTemp op4addr = newTemp(Ity_I64);
2109
2110 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2111 mkU64(0)));
2112
2113 mnm = irgen(r1, r2, m3, op4addr);
2114
sewardj7ee97522011-05-09 21:45:04 +00002115 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002116 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2117 r2, m3, d4, 0, b4);
2118}
2119
2120static void
florian55085f82012-11-21 00:36:55 +00002121s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002122 UChar r1, UChar b2, UShort d2)
2123{
florian55085f82012-11-21 00:36:55 +00002124 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002125 IRTemp op2addr = newTemp(Ity_I64);
2126
2127 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2128 mkU64(0)));
2129
2130 mnm = irgen(r1, op2addr);
2131
sewardj7ee97522011-05-09 21:45:04 +00002132 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002133 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2134}
2135
2136static void
florian55085f82012-11-21 00:36:55 +00002137s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002138 UChar r1, UChar r3, UChar b2, UShort d2)
2139{
florian55085f82012-11-21 00:36:55 +00002140 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002141 IRTemp op2addr = newTemp(Ity_I64);
2142
2143 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2144 mkU64(0)));
2145
2146 mnm = irgen(r1, r3, op2addr);
2147
sewardj7ee97522011-05-09 21:45:04 +00002148 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002149 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2150}
2151
2152static void
florian55085f82012-11-21 00:36:55 +00002153s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002154 UChar r1, UChar r3, UChar b2, UShort d2)
2155{
florian55085f82012-11-21 00:36:55 +00002156 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002157 IRTemp op2addr = newTemp(Ity_I64);
2158
2159 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2160 mkU64(0)));
2161
2162 mnm = irgen(r1, r3, op2addr);
2163
sewardj7ee97522011-05-09 21:45:04 +00002164 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002165 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2166}
2167
2168static void
florian55085f82012-11-21 00:36:55 +00002169s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002170 UChar r1, UChar r3, UChar b2, UShort d2)
2171{
florian55085f82012-11-21 00:36:55 +00002172 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002173 IRTemp op2addr = newTemp(Ity_I64);
2174
2175 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2176 mkU64(0)));
2177
2178 mnm = irgen(r1, r3, op2addr);
2179
sewardj7ee97522011-05-09 21:45:04 +00002180 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002181 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2182}
2183
2184static void
florian55085f82012-11-21 00:36:55 +00002185s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002186 UChar r1, UChar r3, UShort i2)
2187{
florian55085f82012-11-21 00:36:55 +00002188 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002189
sewardj7ee97522011-05-09 21:45:04 +00002190 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002191 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2192}
2193
2194static void
florian55085f82012-11-21 00:36:55 +00002195s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002196 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2197{
florian55085f82012-11-21 00:36:55 +00002198 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002199 IRTemp op2addr = newTemp(Ity_I64);
2200 IRTemp d2 = newTemp(Ity_I64);
2201
2202 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2203 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2204 mkU64(0)));
2205
2206 mnm = irgen(r1, r3, op2addr);
2207
sewardj7ee97522011-05-09 21:45:04 +00002208 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002209 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2210}
2211
2212static void
florian55085f82012-11-21 00:36:55 +00002213s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002214 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2215{
florian55085f82012-11-21 00:36:55 +00002216 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002217 IRTemp op2addr = newTemp(Ity_I64);
2218 IRTemp d2 = newTemp(Ity_I64);
2219
2220 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2221 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2222 mkU64(0)));
2223
2224 mnm = irgen(r1, r3, op2addr);
2225
sewardj7ee97522011-05-09 21:45:04 +00002226 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002227 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2228}
2229
2230static void
florian55085f82012-11-21 00:36:55 +00002231s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002232 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2233{
florian55085f82012-11-21 00:36:55 +00002234 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002235 IRTemp op2addr = newTemp(Ity_I64);
2236 IRTemp d2 = newTemp(Ity_I64);
2237
2238 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2239 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2240 mkU64(0)));
2241
2242 mnm = irgen(r1, r3, op2addr);
2243
sewardj7ee97522011-05-09 21:45:04 +00002244 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002245 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2246}
2247
2248static void
florian55085f82012-11-21 00:36:55 +00002249s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002250 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2251 Int xmnm_kind)
2252{
2253 IRTemp op2addr = newTemp(Ity_I64);
2254 IRTemp d2 = newTemp(Ity_I64);
2255
florian6820ba52012-07-26 02:01:50 +00002256 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2257
sewardjd7bde722011-04-05 13:19:33 +00002258 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2259 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2260 mkU64(0)));
2261
2262 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002263
2264 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002265
sewardj7ee97522011-05-09 21:45:04 +00002266 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002267 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2268}
2269
2270static void
florian55085f82012-11-21 00:36:55 +00002271s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002272 IRTemp op2addr),
2273 UChar r1, UChar x2, UChar b2, UShort d2)
2274{
2275 IRTemp op2addr = newTemp(Ity_I64);
2276
2277 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2278 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2279 mkU64(0)));
2280
2281 irgen(r1, x2, b2, d2, op2addr);
2282}
2283
2284static void
florian55085f82012-11-21 00:36:55 +00002285s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002286 UChar r1, UChar x2, UChar b2, UShort d2)
2287{
florian55085f82012-11-21 00:36:55 +00002288 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002289 IRTemp op2addr = newTemp(Ity_I64);
2290
2291 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2292 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2293 mkU64(0)));
2294
2295 mnm = irgen(r1, op2addr);
2296
sewardj7ee97522011-05-09 21:45:04 +00002297 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002298 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2299}
2300
2301static void
florian55085f82012-11-21 00:36:55 +00002302s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002303 UChar r1, UChar x2, UChar b2, UShort d2)
2304{
florian55085f82012-11-21 00:36:55 +00002305 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002306 IRTemp op2addr = newTemp(Ity_I64);
2307
2308 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2309 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2310 mkU64(0)));
2311
2312 mnm = irgen(r1, op2addr);
2313
sewardj7ee97522011-05-09 21:45:04 +00002314 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002315 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2316}
2317
2318static void
florian55085f82012-11-21 00:36:55 +00002319s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002320 UChar r1, UChar x2, UChar b2, UShort d2)
2321{
florian55085f82012-11-21 00:36:55 +00002322 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002323 IRTemp op2addr = newTemp(Ity_I64);
2324
2325 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2326 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2327 mkU64(0)));
2328
2329 mnm = irgen(r1, op2addr);
2330
sewardj7ee97522011-05-09 21:45:04 +00002331 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002332 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2333}
2334
2335static void
florian55085f82012-11-21 00:36:55 +00002336s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002337 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2338{
florian55085f82012-11-21 00:36:55 +00002339 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002340 IRTemp op2addr = newTemp(Ity_I64);
2341
2342 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2343 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2344 mkU64(0)));
2345
2346 mnm = irgen(r3, op2addr, r1);
2347
sewardj7ee97522011-05-09 21:45:04 +00002348 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002349 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2350}
2351
2352static void
florian55085f82012-11-21 00:36:55 +00002353s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002354 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2355{
florian55085f82012-11-21 00:36:55 +00002356 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002357 IRTemp op2addr = newTemp(Ity_I64);
2358 IRTemp d2 = newTemp(Ity_I64);
2359
2360 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2361 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2362 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2363 mkU64(0)));
2364
2365 mnm = irgen(r1, op2addr);
2366
sewardj7ee97522011-05-09 21:45:04 +00002367 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002368 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2369}
2370
2371static void
florian55085f82012-11-21 00:36:55 +00002372s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002373 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2374{
florian55085f82012-11-21 00:36:55 +00002375 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002376 IRTemp op2addr = newTemp(Ity_I64);
2377 IRTemp d2 = newTemp(Ity_I64);
2378
2379 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2380 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2381 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2382 mkU64(0)));
2383
2384 mnm = irgen(r1, op2addr);
2385
sewardj7ee97522011-05-09 21:45:04 +00002386 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002387 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2388}
2389
2390static void
florian55085f82012-11-21 00:36:55 +00002391s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002392 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2393{
florian55085f82012-11-21 00:36:55 +00002394 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002395 IRTemp op2addr = newTemp(Ity_I64);
2396 IRTemp d2 = newTemp(Ity_I64);
2397
2398 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2399 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2400 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2401 mkU64(0)));
2402
2403 mnm = irgen();
2404
sewardj7ee97522011-05-09 21:45:04 +00002405 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002406 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2407}
2408
2409static void
florian55085f82012-11-21 00:36:55 +00002410s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002411 UChar b2, UShort d2)
2412{
florian55085f82012-11-21 00:36:55 +00002413 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002414 IRTemp op2addr = newTemp(Ity_I64);
2415
2416 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2417 mkU64(0)));
2418
2419 mnm = irgen(op2addr);
2420
sewardj7ee97522011-05-09 21:45:04 +00002421 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002422 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2423}
2424
2425static void
florian55085f82012-11-21 00:36:55 +00002426s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002427 UChar i2, UChar b1, UShort d1)
2428{
florian55085f82012-11-21 00:36:55 +00002429 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002430 IRTemp op1addr = newTemp(Ity_I64);
2431
2432 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2433 mkU64(0)));
2434
2435 mnm = irgen(i2, op1addr);
2436
sewardj7ee97522011-05-09 21:45:04 +00002437 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002438 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2439}
2440
2441static void
florian55085f82012-11-21 00:36:55 +00002442s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002443 UChar i2, UChar b1, UShort dl1, UChar dh1)
2444{
florian55085f82012-11-21 00:36:55 +00002445 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002446 IRTemp op1addr = newTemp(Ity_I64);
2447 IRTemp d1 = newTemp(Ity_I64);
2448
2449 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2450 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2451 mkU64(0)));
2452
2453 mnm = irgen(i2, op1addr);
2454
sewardj7ee97522011-05-09 21:45:04 +00002455 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002456 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2457}
2458
2459static void
florian55085f82012-11-21 00:36:55 +00002460s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002461 UChar i2, UChar b1, UShort dl1, UChar dh1)
2462{
florian55085f82012-11-21 00:36:55 +00002463 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002464 IRTemp op1addr = newTemp(Ity_I64);
2465 IRTemp d1 = newTemp(Ity_I64);
2466
2467 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2468 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2469 mkU64(0)));
2470
2471 mnm = irgen(i2, op1addr);
2472
sewardj7ee97522011-05-09 21:45:04 +00002473 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002474 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2475}
2476
2477static void
florian55085f82012-11-21 00:36:55 +00002478s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002479 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2480{
florian55085f82012-11-21 00:36:55 +00002481 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002482 IRTemp op1addr = newTemp(Ity_I64);
2483 IRTemp op2addr = newTemp(Ity_I64);
2484
2485 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2486 mkU64(0)));
2487 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2488 mkU64(0)));
2489
2490 mnm = irgen(l, op1addr, op2addr);
2491
sewardj7ee97522011-05-09 21:45:04 +00002492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002493 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2494}
2495
2496static void
florian55085f82012-11-21 00:36:55 +00002497s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002498 UChar b1, UShort d1, UShort i2)
2499{
florian55085f82012-11-21 00:36:55 +00002500 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002501 IRTemp op1addr = newTemp(Ity_I64);
2502
2503 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2504 mkU64(0)));
2505
2506 mnm = irgen(i2, op1addr);
2507
sewardj7ee97522011-05-09 21:45:04 +00002508 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002509 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2510}
2511
2512static void
florian55085f82012-11-21 00:36:55 +00002513s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002514 UChar b1, UShort d1, UShort i2)
2515{
florian55085f82012-11-21 00:36:55 +00002516 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002517 IRTemp op1addr = newTemp(Ity_I64);
2518
2519 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2520 mkU64(0)));
2521
2522 mnm = irgen(i2, op1addr);
2523
sewardj7ee97522011-05-09 21:45:04 +00002524 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002525 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2526}
2527
2528
2529
2530/*------------------------------------------------------------*/
2531/*--- Build IR for opcodes ---*/
2532/*------------------------------------------------------------*/
2533
florian55085f82012-11-21 00:36:55 +00002534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002535s390_irgen_AR(UChar r1, UChar r2)
2536{
2537 IRTemp op1 = newTemp(Ity_I32);
2538 IRTemp op2 = newTemp(Ity_I32);
2539 IRTemp result = newTemp(Ity_I32);
2540
2541 assign(op1, get_gpr_w1(r1));
2542 assign(op2, get_gpr_w1(r2));
2543 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2544 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2545 put_gpr_w1(r1, mkexpr(result));
2546
2547 return "ar";
2548}
2549
florian55085f82012-11-21 00:36:55 +00002550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002551s390_irgen_AGR(UChar r1, UChar r2)
2552{
2553 IRTemp op1 = newTemp(Ity_I64);
2554 IRTemp op2 = newTemp(Ity_I64);
2555 IRTemp result = newTemp(Ity_I64);
2556
2557 assign(op1, get_gpr_dw0(r1));
2558 assign(op2, get_gpr_dw0(r2));
2559 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2560 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2561 put_gpr_dw0(r1, mkexpr(result));
2562
2563 return "agr";
2564}
2565
florian55085f82012-11-21 00:36:55 +00002566static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002567s390_irgen_AGFR(UChar r1, UChar r2)
2568{
2569 IRTemp op1 = newTemp(Ity_I64);
2570 IRTemp op2 = newTemp(Ity_I64);
2571 IRTemp result = newTemp(Ity_I64);
2572
2573 assign(op1, get_gpr_dw0(r1));
2574 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2575 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2576 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2577 put_gpr_dw0(r1, mkexpr(result));
2578
2579 return "agfr";
2580}
2581
florian55085f82012-11-21 00:36:55 +00002582static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002583s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2584{
2585 IRTemp op2 = newTemp(Ity_I32);
2586 IRTemp op3 = newTemp(Ity_I32);
2587 IRTemp result = newTemp(Ity_I32);
2588
2589 assign(op2, get_gpr_w1(r2));
2590 assign(op3, get_gpr_w1(r3));
2591 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2592 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2593 put_gpr_w1(r1, mkexpr(result));
2594
2595 return "ark";
2596}
2597
florian55085f82012-11-21 00:36:55 +00002598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002599s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2600{
2601 IRTemp op2 = newTemp(Ity_I64);
2602 IRTemp op3 = newTemp(Ity_I64);
2603 IRTemp result = newTemp(Ity_I64);
2604
2605 assign(op2, get_gpr_dw0(r2));
2606 assign(op3, get_gpr_dw0(r3));
2607 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2608 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2609 put_gpr_dw0(r1, mkexpr(result));
2610
2611 return "agrk";
2612}
2613
florian55085f82012-11-21 00:36:55 +00002614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002615s390_irgen_A(UChar r1, IRTemp op2addr)
2616{
2617 IRTemp op1 = newTemp(Ity_I32);
2618 IRTemp op2 = newTemp(Ity_I32);
2619 IRTemp result = newTemp(Ity_I32);
2620
2621 assign(op1, get_gpr_w1(r1));
2622 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2623 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2624 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2625 put_gpr_w1(r1, mkexpr(result));
2626
2627 return "a";
2628}
2629
florian55085f82012-11-21 00:36:55 +00002630static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002631s390_irgen_AY(UChar r1, IRTemp op2addr)
2632{
2633 IRTemp op1 = newTemp(Ity_I32);
2634 IRTemp op2 = newTemp(Ity_I32);
2635 IRTemp result = newTemp(Ity_I32);
2636
2637 assign(op1, get_gpr_w1(r1));
2638 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2639 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2640 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2641 put_gpr_w1(r1, mkexpr(result));
2642
2643 return "ay";
2644}
2645
florian55085f82012-11-21 00:36:55 +00002646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002647s390_irgen_AG(UChar r1, IRTemp op2addr)
2648{
2649 IRTemp op1 = newTemp(Ity_I64);
2650 IRTemp op2 = newTemp(Ity_I64);
2651 IRTemp result = newTemp(Ity_I64);
2652
2653 assign(op1, get_gpr_dw0(r1));
2654 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2655 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2656 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2657 put_gpr_dw0(r1, mkexpr(result));
2658
2659 return "ag";
2660}
2661
florian55085f82012-11-21 00:36:55 +00002662static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002663s390_irgen_AGF(UChar r1, IRTemp op2addr)
2664{
2665 IRTemp op1 = newTemp(Ity_I64);
2666 IRTemp op2 = newTemp(Ity_I64);
2667 IRTemp result = newTemp(Ity_I64);
2668
2669 assign(op1, get_gpr_dw0(r1));
2670 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2671 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2672 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2673 put_gpr_dw0(r1, mkexpr(result));
2674
2675 return "agf";
2676}
2677
florian55085f82012-11-21 00:36:55 +00002678static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002679s390_irgen_AFI(UChar r1, UInt i2)
2680{
2681 IRTemp op1 = newTemp(Ity_I32);
2682 Int op2;
2683 IRTemp result = newTemp(Ity_I32);
2684
2685 assign(op1, get_gpr_w1(r1));
2686 op2 = (Int)i2;
2687 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2688 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2689 mkU32((UInt)op2)));
2690 put_gpr_w1(r1, mkexpr(result));
2691
2692 return "afi";
2693}
2694
florian55085f82012-11-21 00:36:55 +00002695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002696s390_irgen_AGFI(UChar r1, UInt i2)
2697{
2698 IRTemp op1 = newTemp(Ity_I64);
2699 Long op2;
2700 IRTemp result = newTemp(Ity_I64);
2701
2702 assign(op1, get_gpr_dw0(r1));
2703 op2 = (Long)(Int)i2;
2704 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2705 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2706 mkU64((ULong)op2)));
2707 put_gpr_dw0(r1, mkexpr(result));
2708
2709 return "agfi";
2710}
2711
florian55085f82012-11-21 00:36:55 +00002712static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002713s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2714{
2715 Int op2;
2716 IRTemp op3 = newTemp(Ity_I32);
2717 IRTemp result = newTemp(Ity_I32);
2718
2719 op2 = (Int)(Short)i2;
2720 assign(op3, get_gpr_w1(r3));
2721 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2722 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2723 op2)), op3);
2724 put_gpr_w1(r1, mkexpr(result));
2725
2726 return "ahik";
2727}
2728
florian55085f82012-11-21 00:36:55 +00002729static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002730s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2731{
2732 Long op2;
2733 IRTemp op3 = newTemp(Ity_I64);
2734 IRTemp result = newTemp(Ity_I64);
2735
2736 op2 = (Long)(Short)i2;
2737 assign(op3, get_gpr_dw0(r3));
2738 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2739 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2740 op2)), op3);
2741 put_gpr_dw0(r1, mkexpr(result));
2742
2743 return "aghik";
2744}
2745
florian55085f82012-11-21 00:36:55 +00002746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002747s390_irgen_ASI(UChar i2, IRTemp op1addr)
2748{
2749 IRTemp op1 = newTemp(Ity_I32);
2750 Int op2;
2751 IRTemp result = newTemp(Ity_I32);
2752
2753 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2754 op2 = (Int)(Char)i2;
2755 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2756 store(mkexpr(op1addr), mkexpr(result));
2757 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2758 mkU32((UInt)op2)));
2759
2760 return "asi";
2761}
2762
florian55085f82012-11-21 00:36:55 +00002763static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002764s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2765{
2766 IRTemp op1 = newTemp(Ity_I64);
2767 Long op2;
2768 IRTemp result = newTemp(Ity_I64);
2769
2770 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2771 op2 = (Long)(Char)i2;
2772 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2773 store(mkexpr(op1addr), mkexpr(result));
2774 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2775 mkU64((ULong)op2)));
2776
2777 return "agsi";
2778}
2779
florian55085f82012-11-21 00:36:55 +00002780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002781s390_irgen_AH(UChar r1, IRTemp op2addr)
2782{
2783 IRTemp op1 = newTemp(Ity_I32);
2784 IRTemp op2 = newTemp(Ity_I32);
2785 IRTemp result = newTemp(Ity_I32);
2786
2787 assign(op1, get_gpr_w1(r1));
2788 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2789 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2790 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2791 put_gpr_w1(r1, mkexpr(result));
2792
2793 return "ah";
2794}
2795
florian55085f82012-11-21 00:36:55 +00002796static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002797s390_irgen_AHY(UChar r1, IRTemp op2addr)
2798{
2799 IRTemp op1 = newTemp(Ity_I32);
2800 IRTemp op2 = newTemp(Ity_I32);
2801 IRTemp result = newTemp(Ity_I32);
2802
2803 assign(op1, get_gpr_w1(r1));
2804 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2805 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2806 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2807 put_gpr_w1(r1, mkexpr(result));
2808
2809 return "ahy";
2810}
2811
florian55085f82012-11-21 00:36:55 +00002812static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002813s390_irgen_AHI(UChar r1, UShort i2)
2814{
2815 IRTemp op1 = newTemp(Ity_I32);
2816 Int op2;
2817 IRTemp result = newTemp(Ity_I32);
2818
2819 assign(op1, get_gpr_w1(r1));
2820 op2 = (Int)(Short)i2;
2821 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2822 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2823 mkU32((UInt)op2)));
2824 put_gpr_w1(r1, mkexpr(result));
2825
2826 return "ahi";
2827}
2828
florian55085f82012-11-21 00:36:55 +00002829static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002830s390_irgen_AGHI(UChar r1, UShort i2)
2831{
2832 IRTemp op1 = newTemp(Ity_I64);
2833 Long op2;
2834 IRTemp result = newTemp(Ity_I64);
2835
2836 assign(op1, get_gpr_dw0(r1));
2837 op2 = (Long)(Short)i2;
2838 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2839 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2840 mkU64((ULong)op2)));
2841 put_gpr_dw0(r1, mkexpr(result));
2842
2843 return "aghi";
2844}
2845
florian55085f82012-11-21 00:36:55 +00002846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002847s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2848{
2849 IRTemp op2 = newTemp(Ity_I32);
2850 IRTemp op3 = newTemp(Ity_I32);
2851 IRTemp result = newTemp(Ity_I32);
2852
2853 assign(op2, get_gpr_w0(r2));
2854 assign(op3, get_gpr_w0(r3));
2855 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2856 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2857 put_gpr_w0(r1, mkexpr(result));
2858
2859 return "ahhhr";
2860}
2861
florian55085f82012-11-21 00:36:55 +00002862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002863s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2864{
2865 IRTemp op2 = newTemp(Ity_I32);
2866 IRTemp op3 = newTemp(Ity_I32);
2867 IRTemp result = newTemp(Ity_I32);
2868
2869 assign(op2, get_gpr_w0(r2));
2870 assign(op3, get_gpr_w1(r3));
2871 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2872 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2873 put_gpr_w0(r1, mkexpr(result));
2874
2875 return "ahhlr";
2876}
2877
florian55085f82012-11-21 00:36:55 +00002878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002879s390_irgen_AIH(UChar r1, UInt i2)
2880{
2881 IRTemp op1 = newTemp(Ity_I32);
2882 Int op2;
2883 IRTemp result = newTemp(Ity_I32);
2884
2885 assign(op1, get_gpr_w0(r1));
2886 op2 = (Int)i2;
2887 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2888 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2889 mkU32((UInt)op2)));
2890 put_gpr_w0(r1, mkexpr(result));
2891
2892 return "aih";
2893}
2894
florian55085f82012-11-21 00:36:55 +00002895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002896s390_irgen_ALR(UChar r1, UChar r2)
2897{
2898 IRTemp op1 = newTemp(Ity_I32);
2899 IRTemp op2 = newTemp(Ity_I32);
2900 IRTemp result = newTemp(Ity_I32);
2901
2902 assign(op1, get_gpr_w1(r1));
2903 assign(op2, get_gpr_w1(r2));
2904 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2905 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2906 put_gpr_w1(r1, mkexpr(result));
2907
2908 return "alr";
2909}
2910
florian55085f82012-11-21 00:36:55 +00002911static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002912s390_irgen_ALGR(UChar r1, UChar r2)
2913{
2914 IRTemp op1 = newTemp(Ity_I64);
2915 IRTemp op2 = newTemp(Ity_I64);
2916 IRTemp result = newTemp(Ity_I64);
2917
2918 assign(op1, get_gpr_dw0(r1));
2919 assign(op2, get_gpr_dw0(r2));
2920 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2921 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2922 put_gpr_dw0(r1, mkexpr(result));
2923
2924 return "algr";
2925}
2926
florian55085f82012-11-21 00:36:55 +00002927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002928s390_irgen_ALGFR(UChar r1, UChar r2)
2929{
2930 IRTemp op1 = newTemp(Ity_I64);
2931 IRTemp op2 = newTemp(Ity_I64);
2932 IRTemp result = newTemp(Ity_I64);
2933
2934 assign(op1, get_gpr_dw0(r1));
2935 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2936 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2937 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2938 put_gpr_dw0(r1, mkexpr(result));
2939
2940 return "algfr";
2941}
2942
florian55085f82012-11-21 00:36:55 +00002943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002944s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2945{
2946 IRTemp op2 = newTemp(Ity_I32);
2947 IRTemp op3 = newTemp(Ity_I32);
2948 IRTemp result = newTemp(Ity_I32);
2949
2950 assign(op2, get_gpr_w1(r2));
2951 assign(op3, get_gpr_w1(r3));
2952 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2953 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2954 put_gpr_w1(r1, mkexpr(result));
2955
2956 return "alrk";
2957}
2958
florian55085f82012-11-21 00:36:55 +00002959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002960s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2961{
2962 IRTemp op2 = newTemp(Ity_I64);
2963 IRTemp op3 = newTemp(Ity_I64);
2964 IRTemp result = newTemp(Ity_I64);
2965
2966 assign(op2, get_gpr_dw0(r2));
2967 assign(op3, get_gpr_dw0(r3));
2968 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2969 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2970 put_gpr_dw0(r1, mkexpr(result));
2971
2972 return "algrk";
2973}
2974
florian55085f82012-11-21 00:36:55 +00002975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002976s390_irgen_AL(UChar r1, IRTemp op2addr)
2977{
2978 IRTemp op1 = newTemp(Ity_I32);
2979 IRTemp op2 = newTemp(Ity_I32);
2980 IRTemp result = newTemp(Ity_I32);
2981
2982 assign(op1, get_gpr_w1(r1));
2983 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2984 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2985 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2986 put_gpr_w1(r1, mkexpr(result));
2987
2988 return "al";
2989}
2990
florian55085f82012-11-21 00:36:55 +00002991static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002992s390_irgen_ALY(UChar r1, IRTemp op2addr)
2993{
2994 IRTemp op1 = newTemp(Ity_I32);
2995 IRTemp op2 = newTemp(Ity_I32);
2996 IRTemp result = newTemp(Ity_I32);
2997
2998 assign(op1, get_gpr_w1(r1));
2999 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3000 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3001 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3002 put_gpr_w1(r1, mkexpr(result));
3003
3004 return "aly";
3005}
3006
florian55085f82012-11-21 00:36:55 +00003007static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003008s390_irgen_ALG(UChar r1, IRTemp op2addr)
3009{
3010 IRTemp op1 = newTemp(Ity_I64);
3011 IRTemp op2 = newTemp(Ity_I64);
3012 IRTemp result = newTemp(Ity_I64);
3013
3014 assign(op1, get_gpr_dw0(r1));
3015 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3016 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3017 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3018 put_gpr_dw0(r1, mkexpr(result));
3019
3020 return "alg";
3021}
3022
florian55085f82012-11-21 00:36:55 +00003023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003024s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3025{
3026 IRTemp op1 = newTemp(Ity_I64);
3027 IRTemp op2 = newTemp(Ity_I64);
3028 IRTemp result = newTemp(Ity_I64);
3029
3030 assign(op1, get_gpr_dw0(r1));
3031 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3032 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3033 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3034 put_gpr_dw0(r1, mkexpr(result));
3035
3036 return "algf";
3037}
3038
florian55085f82012-11-21 00:36:55 +00003039static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003040s390_irgen_ALFI(UChar r1, UInt i2)
3041{
3042 IRTemp op1 = newTemp(Ity_I32);
3043 UInt op2;
3044 IRTemp result = newTemp(Ity_I32);
3045
3046 assign(op1, get_gpr_w1(r1));
3047 op2 = i2;
3048 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3049 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3050 mkU32(op2)));
3051 put_gpr_w1(r1, mkexpr(result));
3052
3053 return "alfi";
3054}
3055
florian55085f82012-11-21 00:36:55 +00003056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003057s390_irgen_ALGFI(UChar r1, UInt i2)
3058{
3059 IRTemp op1 = newTemp(Ity_I64);
3060 ULong op2;
3061 IRTemp result = newTemp(Ity_I64);
3062
3063 assign(op1, get_gpr_dw0(r1));
3064 op2 = (ULong)i2;
3065 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3066 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3067 mkU64(op2)));
3068 put_gpr_dw0(r1, mkexpr(result));
3069
3070 return "algfi";
3071}
3072
florian55085f82012-11-21 00:36:55 +00003073static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003074s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3075{
3076 IRTemp op2 = newTemp(Ity_I32);
3077 IRTemp op3 = newTemp(Ity_I32);
3078 IRTemp result = newTemp(Ity_I32);
3079
3080 assign(op2, get_gpr_w0(r2));
3081 assign(op3, get_gpr_w0(r3));
3082 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3083 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3084 put_gpr_w0(r1, mkexpr(result));
3085
3086 return "alhhhr";
3087}
3088
florian55085f82012-11-21 00:36:55 +00003089static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003090s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3091{
3092 IRTemp op2 = newTemp(Ity_I32);
3093 IRTemp op3 = newTemp(Ity_I32);
3094 IRTemp result = newTemp(Ity_I32);
3095
3096 assign(op2, get_gpr_w0(r2));
3097 assign(op3, get_gpr_w1(r3));
3098 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3099 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3100 put_gpr_w0(r1, mkexpr(result));
3101
3102 return "alhhlr";
3103}
3104
florian55085f82012-11-21 00:36:55 +00003105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003106s390_irgen_ALCR(UChar r1, UChar r2)
3107{
3108 IRTemp op1 = newTemp(Ity_I32);
3109 IRTemp op2 = newTemp(Ity_I32);
3110 IRTemp result = newTemp(Ity_I32);
3111 IRTemp carry_in = newTemp(Ity_I32);
3112
3113 assign(op1, get_gpr_w1(r1));
3114 assign(op2, get_gpr_w1(r2));
3115 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3116 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3117 mkexpr(carry_in)));
3118 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3119 put_gpr_w1(r1, mkexpr(result));
3120
3121 return "alcr";
3122}
3123
florian55085f82012-11-21 00:36:55 +00003124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003125s390_irgen_ALCGR(UChar r1, UChar r2)
3126{
3127 IRTemp op1 = newTemp(Ity_I64);
3128 IRTemp op2 = newTemp(Ity_I64);
3129 IRTemp result = newTemp(Ity_I64);
3130 IRTemp carry_in = newTemp(Ity_I64);
3131
3132 assign(op1, get_gpr_dw0(r1));
3133 assign(op2, get_gpr_dw0(r2));
3134 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3135 mkU8(1))));
3136 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3137 mkexpr(carry_in)));
3138 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3139 put_gpr_dw0(r1, mkexpr(result));
3140
3141 return "alcgr";
3142}
3143
florian55085f82012-11-21 00:36:55 +00003144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003145s390_irgen_ALC(UChar r1, IRTemp op2addr)
3146{
3147 IRTemp op1 = newTemp(Ity_I32);
3148 IRTemp op2 = newTemp(Ity_I32);
3149 IRTemp result = newTemp(Ity_I32);
3150 IRTemp carry_in = newTemp(Ity_I32);
3151
3152 assign(op1, get_gpr_w1(r1));
3153 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3154 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3155 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3156 mkexpr(carry_in)));
3157 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3158 put_gpr_w1(r1, mkexpr(result));
3159
3160 return "alc";
3161}
3162
florian55085f82012-11-21 00:36:55 +00003163static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003164s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3165{
3166 IRTemp op1 = newTemp(Ity_I64);
3167 IRTemp op2 = newTemp(Ity_I64);
3168 IRTemp result = newTemp(Ity_I64);
3169 IRTemp carry_in = newTemp(Ity_I64);
3170
3171 assign(op1, get_gpr_dw0(r1));
3172 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3173 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3174 mkU8(1))));
3175 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3176 mkexpr(carry_in)));
3177 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3178 put_gpr_dw0(r1, mkexpr(result));
3179
3180 return "alcg";
3181}
3182
florian55085f82012-11-21 00:36:55 +00003183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003184s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3185{
3186 IRTemp op1 = newTemp(Ity_I32);
3187 UInt op2;
3188 IRTemp result = newTemp(Ity_I32);
3189
3190 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3191 op2 = (UInt)(Int)(Char)i2;
3192 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3193 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3194 mkU32(op2)));
3195 store(mkexpr(op1addr), mkexpr(result));
3196
3197 return "alsi";
3198}
3199
florian55085f82012-11-21 00:36:55 +00003200static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003201s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3202{
3203 IRTemp op1 = newTemp(Ity_I64);
3204 ULong op2;
3205 IRTemp result = newTemp(Ity_I64);
3206
3207 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3208 op2 = (ULong)(Long)(Char)i2;
3209 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3210 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3211 mkU64(op2)));
3212 store(mkexpr(op1addr), mkexpr(result));
3213
3214 return "algsi";
3215}
3216
florian55085f82012-11-21 00:36:55 +00003217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003218s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3219{
3220 UInt op2;
3221 IRTemp op3 = newTemp(Ity_I32);
3222 IRTemp result = newTemp(Ity_I32);
3223
3224 op2 = (UInt)(Int)(Short)i2;
3225 assign(op3, get_gpr_w1(r3));
3226 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3227 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3228 op3);
3229 put_gpr_w1(r1, mkexpr(result));
3230
3231 return "alhsik";
3232}
3233
florian55085f82012-11-21 00:36:55 +00003234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003235s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3236{
3237 ULong op2;
3238 IRTemp op3 = newTemp(Ity_I64);
3239 IRTemp result = newTemp(Ity_I64);
3240
3241 op2 = (ULong)(Long)(Short)i2;
3242 assign(op3, get_gpr_dw0(r3));
3243 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3244 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3245 op3);
3246 put_gpr_dw0(r1, mkexpr(result));
3247
3248 return "alghsik";
3249}
3250
florian55085f82012-11-21 00:36:55 +00003251static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003252s390_irgen_ALSIH(UChar r1, UInt i2)
3253{
3254 IRTemp op1 = newTemp(Ity_I32);
3255 UInt op2;
3256 IRTemp result = newTemp(Ity_I32);
3257
3258 assign(op1, get_gpr_w0(r1));
3259 op2 = i2;
3260 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3261 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3262 mkU32(op2)));
3263 put_gpr_w0(r1, mkexpr(result));
3264
3265 return "alsih";
3266}
3267
florian55085f82012-11-21 00:36:55 +00003268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003269s390_irgen_ALSIHN(UChar r1, UInt i2)
3270{
3271 IRTemp op1 = newTemp(Ity_I32);
3272 UInt op2;
3273 IRTemp result = newTemp(Ity_I32);
3274
3275 assign(op1, get_gpr_w0(r1));
3276 op2 = i2;
3277 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3278 put_gpr_w0(r1, mkexpr(result));
3279
3280 return "alsihn";
3281}
3282
florian55085f82012-11-21 00:36:55 +00003283static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003284s390_irgen_NR(UChar r1, UChar r2)
3285{
3286 IRTemp op1 = newTemp(Ity_I32);
3287 IRTemp op2 = newTemp(Ity_I32);
3288 IRTemp result = newTemp(Ity_I32);
3289
3290 assign(op1, get_gpr_w1(r1));
3291 assign(op2, get_gpr_w1(r2));
3292 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3293 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3294 put_gpr_w1(r1, mkexpr(result));
3295
3296 return "nr";
3297}
3298
florian55085f82012-11-21 00:36:55 +00003299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003300s390_irgen_NGR(UChar r1, UChar r2)
3301{
3302 IRTemp op1 = newTemp(Ity_I64);
3303 IRTemp op2 = newTemp(Ity_I64);
3304 IRTemp result = newTemp(Ity_I64);
3305
3306 assign(op1, get_gpr_dw0(r1));
3307 assign(op2, get_gpr_dw0(r2));
3308 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3309 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3310 put_gpr_dw0(r1, mkexpr(result));
3311
3312 return "ngr";
3313}
3314
florian55085f82012-11-21 00:36:55 +00003315static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003316s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3317{
3318 IRTemp op2 = newTemp(Ity_I32);
3319 IRTemp op3 = newTemp(Ity_I32);
3320 IRTemp result = newTemp(Ity_I32);
3321
3322 assign(op2, get_gpr_w1(r2));
3323 assign(op3, get_gpr_w1(r3));
3324 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3325 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3326 put_gpr_w1(r1, mkexpr(result));
3327
3328 return "nrk";
3329}
3330
florian55085f82012-11-21 00:36:55 +00003331static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003332s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3333{
3334 IRTemp op2 = newTemp(Ity_I64);
3335 IRTemp op3 = newTemp(Ity_I64);
3336 IRTemp result = newTemp(Ity_I64);
3337
3338 assign(op2, get_gpr_dw0(r2));
3339 assign(op3, get_gpr_dw0(r3));
3340 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3341 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3342 put_gpr_dw0(r1, mkexpr(result));
3343
3344 return "ngrk";
3345}
3346
florian55085f82012-11-21 00:36:55 +00003347static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003348s390_irgen_N(UChar r1, IRTemp op2addr)
3349{
3350 IRTemp op1 = newTemp(Ity_I32);
3351 IRTemp op2 = newTemp(Ity_I32);
3352 IRTemp result = newTemp(Ity_I32);
3353
3354 assign(op1, get_gpr_w1(r1));
3355 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3356 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3357 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3358 put_gpr_w1(r1, mkexpr(result));
3359
3360 return "n";
3361}
3362
florian55085f82012-11-21 00:36:55 +00003363static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003364s390_irgen_NY(UChar r1, IRTemp op2addr)
3365{
3366 IRTemp op1 = newTemp(Ity_I32);
3367 IRTemp op2 = newTemp(Ity_I32);
3368 IRTemp result = newTemp(Ity_I32);
3369
3370 assign(op1, get_gpr_w1(r1));
3371 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3372 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3373 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3374 put_gpr_w1(r1, mkexpr(result));
3375
3376 return "ny";
3377}
3378
florian55085f82012-11-21 00:36:55 +00003379static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003380s390_irgen_NG(UChar r1, IRTemp op2addr)
3381{
3382 IRTemp op1 = newTemp(Ity_I64);
3383 IRTemp op2 = newTemp(Ity_I64);
3384 IRTemp result = newTemp(Ity_I64);
3385
3386 assign(op1, get_gpr_dw0(r1));
3387 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3388 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3389 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3390 put_gpr_dw0(r1, mkexpr(result));
3391
3392 return "ng";
3393}
3394
florian55085f82012-11-21 00:36:55 +00003395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003396s390_irgen_NI(UChar i2, IRTemp op1addr)
3397{
3398 IRTemp op1 = newTemp(Ity_I8);
3399 UChar op2;
3400 IRTemp result = newTemp(Ity_I8);
3401
3402 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3403 op2 = i2;
3404 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3405 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3406 store(mkexpr(op1addr), mkexpr(result));
3407
3408 return "ni";
3409}
3410
florian55085f82012-11-21 00:36:55 +00003411static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003412s390_irgen_NIY(UChar i2, IRTemp op1addr)
3413{
3414 IRTemp op1 = newTemp(Ity_I8);
3415 UChar op2;
3416 IRTemp result = newTemp(Ity_I8);
3417
3418 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3419 op2 = i2;
3420 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3421 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3422 store(mkexpr(op1addr), mkexpr(result));
3423
3424 return "niy";
3425}
3426
florian55085f82012-11-21 00:36:55 +00003427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003428s390_irgen_NIHF(UChar r1, UInt i2)
3429{
3430 IRTemp op1 = newTemp(Ity_I32);
3431 UInt op2;
3432 IRTemp result = newTemp(Ity_I32);
3433
3434 assign(op1, get_gpr_w0(r1));
3435 op2 = i2;
3436 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3437 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3438 put_gpr_w0(r1, mkexpr(result));
3439
3440 return "nihf";
3441}
3442
florian55085f82012-11-21 00:36:55 +00003443static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003444s390_irgen_NIHH(UChar r1, UShort i2)
3445{
3446 IRTemp op1 = newTemp(Ity_I16);
3447 UShort op2;
3448 IRTemp result = newTemp(Ity_I16);
3449
3450 assign(op1, get_gpr_hw0(r1));
3451 op2 = i2;
3452 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3453 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3454 put_gpr_hw0(r1, mkexpr(result));
3455
3456 return "nihh";
3457}
3458
florian55085f82012-11-21 00:36:55 +00003459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003460s390_irgen_NIHL(UChar r1, UShort i2)
3461{
3462 IRTemp op1 = newTemp(Ity_I16);
3463 UShort op2;
3464 IRTemp result = newTemp(Ity_I16);
3465
3466 assign(op1, get_gpr_hw1(r1));
3467 op2 = i2;
3468 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3469 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3470 put_gpr_hw1(r1, mkexpr(result));
3471
3472 return "nihl";
3473}
3474
florian55085f82012-11-21 00:36:55 +00003475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003476s390_irgen_NILF(UChar r1, UInt i2)
3477{
3478 IRTemp op1 = newTemp(Ity_I32);
3479 UInt op2;
3480 IRTemp result = newTemp(Ity_I32);
3481
3482 assign(op1, get_gpr_w1(r1));
3483 op2 = i2;
3484 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3485 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3486 put_gpr_w1(r1, mkexpr(result));
3487
3488 return "nilf";
3489}
3490
florian55085f82012-11-21 00:36:55 +00003491static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003492s390_irgen_NILH(UChar r1, UShort i2)
3493{
3494 IRTemp op1 = newTemp(Ity_I16);
3495 UShort op2;
3496 IRTemp result = newTemp(Ity_I16);
3497
3498 assign(op1, get_gpr_hw2(r1));
3499 op2 = i2;
3500 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3501 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3502 put_gpr_hw2(r1, mkexpr(result));
3503
3504 return "nilh";
3505}
3506
florian55085f82012-11-21 00:36:55 +00003507static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003508s390_irgen_NILL(UChar r1, UShort i2)
3509{
3510 IRTemp op1 = newTemp(Ity_I16);
3511 UShort op2;
3512 IRTemp result = newTemp(Ity_I16);
3513
3514 assign(op1, get_gpr_hw3(r1));
3515 op2 = i2;
3516 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3517 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3518 put_gpr_hw3(r1, mkexpr(result));
3519
3520 return "nill";
3521}
3522
florian55085f82012-11-21 00:36:55 +00003523static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003524s390_irgen_BASR(UChar r1, UChar r2)
3525{
3526 IRTemp target = newTemp(Ity_I64);
3527
3528 if (r2 == 0) {
3529 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3530 } else {
3531 if (r1 != r2) {
3532 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3533 call_function(get_gpr_dw0(r2));
3534 } else {
3535 assign(target, get_gpr_dw0(r2));
3536 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3537 call_function(mkexpr(target));
3538 }
3539 }
3540
3541 return "basr";
3542}
3543
florian55085f82012-11-21 00:36:55 +00003544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003545s390_irgen_BAS(UChar r1, IRTemp op2addr)
3546{
3547 IRTemp target = newTemp(Ity_I64);
3548
3549 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3550 assign(target, mkexpr(op2addr));
3551 call_function(mkexpr(target));
3552
3553 return "bas";
3554}
3555
florian55085f82012-11-21 00:36:55 +00003556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003557s390_irgen_BCR(UChar r1, UChar r2)
3558{
3559 IRTemp cond = newTemp(Ity_I32);
3560
sewardja52e37e2011-04-28 18:48:06 +00003561 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3562 stmt(IRStmt_MBE(Imbe_Fence));
3563 }
3564
sewardj2019a972011-03-07 16:04:07 +00003565 if ((r2 == 0) || (r1 == 0)) {
3566 } else {
3567 if (r1 == 15) {
3568 return_from_function(get_gpr_dw0(r2));
3569 } else {
3570 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003571 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3572 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003573 }
3574 }
sewardj7ee97522011-05-09 21:45:04 +00003575 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003576 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3577
3578 return "bcr";
3579}
3580
florian55085f82012-11-21 00:36:55 +00003581static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003582s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3583{
3584 IRTemp cond = newTemp(Ity_I32);
3585
3586 if (r1 == 0) {
3587 } else {
3588 if (r1 == 15) {
3589 always_goto(mkexpr(op2addr));
3590 } else {
3591 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003592 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3593 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003594 }
3595 }
sewardj7ee97522011-05-09 21:45:04 +00003596 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003597 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3598
3599 return "bc";
3600}
3601
florian55085f82012-11-21 00:36:55 +00003602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003603s390_irgen_BCTR(UChar r1, UChar r2)
3604{
3605 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3606 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003607 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3608 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003609 }
3610
3611 return "bctr";
3612}
3613
florian55085f82012-11-21 00:36:55 +00003614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003615s390_irgen_BCTGR(UChar r1, UChar r2)
3616{
3617 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3618 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003619 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3620 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003621 }
3622
3623 return "bctgr";
3624}
3625
florian55085f82012-11-21 00:36:55 +00003626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003627s390_irgen_BCT(UChar r1, IRTemp op2addr)
3628{
3629 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003630 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3631 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003632
3633 return "bct";
3634}
3635
florian55085f82012-11-21 00:36:55 +00003636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003637s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3638{
3639 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003640 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3641 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003642
3643 return "bctg";
3644}
3645
florian55085f82012-11-21 00:36:55 +00003646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003647s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3648{
3649 IRTemp value = newTemp(Ity_I32);
3650
3651 assign(value, get_gpr_w1(r3 | 1));
3652 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003653 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3654 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003655
3656 return "bxh";
3657}
3658
florian55085f82012-11-21 00:36:55 +00003659static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003660s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3661{
3662 IRTemp value = newTemp(Ity_I64);
3663
3664 assign(value, get_gpr_dw0(r3 | 1));
3665 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003666 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3667 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003668
3669 return "bxhg";
3670}
3671
florian55085f82012-11-21 00:36:55 +00003672static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003673s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3674{
3675 IRTemp value = newTemp(Ity_I32);
3676
3677 assign(value, get_gpr_w1(r3 | 1));
3678 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003679 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3680 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003681
3682 return "bxle";
3683}
3684
florian55085f82012-11-21 00:36:55 +00003685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003686s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3687{
3688 IRTemp value = newTemp(Ity_I64);
3689
3690 assign(value, get_gpr_dw0(r3 | 1));
3691 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003692 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3693 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003694
3695 return "bxleg";
3696}
3697
florian55085f82012-11-21 00:36:55 +00003698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003699s390_irgen_BRAS(UChar r1, UShort i2)
3700{
3701 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003702 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003703
3704 return "bras";
3705}
3706
florian55085f82012-11-21 00:36:55 +00003707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003708s390_irgen_BRASL(UChar r1, UInt i2)
3709{
3710 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003711 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003712
3713 return "brasl";
3714}
3715
florian55085f82012-11-21 00:36:55 +00003716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003717s390_irgen_BRC(UChar r1, UShort i2)
3718{
3719 IRTemp cond = newTemp(Ity_I32);
3720
3721 if (r1 == 0) {
3722 } else {
3723 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003724 always_goto_and_chase(
3725 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003726 } else {
3727 assign(cond, s390_call_calculate_cond(r1));
3728 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3729 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3730
3731 }
3732 }
sewardj7ee97522011-05-09 21:45:04 +00003733 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003734 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3735
3736 return "brc";
3737}
3738
florian55085f82012-11-21 00:36:55 +00003739static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003740s390_irgen_BRCL(UChar r1, UInt i2)
3741{
3742 IRTemp cond = newTemp(Ity_I32);
3743
3744 if (r1 == 0) {
3745 } else {
3746 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003747 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003748 } else {
3749 assign(cond, s390_call_calculate_cond(r1));
3750 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3751 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3752 }
3753 }
sewardj7ee97522011-05-09 21:45:04 +00003754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003755 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3756
3757 return "brcl";
3758}
3759
florian55085f82012-11-21 00:36:55 +00003760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003761s390_irgen_BRCT(UChar r1, UShort i2)
3762{
3763 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3764 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3765 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3766
3767 return "brct";
3768}
3769
florian55085f82012-11-21 00:36:55 +00003770static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003771s390_irgen_BRCTG(UChar r1, UShort i2)
3772{
3773 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3774 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3775 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3776
3777 return "brctg";
3778}
3779
florian55085f82012-11-21 00:36:55 +00003780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003781s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3782{
3783 IRTemp value = newTemp(Ity_I32);
3784
3785 assign(value, get_gpr_w1(r3 | 1));
3786 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3787 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3788 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3789
3790 return "brxh";
3791}
3792
florian55085f82012-11-21 00:36:55 +00003793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003794s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3795{
3796 IRTemp value = newTemp(Ity_I64);
3797
3798 assign(value, get_gpr_dw0(r3 | 1));
3799 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3800 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3801 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3802
3803 return "brxhg";
3804}
3805
florian55085f82012-11-21 00:36:55 +00003806static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003807s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3808{
3809 IRTemp value = newTemp(Ity_I32);
3810
3811 assign(value, get_gpr_w1(r3 | 1));
3812 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3813 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3814 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3815
3816 return "brxle";
3817}
3818
florian55085f82012-11-21 00:36:55 +00003819static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003820s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3821{
3822 IRTemp value = newTemp(Ity_I64);
3823
3824 assign(value, get_gpr_dw0(r3 | 1));
3825 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3826 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3827 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3828
3829 return "brxlg";
3830}
3831
florian55085f82012-11-21 00:36:55 +00003832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003833s390_irgen_CR(UChar r1, UChar r2)
3834{
3835 IRTemp op1 = newTemp(Ity_I32);
3836 IRTemp op2 = newTemp(Ity_I32);
3837
3838 assign(op1, get_gpr_w1(r1));
3839 assign(op2, get_gpr_w1(r2));
3840 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3841
3842 return "cr";
3843}
3844
florian55085f82012-11-21 00:36:55 +00003845static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003846s390_irgen_CGR(UChar r1, UChar r2)
3847{
3848 IRTemp op1 = newTemp(Ity_I64);
3849 IRTemp op2 = newTemp(Ity_I64);
3850
3851 assign(op1, get_gpr_dw0(r1));
3852 assign(op2, get_gpr_dw0(r2));
3853 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3854
3855 return "cgr";
3856}
3857
florian55085f82012-11-21 00:36:55 +00003858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003859s390_irgen_CGFR(UChar r1, UChar r2)
3860{
3861 IRTemp op1 = newTemp(Ity_I64);
3862 IRTemp op2 = newTemp(Ity_I64);
3863
3864 assign(op1, get_gpr_dw0(r1));
3865 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3866 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3867
3868 return "cgfr";
3869}
3870
florian55085f82012-11-21 00:36:55 +00003871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003872s390_irgen_C(UChar r1, IRTemp op2addr)
3873{
3874 IRTemp op1 = newTemp(Ity_I32);
3875 IRTemp op2 = newTemp(Ity_I32);
3876
3877 assign(op1, get_gpr_w1(r1));
3878 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3879 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3880
3881 return "c";
3882}
3883
florian55085f82012-11-21 00:36:55 +00003884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003885s390_irgen_CY(UChar r1, IRTemp op2addr)
3886{
3887 IRTemp op1 = newTemp(Ity_I32);
3888 IRTemp op2 = newTemp(Ity_I32);
3889
3890 assign(op1, get_gpr_w1(r1));
3891 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3892 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3893
3894 return "cy";
3895}
3896
florian55085f82012-11-21 00:36:55 +00003897static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003898s390_irgen_CG(UChar r1, IRTemp op2addr)
3899{
3900 IRTemp op1 = newTemp(Ity_I64);
3901 IRTemp op2 = newTemp(Ity_I64);
3902
3903 assign(op1, get_gpr_dw0(r1));
3904 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3905 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3906
3907 return "cg";
3908}
3909
florian55085f82012-11-21 00:36:55 +00003910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003911s390_irgen_CGF(UChar r1, IRTemp op2addr)
3912{
3913 IRTemp op1 = newTemp(Ity_I64);
3914 IRTemp op2 = newTemp(Ity_I64);
3915
3916 assign(op1, get_gpr_dw0(r1));
3917 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3918 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3919
3920 return "cgf";
3921}
3922
florian55085f82012-11-21 00:36:55 +00003923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003924s390_irgen_CFI(UChar r1, UInt i2)
3925{
3926 IRTemp op1 = newTemp(Ity_I32);
3927 Int op2;
3928
3929 assign(op1, get_gpr_w1(r1));
3930 op2 = (Int)i2;
3931 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3932 mkU32((UInt)op2)));
3933
3934 return "cfi";
3935}
3936
florian55085f82012-11-21 00:36:55 +00003937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003938s390_irgen_CGFI(UChar r1, UInt i2)
3939{
3940 IRTemp op1 = newTemp(Ity_I64);
3941 Long op2;
3942
3943 assign(op1, get_gpr_dw0(r1));
3944 op2 = (Long)(Int)i2;
3945 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3946 mkU64((ULong)op2)));
3947
3948 return "cgfi";
3949}
3950
florian55085f82012-11-21 00:36:55 +00003951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003952s390_irgen_CRL(UChar r1, UInt i2)
3953{
3954 IRTemp op1 = newTemp(Ity_I32);
3955 IRTemp op2 = newTemp(Ity_I32);
3956
3957 assign(op1, get_gpr_w1(r1));
3958 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3959 i2 << 1))));
3960 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3961
3962 return "crl";
3963}
3964
florian55085f82012-11-21 00:36:55 +00003965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003966s390_irgen_CGRL(UChar r1, UInt i2)
3967{
3968 IRTemp op1 = newTemp(Ity_I64);
3969 IRTemp op2 = newTemp(Ity_I64);
3970
3971 assign(op1, get_gpr_dw0(r1));
3972 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3973 i2 << 1))));
3974 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3975
3976 return "cgrl";
3977}
3978
florian55085f82012-11-21 00:36:55 +00003979static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003980s390_irgen_CGFRL(UChar r1, UInt i2)
3981{
3982 IRTemp op1 = newTemp(Ity_I64);
3983 IRTemp op2 = newTemp(Ity_I64);
3984
3985 assign(op1, get_gpr_dw0(r1));
3986 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3987 ((ULong)(Long)(Int)i2 << 1)))));
3988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3989
3990 return "cgfrl";
3991}
3992
florian55085f82012-11-21 00:36:55 +00003993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003994s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3995{
3996 IRTemp op1 = newTemp(Ity_I32);
3997 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003998 IRTemp cond = newTemp(Ity_I32);
3999
4000 if (m3 == 0) {
4001 } else {
4002 if (m3 == 14) {
4003 always_goto(mkexpr(op4addr));
4004 } else {
4005 assign(op1, get_gpr_w1(r1));
4006 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004007 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4008 op1, op2));
florianf321da72012-07-21 20:32:57 +00004009 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4010 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004011 }
4012 }
4013
4014 return "crb";
4015}
4016
florian55085f82012-11-21 00:36:55 +00004017static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004018s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4019{
4020 IRTemp op1 = newTemp(Ity_I64);
4021 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004022 IRTemp cond = newTemp(Ity_I32);
4023
4024 if (m3 == 0) {
4025 } else {
4026 if (m3 == 14) {
4027 always_goto(mkexpr(op4addr));
4028 } else {
4029 assign(op1, get_gpr_dw0(r1));
4030 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004031 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4032 op1, op2));
florianf321da72012-07-21 20:32:57 +00004033 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4034 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004035 }
4036 }
4037
4038 return "cgrb";
4039}
4040
florian55085f82012-11-21 00:36:55 +00004041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004042s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4043{
4044 IRTemp op1 = newTemp(Ity_I32);
4045 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004046 IRTemp cond = newTemp(Ity_I32);
4047
4048 if (m3 == 0) {
4049 } else {
4050 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004051 always_goto_and_chase(
4052 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004053 } else {
4054 assign(op1, get_gpr_w1(r1));
4055 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004056 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4057 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004058 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4059 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4060
4061 }
4062 }
4063
4064 return "crj";
4065}
4066
florian55085f82012-11-21 00:36:55 +00004067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004068s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4069{
4070 IRTemp op1 = newTemp(Ity_I64);
4071 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004072 IRTemp cond = newTemp(Ity_I32);
4073
4074 if (m3 == 0) {
4075 } else {
4076 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004077 always_goto_and_chase(
4078 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004079 } else {
4080 assign(op1, get_gpr_dw0(r1));
4081 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004082 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4083 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004084 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4085 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4086
4087 }
4088 }
4089
4090 return "cgrj";
4091}
4092
florian55085f82012-11-21 00:36:55 +00004093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004094s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4095{
4096 IRTemp op1 = newTemp(Ity_I32);
4097 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004098 IRTemp cond = newTemp(Ity_I32);
4099
4100 if (m3 == 0) {
4101 } else {
4102 if (m3 == 14) {
4103 always_goto(mkexpr(op4addr));
4104 } else {
4105 assign(op1, get_gpr_w1(r1));
4106 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004107 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4108 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004109 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4110 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004111 }
4112 }
4113
4114 return "cib";
4115}
4116
florian55085f82012-11-21 00:36:55 +00004117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004118s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4119{
4120 IRTemp op1 = newTemp(Ity_I64);
4121 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004122 IRTemp cond = newTemp(Ity_I32);
4123
4124 if (m3 == 0) {
4125 } else {
4126 if (m3 == 14) {
4127 always_goto(mkexpr(op4addr));
4128 } else {
4129 assign(op1, get_gpr_dw0(r1));
4130 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004131 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4132 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004133 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4134 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004135 }
4136 }
4137
4138 return "cgib";
4139}
4140
florian55085f82012-11-21 00:36:55 +00004141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004142s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4143{
4144 IRTemp op1 = newTemp(Ity_I32);
4145 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004146 IRTemp cond = newTemp(Ity_I32);
4147
4148 if (m3 == 0) {
4149 } else {
4150 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004151 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004152 } else {
4153 assign(op1, get_gpr_w1(r1));
4154 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004155 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4156 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004157 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4158 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4159
4160 }
4161 }
4162
4163 return "cij";
4164}
4165
florian55085f82012-11-21 00:36:55 +00004166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004167s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4168{
4169 IRTemp op1 = newTemp(Ity_I64);
4170 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004171 IRTemp cond = newTemp(Ity_I32);
4172
4173 if (m3 == 0) {
4174 } else {
4175 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004176 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004177 } else {
4178 assign(op1, get_gpr_dw0(r1));
4179 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004180 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4181 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004182 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4183 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4184
4185 }
4186 }
4187
4188 return "cgij";
4189}
4190
florian55085f82012-11-21 00:36:55 +00004191static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004192s390_irgen_CH(UChar r1, IRTemp op2addr)
4193{
4194 IRTemp op1 = newTemp(Ity_I32);
4195 IRTemp op2 = newTemp(Ity_I32);
4196
4197 assign(op1, get_gpr_w1(r1));
4198 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4199 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4200
4201 return "ch";
4202}
4203
florian55085f82012-11-21 00:36:55 +00004204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004205s390_irgen_CHY(UChar r1, IRTemp op2addr)
4206{
4207 IRTemp op1 = newTemp(Ity_I32);
4208 IRTemp op2 = newTemp(Ity_I32);
4209
4210 assign(op1, get_gpr_w1(r1));
4211 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4212 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4213
4214 return "chy";
4215}
4216
florian55085f82012-11-21 00:36:55 +00004217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004218s390_irgen_CGH(UChar r1, IRTemp op2addr)
4219{
4220 IRTemp op1 = newTemp(Ity_I64);
4221 IRTemp op2 = newTemp(Ity_I64);
4222
4223 assign(op1, get_gpr_dw0(r1));
4224 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4225 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4226
4227 return "cgh";
4228}
4229
florian55085f82012-11-21 00:36:55 +00004230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004231s390_irgen_CHI(UChar r1, UShort i2)
4232{
4233 IRTemp op1 = newTemp(Ity_I32);
4234 Int op2;
4235
4236 assign(op1, get_gpr_w1(r1));
4237 op2 = (Int)(Short)i2;
4238 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4239 mkU32((UInt)op2)));
4240
4241 return "chi";
4242}
4243
florian55085f82012-11-21 00:36:55 +00004244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004245s390_irgen_CGHI(UChar r1, UShort i2)
4246{
4247 IRTemp op1 = newTemp(Ity_I64);
4248 Long op2;
4249
4250 assign(op1, get_gpr_dw0(r1));
4251 op2 = (Long)(Short)i2;
4252 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4253 mkU64((ULong)op2)));
4254
4255 return "cghi";
4256}
4257
florian55085f82012-11-21 00:36:55 +00004258static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004259s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4260{
4261 IRTemp op1 = newTemp(Ity_I16);
4262 Short op2;
4263
4264 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4265 op2 = (Short)i2;
4266 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4267 mkU16((UShort)op2)));
4268
4269 return "chhsi";
4270}
4271
florian55085f82012-11-21 00:36:55 +00004272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004273s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4274{
4275 IRTemp op1 = newTemp(Ity_I32);
4276 Int op2;
4277
4278 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4279 op2 = (Int)(Short)i2;
4280 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4281 mkU32((UInt)op2)));
4282
4283 return "chsi";
4284}
4285
florian55085f82012-11-21 00:36:55 +00004286static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004287s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4288{
4289 IRTemp op1 = newTemp(Ity_I64);
4290 Long op2;
4291
4292 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4293 op2 = (Long)(Short)i2;
4294 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4295 mkU64((ULong)op2)));
4296
4297 return "cghsi";
4298}
4299
florian55085f82012-11-21 00:36:55 +00004300static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004301s390_irgen_CHRL(UChar r1, UInt i2)
4302{
4303 IRTemp op1 = newTemp(Ity_I32);
4304 IRTemp op2 = newTemp(Ity_I32);
4305
4306 assign(op1, get_gpr_w1(r1));
4307 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4308 ((ULong)(Long)(Int)i2 << 1)))));
4309 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4310
4311 return "chrl";
4312}
4313
florian55085f82012-11-21 00:36:55 +00004314static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004315s390_irgen_CGHRL(UChar r1, UInt i2)
4316{
4317 IRTemp op1 = newTemp(Ity_I64);
4318 IRTemp op2 = newTemp(Ity_I64);
4319
4320 assign(op1, get_gpr_dw0(r1));
4321 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4322 ((ULong)(Long)(Int)i2 << 1)))));
4323 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4324
4325 return "cghrl";
4326}
4327
florian55085f82012-11-21 00:36:55 +00004328static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004329s390_irgen_CHHR(UChar r1, UChar r2)
4330{
4331 IRTemp op1 = newTemp(Ity_I32);
4332 IRTemp op2 = newTemp(Ity_I32);
4333
4334 assign(op1, get_gpr_w0(r1));
4335 assign(op2, get_gpr_w0(r2));
4336 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4337
4338 return "chhr";
4339}
4340
florian55085f82012-11-21 00:36:55 +00004341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004342s390_irgen_CHLR(UChar r1, UChar r2)
4343{
4344 IRTemp op1 = newTemp(Ity_I32);
4345 IRTemp op2 = newTemp(Ity_I32);
4346
4347 assign(op1, get_gpr_w0(r1));
4348 assign(op2, get_gpr_w1(r2));
4349 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4350
4351 return "chlr";
4352}
4353
florian55085f82012-11-21 00:36:55 +00004354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004355s390_irgen_CHF(UChar r1, IRTemp op2addr)
4356{
4357 IRTemp op1 = newTemp(Ity_I32);
4358 IRTemp op2 = newTemp(Ity_I32);
4359
4360 assign(op1, get_gpr_w0(r1));
4361 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4362 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4363
4364 return "chf";
4365}
4366
florian55085f82012-11-21 00:36:55 +00004367static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004368s390_irgen_CIH(UChar r1, UInt i2)
4369{
4370 IRTemp op1 = newTemp(Ity_I32);
4371 Int op2;
4372
4373 assign(op1, get_gpr_w0(r1));
4374 op2 = (Int)i2;
4375 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4376 mkU32((UInt)op2)));
4377
4378 return "cih";
4379}
4380
florian55085f82012-11-21 00:36:55 +00004381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004382s390_irgen_CLR(UChar r1, UChar r2)
4383{
4384 IRTemp op1 = newTemp(Ity_I32);
4385 IRTemp op2 = newTemp(Ity_I32);
4386
4387 assign(op1, get_gpr_w1(r1));
4388 assign(op2, get_gpr_w1(r2));
4389 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4390
4391 return "clr";
4392}
4393
florian55085f82012-11-21 00:36:55 +00004394static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004395s390_irgen_CLGR(UChar r1, UChar r2)
4396{
4397 IRTemp op1 = newTemp(Ity_I64);
4398 IRTemp op2 = newTemp(Ity_I64);
4399
4400 assign(op1, get_gpr_dw0(r1));
4401 assign(op2, get_gpr_dw0(r2));
4402 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4403
4404 return "clgr";
4405}
4406
florian55085f82012-11-21 00:36:55 +00004407static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004408s390_irgen_CLGFR(UChar r1, UChar r2)
4409{
4410 IRTemp op1 = newTemp(Ity_I64);
4411 IRTemp op2 = newTemp(Ity_I64);
4412
4413 assign(op1, get_gpr_dw0(r1));
4414 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4415 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4416
4417 return "clgfr";
4418}
4419
florian55085f82012-11-21 00:36:55 +00004420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004421s390_irgen_CL(UChar r1, IRTemp op2addr)
4422{
4423 IRTemp op1 = newTemp(Ity_I32);
4424 IRTemp op2 = newTemp(Ity_I32);
4425
4426 assign(op1, get_gpr_w1(r1));
4427 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4428 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4429
4430 return "cl";
4431}
4432
florian55085f82012-11-21 00:36:55 +00004433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004434s390_irgen_CLY(UChar r1, IRTemp op2addr)
4435{
4436 IRTemp op1 = newTemp(Ity_I32);
4437 IRTemp op2 = newTemp(Ity_I32);
4438
4439 assign(op1, get_gpr_w1(r1));
4440 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4441 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4442
4443 return "cly";
4444}
4445
florian55085f82012-11-21 00:36:55 +00004446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004447s390_irgen_CLG(UChar r1, IRTemp op2addr)
4448{
4449 IRTemp op1 = newTemp(Ity_I64);
4450 IRTemp op2 = newTemp(Ity_I64);
4451
4452 assign(op1, get_gpr_dw0(r1));
4453 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4454 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4455
4456 return "clg";
4457}
4458
florian55085f82012-11-21 00:36:55 +00004459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004460s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4461{
4462 IRTemp op1 = newTemp(Ity_I64);
4463 IRTemp op2 = newTemp(Ity_I64);
4464
4465 assign(op1, get_gpr_dw0(r1));
4466 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4467 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4468
4469 return "clgf";
4470}
4471
florian55085f82012-11-21 00:36:55 +00004472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004473s390_irgen_CLFI(UChar r1, UInt i2)
4474{
4475 IRTemp op1 = newTemp(Ity_I32);
4476 UInt op2;
4477
4478 assign(op1, get_gpr_w1(r1));
4479 op2 = i2;
4480 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4481 mkU32(op2)));
4482
4483 return "clfi";
4484}
4485
florian55085f82012-11-21 00:36:55 +00004486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004487s390_irgen_CLGFI(UChar r1, UInt i2)
4488{
4489 IRTemp op1 = newTemp(Ity_I64);
4490 ULong op2;
4491
4492 assign(op1, get_gpr_dw0(r1));
4493 op2 = (ULong)i2;
4494 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4495 mkU64(op2)));
4496
4497 return "clgfi";
4498}
4499
florian55085f82012-11-21 00:36:55 +00004500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004501s390_irgen_CLI(UChar i2, IRTemp op1addr)
4502{
4503 IRTemp op1 = newTemp(Ity_I8);
4504 UChar op2;
4505
4506 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4507 op2 = i2;
4508 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4509 mkU8(op2)));
4510
4511 return "cli";
4512}
4513
florian55085f82012-11-21 00:36:55 +00004514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004515s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4516{
4517 IRTemp op1 = newTemp(Ity_I8);
4518 UChar op2;
4519
4520 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4521 op2 = i2;
4522 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4523 mkU8(op2)));
4524
4525 return "cliy";
4526}
4527
florian55085f82012-11-21 00:36:55 +00004528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004529s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4530{
4531 IRTemp op1 = newTemp(Ity_I32);
4532 UInt op2;
4533
4534 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4535 op2 = (UInt)i2;
4536 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4537 mkU32(op2)));
4538
4539 return "clfhsi";
4540}
4541
florian55085f82012-11-21 00:36:55 +00004542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004543s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4544{
4545 IRTemp op1 = newTemp(Ity_I64);
4546 ULong op2;
4547
4548 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4549 op2 = (ULong)i2;
4550 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4551 mkU64(op2)));
4552
4553 return "clghsi";
4554}
4555
florian55085f82012-11-21 00:36:55 +00004556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004557s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4558{
4559 IRTemp op1 = newTemp(Ity_I16);
4560 UShort op2;
4561
4562 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4563 op2 = i2;
4564 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4565 mkU16(op2)));
4566
4567 return "clhhsi";
4568}
4569
florian55085f82012-11-21 00:36:55 +00004570static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004571s390_irgen_CLRL(UChar r1, UInt i2)
4572{
4573 IRTemp op1 = newTemp(Ity_I32);
4574 IRTemp op2 = newTemp(Ity_I32);
4575
4576 assign(op1, get_gpr_w1(r1));
4577 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4578 i2 << 1))));
4579 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4580
4581 return "clrl";
4582}
4583
florian55085f82012-11-21 00:36:55 +00004584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004585s390_irgen_CLGRL(UChar r1, UInt i2)
4586{
4587 IRTemp op1 = newTemp(Ity_I64);
4588 IRTemp op2 = newTemp(Ity_I64);
4589
4590 assign(op1, get_gpr_dw0(r1));
4591 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4592 i2 << 1))));
4593 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4594
4595 return "clgrl";
4596}
4597
florian55085f82012-11-21 00:36:55 +00004598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004599s390_irgen_CLGFRL(UChar r1, UInt i2)
4600{
4601 IRTemp op1 = newTemp(Ity_I64);
4602 IRTemp op2 = newTemp(Ity_I64);
4603
4604 assign(op1, get_gpr_dw0(r1));
4605 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4606 ((ULong)(Long)(Int)i2 << 1)))));
4607 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4608
4609 return "clgfrl";
4610}
4611
florian55085f82012-11-21 00:36:55 +00004612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004613s390_irgen_CLHRL(UChar r1, UInt i2)
4614{
4615 IRTemp op1 = newTemp(Ity_I32);
4616 IRTemp op2 = newTemp(Ity_I32);
4617
4618 assign(op1, get_gpr_w1(r1));
4619 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4620 ((ULong)(Long)(Int)i2 << 1)))));
4621 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4622
4623 return "clhrl";
4624}
4625
florian55085f82012-11-21 00:36:55 +00004626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004627s390_irgen_CLGHRL(UChar r1, UInt i2)
4628{
4629 IRTemp op1 = newTemp(Ity_I64);
4630 IRTemp op2 = newTemp(Ity_I64);
4631
4632 assign(op1, get_gpr_dw0(r1));
4633 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4634 ((ULong)(Long)(Int)i2 << 1)))));
4635 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4636
4637 return "clghrl";
4638}
4639
florian55085f82012-11-21 00:36:55 +00004640static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004641s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4642{
4643 IRTemp op1 = newTemp(Ity_I32);
4644 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004645 IRTemp cond = newTemp(Ity_I32);
4646
4647 if (m3 == 0) {
4648 } else {
4649 if (m3 == 14) {
4650 always_goto(mkexpr(op4addr));
4651 } else {
4652 assign(op1, get_gpr_w1(r1));
4653 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004654 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4655 op1, op2));
florianf321da72012-07-21 20:32:57 +00004656 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4657 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004658 }
4659 }
4660
4661 return "clrb";
4662}
4663
florian55085f82012-11-21 00:36:55 +00004664static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004665s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4666{
4667 IRTemp op1 = newTemp(Ity_I64);
4668 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004669 IRTemp cond = newTemp(Ity_I32);
4670
4671 if (m3 == 0) {
4672 } else {
4673 if (m3 == 14) {
4674 always_goto(mkexpr(op4addr));
4675 } else {
4676 assign(op1, get_gpr_dw0(r1));
4677 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004678 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4679 op1, op2));
florianf321da72012-07-21 20:32:57 +00004680 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4681 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004682 }
4683 }
4684
4685 return "clgrb";
4686}
4687
florian55085f82012-11-21 00:36:55 +00004688static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004689s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4690{
4691 IRTemp op1 = newTemp(Ity_I32);
4692 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004693 IRTemp cond = newTemp(Ity_I32);
4694
4695 if (m3 == 0) {
4696 } else {
4697 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004698 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004699 } else {
4700 assign(op1, get_gpr_w1(r1));
4701 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004702 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4703 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004704 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4705 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4706
4707 }
4708 }
4709
4710 return "clrj";
4711}
4712
florian55085f82012-11-21 00:36:55 +00004713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004714s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4715{
4716 IRTemp op1 = newTemp(Ity_I64);
4717 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004718 IRTemp cond = newTemp(Ity_I32);
4719
4720 if (m3 == 0) {
4721 } else {
4722 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004723 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004724 } else {
4725 assign(op1, get_gpr_dw0(r1));
4726 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004727 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4728 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004729 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4730 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4731
4732 }
4733 }
4734
4735 return "clgrj";
4736}
4737
florian55085f82012-11-21 00:36:55 +00004738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004739s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4740{
4741 IRTemp op1 = newTemp(Ity_I32);
4742 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004743 IRTemp cond = newTemp(Ity_I32);
4744
4745 if (m3 == 0) {
4746 } else {
4747 if (m3 == 14) {
4748 always_goto(mkexpr(op4addr));
4749 } else {
4750 assign(op1, get_gpr_w1(r1));
4751 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004752 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4753 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004754 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4755 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004756 }
4757 }
4758
4759 return "clib";
4760}
4761
florian55085f82012-11-21 00:36:55 +00004762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004763s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4764{
4765 IRTemp op1 = newTemp(Ity_I64);
4766 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004767 IRTemp cond = newTemp(Ity_I32);
4768
4769 if (m3 == 0) {
4770 } else {
4771 if (m3 == 14) {
4772 always_goto(mkexpr(op4addr));
4773 } else {
4774 assign(op1, get_gpr_dw0(r1));
4775 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004776 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4777 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004778 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4779 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004780 }
4781 }
4782
4783 return "clgib";
4784}
4785
florian55085f82012-11-21 00:36:55 +00004786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004787s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4788{
4789 IRTemp op1 = newTemp(Ity_I32);
4790 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004791 IRTemp cond = newTemp(Ity_I32);
4792
4793 if (m3 == 0) {
4794 } else {
4795 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004796 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004797 } else {
4798 assign(op1, get_gpr_w1(r1));
4799 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004800 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4801 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004802 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4803 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4804
4805 }
4806 }
4807
4808 return "clij";
4809}
4810
florian55085f82012-11-21 00:36:55 +00004811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004812s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4813{
4814 IRTemp op1 = newTemp(Ity_I64);
4815 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004816 IRTemp cond = newTemp(Ity_I32);
4817
4818 if (m3 == 0) {
4819 } else {
4820 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004821 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004822 } else {
4823 assign(op1, get_gpr_dw0(r1));
4824 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004825 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4826 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004827 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4828 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4829
4830 }
4831 }
4832
4833 return "clgij";
4834}
4835
florian55085f82012-11-21 00:36:55 +00004836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004837s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4838{
4839 IRTemp op1 = newTemp(Ity_I32);
4840 IRTemp op2 = newTemp(Ity_I32);
4841 IRTemp b0 = newTemp(Ity_I32);
4842 IRTemp b1 = newTemp(Ity_I32);
4843 IRTemp b2 = newTemp(Ity_I32);
4844 IRTemp b3 = newTemp(Ity_I32);
4845 IRTemp c0 = newTemp(Ity_I32);
4846 IRTemp c1 = newTemp(Ity_I32);
4847 IRTemp c2 = newTemp(Ity_I32);
4848 IRTemp c3 = newTemp(Ity_I32);
4849 UChar n;
4850
4851 n = 0;
4852 if ((r3 & 8) != 0) {
4853 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4854 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4855 n = n + 1;
4856 } else {
4857 assign(b0, mkU32(0));
4858 assign(c0, mkU32(0));
4859 }
4860 if ((r3 & 4) != 0) {
4861 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4862 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4863 mkU64(n)))));
4864 n = n + 1;
4865 } else {
4866 assign(b1, mkU32(0));
4867 assign(c1, mkU32(0));
4868 }
4869 if ((r3 & 2) != 0) {
4870 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4871 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4872 mkU64(n)))));
4873 n = n + 1;
4874 } else {
4875 assign(b2, mkU32(0));
4876 assign(c2, mkU32(0));
4877 }
4878 if ((r3 & 1) != 0) {
4879 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4880 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4881 mkU64(n)))));
4882 n = n + 1;
4883 } else {
4884 assign(b3, mkU32(0));
4885 assign(c3, mkU32(0));
4886 }
4887 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4888 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4889 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4890 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4891 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4892 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4893 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4894
4895 return "clm";
4896}
4897
florian55085f82012-11-21 00:36:55 +00004898static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004899s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4900{
4901 IRTemp op1 = newTemp(Ity_I32);
4902 IRTemp op2 = newTemp(Ity_I32);
4903 IRTemp b0 = newTemp(Ity_I32);
4904 IRTemp b1 = newTemp(Ity_I32);
4905 IRTemp b2 = newTemp(Ity_I32);
4906 IRTemp b3 = newTemp(Ity_I32);
4907 IRTemp c0 = newTemp(Ity_I32);
4908 IRTemp c1 = newTemp(Ity_I32);
4909 IRTemp c2 = newTemp(Ity_I32);
4910 IRTemp c3 = newTemp(Ity_I32);
4911 UChar n;
4912
4913 n = 0;
4914 if ((r3 & 8) != 0) {
4915 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4916 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4917 n = n + 1;
4918 } else {
4919 assign(b0, mkU32(0));
4920 assign(c0, mkU32(0));
4921 }
4922 if ((r3 & 4) != 0) {
4923 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4924 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4925 mkU64(n)))));
4926 n = n + 1;
4927 } else {
4928 assign(b1, mkU32(0));
4929 assign(c1, mkU32(0));
4930 }
4931 if ((r3 & 2) != 0) {
4932 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4933 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4934 mkU64(n)))));
4935 n = n + 1;
4936 } else {
4937 assign(b2, mkU32(0));
4938 assign(c2, mkU32(0));
4939 }
4940 if ((r3 & 1) != 0) {
4941 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4942 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4943 mkU64(n)))));
4944 n = n + 1;
4945 } else {
4946 assign(b3, mkU32(0));
4947 assign(c3, mkU32(0));
4948 }
4949 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4950 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4951 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4952 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4953 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4954 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4955 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4956
4957 return "clmy";
4958}
4959
florian55085f82012-11-21 00:36:55 +00004960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004961s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4962{
4963 IRTemp op1 = newTemp(Ity_I32);
4964 IRTemp op2 = newTemp(Ity_I32);
4965 IRTemp b0 = newTemp(Ity_I32);
4966 IRTemp b1 = newTemp(Ity_I32);
4967 IRTemp b2 = newTemp(Ity_I32);
4968 IRTemp b3 = newTemp(Ity_I32);
4969 IRTemp c0 = newTemp(Ity_I32);
4970 IRTemp c1 = newTemp(Ity_I32);
4971 IRTemp c2 = newTemp(Ity_I32);
4972 IRTemp c3 = newTemp(Ity_I32);
4973 UChar n;
4974
4975 n = 0;
4976 if ((r3 & 8) != 0) {
4977 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4978 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4979 n = n + 1;
4980 } else {
4981 assign(b0, mkU32(0));
4982 assign(c0, mkU32(0));
4983 }
4984 if ((r3 & 4) != 0) {
4985 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4986 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4987 mkU64(n)))));
4988 n = n + 1;
4989 } else {
4990 assign(b1, mkU32(0));
4991 assign(c1, mkU32(0));
4992 }
4993 if ((r3 & 2) != 0) {
4994 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4995 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4996 mkU64(n)))));
4997 n = n + 1;
4998 } else {
4999 assign(b2, mkU32(0));
5000 assign(c2, mkU32(0));
5001 }
5002 if ((r3 & 1) != 0) {
5003 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5004 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5005 mkU64(n)))));
5006 n = n + 1;
5007 } else {
5008 assign(b3, mkU32(0));
5009 assign(c3, mkU32(0));
5010 }
5011 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5012 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5013 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5014 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5015 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5016 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5017 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5018
5019 return "clmh";
5020}
5021
florian55085f82012-11-21 00:36:55 +00005022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005023s390_irgen_CLHHR(UChar r1, UChar r2)
5024{
5025 IRTemp op1 = newTemp(Ity_I32);
5026 IRTemp op2 = newTemp(Ity_I32);
5027
5028 assign(op1, get_gpr_w0(r1));
5029 assign(op2, get_gpr_w0(r2));
5030 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5031
5032 return "clhhr";
5033}
5034
florian55085f82012-11-21 00:36:55 +00005035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005036s390_irgen_CLHLR(UChar r1, UChar r2)
5037{
5038 IRTemp op1 = newTemp(Ity_I32);
5039 IRTemp op2 = newTemp(Ity_I32);
5040
5041 assign(op1, get_gpr_w0(r1));
5042 assign(op2, get_gpr_w1(r2));
5043 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5044
5045 return "clhlr";
5046}
5047
florian55085f82012-11-21 00:36:55 +00005048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005049s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5050{
5051 IRTemp op1 = newTemp(Ity_I32);
5052 IRTemp op2 = newTemp(Ity_I32);
5053
5054 assign(op1, get_gpr_w0(r1));
5055 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5056 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5057
5058 return "clhf";
5059}
5060
florian55085f82012-11-21 00:36:55 +00005061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005062s390_irgen_CLIH(UChar r1, UInt i2)
5063{
5064 IRTemp op1 = newTemp(Ity_I32);
5065 UInt op2;
5066
5067 assign(op1, get_gpr_w0(r1));
5068 op2 = i2;
5069 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5070 mkU32(op2)));
5071
5072 return "clih";
5073}
5074
florian55085f82012-11-21 00:36:55 +00005075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005076s390_irgen_CPYA(UChar r1, UChar r2)
5077{
5078 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005079 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005080 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5081
5082 return "cpya";
5083}
5084
florian55085f82012-11-21 00:36:55 +00005085static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005086s390_irgen_XR(UChar r1, UChar r2)
5087{
5088 IRTemp op1 = newTemp(Ity_I32);
5089 IRTemp op2 = newTemp(Ity_I32);
5090 IRTemp result = newTemp(Ity_I32);
5091
5092 if (r1 == r2) {
5093 assign(result, mkU32(0));
5094 } else {
5095 assign(op1, get_gpr_w1(r1));
5096 assign(op2, get_gpr_w1(r2));
5097 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5098 }
5099 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5100 put_gpr_w1(r1, mkexpr(result));
5101
5102 return "xr";
5103}
5104
florian55085f82012-11-21 00:36:55 +00005105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005106s390_irgen_XGR(UChar r1, UChar r2)
5107{
5108 IRTemp op1 = newTemp(Ity_I64);
5109 IRTemp op2 = newTemp(Ity_I64);
5110 IRTemp result = newTemp(Ity_I64);
5111
5112 if (r1 == r2) {
5113 assign(result, mkU64(0));
5114 } else {
5115 assign(op1, get_gpr_dw0(r1));
5116 assign(op2, get_gpr_dw0(r2));
5117 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5118 }
5119 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5120 put_gpr_dw0(r1, mkexpr(result));
5121
5122 return "xgr";
5123}
5124
florian55085f82012-11-21 00:36:55 +00005125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005126s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5127{
5128 IRTemp op2 = newTemp(Ity_I32);
5129 IRTemp op3 = newTemp(Ity_I32);
5130 IRTemp result = newTemp(Ity_I32);
5131
5132 assign(op2, get_gpr_w1(r2));
5133 assign(op3, get_gpr_w1(r3));
5134 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5135 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5136 put_gpr_w1(r1, mkexpr(result));
5137
5138 return "xrk";
5139}
5140
florian55085f82012-11-21 00:36:55 +00005141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005142s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5143{
5144 IRTemp op2 = newTemp(Ity_I64);
5145 IRTemp op3 = newTemp(Ity_I64);
5146 IRTemp result = newTemp(Ity_I64);
5147
5148 assign(op2, get_gpr_dw0(r2));
5149 assign(op3, get_gpr_dw0(r3));
5150 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5151 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5152 put_gpr_dw0(r1, mkexpr(result));
5153
5154 return "xgrk";
5155}
5156
florian55085f82012-11-21 00:36:55 +00005157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005158s390_irgen_X(UChar r1, IRTemp op2addr)
5159{
5160 IRTemp op1 = newTemp(Ity_I32);
5161 IRTemp op2 = newTemp(Ity_I32);
5162 IRTemp result = newTemp(Ity_I32);
5163
5164 assign(op1, get_gpr_w1(r1));
5165 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5166 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5167 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5168 put_gpr_w1(r1, mkexpr(result));
5169
5170 return "x";
5171}
5172
florian55085f82012-11-21 00:36:55 +00005173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005174s390_irgen_XY(UChar r1, IRTemp op2addr)
5175{
5176 IRTemp op1 = newTemp(Ity_I32);
5177 IRTemp op2 = newTemp(Ity_I32);
5178 IRTemp result = newTemp(Ity_I32);
5179
5180 assign(op1, get_gpr_w1(r1));
5181 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5182 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5183 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5184 put_gpr_w1(r1, mkexpr(result));
5185
5186 return "xy";
5187}
5188
florian55085f82012-11-21 00:36:55 +00005189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005190s390_irgen_XG(UChar r1, IRTemp op2addr)
5191{
5192 IRTemp op1 = newTemp(Ity_I64);
5193 IRTemp op2 = newTemp(Ity_I64);
5194 IRTemp result = newTemp(Ity_I64);
5195
5196 assign(op1, get_gpr_dw0(r1));
5197 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5198 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5199 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5200 put_gpr_dw0(r1, mkexpr(result));
5201
5202 return "xg";
5203}
5204
florian55085f82012-11-21 00:36:55 +00005205static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005206s390_irgen_XI(UChar i2, IRTemp op1addr)
5207{
5208 IRTemp op1 = newTemp(Ity_I8);
5209 UChar op2;
5210 IRTemp result = newTemp(Ity_I8);
5211
5212 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5213 op2 = i2;
5214 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5215 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5216 store(mkexpr(op1addr), mkexpr(result));
5217
5218 return "xi";
5219}
5220
florian55085f82012-11-21 00:36:55 +00005221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005222s390_irgen_XIY(UChar i2, IRTemp op1addr)
5223{
5224 IRTemp op1 = newTemp(Ity_I8);
5225 UChar op2;
5226 IRTemp result = newTemp(Ity_I8);
5227
5228 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5229 op2 = i2;
5230 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5231 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5232 store(mkexpr(op1addr), mkexpr(result));
5233
5234 return "xiy";
5235}
5236
florian55085f82012-11-21 00:36:55 +00005237static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005238s390_irgen_XIHF(UChar r1, UInt i2)
5239{
5240 IRTemp op1 = newTemp(Ity_I32);
5241 UInt op2;
5242 IRTemp result = newTemp(Ity_I32);
5243
5244 assign(op1, get_gpr_w0(r1));
5245 op2 = i2;
5246 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5247 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5248 put_gpr_w0(r1, mkexpr(result));
5249
5250 return "xihf";
5251}
5252
florian55085f82012-11-21 00:36:55 +00005253static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005254s390_irgen_XILF(UChar r1, UInt i2)
5255{
5256 IRTemp op1 = newTemp(Ity_I32);
5257 UInt op2;
5258 IRTemp result = newTemp(Ity_I32);
5259
5260 assign(op1, get_gpr_w1(r1));
5261 op2 = i2;
5262 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5263 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5264 put_gpr_w1(r1, mkexpr(result));
5265
5266 return "xilf";
5267}
5268
florian55085f82012-11-21 00:36:55 +00005269static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005270s390_irgen_EAR(UChar r1, UChar r2)
5271{
5272 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005273 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005274 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5275
5276 return "ear";
5277}
5278
florian55085f82012-11-21 00:36:55 +00005279static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005280s390_irgen_IC(UChar r1, IRTemp op2addr)
5281{
5282 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5283
5284 return "ic";
5285}
5286
florian55085f82012-11-21 00:36:55 +00005287static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005288s390_irgen_ICY(UChar r1, IRTemp op2addr)
5289{
5290 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5291
5292 return "icy";
5293}
5294
florian55085f82012-11-21 00:36:55 +00005295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005296s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5297{
5298 UChar n;
5299 IRTemp result = newTemp(Ity_I32);
5300 UInt mask;
5301
5302 n = 0;
5303 mask = (UInt)r3;
5304 if ((mask & 8) != 0) {
5305 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5306 n = n + 1;
5307 }
5308 if ((mask & 4) != 0) {
5309 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5310
5311 n = n + 1;
5312 }
5313 if ((mask & 2) != 0) {
5314 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5315
5316 n = n + 1;
5317 }
5318 if ((mask & 1) != 0) {
5319 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5320
5321 n = n + 1;
5322 }
5323 assign(result, get_gpr_w1(r1));
5324 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5325 mkU32(mask)));
5326
5327 return "icm";
5328}
5329
florian55085f82012-11-21 00:36:55 +00005330static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005331s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5332{
5333 UChar n;
5334 IRTemp result = newTemp(Ity_I32);
5335 UInt mask;
5336
5337 n = 0;
5338 mask = (UInt)r3;
5339 if ((mask & 8) != 0) {
5340 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5341 n = n + 1;
5342 }
5343 if ((mask & 4) != 0) {
5344 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5345
5346 n = n + 1;
5347 }
5348 if ((mask & 2) != 0) {
5349 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5350
5351 n = n + 1;
5352 }
5353 if ((mask & 1) != 0) {
5354 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5355
5356 n = n + 1;
5357 }
5358 assign(result, get_gpr_w1(r1));
5359 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5360 mkU32(mask)));
5361
5362 return "icmy";
5363}
5364
florian55085f82012-11-21 00:36:55 +00005365static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005366s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5367{
5368 UChar n;
5369 IRTemp result = newTemp(Ity_I32);
5370 UInt mask;
5371
5372 n = 0;
5373 mask = (UInt)r3;
5374 if ((mask & 8) != 0) {
5375 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5376 n = n + 1;
5377 }
5378 if ((mask & 4) != 0) {
5379 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5380
5381 n = n + 1;
5382 }
5383 if ((mask & 2) != 0) {
5384 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5385
5386 n = n + 1;
5387 }
5388 if ((mask & 1) != 0) {
5389 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5390
5391 n = n + 1;
5392 }
5393 assign(result, get_gpr_w0(r1));
5394 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5395 mkU32(mask)));
5396
5397 return "icmh";
5398}
5399
florian55085f82012-11-21 00:36:55 +00005400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005401s390_irgen_IIHF(UChar r1, UInt i2)
5402{
5403 put_gpr_w0(r1, mkU32(i2));
5404
5405 return "iihf";
5406}
5407
florian55085f82012-11-21 00:36:55 +00005408static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005409s390_irgen_IIHH(UChar r1, UShort i2)
5410{
5411 put_gpr_hw0(r1, mkU16(i2));
5412
5413 return "iihh";
5414}
5415
florian55085f82012-11-21 00:36:55 +00005416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005417s390_irgen_IIHL(UChar r1, UShort i2)
5418{
5419 put_gpr_hw1(r1, mkU16(i2));
5420
5421 return "iihl";
5422}
5423
florian55085f82012-11-21 00:36:55 +00005424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005425s390_irgen_IILF(UChar r1, UInt i2)
5426{
5427 put_gpr_w1(r1, mkU32(i2));
5428
5429 return "iilf";
5430}
5431
florian55085f82012-11-21 00:36:55 +00005432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005433s390_irgen_IILH(UChar r1, UShort i2)
5434{
5435 put_gpr_hw2(r1, mkU16(i2));
5436
5437 return "iilh";
5438}
5439
florian55085f82012-11-21 00:36:55 +00005440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005441s390_irgen_IILL(UChar r1, UShort i2)
5442{
5443 put_gpr_hw3(r1, mkU16(i2));
5444
5445 return "iill";
5446}
5447
florian55085f82012-11-21 00:36:55 +00005448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005449s390_irgen_LR(UChar r1, UChar r2)
5450{
5451 put_gpr_w1(r1, get_gpr_w1(r2));
5452
5453 return "lr";
5454}
5455
florian55085f82012-11-21 00:36:55 +00005456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005457s390_irgen_LGR(UChar r1, UChar r2)
5458{
5459 put_gpr_dw0(r1, get_gpr_dw0(r2));
5460
5461 return "lgr";
5462}
5463
florian55085f82012-11-21 00:36:55 +00005464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005465s390_irgen_LGFR(UChar r1, UChar r2)
5466{
5467 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5468
5469 return "lgfr";
5470}
5471
florian55085f82012-11-21 00:36:55 +00005472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005473s390_irgen_L(UChar r1, IRTemp op2addr)
5474{
5475 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5476
5477 return "l";
5478}
5479
florian55085f82012-11-21 00:36:55 +00005480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005481s390_irgen_LY(UChar r1, IRTemp op2addr)
5482{
5483 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5484
5485 return "ly";
5486}
5487
florian55085f82012-11-21 00:36:55 +00005488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005489s390_irgen_LG(UChar r1, IRTemp op2addr)
5490{
5491 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5492
5493 return "lg";
5494}
5495
florian55085f82012-11-21 00:36:55 +00005496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005497s390_irgen_LGF(UChar r1, IRTemp op2addr)
5498{
5499 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5500
5501 return "lgf";
5502}
5503
florian55085f82012-11-21 00:36:55 +00005504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005505s390_irgen_LGFI(UChar r1, UInt i2)
5506{
5507 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5508
5509 return "lgfi";
5510}
5511
florian55085f82012-11-21 00:36:55 +00005512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005513s390_irgen_LRL(UChar r1, UInt i2)
5514{
5515 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5516 i2 << 1))));
5517
5518 return "lrl";
5519}
5520
florian55085f82012-11-21 00:36:55 +00005521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005522s390_irgen_LGRL(UChar r1, UInt i2)
5523{
5524 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5525 i2 << 1))));
5526
5527 return "lgrl";
5528}
5529
florian55085f82012-11-21 00:36:55 +00005530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005531s390_irgen_LGFRL(UChar r1, UInt i2)
5532{
5533 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5534 ((ULong)(Long)(Int)i2 << 1)))));
5535
5536 return "lgfrl";
5537}
5538
florian55085f82012-11-21 00:36:55 +00005539static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005540s390_irgen_LA(UChar r1, IRTemp op2addr)
5541{
5542 put_gpr_dw0(r1, mkexpr(op2addr));
5543
5544 return "la";
5545}
5546
florian55085f82012-11-21 00:36:55 +00005547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005548s390_irgen_LAY(UChar r1, IRTemp op2addr)
5549{
5550 put_gpr_dw0(r1, mkexpr(op2addr));
5551
5552 return "lay";
5553}
5554
florian55085f82012-11-21 00:36:55 +00005555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005556s390_irgen_LAE(UChar r1, IRTemp op2addr)
5557{
5558 put_gpr_dw0(r1, mkexpr(op2addr));
5559
5560 return "lae";
5561}
5562
florian55085f82012-11-21 00:36:55 +00005563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005564s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5565{
5566 put_gpr_dw0(r1, mkexpr(op2addr));
5567
5568 return "laey";
5569}
5570
florian55085f82012-11-21 00:36:55 +00005571static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005572s390_irgen_LARL(UChar r1, UInt i2)
5573{
5574 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5575
5576 return "larl";
5577}
5578
floriana265ee72012-12-02 20:58:17 +00005579/* The IR representation of LAA and friends is an approximation of what
5580 happens natively. Essentially a loop containing a compare-and-swap is
5581 constructed which will iterate until the CAS succeeds. As a consequence,
5582 instrumenters may see more memory accesses than happen natively. See also
5583 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005584static void
5585s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005586{
floriana265ee72012-12-02 20:58:17 +00005587 IRCAS *cas;
5588 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005589 IRTemp op2 = newTemp(Ity_I32);
5590 IRTemp op3 = newTemp(Ity_I32);
5591 IRTemp result = newTemp(Ity_I32);
5592
5593 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5594 assign(op3, get_gpr_w1(r3));
5595 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005596
5597 /* Place the addition of second operand and third operand at the
5598 second-operand location everytime */
5599 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5600 Iend_BE, mkexpr(op2addr),
5601 NULL, mkexpr(op2), /* expected value */
5602 NULL, mkexpr(result) /* new value */);
5603 stmt(IRStmt_CAS(cas));
5604
florianffc94012012-12-02 21:31:15 +00005605 /* Set CC according to 32-bit addition */
5606 if (is_signed) {
5607 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5608 } else {
5609 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5610 }
floriana265ee72012-12-02 20:58:17 +00005611
5612 /* If old_mem contains the expected value, then the CAS succeeded.
5613 Otherwise, it did not */
5614 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5615 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005616}
5617
5618static void
5619s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5620{
5621 IRCAS *cas;
5622 IRTemp old_mem = newTemp(Ity_I64);
5623 IRTemp op2 = newTemp(Ity_I64);
5624 IRTemp op3 = newTemp(Ity_I64);
5625 IRTemp result = newTemp(Ity_I64);
5626
5627 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5628 assign(op3, get_gpr_dw0(r3));
5629 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5630
5631 /* Place the addition of second operand and third operand at the
5632 second-operand location everytime */
5633 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5634 Iend_BE, mkexpr(op2addr),
5635 NULL, mkexpr(op2), /* expected value */
5636 NULL, mkexpr(result) /* new value */);
5637 stmt(IRStmt_CAS(cas));
5638
5639 /* Set CC according to 64-bit addition */
5640 if (is_signed) {
5641 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5642 } else {
5643 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5644 }
5645
5646 /* If old_mem contains the expected value, then the CAS succeeded.
5647 Otherwise, it did not */
5648 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5649 put_gpr_dw0(r1, mkexpr(old_mem));
5650}
5651
5652static void
5653s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5654{
5655 IRCAS *cas;
5656 IRTemp old_mem = newTemp(Ity_I32);
5657 IRTemp op2 = newTemp(Ity_I32);
5658 IRTemp op3 = newTemp(Ity_I32);
5659 IRTemp result = newTemp(Ity_I32);
5660
5661 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5662 assign(op3, get_gpr_w1(r3));
5663 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5664
5665 /* Place the addition of second operand and third operand at the
5666 second-operand location everytime */
5667 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5668 Iend_BE, mkexpr(op2addr),
5669 NULL, mkexpr(op2), /* expected value */
5670 NULL, mkexpr(result) /* new value */);
5671 stmt(IRStmt_CAS(cas));
5672
5673 /* Set CC according to bitwise operation */
5674 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5675
5676 /* If old_mem contains the expected value, then the CAS succeeded.
5677 Otherwise, it did not */
5678 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5679 put_gpr_w1(r1, mkexpr(old_mem));
5680}
5681
5682static void
5683s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5684{
5685 IRCAS *cas;
5686 IRTemp old_mem = newTemp(Ity_I64);
5687 IRTemp op2 = newTemp(Ity_I64);
5688 IRTemp op3 = newTemp(Ity_I64);
5689 IRTemp result = newTemp(Ity_I64);
5690
5691 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5692 assign(op3, get_gpr_dw0(r3));
5693 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5694
5695 /* Place the addition of second operand and third operand at the
5696 second-operand location everytime */
5697 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5698 Iend_BE, mkexpr(op2addr),
5699 NULL, mkexpr(op2), /* expected value */
5700 NULL, mkexpr(result) /* new value */);
5701 stmt(IRStmt_CAS(cas));
5702
5703 /* Set CC according to bitwise operation */
5704 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5705
5706 /* If old_mem contains the expected value, then the CAS succeeded.
5707 Otherwise, it did not */
5708 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5709 put_gpr_dw0(r1, mkexpr(old_mem));
5710}
5711
5712static const HChar *
5713s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5714{
5715 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005716
5717 return "laa";
5718}
5719
florian55085f82012-11-21 00:36:55 +00005720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005721s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5722{
florianffc94012012-12-02 21:31:15 +00005723 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005724
5725 return "laag";
5726}
5727
florian55085f82012-11-21 00:36:55 +00005728static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005729s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5730{
florianffc94012012-12-02 21:31:15 +00005731 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005732
5733 return "laal";
5734}
5735
florian55085f82012-11-21 00:36:55 +00005736static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005737s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5738{
florianffc94012012-12-02 21:31:15 +00005739 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005740
5741 return "laalg";
5742}
5743
florian55085f82012-11-21 00:36:55 +00005744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005745s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5746{
florianffc94012012-12-02 21:31:15 +00005747 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005748
5749 return "lan";
5750}
5751
florian55085f82012-11-21 00:36:55 +00005752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005753s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5754{
florianffc94012012-12-02 21:31:15 +00005755 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005756
5757 return "lang";
5758}
5759
florian55085f82012-11-21 00:36:55 +00005760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005761s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5762{
florianffc94012012-12-02 21:31:15 +00005763 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005764
5765 return "lax";
5766}
5767
florian55085f82012-11-21 00:36:55 +00005768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005769s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5770{
florianffc94012012-12-02 21:31:15 +00005771 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005772
5773 return "laxg";
5774}
5775
florian55085f82012-11-21 00:36:55 +00005776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005777s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5778{
florianffc94012012-12-02 21:31:15 +00005779 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005780
5781 return "lao";
5782}
5783
florian55085f82012-11-21 00:36:55 +00005784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005785s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5786{
florianffc94012012-12-02 21:31:15 +00005787 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005788
5789 return "laog";
5790}
5791
florian55085f82012-11-21 00:36:55 +00005792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005793s390_irgen_LTR(UChar r1, UChar r2)
5794{
5795 IRTemp op2 = newTemp(Ity_I32);
5796
5797 assign(op2, get_gpr_w1(r2));
5798 put_gpr_w1(r1, mkexpr(op2));
5799 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5800
5801 return "ltr";
5802}
5803
florian55085f82012-11-21 00:36:55 +00005804static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005805s390_irgen_LTGR(UChar r1, UChar r2)
5806{
5807 IRTemp op2 = newTemp(Ity_I64);
5808
5809 assign(op2, get_gpr_dw0(r2));
5810 put_gpr_dw0(r1, mkexpr(op2));
5811 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5812
5813 return "ltgr";
5814}
5815
florian55085f82012-11-21 00:36:55 +00005816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005817s390_irgen_LTGFR(UChar r1, UChar r2)
5818{
5819 IRTemp op2 = newTemp(Ity_I64);
5820
5821 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5822 put_gpr_dw0(r1, mkexpr(op2));
5823 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5824
5825 return "ltgfr";
5826}
5827
florian55085f82012-11-21 00:36:55 +00005828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005829s390_irgen_LT(UChar r1, IRTemp op2addr)
5830{
5831 IRTemp op2 = newTemp(Ity_I32);
5832
5833 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5834 put_gpr_w1(r1, mkexpr(op2));
5835 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5836
5837 return "lt";
5838}
5839
florian55085f82012-11-21 00:36:55 +00005840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005841s390_irgen_LTG(UChar r1, IRTemp op2addr)
5842{
5843 IRTemp op2 = newTemp(Ity_I64);
5844
5845 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5846 put_gpr_dw0(r1, mkexpr(op2));
5847 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5848
5849 return "ltg";
5850}
5851
florian55085f82012-11-21 00:36:55 +00005852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005853s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5854{
5855 IRTemp op2 = newTemp(Ity_I64);
5856
5857 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5858 put_gpr_dw0(r1, mkexpr(op2));
5859 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5860
5861 return "ltgf";
5862}
5863
florian55085f82012-11-21 00:36:55 +00005864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005865s390_irgen_LBR(UChar r1, UChar r2)
5866{
5867 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5868
5869 return "lbr";
5870}
5871
florian55085f82012-11-21 00:36:55 +00005872static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005873s390_irgen_LGBR(UChar r1, UChar r2)
5874{
5875 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5876
5877 return "lgbr";
5878}
5879
florian55085f82012-11-21 00:36:55 +00005880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005881s390_irgen_LB(UChar r1, IRTemp op2addr)
5882{
5883 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5884
5885 return "lb";
5886}
5887
florian55085f82012-11-21 00:36:55 +00005888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005889s390_irgen_LGB(UChar r1, IRTemp op2addr)
5890{
5891 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5892
5893 return "lgb";
5894}
5895
florian55085f82012-11-21 00:36:55 +00005896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005897s390_irgen_LBH(UChar r1, IRTemp op2addr)
5898{
5899 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5900
5901 return "lbh";
5902}
5903
florian55085f82012-11-21 00:36:55 +00005904static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005905s390_irgen_LCR(UChar r1, UChar r2)
5906{
5907 Int op1;
5908 IRTemp op2 = newTemp(Ity_I32);
5909 IRTemp result = newTemp(Ity_I32);
5910
5911 op1 = 0;
5912 assign(op2, get_gpr_w1(r2));
5913 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5914 put_gpr_w1(r1, mkexpr(result));
5915 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5916 op1)), op2);
5917
5918 return "lcr";
5919}
5920
florian55085f82012-11-21 00:36:55 +00005921static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005922s390_irgen_LCGR(UChar r1, UChar r2)
5923{
5924 Long op1;
5925 IRTemp op2 = newTemp(Ity_I64);
5926 IRTemp result = newTemp(Ity_I64);
5927
5928 op1 = 0ULL;
5929 assign(op2, get_gpr_dw0(r2));
5930 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5931 put_gpr_dw0(r1, mkexpr(result));
5932 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5933 op1)), op2);
5934
5935 return "lcgr";
5936}
5937
florian55085f82012-11-21 00:36:55 +00005938static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005939s390_irgen_LCGFR(UChar r1, UChar r2)
5940{
5941 Long op1;
5942 IRTemp op2 = newTemp(Ity_I64);
5943 IRTemp result = newTemp(Ity_I64);
5944
5945 op1 = 0ULL;
5946 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5947 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5948 put_gpr_dw0(r1, mkexpr(result));
5949 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5950 op1)), op2);
5951
5952 return "lcgfr";
5953}
5954
florian55085f82012-11-21 00:36:55 +00005955static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005956s390_irgen_LHR(UChar r1, UChar r2)
5957{
5958 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5959
5960 return "lhr";
5961}
5962
florian55085f82012-11-21 00:36:55 +00005963static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005964s390_irgen_LGHR(UChar r1, UChar r2)
5965{
5966 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5967
5968 return "lghr";
5969}
5970
florian55085f82012-11-21 00:36:55 +00005971static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005972s390_irgen_LH(UChar r1, IRTemp op2addr)
5973{
5974 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5975
5976 return "lh";
5977}
5978
florian55085f82012-11-21 00:36:55 +00005979static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005980s390_irgen_LHY(UChar r1, IRTemp op2addr)
5981{
5982 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5983
5984 return "lhy";
5985}
5986
florian55085f82012-11-21 00:36:55 +00005987static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005988s390_irgen_LGH(UChar r1, IRTemp op2addr)
5989{
5990 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5991
5992 return "lgh";
5993}
5994
florian55085f82012-11-21 00:36:55 +00005995static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005996s390_irgen_LHI(UChar r1, UShort i2)
5997{
5998 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5999
6000 return "lhi";
6001}
6002
florian55085f82012-11-21 00:36:55 +00006003static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006004s390_irgen_LGHI(UChar r1, UShort i2)
6005{
6006 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6007
6008 return "lghi";
6009}
6010
florian55085f82012-11-21 00:36:55 +00006011static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006012s390_irgen_LHRL(UChar r1, UInt i2)
6013{
6014 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6015 ((ULong)(Long)(Int)i2 << 1)))));
6016
6017 return "lhrl";
6018}
6019
florian55085f82012-11-21 00:36:55 +00006020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006021s390_irgen_LGHRL(UChar r1, UInt i2)
6022{
6023 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6024 ((ULong)(Long)(Int)i2 << 1)))));
6025
6026 return "lghrl";
6027}
6028
florian55085f82012-11-21 00:36:55 +00006029static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006030s390_irgen_LHH(UChar r1, IRTemp op2addr)
6031{
6032 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6033
6034 return "lhh";
6035}
6036
florian55085f82012-11-21 00:36:55 +00006037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006038s390_irgen_LFH(UChar r1, IRTemp op2addr)
6039{
6040 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6041
6042 return "lfh";
6043}
6044
florian55085f82012-11-21 00:36:55 +00006045static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006046s390_irgen_LLGFR(UChar r1, UChar r2)
6047{
6048 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6049
6050 return "llgfr";
6051}
6052
florian55085f82012-11-21 00:36:55 +00006053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006054s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6055{
6056 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6057
6058 return "llgf";
6059}
6060
florian55085f82012-11-21 00:36:55 +00006061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006062s390_irgen_LLGFRL(UChar r1, UInt i2)
6063{
6064 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6065 ((ULong)(Long)(Int)i2 << 1)))));
6066
6067 return "llgfrl";
6068}
6069
florian55085f82012-11-21 00:36:55 +00006070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006071s390_irgen_LLCR(UChar r1, UChar r2)
6072{
6073 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6074
6075 return "llcr";
6076}
6077
florian55085f82012-11-21 00:36:55 +00006078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006079s390_irgen_LLGCR(UChar r1, UChar r2)
6080{
6081 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6082
6083 return "llgcr";
6084}
6085
florian55085f82012-11-21 00:36:55 +00006086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006087s390_irgen_LLC(UChar r1, IRTemp op2addr)
6088{
6089 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6090
6091 return "llc";
6092}
6093
florian55085f82012-11-21 00:36:55 +00006094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006095s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6096{
6097 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6098
6099 return "llgc";
6100}
6101
florian55085f82012-11-21 00:36:55 +00006102static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006103s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6104{
6105 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6106
6107 return "llch";
6108}
6109
florian55085f82012-11-21 00:36:55 +00006110static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006111s390_irgen_LLHR(UChar r1, UChar r2)
6112{
6113 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6114
6115 return "llhr";
6116}
6117
florian55085f82012-11-21 00:36:55 +00006118static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006119s390_irgen_LLGHR(UChar r1, UChar r2)
6120{
6121 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6122
6123 return "llghr";
6124}
6125
florian55085f82012-11-21 00:36:55 +00006126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006127s390_irgen_LLH(UChar r1, IRTemp op2addr)
6128{
6129 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6130
6131 return "llh";
6132}
6133
florian55085f82012-11-21 00:36:55 +00006134static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006135s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6136{
6137 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6138
6139 return "llgh";
6140}
6141
florian55085f82012-11-21 00:36:55 +00006142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006143s390_irgen_LLHRL(UChar r1, UInt i2)
6144{
6145 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6146 ((ULong)(Long)(Int)i2 << 1)))));
6147
6148 return "llhrl";
6149}
6150
florian55085f82012-11-21 00:36:55 +00006151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006152s390_irgen_LLGHRL(UChar r1, UInt i2)
6153{
6154 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6155 ((ULong)(Long)(Int)i2 << 1)))));
6156
6157 return "llghrl";
6158}
6159
florian55085f82012-11-21 00:36:55 +00006160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006161s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6162{
6163 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6164
6165 return "llhh";
6166}
6167
florian55085f82012-11-21 00:36:55 +00006168static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006169s390_irgen_LLIHF(UChar r1, UInt i2)
6170{
6171 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6172
6173 return "llihf";
6174}
6175
florian55085f82012-11-21 00:36:55 +00006176static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006177s390_irgen_LLIHH(UChar r1, UShort i2)
6178{
6179 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6180
6181 return "llihh";
6182}
6183
florian55085f82012-11-21 00:36:55 +00006184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006185s390_irgen_LLIHL(UChar r1, UShort i2)
6186{
6187 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6188
6189 return "llihl";
6190}
6191
florian55085f82012-11-21 00:36:55 +00006192static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006193s390_irgen_LLILF(UChar r1, UInt i2)
6194{
6195 put_gpr_dw0(r1, mkU64(i2));
6196
6197 return "llilf";
6198}
6199
florian55085f82012-11-21 00:36:55 +00006200static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006201s390_irgen_LLILH(UChar r1, UShort i2)
6202{
6203 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6204
6205 return "llilh";
6206}
6207
florian55085f82012-11-21 00:36:55 +00006208static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006209s390_irgen_LLILL(UChar r1, UShort i2)
6210{
6211 put_gpr_dw0(r1, mkU64(i2));
6212
6213 return "llill";
6214}
6215
florian55085f82012-11-21 00:36:55 +00006216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006217s390_irgen_LLGTR(UChar r1, UChar r2)
6218{
6219 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6220 mkU32(2147483647))));
6221
6222 return "llgtr";
6223}
6224
florian55085f82012-11-21 00:36:55 +00006225static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006226s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6227{
6228 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6229 mkexpr(op2addr)), mkU32(2147483647))));
6230
6231 return "llgt";
6232}
6233
florian55085f82012-11-21 00:36:55 +00006234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006235s390_irgen_LNR(UChar r1, UChar r2)
6236{
6237 IRTemp op2 = newTemp(Ity_I32);
6238 IRTemp result = newTemp(Ity_I32);
6239
6240 assign(op2, get_gpr_w1(r2));
6241 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6242 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6243 put_gpr_w1(r1, mkexpr(result));
6244 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6245
6246 return "lnr";
6247}
6248
florian55085f82012-11-21 00:36:55 +00006249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006250s390_irgen_LNGR(UChar r1, UChar r2)
6251{
6252 IRTemp op2 = newTemp(Ity_I64);
6253 IRTemp result = newTemp(Ity_I64);
6254
6255 assign(op2, get_gpr_dw0(r2));
6256 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6257 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6258 put_gpr_dw0(r1, mkexpr(result));
6259 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6260
6261 return "lngr";
6262}
6263
florian55085f82012-11-21 00:36:55 +00006264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006265s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6266{
6267 IRTemp op2 = newTemp(Ity_I64);
6268 IRTemp result = newTemp(Ity_I64);
6269
6270 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6271 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6272 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6273 put_gpr_dw0(r1, mkexpr(result));
6274 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6275
6276 return "lngfr";
6277}
6278
florian55085f82012-11-21 00:36:55 +00006279static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006280s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6281{
florian6820ba52012-07-26 02:01:50 +00006282 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006283 put_gpr_w1(r1, get_gpr_w1(r2));
6284
6285 return "locr";
6286}
6287
florian55085f82012-11-21 00:36:55 +00006288static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006289s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6290{
florian6820ba52012-07-26 02:01:50 +00006291 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006292 put_gpr_dw0(r1, get_gpr_dw0(r2));
6293
6294 return "locgr";
6295}
6296
florian55085f82012-11-21 00:36:55 +00006297static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006298s390_irgen_LOC(UChar r1, IRTemp op2addr)
6299{
6300 /* condition is checked in format handler */
6301 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6302
6303 return "loc";
6304}
6305
florian55085f82012-11-21 00:36:55 +00006306static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006307s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6308{
6309 /* condition is checked in format handler */
6310 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6311
6312 return "locg";
6313}
6314
florian55085f82012-11-21 00:36:55 +00006315static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006316s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6317{
6318 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6319 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6320 ));
6321
6322 return "lpq";
6323}
6324
florian55085f82012-11-21 00:36:55 +00006325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006326s390_irgen_LPR(UChar r1, UChar r2)
6327{
6328 IRTemp op2 = newTemp(Ity_I32);
6329 IRTemp result = newTemp(Ity_I32);
6330
6331 assign(op2, get_gpr_w1(r2));
6332 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6333 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6334 put_gpr_w1(r1, mkexpr(result));
6335 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6336
6337 return "lpr";
6338}
6339
florian55085f82012-11-21 00:36:55 +00006340static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006341s390_irgen_LPGR(UChar r1, UChar r2)
6342{
6343 IRTemp op2 = newTemp(Ity_I64);
6344 IRTemp result = newTemp(Ity_I64);
6345
6346 assign(op2, get_gpr_dw0(r2));
6347 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6348 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6349 put_gpr_dw0(r1, mkexpr(result));
6350 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6351
6352 return "lpgr";
6353}
6354
florian55085f82012-11-21 00:36:55 +00006355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006356s390_irgen_LPGFR(UChar r1, UChar r2)
6357{
6358 IRTemp op2 = newTemp(Ity_I64);
6359 IRTemp result = newTemp(Ity_I64);
6360
6361 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6362 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6363 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6364 put_gpr_dw0(r1, mkexpr(result));
6365 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6366
6367 return "lpgfr";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006371s390_irgen_LRVR(UChar r1, UChar r2)
6372{
6373 IRTemp b0 = newTemp(Ity_I8);
6374 IRTemp b1 = newTemp(Ity_I8);
6375 IRTemp b2 = newTemp(Ity_I8);
6376 IRTemp b3 = newTemp(Ity_I8);
6377
6378 assign(b3, get_gpr_b7(r2));
6379 assign(b2, get_gpr_b6(r2));
6380 assign(b1, get_gpr_b5(r2));
6381 assign(b0, get_gpr_b4(r2));
6382 put_gpr_b4(r1, mkexpr(b3));
6383 put_gpr_b5(r1, mkexpr(b2));
6384 put_gpr_b6(r1, mkexpr(b1));
6385 put_gpr_b7(r1, mkexpr(b0));
6386
6387 return "lrvr";
6388}
6389
florian55085f82012-11-21 00:36:55 +00006390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006391s390_irgen_LRVGR(UChar r1, UChar r2)
6392{
6393 IRTemp b0 = newTemp(Ity_I8);
6394 IRTemp b1 = newTemp(Ity_I8);
6395 IRTemp b2 = newTemp(Ity_I8);
6396 IRTemp b3 = newTemp(Ity_I8);
6397 IRTemp b4 = newTemp(Ity_I8);
6398 IRTemp b5 = newTemp(Ity_I8);
6399 IRTemp b6 = newTemp(Ity_I8);
6400 IRTemp b7 = newTemp(Ity_I8);
6401
6402 assign(b7, get_gpr_b7(r2));
6403 assign(b6, get_gpr_b6(r2));
6404 assign(b5, get_gpr_b5(r2));
6405 assign(b4, get_gpr_b4(r2));
6406 assign(b3, get_gpr_b3(r2));
6407 assign(b2, get_gpr_b2(r2));
6408 assign(b1, get_gpr_b1(r2));
6409 assign(b0, get_gpr_b0(r2));
6410 put_gpr_b0(r1, mkexpr(b7));
6411 put_gpr_b1(r1, mkexpr(b6));
6412 put_gpr_b2(r1, mkexpr(b5));
6413 put_gpr_b3(r1, mkexpr(b4));
6414 put_gpr_b4(r1, mkexpr(b3));
6415 put_gpr_b5(r1, mkexpr(b2));
6416 put_gpr_b6(r1, mkexpr(b1));
6417 put_gpr_b7(r1, mkexpr(b0));
6418
6419 return "lrvgr";
6420}
6421
florian55085f82012-11-21 00:36:55 +00006422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006423s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6424{
6425 IRTemp op2 = newTemp(Ity_I16);
6426
6427 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6428 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6429 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6430
6431 return "lrvh";
6432}
6433
florian55085f82012-11-21 00:36:55 +00006434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006435s390_irgen_LRV(UChar r1, IRTemp op2addr)
6436{
6437 IRTemp op2 = newTemp(Ity_I32);
6438
6439 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6440 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6441 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6442 mkU8(8)), mkU32(255))));
6443 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6444 mkU8(16)), mkU32(255))));
6445 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6446 mkU8(24)), mkU32(255))));
6447
6448 return "lrv";
6449}
6450
florian55085f82012-11-21 00:36:55 +00006451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006452s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6453{
6454 IRTemp op2 = newTemp(Ity_I64);
6455
6456 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6457 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6458 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6459 mkU8(8)), mkU64(255))));
6460 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6461 mkU8(16)), mkU64(255))));
6462 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6463 mkU8(24)), mkU64(255))));
6464 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6465 mkU8(32)), mkU64(255))));
6466 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6467 mkU8(40)), mkU64(255))));
6468 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6469 mkU8(48)), mkU64(255))));
6470 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6471 mkU8(56)), mkU64(255))));
6472
6473 return "lrvg";
6474}
6475
florian55085f82012-11-21 00:36:55 +00006476static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006477s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6478{
6479 store(mkexpr(op1addr), mkU16(i2));
6480
6481 return "mvhhi";
6482}
6483
florian55085f82012-11-21 00:36:55 +00006484static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006485s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6486{
6487 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6488
6489 return "mvhi";
6490}
6491
florian55085f82012-11-21 00:36:55 +00006492static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006493s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6494{
6495 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6496
6497 return "mvghi";
6498}
6499
florian55085f82012-11-21 00:36:55 +00006500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006501s390_irgen_MVI(UChar i2, IRTemp op1addr)
6502{
6503 store(mkexpr(op1addr), mkU8(i2));
6504
6505 return "mvi";
6506}
6507
florian55085f82012-11-21 00:36:55 +00006508static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006509s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6510{
6511 store(mkexpr(op1addr), mkU8(i2));
6512
6513 return "mviy";
6514}
6515
florian55085f82012-11-21 00:36:55 +00006516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006517s390_irgen_MR(UChar r1, UChar r2)
6518{
6519 IRTemp op1 = newTemp(Ity_I32);
6520 IRTemp op2 = newTemp(Ity_I32);
6521 IRTemp result = newTemp(Ity_I64);
6522
6523 assign(op1, get_gpr_w1(r1 + 1));
6524 assign(op2, get_gpr_w1(r2));
6525 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6526 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6527 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6528
6529 return "mr";
6530}
6531
florian55085f82012-11-21 00:36:55 +00006532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006533s390_irgen_M(UChar r1, IRTemp op2addr)
6534{
6535 IRTemp op1 = newTemp(Ity_I32);
6536 IRTemp op2 = newTemp(Ity_I32);
6537 IRTemp result = newTemp(Ity_I64);
6538
6539 assign(op1, get_gpr_w1(r1 + 1));
6540 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6541 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6542 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6543 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6544
6545 return "m";
6546}
6547
florian55085f82012-11-21 00:36:55 +00006548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006549s390_irgen_MFY(UChar r1, IRTemp op2addr)
6550{
6551 IRTemp op1 = newTemp(Ity_I32);
6552 IRTemp op2 = newTemp(Ity_I32);
6553 IRTemp result = newTemp(Ity_I64);
6554
6555 assign(op1, get_gpr_w1(r1 + 1));
6556 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6557 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6558 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6559 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6560
6561 return "mfy";
6562}
6563
florian55085f82012-11-21 00:36:55 +00006564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006565s390_irgen_MH(UChar r1, IRTemp op2addr)
6566{
6567 IRTemp op1 = newTemp(Ity_I32);
6568 IRTemp op2 = newTemp(Ity_I16);
6569 IRTemp result = newTemp(Ity_I64);
6570
6571 assign(op1, get_gpr_w1(r1));
6572 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6573 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6574 ));
6575 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6576
6577 return "mh";
6578}
6579
florian55085f82012-11-21 00:36:55 +00006580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006581s390_irgen_MHY(UChar r1, IRTemp op2addr)
6582{
6583 IRTemp op1 = newTemp(Ity_I32);
6584 IRTemp op2 = newTemp(Ity_I16);
6585 IRTemp result = newTemp(Ity_I64);
6586
6587 assign(op1, get_gpr_w1(r1));
6588 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6589 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6590 ));
6591 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6592
6593 return "mhy";
6594}
6595
florian55085f82012-11-21 00:36:55 +00006596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006597s390_irgen_MHI(UChar r1, UShort i2)
6598{
6599 IRTemp op1 = newTemp(Ity_I32);
6600 Short op2;
6601 IRTemp result = newTemp(Ity_I64);
6602
6603 assign(op1, get_gpr_w1(r1));
6604 op2 = (Short)i2;
6605 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6606 mkU16((UShort)op2))));
6607 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6608
6609 return "mhi";
6610}
6611
florian55085f82012-11-21 00:36:55 +00006612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006613s390_irgen_MGHI(UChar r1, UShort i2)
6614{
6615 IRTemp op1 = newTemp(Ity_I64);
6616 Short op2;
6617 IRTemp result = newTemp(Ity_I128);
6618
6619 assign(op1, get_gpr_dw0(r1));
6620 op2 = (Short)i2;
6621 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6622 mkU16((UShort)op2))));
6623 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6624
6625 return "mghi";
6626}
6627
florian55085f82012-11-21 00:36:55 +00006628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006629s390_irgen_MLR(UChar r1, UChar r2)
6630{
6631 IRTemp op1 = newTemp(Ity_I32);
6632 IRTemp op2 = newTemp(Ity_I32);
6633 IRTemp result = newTemp(Ity_I64);
6634
6635 assign(op1, get_gpr_w1(r1 + 1));
6636 assign(op2, get_gpr_w1(r2));
6637 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6638 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6639 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6640
6641 return "mlr";
6642}
6643
florian55085f82012-11-21 00:36:55 +00006644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006645s390_irgen_MLGR(UChar r1, UChar r2)
6646{
6647 IRTemp op1 = newTemp(Ity_I64);
6648 IRTemp op2 = newTemp(Ity_I64);
6649 IRTemp result = newTemp(Ity_I128);
6650
6651 assign(op1, get_gpr_dw0(r1 + 1));
6652 assign(op2, get_gpr_dw0(r2));
6653 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6654 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6655 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6656
6657 return "mlgr";
6658}
6659
florian55085f82012-11-21 00:36:55 +00006660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006661s390_irgen_ML(UChar r1, IRTemp op2addr)
6662{
6663 IRTemp op1 = newTemp(Ity_I32);
6664 IRTemp op2 = newTemp(Ity_I32);
6665 IRTemp result = newTemp(Ity_I64);
6666
6667 assign(op1, get_gpr_w1(r1 + 1));
6668 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6669 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6670 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6671 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6672
6673 return "ml";
6674}
6675
florian55085f82012-11-21 00:36:55 +00006676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006677s390_irgen_MLG(UChar r1, IRTemp op2addr)
6678{
6679 IRTemp op1 = newTemp(Ity_I64);
6680 IRTemp op2 = newTemp(Ity_I64);
6681 IRTemp result = newTemp(Ity_I128);
6682
6683 assign(op1, get_gpr_dw0(r1 + 1));
6684 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6685 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6686 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6687 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6688
6689 return "mlg";
6690}
6691
florian55085f82012-11-21 00:36:55 +00006692static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006693s390_irgen_MSR(UChar r1, UChar r2)
6694{
6695 IRTemp op1 = newTemp(Ity_I32);
6696 IRTemp op2 = newTemp(Ity_I32);
6697 IRTemp result = newTemp(Ity_I64);
6698
6699 assign(op1, get_gpr_w1(r1));
6700 assign(op2, get_gpr_w1(r2));
6701 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6702 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6703
6704 return "msr";
6705}
6706
florian55085f82012-11-21 00:36:55 +00006707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006708s390_irgen_MSGR(UChar r1, UChar r2)
6709{
6710 IRTemp op1 = newTemp(Ity_I64);
6711 IRTemp op2 = newTemp(Ity_I64);
6712 IRTemp result = newTemp(Ity_I128);
6713
6714 assign(op1, get_gpr_dw0(r1));
6715 assign(op2, get_gpr_dw0(r2));
6716 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6717 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6718
6719 return "msgr";
6720}
6721
florian55085f82012-11-21 00:36:55 +00006722static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006723s390_irgen_MSGFR(UChar r1, UChar r2)
6724{
6725 IRTemp op1 = newTemp(Ity_I64);
6726 IRTemp op2 = newTemp(Ity_I32);
6727 IRTemp result = newTemp(Ity_I128);
6728
6729 assign(op1, get_gpr_dw0(r1));
6730 assign(op2, get_gpr_w1(r2));
6731 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6732 ));
6733 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6734
6735 return "msgfr";
6736}
6737
florian55085f82012-11-21 00:36:55 +00006738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006739s390_irgen_MS(UChar r1, IRTemp op2addr)
6740{
6741 IRTemp op1 = newTemp(Ity_I32);
6742 IRTemp op2 = newTemp(Ity_I32);
6743 IRTemp result = newTemp(Ity_I64);
6744
6745 assign(op1, get_gpr_w1(r1));
6746 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6747 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6748 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6749
6750 return "ms";
6751}
6752
florian55085f82012-11-21 00:36:55 +00006753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006754s390_irgen_MSY(UChar r1, IRTemp op2addr)
6755{
6756 IRTemp op1 = newTemp(Ity_I32);
6757 IRTemp op2 = newTemp(Ity_I32);
6758 IRTemp result = newTemp(Ity_I64);
6759
6760 assign(op1, get_gpr_w1(r1));
6761 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6762 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6763 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6764
6765 return "msy";
6766}
6767
florian55085f82012-11-21 00:36:55 +00006768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006769s390_irgen_MSG(UChar r1, IRTemp op2addr)
6770{
6771 IRTemp op1 = newTemp(Ity_I64);
6772 IRTemp op2 = newTemp(Ity_I64);
6773 IRTemp result = newTemp(Ity_I128);
6774
6775 assign(op1, get_gpr_dw0(r1));
6776 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6777 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6778 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6779
6780 return "msg";
6781}
6782
florian55085f82012-11-21 00:36:55 +00006783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006784s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6785{
6786 IRTemp op1 = newTemp(Ity_I64);
6787 IRTemp op2 = newTemp(Ity_I32);
6788 IRTemp result = newTemp(Ity_I128);
6789
6790 assign(op1, get_gpr_dw0(r1));
6791 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6792 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6793 ));
6794 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6795
6796 return "msgf";
6797}
6798
florian55085f82012-11-21 00:36:55 +00006799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006800s390_irgen_MSFI(UChar r1, UInt i2)
6801{
6802 IRTemp op1 = newTemp(Ity_I32);
6803 Int op2;
6804 IRTemp result = newTemp(Ity_I64);
6805
6806 assign(op1, get_gpr_w1(r1));
6807 op2 = (Int)i2;
6808 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6809 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6810
6811 return "msfi";
6812}
6813
florian55085f82012-11-21 00:36:55 +00006814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006815s390_irgen_MSGFI(UChar r1, UInt i2)
6816{
6817 IRTemp op1 = newTemp(Ity_I64);
6818 Int op2;
6819 IRTemp result = newTemp(Ity_I128);
6820
6821 assign(op1, get_gpr_dw0(r1));
6822 op2 = (Int)i2;
6823 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6824 op2))));
6825 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6826
6827 return "msgfi";
6828}
6829
florian55085f82012-11-21 00:36:55 +00006830static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006831s390_irgen_OR(UChar r1, UChar r2)
6832{
6833 IRTemp op1 = newTemp(Ity_I32);
6834 IRTemp op2 = newTemp(Ity_I32);
6835 IRTemp result = newTemp(Ity_I32);
6836
6837 assign(op1, get_gpr_w1(r1));
6838 assign(op2, get_gpr_w1(r2));
6839 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6840 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6841 put_gpr_w1(r1, mkexpr(result));
6842
6843 return "or";
6844}
6845
florian55085f82012-11-21 00:36:55 +00006846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006847s390_irgen_OGR(UChar r1, UChar r2)
6848{
6849 IRTemp op1 = newTemp(Ity_I64);
6850 IRTemp op2 = newTemp(Ity_I64);
6851 IRTemp result = newTemp(Ity_I64);
6852
6853 assign(op1, get_gpr_dw0(r1));
6854 assign(op2, get_gpr_dw0(r2));
6855 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6856 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6857 put_gpr_dw0(r1, mkexpr(result));
6858
6859 return "ogr";
6860}
6861
florian55085f82012-11-21 00:36:55 +00006862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006863s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6864{
6865 IRTemp op2 = newTemp(Ity_I32);
6866 IRTemp op3 = newTemp(Ity_I32);
6867 IRTemp result = newTemp(Ity_I32);
6868
6869 assign(op2, get_gpr_w1(r2));
6870 assign(op3, get_gpr_w1(r3));
6871 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6872 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6873 put_gpr_w1(r1, mkexpr(result));
6874
6875 return "ork";
6876}
6877
florian55085f82012-11-21 00:36:55 +00006878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006879s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6880{
6881 IRTemp op2 = newTemp(Ity_I64);
6882 IRTemp op3 = newTemp(Ity_I64);
6883 IRTemp result = newTemp(Ity_I64);
6884
6885 assign(op2, get_gpr_dw0(r2));
6886 assign(op3, get_gpr_dw0(r3));
6887 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6888 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6889 put_gpr_dw0(r1, mkexpr(result));
6890
6891 return "ogrk";
6892}
6893
florian55085f82012-11-21 00:36:55 +00006894static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006895s390_irgen_O(UChar r1, IRTemp op2addr)
6896{
6897 IRTemp op1 = newTemp(Ity_I32);
6898 IRTemp op2 = newTemp(Ity_I32);
6899 IRTemp result = newTemp(Ity_I32);
6900
6901 assign(op1, get_gpr_w1(r1));
6902 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6903 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6904 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6905 put_gpr_w1(r1, mkexpr(result));
6906
6907 return "o";
6908}
6909
florian55085f82012-11-21 00:36:55 +00006910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006911s390_irgen_OY(UChar r1, IRTemp op2addr)
6912{
6913 IRTemp op1 = newTemp(Ity_I32);
6914 IRTemp op2 = newTemp(Ity_I32);
6915 IRTemp result = newTemp(Ity_I32);
6916
6917 assign(op1, get_gpr_w1(r1));
6918 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6919 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6920 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6921 put_gpr_w1(r1, mkexpr(result));
6922
6923 return "oy";
6924}
6925
florian55085f82012-11-21 00:36:55 +00006926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006927s390_irgen_OG(UChar r1, IRTemp op2addr)
6928{
6929 IRTemp op1 = newTemp(Ity_I64);
6930 IRTemp op2 = newTemp(Ity_I64);
6931 IRTemp result = newTemp(Ity_I64);
6932
6933 assign(op1, get_gpr_dw0(r1));
6934 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6935 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6936 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6937 put_gpr_dw0(r1, mkexpr(result));
6938
6939 return "og";
6940}
6941
florian55085f82012-11-21 00:36:55 +00006942static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006943s390_irgen_OI(UChar i2, IRTemp op1addr)
6944{
6945 IRTemp op1 = newTemp(Ity_I8);
6946 UChar op2;
6947 IRTemp result = newTemp(Ity_I8);
6948
6949 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6950 op2 = i2;
6951 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6952 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6953 store(mkexpr(op1addr), mkexpr(result));
6954
6955 return "oi";
6956}
6957
florian55085f82012-11-21 00:36:55 +00006958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006959s390_irgen_OIY(UChar i2, IRTemp op1addr)
6960{
6961 IRTemp op1 = newTemp(Ity_I8);
6962 UChar op2;
6963 IRTemp result = newTemp(Ity_I8);
6964
6965 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6966 op2 = i2;
6967 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6968 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6969 store(mkexpr(op1addr), mkexpr(result));
6970
6971 return "oiy";
6972}
6973
florian55085f82012-11-21 00:36:55 +00006974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006975s390_irgen_OIHF(UChar r1, UInt i2)
6976{
6977 IRTemp op1 = newTemp(Ity_I32);
6978 UInt op2;
6979 IRTemp result = newTemp(Ity_I32);
6980
6981 assign(op1, get_gpr_w0(r1));
6982 op2 = i2;
6983 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6984 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6985 put_gpr_w0(r1, mkexpr(result));
6986
6987 return "oihf";
6988}
6989
florian55085f82012-11-21 00:36:55 +00006990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006991s390_irgen_OIHH(UChar r1, UShort i2)
6992{
6993 IRTemp op1 = newTemp(Ity_I16);
6994 UShort op2;
6995 IRTemp result = newTemp(Ity_I16);
6996
6997 assign(op1, get_gpr_hw0(r1));
6998 op2 = i2;
6999 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7000 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7001 put_gpr_hw0(r1, mkexpr(result));
7002
7003 return "oihh";
7004}
7005
florian55085f82012-11-21 00:36:55 +00007006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007007s390_irgen_OIHL(UChar r1, UShort i2)
7008{
7009 IRTemp op1 = newTemp(Ity_I16);
7010 UShort op2;
7011 IRTemp result = newTemp(Ity_I16);
7012
7013 assign(op1, get_gpr_hw1(r1));
7014 op2 = i2;
7015 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7016 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7017 put_gpr_hw1(r1, mkexpr(result));
7018
7019 return "oihl";
7020}
7021
florian55085f82012-11-21 00:36:55 +00007022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007023s390_irgen_OILF(UChar r1, UInt i2)
7024{
7025 IRTemp op1 = newTemp(Ity_I32);
7026 UInt op2;
7027 IRTemp result = newTemp(Ity_I32);
7028
7029 assign(op1, get_gpr_w1(r1));
7030 op2 = i2;
7031 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7032 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7033 put_gpr_w1(r1, mkexpr(result));
7034
7035 return "oilf";
7036}
7037
florian55085f82012-11-21 00:36:55 +00007038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007039s390_irgen_OILH(UChar r1, UShort i2)
7040{
7041 IRTemp op1 = newTemp(Ity_I16);
7042 UShort op2;
7043 IRTemp result = newTemp(Ity_I16);
7044
7045 assign(op1, get_gpr_hw2(r1));
7046 op2 = i2;
7047 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7048 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7049 put_gpr_hw2(r1, mkexpr(result));
7050
7051 return "oilh";
7052}
7053
florian55085f82012-11-21 00:36:55 +00007054static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007055s390_irgen_OILL(UChar r1, UShort i2)
7056{
7057 IRTemp op1 = newTemp(Ity_I16);
7058 UShort op2;
7059 IRTemp result = newTemp(Ity_I16);
7060
7061 assign(op1, get_gpr_hw3(r1));
7062 op2 = i2;
7063 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7064 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7065 put_gpr_hw3(r1, mkexpr(result));
7066
7067 return "oill";
7068}
7069
florian55085f82012-11-21 00:36:55 +00007070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007071s390_irgen_PFD(void)
7072{
7073
7074 return "pfd";
7075}
7076
florian55085f82012-11-21 00:36:55 +00007077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007078s390_irgen_PFDRL(void)
7079{
7080
7081 return "pfdrl";
7082}
7083
florian55085f82012-11-21 00:36:55 +00007084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007085s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7086{
7087 IRTemp amount = newTemp(Ity_I64);
7088 IRTemp op = newTemp(Ity_I32);
7089
7090 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7091 assign(op, get_gpr_w1(r3));
7092 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7093 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7094 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7095
7096 return "rll";
7097}
7098
florian55085f82012-11-21 00:36:55 +00007099static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007100s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7101{
7102 IRTemp amount = newTemp(Ity_I64);
7103 IRTemp op = newTemp(Ity_I64);
7104
7105 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7106 assign(op, get_gpr_dw0(r3));
7107 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7108 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7109 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7110
7111 return "rllg";
7112}
7113
florian55085f82012-11-21 00:36:55 +00007114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007115s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7116{
7117 UChar from;
7118 UChar to;
7119 UChar rot;
7120 UChar t_bit;
7121 ULong mask;
7122 ULong maskc;
7123 IRTemp result = newTemp(Ity_I64);
7124 IRTemp op2 = newTemp(Ity_I64);
7125
7126 from = i3 & 63;
7127 to = i4 & 63;
7128 rot = i5 & 63;
7129 t_bit = i3 & 128;
7130 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7131 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7132 mkU8(64 - rot))));
7133 if (from <= to) {
7134 mask = ~0ULL;
7135 mask = (mask >> from) & (mask << (63 - to));
7136 maskc = ~mask;
7137 } else {
7138 maskc = ~0ULL;
7139 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7140 mask = ~maskc;
7141 }
7142 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7143 ), mkU64(mask)));
7144 if (t_bit == 0) {
7145 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7146 mkU64(maskc)), mkexpr(result)));
7147 }
7148 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7149
7150 return "rnsbg";
7151}
7152
florian55085f82012-11-21 00:36:55 +00007153static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007154s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7155{
7156 UChar from;
7157 UChar to;
7158 UChar rot;
7159 UChar t_bit;
7160 ULong mask;
7161 ULong maskc;
7162 IRTemp result = newTemp(Ity_I64);
7163 IRTemp op2 = newTemp(Ity_I64);
7164
7165 from = i3 & 63;
7166 to = i4 & 63;
7167 rot = i5 & 63;
7168 t_bit = i3 & 128;
7169 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7170 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7171 mkU8(64 - rot))));
7172 if (from <= to) {
7173 mask = ~0ULL;
7174 mask = (mask >> from) & (mask << (63 - to));
7175 maskc = ~mask;
7176 } else {
7177 maskc = ~0ULL;
7178 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7179 mask = ~maskc;
7180 }
7181 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7182 ), mkU64(mask)));
7183 if (t_bit == 0) {
7184 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7185 mkU64(maskc)), mkexpr(result)));
7186 }
7187 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7188
7189 return "rxsbg";
7190}
7191
florian55085f82012-11-21 00:36:55 +00007192static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007193s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7194{
7195 UChar from;
7196 UChar to;
7197 UChar rot;
7198 UChar t_bit;
7199 ULong mask;
7200 ULong maskc;
7201 IRTemp result = newTemp(Ity_I64);
7202 IRTemp op2 = newTemp(Ity_I64);
7203
7204 from = i3 & 63;
7205 to = i4 & 63;
7206 rot = i5 & 63;
7207 t_bit = i3 & 128;
7208 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7209 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7210 mkU8(64 - rot))));
7211 if (from <= to) {
7212 mask = ~0ULL;
7213 mask = (mask >> from) & (mask << (63 - to));
7214 maskc = ~mask;
7215 } else {
7216 maskc = ~0ULL;
7217 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7218 mask = ~maskc;
7219 }
7220 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7221 ), mkU64(mask)));
7222 if (t_bit == 0) {
7223 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7224 mkU64(maskc)), mkexpr(result)));
7225 }
7226 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7227
7228 return "rosbg";
7229}
7230
florian55085f82012-11-21 00:36:55 +00007231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007232s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7233{
7234 UChar from;
7235 UChar to;
7236 UChar rot;
7237 UChar z_bit;
7238 ULong mask;
7239 ULong maskc;
7240 IRTemp op2 = newTemp(Ity_I64);
7241 IRTemp result = newTemp(Ity_I64);
7242
7243 from = i3 & 63;
7244 to = i4 & 63;
7245 rot = i5 & 63;
7246 z_bit = i4 & 128;
7247 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7248 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7249 mkU8(64 - rot))));
7250 if (from <= to) {
7251 mask = ~0ULL;
7252 mask = (mask >> from) & (mask << (63 - to));
7253 maskc = ~mask;
7254 } else {
7255 maskc = ~0ULL;
7256 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7257 mask = ~maskc;
7258 }
7259 if (z_bit == 0) {
7260 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7261 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7262 } else {
7263 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7264 }
7265 assign(result, get_gpr_dw0(r1));
7266 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7267
7268 return "risbg";
7269}
7270
florian55085f82012-11-21 00:36:55 +00007271static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007272s390_irgen_SAR(UChar r1, UChar r2)
7273{
7274 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007275 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007276 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7277
7278 return "sar";
7279}
7280
florian55085f82012-11-21 00:36:55 +00007281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007282s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7283{
7284 IRTemp p1 = newTemp(Ity_I64);
7285 IRTemp p2 = newTemp(Ity_I64);
7286 IRTemp op = newTemp(Ity_I64);
7287 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007288 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007289 IRTemp shift_amount = newTemp(Ity_I64);
7290
7291 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7292 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7293 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7294 ));
7295 sign_mask = 1ULL << 63;
7296 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7297 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007298 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7299 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007300 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7301 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7302 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7303
7304 return "slda";
7305}
7306
florian55085f82012-11-21 00:36:55 +00007307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007308s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7309{
7310 IRTemp p1 = newTemp(Ity_I64);
7311 IRTemp p2 = newTemp(Ity_I64);
7312 IRTemp result = newTemp(Ity_I64);
7313
7314 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7315 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7316 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7317 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7318 mkexpr(op2addr), mkU64(63)))));
7319 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7320 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7321
7322 return "sldl";
7323}
7324
florian55085f82012-11-21 00:36:55 +00007325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007326s390_irgen_SLA(UChar r1, IRTemp op2addr)
7327{
7328 IRTemp uop = newTemp(Ity_I32);
7329 IRTemp result = newTemp(Ity_I32);
7330 UInt sign_mask;
7331 IRTemp shift_amount = newTemp(Ity_I64);
7332 IRTemp op = newTemp(Ity_I32);
7333
7334 assign(op, get_gpr_w1(r1));
7335 assign(uop, get_gpr_w1(r1));
7336 sign_mask = 2147483648U;
7337 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7338 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7339 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7340 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7341 put_gpr_w1(r1, mkexpr(result));
7342 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7343
7344 return "sla";
7345}
7346
florian55085f82012-11-21 00:36:55 +00007347static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007348s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7349{
7350 IRTemp uop = newTemp(Ity_I32);
7351 IRTemp result = newTemp(Ity_I32);
7352 UInt sign_mask;
7353 IRTemp shift_amount = newTemp(Ity_I64);
7354 IRTemp op = newTemp(Ity_I32);
7355
7356 assign(op, get_gpr_w1(r3));
7357 assign(uop, get_gpr_w1(r3));
7358 sign_mask = 2147483648U;
7359 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7360 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7361 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7362 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7363 put_gpr_w1(r1, mkexpr(result));
7364 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7365
7366 return "slak";
7367}
7368
florian55085f82012-11-21 00:36:55 +00007369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007370s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7371{
7372 IRTemp uop = newTemp(Ity_I64);
7373 IRTemp result = newTemp(Ity_I64);
7374 ULong sign_mask;
7375 IRTemp shift_amount = newTemp(Ity_I64);
7376 IRTemp op = newTemp(Ity_I64);
7377
7378 assign(op, get_gpr_dw0(r3));
7379 assign(uop, get_gpr_dw0(r3));
7380 sign_mask = 9223372036854775808ULL;
7381 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7382 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7383 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7384 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7385 put_gpr_dw0(r1, mkexpr(result));
7386 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7387
7388 return "slag";
7389}
7390
florian55085f82012-11-21 00:36:55 +00007391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007392s390_irgen_SLL(UChar r1, IRTemp op2addr)
7393{
7394 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7395 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7396
7397 return "sll";
7398}
7399
florian55085f82012-11-21 00:36:55 +00007400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007401s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7402{
7403 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7404 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7405
7406 return "sllk";
7407}
7408
florian55085f82012-11-21 00:36:55 +00007409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007410s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7411{
7412 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7413 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7414
7415 return "sllg";
7416}
7417
florian55085f82012-11-21 00:36:55 +00007418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007419s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7420{
7421 IRTemp p1 = newTemp(Ity_I64);
7422 IRTemp p2 = newTemp(Ity_I64);
7423 IRTemp result = newTemp(Ity_I64);
7424
7425 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7426 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7427 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7428 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7429 mkexpr(op2addr), mkU64(63)))));
7430 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7431 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7432 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7433
7434 return "srda";
7435}
7436
florian55085f82012-11-21 00:36:55 +00007437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007438s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7439{
7440 IRTemp p1 = newTemp(Ity_I64);
7441 IRTemp p2 = newTemp(Ity_I64);
7442 IRTemp result = newTemp(Ity_I64);
7443
7444 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7445 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7446 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7447 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7448 mkexpr(op2addr), mkU64(63)))));
7449 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7450 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7451
7452 return "srdl";
7453}
7454
florian55085f82012-11-21 00:36:55 +00007455static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007456s390_irgen_SRA(UChar r1, IRTemp op2addr)
7457{
7458 IRTemp result = newTemp(Ity_I32);
7459 IRTemp op = newTemp(Ity_I32);
7460
7461 assign(op, get_gpr_w1(r1));
7462 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7463 mkexpr(op2addr), mkU64(63)))));
7464 put_gpr_w1(r1, mkexpr(result));
7465 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7466
7467 return "sra";
7468}
7469
florian55085f82012-11-21 00:36:55 +00007470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007471s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7472{
7473 IRTemp result = newTemp(Ity_I32);
7474 IRTemp op = newTemp(Ity_I32);
7475
7476 assign(op, get_gpr_w1(r3));
7477 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7478 mkexpr(op2addr), mkU64(63)))));
7479 put_gpr_w1(r1, mkexpr(result));
7480 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7481
7482 return "srak";
7483}
7484
florian55085f82012-11-21 00:36:55 +00007485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007486s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7487{
7488 IRTemp result = newTemp(Ity_I64);
7489 IRTemp op = newTemp(Ity_I64);
7490
7491 assign(op, get_gpr_dw0(r3));
7492 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7493 mkexpr(op2addr), mkU64(63)))));
7494 put_gpr_dw0(r1, mkexpr(result));
7495 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7496
7497 return "srag";
7498}
7499
florian55085f82012-11-21 00:36:55 +00007500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007501s390_irgen_SRL(UChar r1, IRTemp op2addr)
7502{
7503 IRTemp op = newTemp(Ity_I32);
7504
7505 assign(op, get_gpr_w1(r1));
7506 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7507 mkexpr(op2addr), mkU64(63)))));
7508
7509 return "srl";
7510}
7511
florian55085f82012-11-21 00:36:55 +00007512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007513s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7514{
7515 IRTemp op = newTemp(Ity_I32);
7516
7517 assign(op, get_gpr_w1(r3));
7518 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7519 mkexpr(op2addr), mkU64(63)))));
7520
7521 return "srlk";
7522}
7523
florian55085f82012-11-21 00:36:55 +00007524static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007525s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7526{
7527 IRTemp op = newTemp(Ity_I64);
7528
7529 assign(op, get_gpr_dw0(r3));
7530 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7531 mkexpr(op2addr), mkU64(63)))));
7532
7533 return "srlg";
7534}
7535
florian55085f82012-11-21 00:36:55 +00007536static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007537s390_irgen_ST(UChar r1, IRTemp op2addr)
7538{
7539 store(mkexpr(op2addr), get_gpr_w1(r1));
7540
7541 return "st";
7542}
7543
florian55085f82012-11-21 00:36:55 +00007544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007545s390_irgen_STY(UChar r1, IRTemp op2addr)
7546{
7547 store(mkexpr(op2addr), get_gpr_w1(r1));
7548
7549 return "sty";
7550}
7551
florian55085f82012-11-21 00:36:55 +00007552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007553s390_irgen_STG(UChar r1, IRTemp op2addr)
7554{
7555 store(mkexpr(op2addr), get_gpr_dw0(r1));
7556
7557 return "stg";
7558}
7559
florian55085f82012-11-21 00:36:55 +00007560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007561s390_irgen_STRL(UChar r1, UInt i2)
7562{
7563 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7564 get_gpr_w1(r1));
7565
7566 return "strl";
7567}
7568
florian55085f82012-11-21 00:36:55 +00007569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007570s390_irgen_STGRL(UChar r1, UInt i2)
7571{
7572 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7573 get_gpr_dw0(r1));
7574
7575 return "stgrl";
7576}
7577
florian55085f82012-11-21 00:36:55 +00007578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007579s390_irgen_STC(UChar r1, IRTemp op2addr)
7580{
7581 store(mkexpr(op2addr), get_gpr_b7(r1));
7582
7583 return "stc";
7584}
7585
florian55085f82012-11-21 00:36:55 +00007586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007587s390_irgen_STCY(UChar r1, IRTemp op2addr)
7588{
7589 store(mkexpr(op2addr), get_gpr_b7(r1));
7590
7591 return "stcy";
7592}
7593
florian55085f82012-11-21 00:36:55 +00007594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007595s390_irgen_STCH(UChar r1, IRTemp op2addr)
7596{
7597 store(mkexpr(op2addr), get_gpr_b3(r1));
7598
7599 return "stch";
7600}
7601
florian55085f82012-11-21 00:36:55 +00007602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007603s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7604{
7605 UChar mask;
7606 UChar n;
7607
7608 mask = (UChar)r3;
7609 n = 0;
7610 if ((mask & 8) != 0) {
7611 store(mkexpr(op2addr), get_gpr_b4(r1));
7612 n = n + 1;
7613 }
7614 if ((mask & 4) != 0) {
7615 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7616 n = n + 1;
7617 }
7618 if ((mask & 2) != 0) {
7619 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7620 n = n + 1;
7621 }
7622 if ((mask & 1) != 0) {
7623 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7624 }
7625
7626 return "stcm";
7627}
7628
florian55085f82012-11-21 00:36:55 +00007629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007630s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7631{
7632 UChar mask;
7633 UChar n;
7634
7635 mask = (UChar)r3;
7636 n = 0;
7637 if ((mask & 8) != 0) {
7638 store(mkexpr(op2addr), get_gpr_b4(r1));
7639 n = n + 1;
7640 }
7641 if ((mask & 4) != 0) {
7642 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7643 n = n + 1;
7644 }
7645 if ((mask & 2) != 0) {
7646 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7647 n = n + 1;
7648 }
7649 if ((mask & 1) != 0) {
7650 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7651 }
7652
7653 return "stcmy";
7654}
7655
florian55085f82012-11-21 00:36:55 +00007656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007657s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7658{
7659 UChar mask;
7660 UChar n;
7661
7662 mask = (UChar)r3;
7663 n = 0;
7664 if ((mask & 8) != 0) {
7665 store(mkexpr(op2addr), get_gpr_b0(r1));
7666 n = n + 1;
7667 }
7668 if ((mask & 4) != 0) {
7669 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7670 n = n + 1;
7671 }
7672 if ((mask & 2) != 0) {
7673 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7674 n = n + 1;
7675 }
7676 if ((mask & 1) != 0) {
7677 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7678 }
7679
7680 return "stcmh";
7681}
7682
florian55085f82012-11-21 00:36:55 +00007683static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007684s390_irgen_STH(UChar r1, IRTemp op2addr)
7685{
7686 store(mkexpr(op2addr), get_gpr_hw3(r1));
7687
7688 return "sth";
7689}
7690
florian55085f82012-11-21 00:36:55 +00007691static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007692s390_irgen_STHY(UChar r1, IRTemp op2addr)
7693{
7694 store(mkexpr(op2addr), get_gpr_hw3(r1));
7695
7696 return "sthy";
7697}
7698
florian55085f82012-11-21 00:36:55 +00007699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007700s390_irgen_STHRL(UChar r1, UInt i2)
7701{
7702 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7703 get_gpr_hw3(r1));
7704
7705 return "sthrl";
7706}
7707
florian55085f82012-11-21 00:36:55 +00007708static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007709s390_irgen_STHH(UChar r1, IRTemp op2addr)
7710{
7711 store(mkexpr(op2addr), get_gpr_hw1(r1));
7712
7713 return "sthh";
7714}
7715
florian55085f82012-11-21 00:36:55 +00007716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007717s390_irgen_STFH(UChar r1, IRTemp op2addr)
7718{
7719 store(mkexpr(op2addr), get_gpr_w0(r1));
7720
7721 return "stfh";
7722}
7723
florian55085f82012-11-21 00:36:55 +00007724static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007725s390_irgen_STOC(UChar r1, IRTemp op2addr)
7726{
7727 /* condition is checked in format handler */
7728 store(mkexpr(op2addr), get_gpr_w1(r1));
7729
7730 return "stoc";
7731}
7732
florian55085f82012-11-21 00:36:55 +00007733static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007734s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7735{
7736 /* condition is checked in format handler */
7737 store(mkexpr(op2addr), get_gpr_dw0(r1));
7738
7739 return "stocg";
7740}
7741
florian55085f82012-11-21 00:36:55 +00007742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007743s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7744{
7745 store(mkexpr(op2addr), get_gpr_dw0(r1));
7746 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7747
7748 return "stpq";
7749}
7750
florian55085f82012-11-21 00:36:55 +00007751static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007752s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7753{
7754 store(mkexpr(op2addr), get_gpr_b7(r1));
7755 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7756
7757 return "strvh";
7758}
7759
florian55085f82012-11-21 00:36:55 +00007760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007761s390_irgen_STRV(UChar r1, IRTemp op2addr)
7762{
7763 store(mkexpr(op2addr), get_gpr_b7(r1));
7764 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7765 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7766 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7767
7768 return "strv";
7769}
7770
florian55085f82012-11-21 00:36:55 +00007771static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007772s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7773{
7774 store(mkexpr(op2addr), get_gpr_b7(r1));
7775 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7776 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7777 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7778 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7779 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7780 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7781 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7782
7783 return "strvg";
7784}
7785
florian55085f82012-11-21 00:36:55 +00007786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007787s390_irgen_SR(UChar r1, UChar r2)
7788{
7789 IRTemp op1 = newTemp(Ity_I32);
7790 IRTemp op2 = newTemp(Ity_I32);
7791 IRTemp result = newTemp(Ity_I32);
7792
7793 assign(op1, get_gpr_w1(r1));
7794 assign(op2, get_gpr_w1(r2));
7795 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7796 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7797 put_gpr_w1(r1, mkexpr(result));
7798
7799 return "sr";
7800}
7801
florian55085f82012-11-21 00:36:55 +00007802static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007803s390_irgen_SGR(UChar r1, UChar r2)
7804{
7805 IRTemp op1 = newTemp(Ity_I64);
7806 IRTemp op2 = newTemp(Ity_I64);
7807 IRTemp result = newTemp(Ity_I64);
7808
7809 assign(op1, get_gpr_dw0(r1));
7810 assign(op2, get_gpr_dw0(r2));
7811 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7812 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7813 put_gpr_dw0(r1, mkexpr(result));
7814
7815 return "sgr";
7816}
7817
florian55085f82012-11-21 00:36:55 +00007818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007819s390_irgen_SGFR(UChar r1, UChar r2)
7820{
7821 IRTemp op1 = newTemp(Ity_I64);
7822 IRTemp op2 = newTemp(Ity_I64);
7823 IRTemp result = newTemp(Ity_I64);
7824
7825 assign(op1, get_gpr_dw0(r1));
7826 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7827 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7828 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7829 put_gpr_dw0(r1, mkexpr(result));
7830
7831 return "sgfr";
7832}
7833
florian55085f82012-11-21 00:36:55 +00007834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007835s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7836{
7837 IRTemp op2 = newTemp(Ity_I32);
7838 IRTemp op3 = newTemp(Ity_I32);
7839 IRTemp result = newTemp(Ity_I32);
7840
7841 assign(op2, get_gpr_w1(r2));
7842 assign(op3, get_gpr_w1(r3));
7843 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7844 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7845 put_gpr_w1(r1, mkexpr(result));
7846
7847 return "srk";
7848}
7849
florian55085f82012-11-21 00:36:55 +00007850static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007851s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7852{
7853 IRTemp op2 = newTemp(Ity_I64);
7854 IRTemp op3 = newTemp(Ity_I64);
7855 IRTemp result = newTemp(Ity_I64);
7856
7857 assign(op2, get_gpr_dw0(r2));
7858 assign(op3, get_gpr_dw0(r3));
7859 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7860 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7861 put_gpr_dw0(r1, mkexpr(result));
7862
7863 return "sgrk";
7864}
7865
florian55085f82012-11-21 00:36:55 +00007866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007867s390_irgen_S(UChar r1, IRTemp op2addr)
7868{
7869 IRTemp op1 = newTemp(Ity_I32);
7870 IRTemp op2 = newTemp(Ity_I32);
7871 IRTemp result = newTemp(Ity_I32);
7872
7873 assign(op1, get_gpr_w1(r1));
7874 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7875 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7876 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7877 put_gpr_w1(r1, mkexpr(result));
7878
7879 return "s";
7880}
7881
florian55085f82012-11-21 00:36:55 +00007882static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007883s390_irgen_SY(UChar r1, IRTemp op2addr)
7884{
7885 IRTemp op1 = newTemp(Ity_I32);
7886 IRTemp op2 = newTemp(Ity_I32);
7887 IRTemp result = newTemp(Ity_I32);
7888
7889 assign(op1, get_gpr_w1(r1));
7890 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7891 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7892 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7893 put_gpr_w1(r1, mkexpr(result));
7894
7895 return "sy";
7896}
7897
florian55085f82012-11-21 00:36:55 +00007898static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007899s390_irgen_SG(UChar r1, IRTemp op2addr)
7900{
7901 IRTemp op1 = newTemp(Ity_I64);
7902 IRTemp op2 = newTemp(Ity_I64);
7903 IRTemp result = newTemp(Ity_I64);
7904
7905 assign(op1, get_gpr_dw0(r1));
7906 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7907 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7908 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7909 put_gpr_dw0(r1, mkexpr(result));
7910
7911 return "sg";
7912}
7913
florian55085f82012-11-21 00:36:55 +00007914static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007915s390_irgen_SGF(UChar r1, IRTemp op2addr)
7916{
7917 IRTemp op1 = newTemp(Ity_I64);
7918 IRTemp op2 = newTemp(Ity_I64);
7919 IRTemp result = newTemp(Ity_I64);
7920
7921 assign(op1, get_gpr_dw0(r1));
7922 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7923 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7924 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7925 put_gpr_dw0(r1, mkexpr(result));
7926
7927 return "sgf";
7928}
7929
florian55085f82012-11-21 00:36:55 +00007930static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007931s390_irgen_SH(UChar r1, IRTemp op2addr)
7932{
7933 IRTemp op1 = newTemp(Ity_I32);
7934 IRTemp op2 = newTemp(Ity_I32);
7935 IRTemp result = newTemp(Ity_I32);
7936
7937 assign(op1, get_gpr_w1(r1));
7938 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7939 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7940 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7941 put_gpr_w1(r1, mkexpr(result));
7942
7943 return "sh";
7944}
7945
florian55085f82012-11-21 00:36:55 +00007946static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007947s390_irgen_SHY(UChar r1, IRTemp op2addr)
7948{
7949 IRTemp op1 = newTemp(Ity_I32);
7950 IRTemp op2 = newTemp(Ity_I32);
7951 IRTemp result = newTemp(Ity_I32);
7952
7953 assign(op1, get_gpr_w1(r1));
7954 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7955 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7956 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7957 put_gpr_w1(r1, mkexpr(result));
7958
7959 return "shy";
7960}
7961
florian55085f82012-11-21 00:36:55 +00007962static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007963s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7964{
7965 IRTemp op2 = newTemp(Ity_I32);
7966 IRTemp op3 = newTemp(Ity_I32);
7967 IRTemp result = newTemp(Ity_I32);
7968
7969 assign(op2, get_gpr_w0(r1));
7970 assign(op3, get_gpr_w0(r2));
7971 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7972 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7973 put_gpr_w0(r1, mkexpr(result));
7974
7975 return "shhhr";
7976}
7977
florian55085f82012-11-21 00:36:55 +00007978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007979s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7980{
7981 IRTemp op2 = newTemp(Ity_I32);
7982 IRTemp op3 = newTemp(Ity_I32);
7983 IRTemp result = newTemp(Ity_I32);
7984
7985 assign(op2, get_gpr_w0(r1));
7986 assign(op3, get_gpr_w1(r2));
7987 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7989 put_gpr_w0(r1, mkexpr(result));
7990
7991 return "shhlr";
7992}
7993
florian55085f82012-11-21 00:36:55 +00007994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007995s390_irgen_SLR(UChar r1, UChar r2)
7996{
7997 IRTemp op1 = newTemp(Ity_I32);
7998 IRTemp op2 = newTemp(Ity_I32);
7999 IRTemp result = newTemp(Ity_I32);
8000
8001 assign(op1, get_gpr_w1(r1));
8002 assign(op2, get_gpr_w1(r2));
8003 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8004 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8005 put_gpr_w1(r1, mkexpr(result));
8006
8007 return "slr";
8008}
8009
florian55085f82012-11-21 00:36:55 +00008010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008011s390_irgen_SLGR(UChar r1, UChar r2)
8012{
8013 IRTemp op1 = newTemp(Ity_I64);
8014 IRTemp op2 = newTemp(Ity_I64);
8015 IRTemp result = newTemp(Ity_I64);
8016
8017 assign(op1, get_gpr_dw0(r1));
8018 assign(op2, get_gpr_dw0(r2));
8019 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8020 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8021 put_gpr_dw0(r1, mkexpr(result));
8022
8023 return "slgr";
8024}
8025
florian55085f82012-11-21 00:36:55 +00008026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008027s390_irgen_SLGFR(UChar r1, UChar r2)
8028{
8029 IRTemp op1 = newTemp(Ity_I64);
8030 IRTemp op2 = newTemp(Ity_I64);
8031 IRTemp result = newTemp(Ity_I64);
8032
8033 assign(op1, get_gpr_dw0(r1));
8034 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8035 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8036 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8037 put_gpr_dw0(r1, mkexpr(result));
8038
8039 return "slgfr";
8040}
8041
florian55085f82012-11-21 00:36:55 +00008042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008043s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8044{
8045 IRTemp op2 = newTemp(Ity_I32);
8046 IRTemp op3 = newTemp(Ity_I32);
8047 IRTemp result = newTemp(Ity_I32);
8048
8049 assign(op2, get_gpr_w1(r2));
8050 assign(op3, get_gpr_w1(r3));
8051 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8052 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8053 put_gpr_w1(r1, mkexpr(result));
8054
8055 return "slrk";
8056}
8057
florian55085f82012-11-21 00:36:55 +00008058static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008059s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8060{
8061 IRTemp op2 = newTemp(Ity_I64);
8062 IRTemp op3 = newTemp(Ity_I64);
8063 IRTemp result = newTemp(Ity_I64);
8064
8065 assign(op2, get_gpr_dw0(r2));
8066 assign(op3, get_gpr_dw0(r3));
8067 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8068 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8069 put_gpr_dw0(r1, mkexpr(result));
8070
8071 return "slgrk";
8072}
8073
florian55085f82012-11-21 00:36:55 +00008074static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008075s390_irgen_SL(UChar r1, IRTemp op2addr)
8076{
8077 IRTemp op1 = newTemp(Ity_I32);
8078 IRTemp op2 = newTemp(Ity_I32);
8079 IRTemp result = newTemp(Ity_I32);
8080
8081 assign(op1, get_gpr_w1(r1));
8082 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8083 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8084 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8085 put_gpr_w1(r1, mkexpr(result));
8086
8087 return "sl";
8088}
8089
florian55085f82012-11-21 00:36:55 +00008090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008091s390_irgen_SLY(UChar r1, IRTemp op2addr)
8092{
8093 IRTemp op1 = newTemp(Ity_I32);
8094 IRTemp op2 = newTemp(Ity_I32);
8095 IRTemp result = newTemp(Ity_I32);
8096
8097 assign(op1, get_gpr_w1(r1));
8098 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8099 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8100 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8101 put_gpr_w1(r1, mkexpr(result));
8102
8103 return "sly";
8104}
8105
florian55085f82012-11-21 00:36:55 +00008106static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008107s390_irgen_SLG(UChar r1, IRTemp op2addr)
8108{
8109 IRTemp op1 = newTemp(Ity_I64);
8110 IRTemp op2 = newTemp(Ity_I64);
8111 IRTemp result = newTemp(Ity_I64);
8112
8113 assign(op1, get_gpr_dw0(r1));
8114 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8115 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8116 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8117 put_gpr_dw0(r1, mkexpr(result));
8118
8119 return "slg";
8120}
8121
florian55085f82012-11-21 00:36:55 +00008122static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008123s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8124{
8125 IRTemp op1 = newTemp(Ity_I64);
8126 IRTemp op2 = newTemp(Ity_I64);
8127 IRTemp result = newTemp(Ity_I64);
8128
8129 assign(op1, get_gpr_dw0(r1));
8130 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8131 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8132 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8133 put_gpr_dw0(r1, mkexpr(result));
8134
8135 return "slgf";
8136}
8137
florian55085f82012-11-21 00:36:55 +00008138static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008139s390_irgen_SLFI(UChar r1, UInt i2)
8140{
8141 IRTemp op1 = newTemp(Ity_I32);
8142 UInt op2;
8143 IRTemp result = newTemp(Ity_I32);
8144
8145 assign(op1, get_gpr_w1(r1));
8146 op2 = i2;
8147 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8148 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8149 mkU32(op2)));
8150 put_gpr_w1(r1, mkexpr(result));
8151
8152 return "slfi";
8153}
8154
florian55085f82012-11-21 00:36:55 +00008155static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008156s390_irgen_SLGFI(UChar r1, UInt i2)
8157{
8158 IRTemp op1 = newTemp(Ity_I64);
8159 ULong op2;
8160 IRTemp result = newTemp(Ity_I64);
8161
8162 assign(op1, get_gpr_dw0(r1));
8163 op2 = (ULong)i2;
8164 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8165 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8166 mkU64(op2)));
8167 put_gpr_dw0(r1, mkexpr(result));
8168
8169 return "slgfi";
8170}
8171
florian55085f82012-11-21 00:36:55 +00008172static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008173s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8174{
8175 IRTemp op2 = newTemp(Ity_I32);
8176 IRTemp op3 = newTemp(Ity_I32);
8177 IRTemp result = newTemp(Ity_I32);
8178
8179 assign(op2, get_gpr_w0(r1));
8180 assign(op3, get_gpr_w0(r2));
8181 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8182 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8183 put_gpr_w0(r1, mkexpr(result));
8184
8185 return "slhhhr";
8186}
8187
florian55085f82012-11-21 00:36:55 +00008188static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008189s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8190{
8191 IRTemp op2 = newTemp(Ity_I32);
8192 IRTemp op3 = newTemp(Ity_I32);
8193 IRTemp result = newTemp(Ity_I32);
8194
8195 assign(op2, get_gpr_w0(r1));
8196 assign(op3, get_gpr_w1(r2));
8197 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8198 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8199 put_gpr_w0(r1, mkexpr(result));
8200
8201 return "slhhlr";
8202}
8203
florian55085f82012-11-21 00:36:55 +00008204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008205s390_irgen_SLBR(UChar r1, UChar r2)
8206{
8207 IRTemp op1 = newTemp(Ity_I32);
8208 IRTemp op2 = newTemp(Ity_I32);
8209 IRTemp result = newTemp(Ity_I32);
8210 IRTemp borrow_in = newTemp(Ity_I32);
8211
8212 assign(op1, get_gpr_w1(r1));
8213 assign(op2, get_gpr_w1(r2));
8214 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8215 s390_call_calculate_cc(), mkU8(1))));
8216 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8217 mkexpr(borrow_in)));
8218 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8219 put_gpr_w1(r1, mkexpr(result));
8220
8221 return "slbr";
8222}
8223
florian55085f82012-11-21 00:36:55 +00008224static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008225s390_irgen_SLBGR(UChar r1, UChar r2)
8226{
8227 IRTemp op1 = newTemp(Ity_I64);
8228 IRTemp op2 = newTemp(Ity_I64);
8229 IRTemp result = newTemp(Ity_I64);
8230 IRTemp borrow_in = newTemp(Ity_I64);
8231
8232 assign(op1, get_gpr_dw0(r1));
8233 assign(op2, get_gpr_dw0(r2));
8234 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8235 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8236 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8237 mkexpr(borrow_in)));
8238 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8239 put_gpr_dw0(r1, mkexpr(result));
8240
8241 return "slbgr";
8242}
8243
florian55085f82012-11-21 00:36:55 +00008244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008245s390_irgen_SLB(UChar r1, IRTemp op2addr)
8246{
8247 IRTemp op1 = newTemp(Ity_I32);
8248 IRTemp op2 = newTemp(Ity_I32);
8249 IRTemp result = newTemp(Ity_I32);
8250 IRTemp borrow_in = newTemp(Ity_I32);
8251
8252 assign(op1, get_gpr_w1(r1));
8253 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8254 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8255 s390_call_calculate_cc(), mkU8(1))));
8256 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8257 mkexpr(borrow_in)));
8258 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8259 put_gpr_w1(r1, mkexpr(result));
8260
8261 return "slb";
8262}
8263
florian55085f82012-11-21 00:36:55 +00008264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008265s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8266{
8267 IRTemp op1 = newTemp(Ity_I64);
8268 IRTemp op2 = newTemp(Ity_I64);
8269 IRTemp result = newTemp(Ity_I64);
8270 IRTemp borrow_in = newTemp(Ity_I64);
8271
8272 assign(op1, get_gpr_dw0(r1));
8273 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8274 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8275 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8276 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8277 mkexpr(borrow_in)));
8278 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8279 put_gpr_dw0(r1, mkexpr(result));
8280
8281 return "slbg";
8282}
8283
florian55085f82012-11-21 00:36:55 +00008284static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008285s390_irgen_SVC(UChar i)
8286{
8287 IRTemp sysno = newTemp(Ity_I64);
8288
8289 if (i != 0) {
8290 assign(sysno, mkU64(i));
8291 } else {
8292 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8293 }
8294 system_call(mkexpr(sysno));
8295
8296 return "svc";
8297}
8298
florian55085f82012-11-21 00:36:55 +00008299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008300s390_irgen_TM(UChar i2, IRTemp op1addr)
8301{
8302 UChar mask;
8303 IRTemp value = newTemp(Ity_I8);
8304
8305 mask = i2;
8306 assign(value, load(Ity_I8, mkexpr(op1addr)));
8307 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8308 mkU8(mask)));
8309
8310 return "tm";
8311}
8312
florian55085f82012-11-21 00:36:55 +00008313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008314s390_irgen_TMY(UChar i2, IRTemp op1addr)
8315{
8316 UChar mask;
8317 IRTemp value = newTemp(Ity_I8);
8318
8319 mask = i2;
8320 assign(value, load(Ity_I8, mkexpr(op1addr)));
8321 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8322 mkU8(mask)));
8323
8324 return "tmy";
8325}
8326
florian55085f82012-11-21 00:36:55 +00008327static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008328s390_irgen_TMHH(UChar r1, UShort i2)
8329{
8330 UShort mask;
8331 IRTemp value = newTemp(Ity_I16);
8332
8333 mask = i2;
8334 assign(value, get_gpr_hw0(r1));
8335 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8336 mkU16(mask)));
8337
8338 return "tmhh";
8339}
8340
florian55085f82012-11-21 00:36:55 +00008341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008342s390_irgen_TMHL(UChar r1, UShort i2)
8343{
8344 UShort mask;
8345 IRTemp value = newTemp(Ity_I16);
8346
8347 mask = i2;
8348 assign(value, get_gpr_hw1(r1));
8349 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8350 mkU16(mask)));
8351
8352 return "tmhl";
8353}
8354
florian55085f82012-11-21 00:36:55 +00008355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008356s390_irgen_TMLH(UChar r1, UShort i2)
8357{
8358 UShort mask;
8359 IRTemp value = newTemp(Ity_I16);
8360
8361 mask = i2;
8362 assign(value, get_gpr_hw2(r1));
8363 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8364 mkU16(mask)));
8365
8366 return "tmlh";
8367}
8368
florian55085f82012-11-21 00:36:55 +00008369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008370s390_irgen_TMLL(UChar r1, UShort i2)
8371{
8372 UShort mask;
8373 IRTemp value = newTemp(Ity_I16);
8374
8375 mask = i2;
8376 assign(value, get_gpr_hw3(r1));
8377 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8378 mkU16(mask)));
8379
8380 return "tmll";
8381}
8382
florian55085f82012-11-21 00:36:55 +00008383static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008384s390_irgen_EFPC(UChar r1)
8385{
8386 put_gpr_w1(r1, get_fpc_w0());
8387
8388 return "efpc";
8389}
8390
florian55085f82012-11-21 00:36:55 +00008391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008392s390_irgen_LER(UChar r1, UChar r2)
8393{
8394 put_fpr_w0(r1, get_fpr_w0(r2));
8395
8396 return "ler";
8397}
8398
florian55085f82012-11-21 00:36:55 +00008399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008400s390_irgen_LDR(UChar r1, UChar r2)
8401{
8402 put_fpr_dw0(r1, get_fpr_dw0(r2));
8403
8404 return "ldr";
8405}
8406
florian55085f82012-11-21 00:36:55 +00008407static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008408s390_irgen_LXR(UChar r1, UChar r2)
8409{
8410 put_fpr_dw0(r1, get_fpr_dw0(r2));
8411 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8412
8413 return "lxr";
8414}
8415
florian55085f82012-11-21 00:36:55 +00008416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008417s390_irgen_LE(UChar r1, IRTemp op2addr)
8418{
8419 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8420
8421 return "le";
8422}
8423
florian55085f82012-11-21 00:36:55 +00008424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008425s390_irgen_LD(UChar r1, IRTemp op2addr)
8426{
8427 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8428
8429 return "ld";
8430}
8431
florian55085f82012-11-21 00:36:55 +00008432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008433s390_irgen_LEY(UChar r1, IRTemp op2addr)
8434{
8435 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8436
8437 return "ley";
8438}
8439
florian55085f82012-11-21 00:36:55 +00008440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008441s390_irgen_LDY(UChar r1, IRTemp op2addr)
8442{
8443 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8444
8445 return "ldy";
8446}
8447
florian55085f82012-11-21 00:36:55 +00008448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008449s390_irgen_LFPC(IRTemp op2addr)
8450{
8451 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8452
8453 return "lfpc";
8454}
8455
florian55085f82012-11-21 00:36:55 +00008456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008457s390_irgen_LZER(UChar r1)
8458{
8459 put_fpr_w0(r1, mkF32i(0x0));
8460
8461 return "lzer";
8462}
8463
florian55085f82012-11-21 00:36:55 +00008464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008465s390_irgen_LZDR(UChar r1)
8466{
8467 put_fpr_dw0(r1, mkF64i(0x0));
8468
8469 return "lzdr";
8470}
8471
florian55085f82012-11-21 00:36:55 +00008472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008473s390_irgen_LZXR(UChar r1)
8474{
8475 put_fpr_dw0(r1, mkF64i(0x0));
8476 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8477
8478 return "lzxr";
8479}
8480
florian55085f82012-11-21 00:36:55 +00008481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008482s390_irgen_SRNM(IRTemp op2addr)
8483{
florianf0fa1be2012-09-18 20:24:38 +00008484 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008485
florianf0fa1be2012-09-18 20:24:38 +00008486 input_mask = 3;
8487 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008488
florianf0fa1be2012-09-18 20:24:38 +00008489 put_fpc_w0(binop(Iop_Or32,
8490 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8491 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8492 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008493 return "srnm";
8494}
8495
florian55085f82012-11-21 00:36:55 +00008496static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008497s390_irgen_SRNMB(IRTemp op2addr)
8498{
8499 UInt input_mask, fpc_mask;
8500
8501 input_mask = 7;
8502 fpc_mask = 7;
8503
8504 put_fpc_w0(binop(Iop_Or32,
8505 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8506 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8507 mkU32(input_mask))));
8508 return "srnmb";
8509}
8510
florian81a4bfe2012-09-20 01:25:28 +00008511static void
florianf0fa1be2012-09-18 20:24:38 +00008512s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8513{
8514 if (b2 == 0) { /* This is the typical case */
8515 if (d2 > 3) {
8516 if (s390_host_has_fpext && d2 == 7) {
8517 /* ok */
8518 } else {
8519 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008520 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008521 }
8522 }
8523 }
8524
8525 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8526}
8527
8528
florian55085f82012-11-21 00:36:55 +00008529static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008530s390_irgen_SFPC(UChar r1)
8531{
8532 put_fpc_w0(get_gpr_w1(r1));
8533
8534 return "sfpc";
8535}
8536
florian55085f82012-11-21 00:36:55 +00008537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008538s390_irgen_STE(UChar r1, IRTemp op2addr)
8539{
8540 store(mkexpr(op2addr), get_fpr_w0(r1));
8541
8542 return "ste";
8543}
8544
florian55085f82012-11-21 00:36:55 +00008545static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008546s390_irgen_STD(UChar r1, IRTemp op2addr)
8547{
8548 store(mkexpr(op2addr), get_fpr_dw0(r1));
8549
8550 return "std";
8551}
8552
florian55085f82012-11-21 00:36:55 +00008553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008554s390_irgen_STEY(UChar r1, IRTemp op2addr)
8555{
8556 store(mkexpr(op2addr), get_fpr_w0(r1));
8557
8558 return "stey";
8559}
8560
florian55085f82012-11-21 00:36:55 +00008561static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008562s390_irgen_STDY(UChar r1, IRTemp op2addr)
8563{
8564 store(mkexpr(op2addr), get_fpr_dw0(r1));
8565
8566 return "stdy";
8567}
8568
florian55085f82012-11-21 00:36:55 +00008569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008570s390_irgen_STFPC(IRTemp op2addr)
8571{
8572 store(mkexpr(op2addr), get_fpc_w0());
8573
8574 return "stfpc";
8575}
8576
florian55085f82012-11-21 00:36:55 +00008577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008578s390_irgen_AEBR(UChar r1, UChar r2)
8579{
8580 IRTemp op1 = newTemp(Ity_F32);
8581 IRTemp op2 = newTemp(Ity_F32);
8582 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008583 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008584
8585 assign(op1, get_fpr_w0(r1));
8586 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008587 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008588 mkexpr(op2)));
8589 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8590 put_fpr_w0(r1, mkexpr(result));
8591
8592 return "aebr";
8593}
8594
florian55085f82012-11-21 00:36:55 +00008595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008596s390_irgen_ADBR(UChar r1, UChar r2)
8597{
8598 IRTemp op1 = newTemp(Ity_F64);
8599 IRTemp op2 = newTemp(Ity_F64);
8600 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008601 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008602
8603 assign(op1, get_fpr_dw0(r1));
8604 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008605 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008606 mkexpr(op2)));
8607 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8608 put_fpr_dw0(r1, mkexpr(result));
8609
8610 return "adbr";
8611}
8612
florian55085f82012-11-21 00:36:55 +00008613static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008614s390_irgen_AEB(UChar r1, IRTemp op2addr)
8615{
8616 IRTemp op1 = newTemp(Ity_F32);
8617 IRTemp op2 = newTemp(Ity_F32);
8618 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008619 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008620
8621 assign(op1, get_fpr_w0(r1));
8622 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008623 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008624 mkexpr(op2)));
8625 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8626 put_fpr_w0(r1, mkexpr(result));
8627
8628 return "aeb";
8629}
8630
florian55085f82012-11-21 00:36:55 +00008631static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008632s390_irgen_ADB(UChar r1, IRTemp op2addr)
8633{
8634 IRTemp op1 = newTemp(Ity_F64);
8635 IRTemp op2 = newTemp(Ity_F64);
8636 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008637 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008638
8639 assign(op1, get_fpr_dw0(r1));
8640 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008641 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008642 mkexpr(op2)));
8643 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8644 put_fpr_dw0(r1, mkexpr(result));
8645
8646 return "adb";
8647}
8648
florian55085f82012-11-21 00:36:55 +00008649static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008650s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8651 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008652{
florian125e20d2012-10-07 15:42:37 +00008653 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008654 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008655 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008656 }
sewardj2019a972011-03-07 16:04:07 +00008657 IRTemp op2 = newTemp(Ity_I32);
8658
8659 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008660 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008661 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008662
8663 return "cefbr";
8664}
8665
florian55085f82012-11-21 00:36:55 +00008666static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008667s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8668 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008669{
8670 IRTemp op2 = newTemp(Ity_I32);
8671
8672 assign(op2, get_gpr_w1(r2));
8673 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8674
8675 return "cdfbr";
8676}
8677
florian55085f82012-11-21 00:36:55 +00008678static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008679s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8680 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008681{
florian125e20d2012-10-07 15:42:37 +00008682 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008683 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008684 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008685 }
sewardj2019a972011-03-07 16:04:07 +00008686 IRTemp op2 = newTemp(Ity_I64);
8687
8688 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008689 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008690 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008691
8692 return "cegbr";
8693}
8694
florian55085f82012-11-21 00:36:55 +00008695static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008696s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8697 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008698{
florian125e20d2012-10-07 15:42:37 +00008699 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008700 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008701 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008702 }
sewardj2019a972011-03-07 16:04:07 +00008703 IRTemp op2 = newTemp(Ity_I64);
8704
8705 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008706 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008707 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008708
8709 return "cdgbr";
8710}
8711
florian55085f82012-11-21 00:36:55 +00008712static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008713s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8714 UChar r1, UChar r2)
8715{
floriane75dafa2012-09-01 17:54:09 +00008716 if (! s390_host_has_fpext) {
8717 emulation_failure(EmFail_S390X_fpext);
8718 } else {
8719 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008720
floriane75dafa2012-09-01 17:54:09 +00008721 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008722 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008723 mkexpr(op2)));
8724 }
florian1c8f7ff2012-09-01 00:12:11 +00008725 return "celfbr";
8726}
8727
florian55085f82012-11-21 00:36:55 +00008728static const HChar *
floriand2129202012-09-01 20:01:39 +00008729s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8730 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008731{
floriane75dafa2012-09-01 17:54:09 +00008732 if (! s390_host_has_fpext) {
8733 emulation_failure(EmFail_S390X_fpext);
8734 } else {
8735 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008736
floriane75dafa2012-09-01 17:54:09 +00008737 assign(op2, get_gpr_w1(r2));
8738 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8739 }
florian1c8f7ff2012-09-01 00:12:11 +00008740 return "cdlfbr";
8741}
8742
florian55085f82012-11-21 00:36:55 +00008743static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008744s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8745 UChar r1, UChar r2)
8746{
floriane75dafa2012-09-01 17:54:09 +00008747 if (! s390_host_has_fpext) {
8748 emulation_failure(EmFail_S390X_fpext);
8749 } else {
8750 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008751
floriane75dafa2012-09-01 17:54:09 +00008752 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008753 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008754 mkexpr(op2)));
8755 }
florian1c8f7ff2012-09-01 00:12:11 +00008756 return "celgbr";
8757}
8758
florian55085f82012-11-21 00:36:55 +00008759static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008760s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8761 UChar r1, UChar r2)
8762{
floriane75dafa2012-09-01 17:54:09 +00008763 if (! s390_host_has_fpext) {
8764 emulation_failure(EmFail_S390X_fpext);
8765 } else {
8766 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008767
floriane75dafa2012-09-01 17:54:09 +00008768 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008769 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8770 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008771 mkexpr(op2)));
8772 }
florian1c8f7ff2012-09-01 00:12:11 +00008773 return "cdlgbr";
8774}
8775
florian55085f82012-11-21 00:36:55 +00008776static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008777s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8778 UChar r1, UChar r2)
8779{
floriane75dafa2012-09-01 17:54:09 +00008780 if (! s390_host_has_fpext) {
8781 emulation_failure(EmFail_S390X_fpext);
8782 } else {
8783 IRTemp op = newTemp(Ity_F32);
8784 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008785 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008786
floriane75dafa2012-09-01 17:54:09 +00008787 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008788 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008789 mkexpr(op)));
8790 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008791 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008792 }
florian1c8f7ff2012-09-01 00:12:11 +00008793 return "clfebr";
8794}
8795
florian55085f82012-11-21 00:36:55 +00008796static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008797s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8798 UChar r1, UChar r2)
8799{
floriane75dafa2012-09-01 17:54:09 +00008800 if (! s390_host_has_fpext) {
8801 emulation_failure(EmFail_S390X_fpext);
8802 } else {
8803 IRTemp op = newTemp(Ity_F64);
8804 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008805 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008806
floriane75dafa2012-09-01 17:54:09 +00008807 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008808 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008809 mkexpr(op)));
8810 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008811 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008812 }
florian1c8f7ff2012-09-01 00:12:11 +00008813 return "clfdbr";
8814}
8815
florian55085f82012-11-21 00:36:55 +00008816static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008817s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8818 UChar r1, UChar r2)
8819{
floriane75dafa2012-09-01 17:54:09 +00008820 if (! s390_host_has_fpext) {
8821 emulation_failure(EmFail_S390X_fpext);
8822 } else {
8823 IRTemp op = newTemp(Ity_F32);
8824 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008825 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008826
floriane75dafa2012-09-01 17:54:09 +00008827 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008828 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008829 mkexpr(op)));
8830 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008831 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008832 }
florian1c8f7ff2012-09-01 00:12:11 +00008833 return "clgebr";
8834}
8835
florian55085f82012-11-21 00:36:55 +00008836static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008837s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8838 UChar r1, UChar r2)
8839{
floriane75dafa2012-09-01 17:54:09 +00008840 if (! s390_host_has_fpext) {
8841 emulation_failure(EmFail_S390X_fpext);
8842 } else {
8843 IRTemp op = newTemp(Ity_F64);
8844 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008845 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008846
floriane75dafa2012-09-01 17:54:09 +00008847 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008848 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008849 mkexpr(op)));
8850 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008851 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008852 }
florian1c8f7ff2012-09-01 00:12:11 +00008853 return "clgdbr";
8854}
8855
florian55085f82012-11-21 00:36:55 +00008856static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008857s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8858 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008859{
8860 IRTemp op = newTemp(Ity_F32);
8861 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008862 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008863
8864 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008865 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008866 mkexpr(op)));
8867 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008868 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008869
8870 return "cfebr";
8871}
8872
florian55085f82012-11-21 00:36:55 +00008873static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008874s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8875 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008876{
8877 IRTemp op = newTemp(Ity_F64);
8878 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008879 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008880
8881 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008882 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008883 mkexpr(op)));
8884 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008885 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008886
8887 return "cfdbr";
8888}
8889
florian55085f82012-11-21 00:36:55 +00008890static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008891s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8892 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008893{
8894 IRTemp op = newTemp(Ity_F32);
8895 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008896 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008897
8898 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008899 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008900 mkexpr(op)));
8901 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008902 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008903
8904 return "cgebr";
8905}
8906
florian55085f82012-11-21 00:36:55 +00008907static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008908s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8909 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008910{
8911 IRTemp op = newTemp(Ity_F64);
8912 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008913 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008914
8915 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008916 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008917 mkexpr(op)));
8918 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008919 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008920
8921 return "cgdbr";
8922}
8923
florian55085f82012-11-21 00:36:55 +00008924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008925s390_irgen_DEBR(UChar r1, UChar r2)
8926{
8927 IRTemp op1 = newTemp(Ity_F32);
8928 IRTemp op2 = newTemp(Ity_F32);
8929 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008930 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008931
8932 assign(op1, get_fpr_w0(r1));
8933 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008934 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008935 mkexpr(op2)));
8936 put_fpr_w0(r1, mkexpr(result));
8937
8938 return "debr";
8939}
8940
florian55085f82012-11-21 00:36:55 +00008941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008942s390_irgen_DDBR(UChar r1, UChar r2)
8943{
8944 IRTemp op1 = newTemp(Ity_F64);
8945 IRTemp op2 = newTemp(Ity_F64);
8946 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008947 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008948
8949 assign(op1, get_fpr_dw0(r1));
8950 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008951 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008952 mkexpr(op2)));
8953 put_fpr_dw0(r1, mkexpr(result));
8954
8955 return "ddbr";
8956}
8957
florian55085f82012-11-21 00:36:55 +00008958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008959s390_irgen_DEB(UChar r1, IRTemp op2addr)
8960{
8961 IRTemp op1 = newTemp(Ity_F32);
8962 IRTemp op2 = newTemp(Ity_F32);
8963 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008964 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008965
8966 assign(op1, get_fpr_w0(r1));
8967 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008968 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008969 mkexpr(op2)));
8970 put_fpr_w0(r1, mkexpr(result));
8971
8972 return "deb";
8973}
8974
florian55085f82012-11-21 00:36:55 +00008975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008976s390_irgen_DDB(UChar r1, IRTemp op2addr)
8977{
8978 IRTemp op1 = newTemp(Ity_F64);
8979 IRTemp op2 = newTemp(Ity_F64);
8980 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008981 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008982
8983 assign(op1, get_fpr_dw0(r1));
8984 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008985 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008986 mkexpr(op2)));
8987 put_fpr_dw0(r1, mkexpr(result));
8988
8989 return "ddb";
8990}
8991
florian55085f82012-11-21 00:36:55 +00008992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008993s390_irgen_LTEBR(UChar r1, UChar r2)
8994{
8995 IRTemp result = newTemp(Ity_F32);
8996
8997 assign(result, get_fpr_w0(r2));
8998 put_fpr_w0(r1, mkexpr(result));
8999 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9000
9001 return "ltebr";
9002}
9003
florian55085f82012-11-21 00:36:55 +00009004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009005s390_irgen_LTDBR(UChar r1, UChar r2)
9006{
9007 IRTemp result = newTemp(Ity_F64);
9008
9009 assign(result, get_fpr_dw0(r2));
9010 put_fpr_dw0(r1, mkexpr(result));
9011 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9012
9013 return "ltdbr";
9014}
9015
florian55085f82012-11-21 00:36:55 +00009016static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009017s390_irgen_LCEBR(UChar r1, UChar r2)
9018{
9019 IRTemp result = newTemp(Ity_F32);
9020
9021 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9022 put_fpr_w0(r1, mkexpr(result));
9023 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9024
9025 return "lcebr";
9026}
9027
florian55085f82012-11-21 00:36:55 +00009028static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009029s390_irgen_LCDBR(UChar r1, UChar r2)
9030{
9031 IRTemp result = newTemp(Ity_F64);
9032
9033 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9034 put_fpr_dw0(r1, mkexpr(result));
9035 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9036
9037 return "lcdbr";
9038}
9039
florian55085f82012-11-21 00:36:55 +00009040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009041s390_irgen_LDEBR(UChar r1, UChar r2)
9042{
9043 IRTemp op = newTemp(Ity_F32);
9044
9045 assign(op, get_fpr_w0(r2));
9046 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9047
9048 return "ldebr";
9049}
9050
florian55085f82012-11-21 00:36:55 +00009051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009052s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9053{
9054 IRTemp op = newTemp(Ity_F32);
9055
9056 assign(op, load(Ity_F32, mkexpr(op2addr)));
9057 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9058
9059 return "ldeb";
9060}
9061
florian55085f82012-11-21 00:36:55 +00009062static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009063s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9064 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009065{
florian125e20d2012-10-07 15:42:37 +00009066 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009067 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009068 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009069 }
sewardj2019a972011-03-07 16:04:07 +00009070 IRTemp op = newTemp(Ity_F64);
9071
9072 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009073 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009074 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009075
9076 return "ledbr";
9077}
9078
florian55085f82012-11-21 00:36:55 +00009079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009080s390_irgen_MEEBR(UChar r1, UChar r2)
9081{
9082 IRTemp op1 = newTemp(Ity_F32);
9083 IRTemp op2 = newTemp(Ity_F32);
9084 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009085 IRRoundingMode rounding_mode =
9086 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009087
9088 assign(op1, get_fpr_w0(r1));
9089 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009090 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009091 mkexpr(op2)));
9092 put_fpr_w0(r1, mkexpr(result));
9093
9094 return "meebr";
9095}
9096
florian55085f82012-11-21 00:36:55 +00009097static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009098s390_irgen_MDBR(UChar r1, UChar r2)
9099{
9100 IRTemp op1 = newTemp(Ity_F64);
9101 IRTemp op2 = newTemp(Ity_F64);
9102 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009103 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009104
9105 assign(op1, get_fpr_dw0(r1));
9106 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009107 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009108 mkexpr(op2)));
9109 put_fpr_dw0(r1, mkexpr(result));
9110
9111 return "mdbr";
9112}
9113
florian55085f82012-11-21 00:36:55 +00009114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009115s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9116{
9117 IRTemp op1 = newTemp(Ity_F32);
9118 IRTemp op2 = newTemp(Ity_F32);
9119 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009120 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009121
9122 assign(op1, get_fpr_w0(r1));
9123 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009124 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009125 mkexpr(op2)));
9126 put_fpr_w0(r1, mkexpr(result));
9127
9128 return "meeb";
9129}
9130
florian55085f82012-11-21 00:36:55 +00009131static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009132s390_irgen_MDB(UChar r1, IRTemp op2addr)
9133{
9134 IRTemp op1 = newTemp(Ity_F64);
9135 IRTemp op2 = newTemp(Ity_F64);
9136 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009137 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009138
9139 assign(op1, get_fpr_dw0(r1));
9140 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009141 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009142 mkexpr(op2)));
9143 put_fpr_dw0(r1, mkexpr(result));
9144
9145 return "mdb";
9146}
9147
florian55085f82012-11-21 00:36:55 +00009148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009149s390_irgen_SEBR(UChar r1, UChar r2)
9150{
9151 IRTemp op1 = newTemp(Ity_F32);
9152 IRTemp op2 = newTemp(Ity_F32);
9153 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009154 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009155
9156 assign(op1, get_fpr_w0(r1));
9157 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009158 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009159 mkexpr(op2)));
9160 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9161 put_fpr_w0(r1, mkexpr(result));
9162
9163 return "sebr";
9164}
9165
florian55085f82012-11-21 00:36:55 +00009166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009167s390_irgen_SDBR(UChar r1, UChar r2)
9168{
9169 IRTemp op1 = newTemp(Ity_F64);
9170 IRTemp op2 = newTemp(Ity_F64);
9171 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009172 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009173
9174 assign(op1, get_fpr_dw0(r1));
9175 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009176 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009177 mkexpr(op2)));
9178 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9179 put_fpr_dw0(r1, mkexpr(result));
9180
9181 return "sdbr";
9182}
9183
florian55085f82012-11-21 00:36:55 +00009184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009185s390_irgen_SEB(UChar r1, IRTemp op2addr)
9186{
9187 IRTemp op1 = newTemp(Ity_F32);
9188 IRTemp op2 = newTemp(Ity_F32);
9189 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009190 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009191
9192 assign(op1, get_fpr_w0(r1));
9193 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009194 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009195 mkexpr(op2)));
9196 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9197 put_fpr_w0(r1, mkexpr(result));
9198
9199 return "seb";
9200}
9201
florian55085f82012-11-21 00:36:55 +00009202static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009203s390_irgen_SDB(UChar r1, IRTemp op2addr)
9204{
9205 IRTemp op1 = newTemp(Ity_F64);
9206 IRTemp op2 = newTemp(Ity_F64);
9207 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009208 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009209
9210 assign(op1, get_fpr_dw0(r1));
9211 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009212 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009213 mkexpr(op2)));
9214 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9215 put_fpr_dw0(r1, mkexpr(result));
9216
9217 return "sdb";
9218}
9219
florian55085f82012-11-21 00:36:55 +00009220static const HChar *
florian12390202012-11-10 22:34:14 +00009221s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9222{
9223 IRTemp op1 = newTemp(Ity_D64);
9224 IRTemp op2 = newTemp(Ity_D64);
9225 IRTemp result = newTemp(Ity_D64);
9226 IRTemp rounding_mode;
9227
9228 vassert(s390_host_has_dfp);
9229 vassert(m4 == 0 || s390_host_has_fpext);
9230 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9231 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9232 rounding_mode = encode_dfp_rounding_mode(m4);
9233 assign(op1, get_dpr_dw0(r2));
9234 assign(op2, get_dpr_dw0(r3));
9235 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9236 mkexpr(op2)));
9237 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9238 put_dpr_dw0(r1, mkexpr(result));
9239
9240 return (m4 == 0) ? "adtr" : "adtra";
9241}
9242
florian55085f82012-11-21 00:36:55 +00009243static const HChar *
floriane38f6412012-12-21 17:32:12 +00009244s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9245{
9246 IRTemp op1 = newTemp(Ity_D128);
9247 IRTemp op2 = newTemp(Ity_D128);
9248 IRTemp result = newTemp(Ity_D128);
9249 IRTemp rounding_mode;
9250
9251 vassert(s390_host_has_dfp);
9252 vassert(m4 == 0 || s390_host_has_fpext);
9253 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9254 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9255 rounding_mode = encode_dfp_rounding_mode(m4);
9256 assign(op1, get_dpr_pair(r2));
9257 assign(op2, get_dpr_pair(r3));
9258 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9259 mkexpr(op2)));
9260 put_dpr_pair(r1, mkexpr(result));
9261
9262 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9263
9264 return (m4 == 0) ? "axtr" : "axtra";
9265}
9266
9267static const HChar *
9268s390_irgen_CDTR(UChar r1, UChar r2)
9269{
9270 IRTemp op1 = newTemp(Ity_D64);
9271 IRTemp op2 = newTemp(Ity_D64);
9272 IRTemp cc_vex = newTemp(Ity_I32);
9273 IRTemp cc_s390 = newTemp(Ity_I32);
9274
9275 assign(op1, get_dpr_dw0(r1));
9276 assign(op2, get_dpr_dw0(r2));
9277 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9278
florian2d3d87f2012-12-21 21:05:17 +00009279 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009280 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9281
9282 return "cdtr";
9283}
9284
9285static const HChar *
9286s390_irgen_CXTR(UChar r1, UChar r2)
9287{
9288 IRTemp op1 = newTemp(Ity_D128);
9289 IRTemp op2 = newTemp(Ity_D128);
9290 IRTemp cc_vex = newTemp(Ity_I32);
9291 IRTemp cc_s390 = newTemp(Ity_I32);
9292
9293 assign(op1, get_dpr_pair(r1));
9294 assign(op2, get_dpr_pair(r2));
9295 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9296
florian2d3d87f2012-12-21 21:05:17 +00009297 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009298 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9299
9300 return "cxtr";
9301}
9302
9303static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009304s390_irgen_CEDTR(UChar r1, UChar r2)
9305{
9306 IRTemp op1 = newTemp(Ity_D64);
9307 IRTemp op2 = newTemp(Ity_D64);
9308 IRTemp cc_vex = newTemp(Ity_I32);
9309 IRTemp cc_s390 = newTemp(Ity_I32);
9310
9311 vassert(s390_host_has_dfp);
9312 assign(op1, get_dpr_dw0(r1));
9313 assign(op2, get_dpr_dw0(r2));
9314 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9315
9316 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9317 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9318
9319 return "cedtr";
9320}
9321
9322static const HChar *
9323s390_irgen_CEXTR(UChar r1, UChar r2)
9324{
9325 IRTemp op1 = newTemp(Ity_D128);
9326 IRTemp op2 = newTemp(Ity_D128);
9327 IRTemp cc_vex = newTemp(Ity_I32);
9328 IRTemp cc_s390 = newTemp(Ity_I32);
9329
9330 vassert(s390_host_has_dfp);
9331 assign(op1, get_dpr_pair(r1));
9332 assign(op2, get_dpr_pair(r2));
9333 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9334
9335 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9336 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9337
9338 return "cextr";
9339}
9340
9341static const HChar *
florian12390202012-11-10 22:34:14 +00009342s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9343{
9344 IRTemp op1 = newTemp(Ity_D64);
9345 IRTemp op2 = newTemp(Ity_D64);
9346 IRTemp result = newTemp(Ity_D64);
9347 IRTemp rounding_mode;
9348
9349 vassert(s390_host_has_dfp);
9350 vassert(m4 == 0 || s390_host_has_fpext);
9351 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9352 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9353 rounding_mode = encode_dfp_rounding_mode(m4);
9354 assign(op1, get_dpr_dw0(r2));
9355 assign(op2, get_dpr_dw0(r3));
9356 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9357 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009358 put_dpr_dw0(r1, mkexpr(result));
9359
9360 return (m4 == 0) ? "ddtr" : "ddtra";
9361}
9362
florian55085f82012-11-21 00:36:55 +00009363static const HChar *
floriane38f6412012-12-21 17:32:12 +00009364s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9365{
9366 IRTemp op1 = newTemp(Ity_D128);
9367 IRTemp op2 = newTemp(Ity_D128);
9368 IRTemp result = newTemp(Ity_D128);
9369 IRTemp rounding_mode;
9370
9371 vassert(s390_host_has_dfp);
9372 vassert(m4 == 0 || s390_host_has_fpext);
9373 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9374 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9375 rounding_mode = encode_dfp_rounding_mode(m4);
9376 assign(op1, get_dpr_pair(r2));
9377 assign(op2, get_dpr_pair(r3));
9378 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9379 mkexpr(op2)));
9380 put_dpr_pair(r1, mkexpr(result));
9381
9382 return (m4 == 0) ? "dxtr" : "dxtra";
9383}
9384
9385static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009386s390_irgen_ESDTR(UChar r1, UChar r2)
9387{
9388 vassert(s390_host_has_dfp);
9389 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
9390 return "esdtr";
9391}
9392
9393static const HChar *
9394s390_irgen_ESXTR(UChar r1, UChar r2)
9395{
9396 vassert(s390_host_has_dfp);
9397 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
9398 return "esxtr";
9399}
9400
9401static const HChar *
floriane38f6412012-12-21 17:32:12 +00009402s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9403{
9404 IRTemp op = newTemp(Ity_D32);
9405
9406 vassert(s390_host_has_dfp);
9407
9408 assign(op, get_dpr_w0(r2));
9409 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
9410
9411 return "ldetr";
9412}
9413
9414static const HChar *
9415s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9416{
9417 IRTemp op = newTemp(Ity_D64);
9418
9419 assign(op, get_dpr_dw0(r2));
9420 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
9421
9422 return "lxdtr";
9423}
9424
9425static const HChar *
9426s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
9427 UChar r1, UChar r2)
9428{
9429 vassert(s390_host_has_dfp);
9430 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9431 emulation_warning(EmWarn_S390X_fpext_rounding);
9432 m3 = S390_DFP_ROUND_PER_FPC_0;
9433 }
9434 IRTemp result = newTemp(Ity_D64);
9435
9436 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
9437 get_dpr_pair(r2)));
9438 put_dpr_dw0(r1, mkexpr(result));
9439
9440 return "ldxtr";
9441}
9442
9443static const HChar *
9444s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
9445 UChar r1, UChar r2)
9446{
9447 vassert(s390_host_has_dfp);
9448 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9449 emulation_warning(EmWarn_S390X_fpext_rounding);
9450 m3 = S390_DFP_ROUND_PER_FPC_0;
9451 }
9452 IRTemp op = newTemp(Ity_D64);
9453
9454 assign(op, get_dpr_dw0(r2));
9455 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
9456 mkexpr(op)));
9457
9458 return "ledtr";
9459}
9460
9461static const HChar *
9462s390_irgen_LTDTR(UChar r1, UChar r2)
9463{
9464 IRTemp result = newTemp(Ity_D64);
9465
9466 assign(result, get_dpr_dw0(r2));
9467 put_dpr_dw0(r1, mkexpr(result));
9468 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9469
9470 return "ltdtr";
9471}
9472
9473static const HChar *
9474s390_irgen_LTXTR(UChar r1, UChar r2)
9475{
9476 IRTemp result = newTemp(Ity_D128);
9477
9478 assign(result, get_dpr_pair(r2));
9479 put_dpr_pair(r1, mkexpr(result));
9480 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9481
9482 return "ltxtr";
9483}
9484
9485static const HChar *
florian12390202012-11-10 22:34:14 +00009486s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9487{
9488 IRTemp op1 = newTemp(Ity_D64);
9489 IRTemp op2 = newTemp(Ity_D64);
9490 IRTemp result = newTemp(Ity_D64);
9491 IRTemp rounding_mode;
9492
9493 vassert(s390_host_has_dfp);
9494 vassert(m4 == 0 || s390_host_has_fpext);
9495 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9496 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9497 rounding_mode = encode_dfp_rounding_mode(m4);
9498 assign(op1, get_dpr_dw0(r2));
9499 assign(op2, get_dpr_dw0(r3));
9500 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9501 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009502 put_dpr_dw0(r1, mkexpr(result));
9503
9504 return (m4 == 0) ? "mdtr" : "mdtra";
9505}
9506
florian55085f82012-11-21 00:36:55 +00009507static const HChar *
floriane38f6412012-12-21 17:32:12 +00009508s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9509{
9510 IRTemp op1 = newTemp(Ity_D128);
9511 IRTemp op2 = newTemp(Ity_D128);
9512 IRTemp result = newTemp(Ity_D128);
9513 IRTemp rounding_mode;
9514
9515 vassert(s390_host_has_dfp);
9516 vassert(m4 == 0 || s390_host_has_fpext);
9517 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9518 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9519 rounding_mode = encode_dfp_rounding_mode(m4);
9520 assign(op1, get_dpr_pair(r2));
9521 assign(op2, get_dpr_pair(r3));
9522 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
9523 mkexpr(op2)));
9524 put_dpr_pair(r1, mkexpr(result));
9525
9526 return (m4 == 0) ? "mxtr" : "mxtra";
9527}
9528
9529static const HChar *
florian12390202012-11-10 22:34:14 +00009530s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9531{
9532 IRTemp op1 = newTemp(Ity_D64);
9533 IRTemp op2 = newTemp(Ity_D64);
9534 IRTemp result = newTemp(Ity_D64);
9535 IRTemp rounding_mode;
9536
9537 vassert(s390_host_has_dfp);
9538 vassert(m4 == 0 || s390_host_has_fpext);
9539 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9540 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9541 rounding_mode = encode_dfp_rounding_mode(m4);
9542 assign(op1, get_dpr_dw0(r2));
9543 assign(op2, get_dpr_dw0(r3));
9544 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9545 mkexpr(op2)));
9546 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9547 put_dpr_dw0(r1, mkexpr(result));
9548
9549 return (m4 == 0) ? "sdtr" : "sdtra";
9550}
9551
floriane38f6412012-12-21 17:32:12 +00009552static const HChar *
9553s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9554{
9555 IRTemp op1 = newTemp(Ity_D128);
9556 IRTemp op2 = newTemp(Ity_D128);
9557 IRTemp result = newTemp(Ity_D128);
9558 IRTemp rounding_mode;
9559
9560 vassert(s390_host_has_dfp);
9561 vassert(m4 == 0 || s390_host_has_fpext);
9562 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9563 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9564 rounding_mode = encode_dfp_rounding_mode(m4);
9565 assign(op1, get_dpr_pair(r2));
9566 assign(op2, get_dpr_pair(r3));
9567 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
9568 mkexpr(op2)));
9569 put_dpr_pair(r1, mkexpr(result));
9570
9571 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9572
9573 return (m4 == 0) ? "sxtr" : "sxtra";
9574}
sewardj2019a972011-03-07 16:04:07 +00009575
florian55085f82012-11-21 00:36:55 +00009576static const HChar *
florian1b901d42013-01-01 22:19:24 +00009577s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
9578{
9579 IRTemp op = newTemp(Ity_D64);
9580
9581 vassert(s390_host_has_dfp);
9582
9583 assign(op, get_dpr_dw0(r3));
9584 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
9585 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9586
9587 return "sldt";
9588}
9589
9590static const HChar *
9591s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
9592{
9593 IRTemp op = newTemp(Ity_D128);
9594
9595 vassert(s390_host_has_dfp);
9596
9597 assign(op, get_dpr_pair(r3));
9598 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
9599 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9600
9601 return "slxt";
9602}
9603
9604static const HChar *
9605s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
9606{
9607 IRTemp op = newTemp(Ity_D64);
9608
9609 vassert(s390_host_has_dfp);
9610
9611 assign(op, get_dpr_dw0(r3));
9612 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
9613 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9614
9615 return "srdt";
9616}
9617
9618static const HChar *
9619s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
9620{
9621 IRTemp op = newTemp(Ity_D128);
9622
9623 vassert(s390_host_has_dfp);
9624
9625 assign(op, get_dpr_pair(r3));
9626 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
9627 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9628
9629 return "srxt";
9630}
9631
9632static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009633s390_irgen_TDCET(UChar r1, IRTemp op2addr)
9634{
9635 IRTemp value = newTemp(Ity_D32);
9636
9637 vassert(s390_host_has_dfp);
9638 assign(value, get_dpr_w0(r1));
9639
9640 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
9641
9642 return "tdcet";
9643}
9644
9645static const HChar *
9646s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
9647{
9648 IRTemp value = newTemp(Ity_D64);
9649
9650 vassert(s390_host_has_dfp);
9651 assign(value, get_dpr_dw0(r1));
9652
9653 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
9654
9655 return "tdcdt";
9656}
9657
9658static const HChar *
9659s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
9660{
9661 IRTemp value = newTemp(Ity_D128);
9662
9663 vassert(s390_host_has_dfp);
9664 assign(value, get_dpr_pair(r1));
9665
9666 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
9667
9668 return "tdcxt";
9669}
9670
9671static const HChar *
9672s390_irgen_TDGET(UChar r1, IRTemp op2addr)
9673{
9674 IRTemp value = newTemp(Ity_D32);
9675
9676 vassert(s390_host_has_dfp);
9677 assign(value, get_dpr_w0(r1));
9678
9679 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
9680
9681 return "tdget";
9682}
9683
9684static const HChar *
9685s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
9686{
9687 IRTemp value = newTemp(Ity_D64);
9688
9689 vassert(s390_host_has_dfp);
9690 assign(value, get_dpr_dw0(r1));
9691
9692 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
9693
9694 return "tdgdt";
9695}
9696
9697static const HChar *
9698s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
9699{
9700 IRTemp value = newTemp(Ity_D128);
9701
9702 vassert(s390_host_has_dfp);
9703 assign(value, get_dpr_pair(r1));
9704
9705 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
9706
9707 return "tdgxt";
9708}
9709
9710static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009711s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9712{
florian79e839e2012-05-05 02:20:30 +00009713 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009714
florian79e839e2012-05-05 02:20:30 +00009715 assign(len, mkU64(length));
9716 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009717
9718 return "clc";
9719}
9720
florian55085f82012-11-21 00:36:55 +00009721static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009722s390_irgen_CLCL(UChar r1, UChar r2)
9723{
9724 IRTemp addr1 = newTemp(Ity_I64);
9725 IRTemp addr2 = newTemp(Ity_I64);
9726 IRTemp addr1_load = newTemp(Ity_I64);
9727 IRTemp addr2_load = newTemp(Ity_I64);
9728 IRTemp len1 = newTemp(Ity_I32);
9729 IRTemp len2 = newTemp(Ity_I32);
9730 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9731 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9732 IRTemp single1 = newTemp(Ity_I8);
9733 IRTemp single2 = newTemp(Ity_I8);
9734 IRTemp pad = newTemp(Ity_I8);
9735
9736 assign(addr1, get_gpr_dw0(r1));
9737 assign(r1p1, get_gpr_w1(r1 + 1));
9738 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9739 assign(addr2, get_gpr_dw0(r2));
9740 assign(r2p1, get_gpr_w1(r2 + 1));
9741 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9742 assign(pad, get_gpr_b4(r2 + 1));
9743
9744 /* len1 == 0 and len2 == 0? Exit */
9745 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009746 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9747 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009748
9749 /* Because mkite evaluates both the then-clause and the else-clause
9750 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9751 may be NULL and loading from there would segfault. So we provide a
9752 valid dummy address in that case. Loading from there does no harm and
9753 the value will be discarded at runtime. */
9754 assign(addr1_load,
9755 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9756 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9757 assign(single1,
9758 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9759 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9760
9761 assign(addr2_load,
9762 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9763 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
9764 assign(single2,
9765 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9766 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
9767
9768 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
9769 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009770 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +00009771
9772 /* Update len1 and addr1, unless len1 == 0. */
9773 put_gpr_dw0(r1,
9774 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9775 mkexpr(addr1),
9776 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
9777
9778 /* When updating len1 we must not modify bits (r1+1)[0:39] */
9779 put_gpr_w1(r1 + 1,
9780 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9781 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
9782 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
9783
9784 /* Update len2 and addr2, unless len2 == 0. */
9785 put_gpr_dw0(r2,
9786 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9787 mkexpr(addr2),
9788 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
9789
9790 /* When updating len2 we must not modify bits (r2+1)[0:39] */
9791 put_gpr_w1(r2 + 1,
9792 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
9793 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
9794 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
9795
florian6820ba52012-07-26 02:01:50 +00009796 iterate();
florianb0c9a132011-09-08 15:37:39 +00009797
9798 return "clcl";
9799}
9800
florian55085f82012-11-21 00:36:55 +00009801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009802s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
9803{
9804 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
9805
9806 addr1 = newTemp(Ity_I64);
9807 addr3 = newTemp(Ity_I64);
9808 addr1_load = newTemp(Ity_I64);
9809 addr3_load = newTemp(Ity_I64);
9810 len1 = newTemp(Ity_I64);
9811 len3 = newTemp(Ity_I64);
9812 single1 = newTemp(Ity_I8);
9813 single3 = newTemp(Ity_I8);
9814
9815 assign(addr1, get_gpr_dw0(r1));
9816 assign(len1, get_gpr_dw0(r1 + 1));
9817 assign(addr3, get_gpr_dw0(r3));
9818 assign(len3, get_gpr_dw0(r3 + 1));
9819
9820 /* len1 == 0 and len3 == 0? Exit */
9821 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009822 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
9823 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +00009824
9825 /* A mux requires both ways to be possible. This is a way to prevent clcle
9826 from reading from addr1 if it should read from the pad. Since the pad
9827 has no address, just read from the instruction, we discard that anyway */
9828 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +00009829 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9830 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +00009831
9832 /* same for addr3 */
9833 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +00009834 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9835 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +00009836
9837 assign(single1,
florian6ad49522011-09-09 02:38:55 +00009838 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9839 unop(Iop_64to8, mkexpr(pad2)),
9840 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +00009841
9842 assign(single3,
florian6ad49522011-09-09 02:38:55 +00009843 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9844 unop(Iop_64to8, mkexpr(pad2)),
9845 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +00009846
9847 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
9848 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009849 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +00009850
9851 /* If a length in 0 we must not change this length and the address */
9852 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +00009853 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9854 mkexpr(addr1),
9855 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009856
9857 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +00009858 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
9859 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009860
9861 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +00009862 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9863 mkexpr(addr3),
9864 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009865
9866 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +00009867 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
9868 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +00009869
florian6820ba52012-07-26 02:01:50 +00009870 iterate();
sewardj2019a972011-03-07 16:04:07 +00009871
9872 return "clcle";
9873}
floriana64c2432011-07-16 02:11:50 +00009874
florianb0bf6602012-05-05 00:01:16 +00009875
sewardj2019a972011-03-07 16:04:07 +00009876static void
9877s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9878{
florianb0bf6602012-05-05 00:01:16 +00009879 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
9880}
sewardj2019a972011-03-07 16:04:07 +00009881
sewardj2019a972011-03-07 16:04:07 +00009882
florianb0bf6602012-05-05 00:01:16 +00009883static void
9884s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9885{
9886 s390_irgen_xonc(Iop_And8, length, start1, start2);
9887}
sewardj2019a972011-03-07 16:04:07 +00009888
sewardj2019a972011-03-07 16:04:07 +00009889
florianb0bf6602012-05-05 00:01:16 +00009890static void
9891s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9892{
9893 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009894}
9895
9896
9897static void
9898s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9899{
9900 IRTemp current1 = newTemp(Ity_I8);
9901 IRTemp current2 = newTemp(Ity_I8);
9902 IRTemp counter = newTemp(Ity_I64);
9903
9904 assign(counter, get_counter_dw0());
9905 put_counter_dw0(mkU64(0));
9906
9907 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
9908 mkexpr(counter))));
9909 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
9910 mkexpr(counter))));
9911 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
9912 False);
9913
9914 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +00009915 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +00009916
9917 /* Check for end of field */
9918 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009919 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009920 put_counter_dw0(mkU64(0));
9921}
9922
9923static void
9924s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
9925{
9926 IRTemp counter = newTemp(Ity_I64);
9927
9928 assign(counter, get_counter_dw0());
9929
9930 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
9931 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
9932
9933 /* Check for end of field */
9934 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009935 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +00009936 put_counter_dw0(mkU64(0));
9937}
9938
florianf87d4fb2012-05-05 02:55:24 +00009939static void
9940s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
9941{
9942 IRTemp op = newTemp(Ity_I8);
9943 IRTemp op1 = newTemp(Ity_I8);
9944 IRTemp result = newTemp(Ity_I64);
9945 IRTemp counter = newTemp(Ity_I64);
9946
9947 assign(counter, get_counter_dw0());
9948
9949 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
9950
9951 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
9952
9953 assign(op1, load(Ity_I8, mkexpr(result)));
9954 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
9955
9956 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +00009957 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +00009958 put_counter_dw0(mkU64(0));
9959}
sewardj2019a972011-03-07 16:04:07 +00009960
9961
9962static void
9963s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +00009964 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +00009965 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +00009966{
9967 struct SS {
9968 unsigned int op : 8;
9969 unsigned int l : 8;
9970 unsigned int b1 : 4;
9971 unsigned int d1 : 12;
9972 unsigned int b2 : 4;
9973 unsigned int d2 : 12;
9974 };
9975 union {
9976 struct SS dec;
9977 unsigned long bytes;
9978 } ss;
9979 IRTemp cond;
9980 IRDirty *d;
9981 IRTemp torun;
9982
9983 IRTemp start1 = newTemp(Ity_I64);
9984 IRTemp start2 = newTemp(Ity_I64);
9985 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
9986 cond = newTemp(Ity_I1);
9987 torun = newTemp(Ity_I64);
9988
9989 assign(torun, load(Ity_I64, mkexpr(addr2)));
9990 /* Start with a check that the saved code is still correct */
9991 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
9992 /* If not, save the new value */
9993 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
9994 mkIRExprVec_1(mkexpr(torun)));
9995 d->guard = mkexpr(cond);
9996 stmt(IRStmt_Dirty(d));
9997
9998 /* and restart */
florian428dfdd2012-03-27 03:09:49 +00009999 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10000 mkU64(guest_IA_curr_instr)));
10001 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010002 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010003
10004 ss.bytes = last_execute_target;
10005 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10006 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10007 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10008 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10009 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10010 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10011 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010012
sewardj2019a972011-03-07 16:04:07 +000010013 last_execute_target = 0;
10014}
10015
florian55085f82012-11-21 00:36:55 +000010016static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010017s390_irgen_EX(UChar r1, IRTemp addr2)
10018{
10019 switch(last_execute_target & 0xff00000000000000ULL) {
10020 case 0:
10021 {
10022 /* no code information yet */
10023 IRDirty *d;
10024
10025 /* so safe the code... */
10026 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10027 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10028 stmt(IRStmt_Dirty(d));
10029 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010030 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10031 mkU64(guest_IA_curr_instr)));
10032 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010033 restart_if(IRExpr_Const(IRConst_U1(True)));
10034
sewardj2019a972011-03-07 16:04:07 +000010035 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010036 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010037 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000010038 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000010039 break;
10040 }
10041
10042 case 0xd200000000000000ULL:
10043 /* special case MVC */
10044 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010045 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010046
10047 case 0xd500000000000000ULL:
10048 /* special case CLC */
10049 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010050 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010051
10052 case 0xd700000000000000ULL:
10053 /* special case XC */
10054 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010055 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010056
florianb0bf6602012-05-05 00:01:16 +000010057 case 0xd600000000000000ULL:
10058 /* special case OC */
10059 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010060 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010061
10062 case 0xd400000000000000ULL:
10063 /* special case NC */
10064 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010065 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010066
florianf87d4fb2012-05-05 02:55:24 +000010067 case 0xdc00000000000000ULL:
10068 /* special case TR */
10069 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010070 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010071
sewardj2019a972011-03-07 16:04:07 +000010072 default:
10073 {
10074 /* everything else will get a self checking prefix that also checks the
10075 register content */
10076 IRDirty *d;
10077 UChar *bytes;
10078 IRTemp cond;
10079 IRTemp orperand;
10080 IRTemp torun;
10081
10082 cond = newTemp(Ity_I1);
10083 orperand = newTemp(Ity_I64);
10084 torun = newTemp(Ity_I64);
10085
10086 if (r1 == 0)
10087 assign(orperand, mkU64(0));
10088 else
10089 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10090 /* This code is going to be translated */
10091 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10092 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10093
10094 /* Start with a check that saved code is still correct */
10095 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10096 mkU64(last_execute_target)));
10097 /* If not, save the new value */
10098 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10099 mkIRExprVec_1(mkexpr(torun)));
10100 d->guard = mkexpr(cond);
10101 stmt(IRStmt_Dirty(d));
10102
10103 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010104 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10105 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010106 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010107
10108 /* Now comes the actual translation */
10109 bytes = (UChar *) &last_execute_target;
10110 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10111 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010112 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010113 vex_printf(" which was executed by\n");
10114 /* dont make useless translations in the next execute */
10115 last_execute_target = 0;
10116 }
10117 }
10118 return "ex";
10119}
10120
florian55085f82012-11-21 00:36:55 +000010121static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010122s390_irgen_EXRL(UChar r1, UInt offset)
10123{
10124 IRTemp addr = newTemp(Ity_I64);
10125 /* we might save one round trip because we know the target */
10126 if (!last_execute_target)
10127 last_execute_target = *(ULong *)(HWord)
10128 (guest_IA_curr_instr + offset * 2UL);
10129 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10130 s390_irgen_EX(r1, addr);
10131 return "exrl";
10132}
10133
florian55085f82012-11-21 00:36:55 +000010134static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010135s390_irgen_IPM(UChar r1)
10136{
10137 // As long as we dont support SPM, lets just assume 0 as program mask
10138 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
10139 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
10140
10141 return "ipm";
10142}
10143
10144
florian55085f82012-11-21 00:36:55 +000010145static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010146s390_irgen_SRST(UChar r1, UChar r2)
10147{
10148 IRTemp address = newTemp(Ity_I64);
10149 IRTemp next = newTemp(Ity_I64);
10150 IRTemp delim = newTemp(Ity_I8);
10151 IRTemp counter = newTemp(Ity_I64);
10152 IRTemp byte = newTemp(Ity_I8);
10153
10154 assign(address, get_gpr_dw0(r2));
10155 assign(next, get_gpr_dw0(r1));
10156
10157 assign(counter, get_counter_dw0());
10158 put_counter_dw0(mkU64(0));
10159
10160 // start = next? CC=2 and out r1 and r2 unchanged
10161 s390_cc_set(2);
10162 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010163 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000010164
10165 assign(byte, load(Ity_I8, mkexpr(address)));
10166 assign(delim, get_gpr_b7(0));
10167
10168 // byte = delim? CC=1, R1=address
10169 s390_cc_set(1);
10170 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000010171 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010172
10173 // else: all equal, no end yet, loop
10174 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10175 put_gpr_dw0(r1, mkexpr(next));
10176 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010177
florian6820ba52012-07-26 02:01:50 +000010178 iterate();
sewardj2019a972011-03-07 16:04:07 +000010179
10180 return "srst";
10181}
10182
florian55085f82012-11-21 00:36:55 +000010183static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010184s390_irgen_CLST(UChar r1, UChar r2)
10185{
10186 IRTemp address1 = newTemp(Ity_I64);
10187 IRTemp address2 = newTemp(Ity_I64);
10188 IRTemp end = newTemp(Ity_I8);
10189 IRTemp counter = newTemp(Ity_I64);
10190 IRTemp byte1 = newTemp(Ity_I8);
10191 IRTemp byte2 = newTemp(Ity_I8);
10192
10193 assign(address1, get_gpr_dw0(r1));
10194 assign(address2, get_gpr_dw0(r2));
10195 assign(end, get_gpr_b7(0));
10196 assign(counter, get_counter_dw0());
10197 put_counter_dw0(mkU64(0));
10198 assign(byte1, load(Ity_I8, mkexpr(address1)));
10199 assign(byte2, load(Ity_I8, mkexpr(address2)));
10200
10201 // end in both? all equal, reset r1 and r2 to start values
10202 s390_cc_set(0);
10203 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
10204 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010205 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10206 binop(Iop_Or8,
10207 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10208 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010209
10210 put_gpr_dw0(r1, mkexpr(address1));
10211 put_gpr_dw0(r2, mkexpr(address2));
10212
10213 // End found in string1
10214 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010215 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010216
10217 // End found in string2
10218 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010219 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010220
10221 // string1 < string2
10222 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010223 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10224 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010225
10226 // string2 < string1
10227 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010228 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10229 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010230
10231 // else: all equal, no end yet, loop
10232 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10233 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10234 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010235
florian6820ba52012-07-26 02:01:50 +000010236 iterate();
sewardj2019a972011-03-07 16:04:07 +000010237
10238 return "clst";
10239}
10240
10241static void
10242s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10243{
10244 UChar reg;
10245 IRTemp addr = newTemp(Ity_I64);
10246
10247 assign(addr, mkexpr(op2addr));
10248 reg = r1;
10249 do {
10250 IRTemp old = addr;
10251
10252 reg %= 16;
10253 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10254 addr = newTemp(Ity_I64);
10255 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10256 reg++;
10257 } while (reg != (r3 + 1));
10258}
10259
florian55085f82012-11-21 00:36:55 +000010260static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010261s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10262{
10263 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10264
10265 return "lm";
10266}
10267
florian55085f82012-11-21 00:36:55 +000010268static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010269s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
10270{
10271 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10272
10273 return "lmy";
10274}
10275
florian55085f82012-11-21 00:36:55 +000010276static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010277s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
10278{
10279 UChar reg;
10280 IRTemp addr = newTemp(Ity_I64);
10281
10282 assign(addr, mkexpr(op2addr));
10283 reg = r1;
10284 do {
10285 IRTemp old = addr;
10286
10287 reg %= 16;
10288 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
10289 addr = newTemp(Ity_I64);
10290 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10291 reg++;
10292 } while (reg != (r3 + 1));
10293
10294 return "lmh";
10295}
10296
florian55085f82012-11-21 00:36:55 +000010297static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010298s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
10299{
10300 UChar reg;
10301 IRTemp addr = newTemp(Ity_I64);
10302
10303 assign(addr, mkexpr(op2addr));
10304 reg = r1;
10305 do {
10306 IRTemp old = addr;
10307
10308 reg %= 16;
10309 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
10310 addr = newTemp(Ity_I64);
10311 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10312 reg++;
10313 } while (reg != (r3 + 1));
10314
10315 return "lmg";
10316}
10317
10318static void
10319s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10320{
10321 UChar reg;
10322 IRTemp addr = newTemp(Ity_I64);
10323
10324 assign(addr, mkexpr(op2addr));
10325 reg = r1;
10326 do {
10327 IRTemp old = addr;
10328
10329 reg %= 16;
10330 store(mkexpr(addr), get_gpr_w1(reg));
10331 addr = newTemp(Ity_I64);
10332 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10333 reg++;
10334 } while( reg != (r3 + 1));
10335}
10336
florian55085f82012-11-21 00:36:55 +000010337static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010338s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
10339{
10340 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10341
10342 return "stm";
10343}
10344
florian55085f82012-11-21 00:36:55 +000010345static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010346s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
10347{
10348 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10349
10350 return "stmy";
10351}
10352
florian55085f82012-11-21 00:36:55 +000010353static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010354s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
10355{
10356 UChar reg;
10357 IRTemp addr = newTemp(Ity_I64);
10358
10359 assign(addr, mkexpr(op2addr));
10360 reg = r1;
10361 do {
10362 IRTemp old = addr;
10363
10364 reg %= 16;
10365 store(mkexpr(addr), get_gpr_w0(reg));
10366 addr = newTemp(Ity_I64);
10367 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10368 reg++;
10369 } while( reg != (r3 + 1));
10370
10371 return "stmh";
10372}
10373
florian55085f82012-11-21 00:36:55 +000010374static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010375s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
10376{
10377 UChar reg;
10378 IRTemp addr = newTemp(Ity_I64);
10379
10380 assign(addr, mkexpr(op2addr));
10381 reg = r1;
10382 do {
10383 IRTemp old = addr;
10384
10385 reg %= 16;
10386 store(mkexpr(addr), get_gpr_dw0(reg));
10387 addr = newTemp(Ity_I64);
10388 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10389 reg++;
10390 } while( reg != (r3 + 1));
10391
10392 return "stmg";
10393}
10394
10395static void
florianb0bf6602012-05-05 00:01:16 +000010396s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000010397{
10398 IRTemp old1 = newTemp(Ity_I8);
10399 IRTemp old2 = newTemp(Ity_I8);
10400 IRTemp new1 = newTemp(Ity_I8);
10401 IRTemp counter = newTemp(Ity_I32);
10402 IRTemp addr1 = newTemp(Ity_I64);
10403
10404 assign(counter, get_counter_w0());
10405
10406 assign(addr1, binop(Iop_Add64, mkexpr(start1),
10407 unop(Iop_32Uto64, mkexpr(counter))));
10408
10409 assign(old1, load(Ity_I8, mkexpr(addr1)));
10410 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10411 unop(Iop_32Uto64,mkexpr(counter)))));
10412 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
10413
10414 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000010415 if (op == Iop_Xor8) {
10416 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000010417 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
10418 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000010419 } else
10420 store(mkexpr(addr1), mkexpr(new1));
10421 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
10422 get_counter_w1()));
10423
10424 /* Check for end of field */
10425 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010426 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010427 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
10428 False);
10429 put_counter_dw0(mkU64(0));
10430}
10431
florian55085f82012-11-21 00:36:55 +000010432static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010433s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
10434{
florianb0bf6602012-05-05 00:01:16 +000010435 IRTemp len = newTemp(Ity_I32);
10436
10437 assign(len, mkU32(length));
10438 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010439
10440 return "xc";
10441}
10442
sewardjb63967e2011-03-24 08:50:04 +000010443static void
10444s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
10445{
10446 IRTemp counter = newTemp(Ity_I32);
10447 IRTemp start = newTemp(Ity_I64);
10448 IRTemp addr = newTemp(Ity_I64);
10449
10450 assign(start,
10451 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
10452
10453 if (length < 8) {
10454 UInt i;
10455
10456 for (i = 0; i <= length; ++i) {
10457 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
10458 }
10459 } else {
10460 assign(counter, get_counter_w0());
10461
10462 assign(addr, binop(Iop_Add64, mkexpr(start),
10463 unop(Iop_32Uto64, mkexpr(counter))));
10464
10465 store(mkexpr(addr), mkU8(0));
10466
10467 /* Check for end of field */
10468 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010469 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000010470
10471 /* Reset counter */
10472 put_counter_dw0(mkU64(0));
10473 }
10474
10475 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
10476
sewardj7ee97522011-05-09 21:45:04 +000010477 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000010478 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
10479}
10480
florian55085f82012-11-21 00:36:55 +000010481static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010482s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
10483{
florianb0bf6602012-05-05 00:01:16 +000010484 IRTemp len = newTemp(Ity_I32);
10485
10486 assign(len, mkU32(length));
10487 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010488
10489 return "nc";
10490}
10491
florian55085f82012-11-21 00:36:55 +000010492static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010493s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
10494{
florianb0bf6602012-05-05 00:01:16 +000010495 IRTemp len = newTemp(Ity_I32);
10496
10497 assign(len, mkU32(length));
10498 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010499
10500 return "oc";
10501}
10502
10503
florian55085f82012-11-21 00:36:55 +000010504static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010505s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
10506{
florian79e839e2012-05-05 02:20:30 +000010507 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010508
florian79e839e2012-05-05 02:20:30 +000010509 assign(len, mkU64(length));
10510 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010511
10512 return "mvc";
10513}
10514
florian55085f82012-11-21 00:36:55 +000010515static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010516s390_irgen_MVCL(UChar r1, UChar r2)
10517{
10518 IRTemp addr1 = newTemp(Ity_I64);
10519 IRTemp addr2 = newTemp(Ity_I64);
10520 IRTemp addr2_load = newTemp(Ity_I64);
10521 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10522 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10523 IRTemp len1 = newTemp(Ity_I32);
10524 IRTemp len2 = newTemp(Ity_I32);
10525 IRTemp pad = newTemp(Ity_I8);
10526 IRTemp single = newTemp(Ity_I8);
10527
10528 assign(addr1, get_gpr_dw0(r1));
10529 assign(r1p1, get_gpr_w1(r1 + 1));
10530 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10531 assign(addr2, get_gpr_dw0(r2));
10532 assign(r2p1, get_gpr_w1(r2 + 1));
10533 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10534 assign(pad, get_gpr_b4(r2 + 1));
10535
10536 /* len1 == 0 ? */
10537 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010538 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010539
10540 /* Check for destructive overlap:
10541 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
10542 s390_cc_set(3);
10543 IRTemp cond1 = newTemp(Ity_I32);
10544 assign(cond1, unop(Iop_1Uto32,
10545 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
10546 IRTemp cond2 = newTemp(Ity_I32);
10547 assign(cond2, unop(Iop_1Uto32,
10548 binop(Iop_CmpLT64U, mkexpr(addr1),
10549 binop(Iop_Add64, mkexpr(addr2),
10550 unop(Iop_32Uto64, mkexpr(len1))))));
10551 IRTemp cond3 = newTemp(Ity_I32);
10552 assign(cond3, unop(Iop_1Uto32,
10553 binop(Iop_CmpLT64U,
10554 mkexpr(addr1),
10555 binop(Iop_Add64, mkexpr(addr2),
10556 unop(Iop_32Uto64, mkexpr(len2))))));
10557
florian6820ba52012-07-26 02:01:50 +000010558 next_insn_if(binop(Iop_CmpEQ32,
10559 binop(Iop_And32,
10560 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10561 mkexpr(cond3)),
10562 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010563
10564 /* See s390_irgen_CLCL for explanation why we cannot load directly
10565 and need two steps. */
10566 assign(addr2_load,
10567 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10568 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10569 assign(single,
10570 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10571 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10572
10573 store(mkexpr(addr1), mkexpr(single));
10574
10575 /* Update addr1 and len1 */
10576 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10577 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10578
10579 /* Update addr2 and len2 */
10580 put_gpr_dw0(r2,
10581 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10582 mkexpr(addr2),
10583 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10584
10585 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10586 put_gpr_w1(r2 + 1,
10587 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10588 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10589 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10590
10591 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010592 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010593
10594 return "mvcl";
10595}
10596
10597
florian55085f82012-11-21 00:36:55 +000010598static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010599s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10600{
10601 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10602
10603 addr1 = newTemp(Ity_I64);
10604 addr3 = newTemp(Ity_I64);
10605 addr3_load = newTemp(Ity_I64);
10606 len1 = newTemp(Ity_I64);
10607 len3 = newTemp(Ity_I64);
10608 single = newTemp(Ity_I8);
10609
10610 assign(addr1, get_gpr_dw0(r1));
10611 assign(len1, get_gpr_dw0(r1 + 1));
10612 assign(addr3, get_gpr_dw0(r3));
10613 assign(len3, get_gpr_dw0(r3 + 1));
10614
10615 // len1 == 0 ?
10616 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010617 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010618
10619 /* This is a hack to prevent mvcle from reading from addr3 if it
10620 should read from the pad. Since the pad has no address, just
10621 read from the instruction, we discard that anyway */
10622 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010623 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10624 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010625
10626 assign(single,
florian6ad49522011-09-09 02:38:55 +000010627 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10628 unop(Iop_64to8, mkexpr(pad2)),
10629 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010630 store(mkexpr(addr1), mkexpr(single));
10631
10632 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10633
10634 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10635
10636 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010637 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10638 mkexpr(addr3),
10639 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010640
10641 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010642 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10643 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010644
sewardj2019a972011-03-07 16:04:07 +000010645 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010646 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010647
10648 return "mvcle";
10649}
10650
florian55085f82012-11-21 00:36:55 +000010651static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010652s390_irgen_MVST(UChar r1, UChar r2)
10653{
10654 IRTemp addr1 = newTemp(Ity_I64);
10655 IRTemp addr2 = newTemp(Ity_I64);
10656 IRTemp end = newTemp(Ity_I8);
10657 IRTemp byte = newTemp(Ity_I8);
10658 IRTemp counter = newTemp(Ity_I64);
10659
10660 assign(addr1, get_gpr_dw0(r1));
10661 assign(addr2, get_gpr_dw0(r2));
10662 assign(counter, get_counter_dw0());
10663 assign(end, get_gpr_b7(0));
10664 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10665 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10666
10667 // We use unlimited as cpu-determined number
10668 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010669 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010670
10671 // and always set cc=1 at the end + update r1
10672 s390_cc_set(1);
10673 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10674 put_counter_dw0(mkU64(0));
10675
10676 return "mvst";
10677}
10678
10679static void
10680s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10681{
10682 IRTemp op1 = newTemp(Ity_I64);
10683 IRTemp result = newTemp(Ity_I64);
10684
10685 assign(op1, binop(Iop_32HLto64,
10686 get_gpr_w1(r1), // high 32 bits
10687 get_gpr_w1(r1 + 1))); // low 32 bits
10688 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10689 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10690 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10691}
10692
10693static void
10694s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10695{
10696 IRTemp op1 = newTemp(Ity_I128);
10697 IRTemp result = newTemp(Ity_I128);
10698
10699 assign(op1, binop(Iop_64HLto128,
10700 get_gpr_dw0(r1), // high 64 bits
10701 get_gpr_dw0(r1 + 1))); // low 64 bits
10702 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10703 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10704 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10705}
10706
10707static void
10708s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10709{
10710 IRTemp op1 = newTemp(Ity_I64);
10711 IRTemp result = newTemp(Ity_I128);
10712
10713 assign(op1, get_gpr_dw0(r1 + 1));
10714 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10715 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10716 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10717}
10718
florian55085f82012-11-21 00:36:55 +000010719static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010720s390_irgen_DR(UChar r1, UChar r2)
10721{
10722 IRTemp op2 = newTemp(Ity_I32);
10723
10724 assign(op2, get_gpr_w1(r2));
10725
10726 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10727
10728 return "dr";
10729}
10730
florian55085f82012-11-21 00:36:55 +000010731static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010732s390_irgen_D(UChar r1, IRTemp op2addr)
10733{
10734 IRTemp op2 = newTemp(Ity_I32);
10735
10736 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10737
10738 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10739
10740 return "d";
10741}
10742
florian55085f82012-11-21 00:36:55 +000010743static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010744s390_irgen_DLR(UChar r1, UChar r2)
10745{
10746 IRTemp op2 = newTemp(Ity_I32);
10747
10748 assign(op2, get_gpr_w1(r2));
10749
10750 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10751
florian7cd1cde2012-08-16 23:57:43 +000010752 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010753}
10754
florian55085f82012-11-21 00:36:55 +000010755static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010756s390_irgen_DL(UChar r1, IRTemp op2addr)
10757{
10758 IRTemp op2 = newTemp(Ity_I32);
10759
10760 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10761
10762 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10763
10764 return "dl";
10765}
10766
florian55085f82012-11-21 00:36:55 +000010767static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010768s390_irgen_DLG(UChar r1, IRTemp op2addr)
10769{
10770 IRTemp op2 = newTemp(Ity_I64);
10771
10772 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10773
10774 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10775
10776 return "dlg";
10777}
10778
florian55085f82012-11-21 00:36:55 +000010779static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010780s390_irgen_DLGR(UChar r1, UChar r2)
10781{
10782 IRTemp op2 = newTemp(Ity_I64);
10783
10784 assign(op2, get_gpr_dw0(r2));
10785
10786 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
10787
10788 return "dlgr";
10789}
10790
florian55085f82012-11-21 00:36:55 +000010791static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010792s390_irgen_DSGR(UChar r1, UChar r2)
10793{
10794 IRTemp op2 = newTemp(Ity_I64);
10795
10796 assign(op2, get_gpr_dw0(r2));
10797
10798 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10799
10800 return "dsgr";
10801}
10802
florian55085f82012-11-21 00:36:55 +000010803static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010804s390_irgen_DSG(UChar r1, IRTemp op2addr)
10805{
10806 IRTemp op2 = newTemp(Ity_I64);
10807
10808 assign(op2, load(Ity_I64, mkexpr(op2addr)));
10809
10810 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10811
10812 return "dsg";
10813}
10814
florian55085f82012-11-21 00:36:55 +000010815static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010816s390_irgen_DSGFR(UChar r1, UChar r2)
10817{
10818 IRTemp op2 = newTemp(Ity_I64);
10819
10820 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
10821
10822 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10823
10824 return "dsgfr";
10825}
10826
florian55085f82012-11-21 00:36:55 +000010827static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010828s390_irgen_DSGF(UChar r1, IRTemp op2addr)
10829{
10830 IRTemp op2 = newTemp(Ity_I64);
10831
10832 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
10833
10834 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
10835
10836 return "dsgf";
10837}
10838
10839static void
10840s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10841{
10842 UChar reg;
10843 IRTemp addr = newTemp(Ity_I64);
10844
10845 assign(addr, mkexpr(op2addr));
10846 reg = r1;
10847 do {
10848 IRTemp old = addr;
10849
10850 reg %= 16;
10851 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
10852 addr = newTemp(Ity_I64);
10853 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10854 reg++;
10855 } while (reg != (r3 + 1));
10856}
10857
florian55085f82012-11-21 00:36:55 +000010858static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010859s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
10860{
10861 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10862
10863 return "lam";
10864}
10865
florian55085f82012-11-21 00:36:55 +000010866static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010867s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
10868{
10869 s390_irgen_load_ar_multiple(r1, r3, op2addr);
10870
10871 return "lamy";
10872}
10873
10874static void
10875s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
10876{
10877 UChar reg;
10878 IRTemp addr = newTemp(Ity_I64);
10879
10880 assign(addr, mkexpr(op2addr));
10881 reg = r1;
10882 do {
10883 IRTemp old = addr;
10884
10885 reg %= 16;
10886 store(mkexpr(addr), get_ar_w0(reg));
10887 addr = newTemp(Ity_I64);
10888 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10889 reg++;
10890 } while (reg != (r3 + 1));
10891}
10892
florian55085f82012-11-21 00:36:55 +000010893static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010894s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
10895{
10896 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10897
10898 return "stam";
10899}
10900
florian55085f82012-11-21 00:36:55 +000010901static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010902s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
10903{
10904 s390_irgen_store_ar_multiple(r1, r3, op2addr);
10905
10906 return "stamy";
10907}
10908
10909
10910/* Implementation for 32-bit compare-and-swap */
10911static void
10912s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
10913{
10914 IRCAS *cas;
10915 IRTemp op1 = newTemp(Ity_I32);
10916 IRTemp old_mem = newTemp(Ity_I32);
10917 IRTemp op3 = newTemp(Ity_I32);
10918 IRTemp result = newTemp(Ity_I32);
10919 IRTemp nequal = newTemp(Ity_I1);
10920
10921 assign(op1, get_gpr_w1(r1));
10922 assign(op3, get_gpr_w1(r3));
10923
10924 /* The first and second operands are compared. If they are equal,
10925 the third operand is stored at the second- operand location. */
10926 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10927 Iend_BE, mkexpr(op2addr),
10928 NULL, mkexpr(op1), /* expected value */
10929 NULL, mkexpr(op3) /* new value */);
10930 stmt(IRStmt_CAS(cas));
10931
10932 /* Set CC. Operands compared equal -> 0, else 1. */
10933 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
10934 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10935
10936 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10937 Otherwise, store the old_value from memory in r1 and yield. */
10938 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10939 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010940 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010941}
10942
florian55085f82012-11-21 00:36:55 +000010943static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010944s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
10945{
10946 s390_irgen_cas_32(r1, r3, op2addr);
10947
10948 return "cs";
10949}
10950
florian55085f82012-11-21 00:36:55 +000010951static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010952s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
10953{
10954 s390_irgen_cas_32(r1, r3, op2addr);
10955
10956 return "csy";
10957}
10958
florian55085f82012-11-21 00:36:55 +000010959static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010960s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
10961{
10962 IRCAS *cas;
10963 IRTemp op1 = newTemp(Ity_I64);
10964 IRTemp old_mem = newTemp(Ity_I64);
10965 IRTemp op3 = newTemp(Ity_I64);
10966 IRTemp result = newTemp(Ity_I64);
10967 IRTemp nequal = newTemp(Ity_I1);
10968
10969 assign(op1, get_gpr_dw0(r1));
10970 assign(op3, get_gpr_dw0(r3));
10971
10972 /* The first and second operands are compared. If they are equal,
10973 the third operand is stored at the second- operand location. */
10974 cas = mkIRCAS(IRTemp_INVALID, old_mem,
10975 Iend_BE, mkexpr(op2addr),
10976 NULL, mkexpr(op1), /* expected value */
10977 NULL, mkexpr(op3) /* new value */);
10978 stmt(IRStmt_CAS(cas));
10979
10980 /* Set CC. Operands compared equal -> 0, else 1. */
10981 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
10982 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
10983
10984 /* If operands were equal (cc == 0) just store the old value op1 in r1.
10985 Otherwise, store the old_value from memory in r1 and yield. */
10986 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
10987 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000010988 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000010989
10990 return "csg";
10991}
10992
florian448cbba2012-06-06 02:26:01 +000010993/* Implementation for 32-bit compare-double-and-swap */
10994static void
10995s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
10996{
10997 IRCAS *cas;
10998 IRTemp op1_high = newTemp(Ity_I32);
10999 IRTemp op1_low = newTemp(Ity_I32);
11000 IRTemp old_mem_high = newTemp(Ity_I32);
11001 IRTemp old_mem_low = newTemp(Ity_I32);
11002 IRTemp op3_high = newTemp(Ity_I32);
11003 IRTemp op3_low = newTemp(Ity_I32);
11004 IRTemp result = newTemp(Ity_I32);
11005 IRTemp nequal = newTemp(Ity_I1);
11006
11007 assign(op1_high, get_gpr_w1(r1));
11008 assign(op1_low, get_gpr_w1(r1+1));
11009 assign(op3_high, get_gpr_w1(r3));
11010 assign(op3_low, get_gpr_w1(r3+1));
11011
11012 /* The first and second operands are compared. If they are equal,
11013 the third operand is stored at the second-operand location. */
11014 cas = mkIRCAS(old_mem_high, old_mem_low,
11015 Iend_BE, mkexpr(op2addr),
11016 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11017 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11018 stmt(IRStmt_CAS(cas));
11019
11020 /* Set CC. Operands compared equal -> 0, else 1. */
11021 assign(result, unop(Iop_1Uto32,
11022 binop(Iop_CmpNE32,
11023 binop(Iop_Or32,
11024 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11025 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11026 mkU32(0))));
11027
11028 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11029
11030 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11031 Otherwise, store the old_value from memory in r1 and yield. */
11032 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11033 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11034 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011035 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011036}
11037
florian55085f82012-11-21 00:36:55 +000011038static const HChar *
florian448cbba2012-06-06 02:26:01 +000011039s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11040{
11041 s390_irgen_cdas_32(r1, r3, op2addr);
11042
11043 return "cds";
11044}
11045
florian55085f82012-11-21 00:36:55 +000011046static const HChar *
florian448cbba2012-06-06 02:26:01 +000011047s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11048{
11049 s390_irgen_cdas_32(r1, r3, op2addr);
11050
11051 return "cdsy";
11052}
11053
florian55085f82012-11-21 00:36:55 +000011054static const HChar *
florian448cbba2012-06-06 02:26:01 +000011055s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11056{
11057 IRCAS *cas;
11058 IRTemp op1_high = newTemp(Ity_I64);
11059 IRTemp op1_low = newTemp(Ity_I64);
11060 IRTemp old_mem_high = newTemp(Ity_I64);
11061 IRTemp old_mem_low = newTemp(Ity_I64);
11062 IRTemp op3_high = newTemp(Ity_I64);
11063 IRTemp op3_low = newTemp(Ity_I64);
11064 IRTemp result = newTemp(Ity_I64);
11065 IRTemp nequal = newTemp(Ity_I1);
11066
11067 assign(op1_high, get_gpr_dw0(r1));
11068 assign(op1_low, get_gpr_dw0(r1+1));
11069 assign(op3_high, get_gpr_dw0(r3));
11070 assign(op3_low, get_gpr_dw0(r3+1));
11071
11072 /* The first and second operands are compared. If they are equal,
11073 the third operand is stored at the second-operand location. */
11074 cas = mkIRCAS(old_mem_high, old_mem_low,
11075 Iend_BE, mkexpr(op2addr),
11076 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11077 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11078 stmt(IRStmt_CAS(cas));
11079
11080 /* Set CC. Operands compared equal -> 0, else 1. */
11081 assign(result, unop(Iop_1Uto64,
11082 binop(Iop_CmpNE64,
11083 binop(Iop_Or64,
11084 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11085 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11086 mkU64(0))));
11087
11088 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11089
11090 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11091 Otherwise, store the old_value from memory in r1 and yield. */
11092 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11093 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11094 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011095 yield_if(mkexpr(nequal));
11096
florian448cbba2012-06-06 02:26:01 +000011097 return "cdsg";
11098}
11099
sewardj2019a972011-03-07 16:04:07 +000011100
11101/* Binary floating point */
11102
florian55085f82012-11-21 00:36:55 +000011103static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011104s390_irgen_AXBR(UChar r1, UChar r2)
11105{
11106 IRTemp op1 = newTemp(Ity_F128);
11107 IRTemp op2 = newTemp(Ity_F128);
11108 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011109 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011110
11111 assign(op1, get_fpr_pair(r1));
11112 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011113 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011114 mkexpr(op2)));
11115 put_fpr_pair(r1, mkexpr(result));
11116
11117 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11118
11119 return "axbr";
11120}
11121
florian55085f82012-11-21 00:36:55 +000011122static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011123s390_irgen_CEBR(UChar r1, UChar r2)
11124{
11125 IRTemp op1 = newTemp(Ity_F32);
11126 IRTemp op2 = newTemp(Ity_F32);
11127 IRTemp cc_vex = newTemp(Ity_I32);
11128 IRTemp cc_s390 = newTemp(Ity_I32);
11129
11130 assign(op1, get_fpr_w0(r1));
11131 assign(op2, get_fpr_w0(r2));
11132 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11133
florian2d3d87f2012-12-21 21:05:17 +000011134 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011135 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11136
11137 return "cebr";
11138}
11139
florian55085f82012-11-21 00:36:55 +000011140static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011141s390_irgen_CDBR(UChar r1, UChar r2)
11142{
11143 IRTemp op1 = newTemp(Ity_F64);
11144 IRTemp op2 = newTemp(Ity_F64);
11145 IRTemp cc_vex = newTemp(Ity_I32);
11146 IRTemp cc_s390 = newTemp(Ity_I32);
11147
11148 assign(op1, get_fpr_dw0(r1));
11149 assign(op2, get_fpr_dw0(r2));
11150 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11151
florian2d3d87f2012-12-21 21:05:17 +000011152 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011153 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11154
11155 return "cdbr";
11156}
11157
florian55085f82012-11-21 00:36:55 +000011158static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011159s390_irgen_CXBR(UChar r1, UChar r2)
11160{
11161 IRTemp op1 = newTemp(Ity_F128);
11162 IRTemp op2 = newTemp(Ity_F128);
11163 IRTemp cc_vex = newTemp(Ity_I32);
11164 IRTemp cc_s390 = newTemp(Ity_I32);
11165
11166 assign(op1, get_fpr_pair(r1));
11167 assign(op2, get_fpr_pair(r2));
11168 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
11169
florian2d3d87f2012-12-21 21:05:17 +000011170 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011171 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11172
11173 return "cxbr";
11174}
11175
florian55085f82012-11-21 00:36:55 +000011176static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011177s390_irgen_CEB(UChar r1, IRTemp op2addr)
11178{
11179 IRTemp op1 = newTemp(Ity_F32);
11180 IRTemp op2 = newTemp(Ity_F32);
11181 IRTemp cc_vex = newTemp(Ity_I32);
11182 IRTemp cc_s390 = newTemp(Ity_I32);
11183
11184 assign(op1, get_fpr_w0(r1));
11185 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11186 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11187
florian2d3d87f2012-12-21 21:05:17 +000011188 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011189 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11190
11191 return "ceb";
11192}
11193
florian55085f82012-11-21 00:36:55 +000011194static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011195s390_irgen_CDB(UChar r1, IRTemp op2addr)
11196{
11197 IRTemp op1 = newTemp(Ity_F64);
11198 IRTemp op2 = newTemp(Ity_F64);
11199 IRTemp cc_vex = newTemp(Ity_I32);
11200 IRTemp cc_s390 = newTemp(Ity_I32);
11201
11202 assign(op1, get_fpr_dw0(r1));
11203 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11204 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11205
florian2d3d87f2012-12-21 21:05:17 +000011206 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011207 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11208
11209 return "cdb";
11210}
11211
florian55085f82012-11-21 00:36:55 +000011212static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011213s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11214 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011215{
11216 IRTemp op2 = newTemp(Ity_I32);
11217
11218 assign(op2, get_gpr_w1(r2));
11219 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11220
11221 return "cxfbr";
11222}
11223
florian55085f82012-11-21 00:36:55 +000011224static const HChar *
floriand2129202012-09-01 20:01:39 +000011225s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11226 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011227{
floriane75dafa2012-09-01 17:54:09 +000011228 if (! s390_host_has_fpext) {
11229 emulation_failure(EmFail_S390X_fpext);
11230 } else {
11231 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011232
floriane75dafa2012-09-01 17:54:09 +000011233 assign(op2, get_gpr_w1(r2));
11234 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11235 }
florian1c8f7ff2012-09-01 00:12:11 +000011236 return "cxlfbr";
11237}
11238
11239
florian55085f82012-11-21 00:36:55 +000011240static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011241s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11242 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011243{
11244 IRTemp op2 = newTemp(Ity_I64);
11245
11246 assign(op2, get_gpr_dw0(r2));
11247 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11248
11249 return "cxgbr";
11250}
11251
florian55085f82012-11-21 00:36:55 +000011252static const HChar *
floriand2129202012-09-01 20:01:39 +000011253s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11254 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011255{
floriane75dafa2012-09-01 17:54:09 +000011256 if (! s390_host_has_fpext) {
11257 emulation_failure(EmFail_S390X_fpext);
11258 } else {
11259 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011260
floriane75dafa2012-09-01 17:54:09 +000011261 assign(op2, get_gpr_dw0(r2));
11262 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11263 }
florian1c8f7ff2012-09-01 00:12:11 +000011264 return "cxlgbr";
11265}
11266
florian55085f82012-11-21 00:36:55 +000011267static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011268s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11269 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011270{
11271 IRTemp op = newTemp(Ity_F128);
11272 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011273 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011274
11275 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011276 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011277 mkexpr(op)));
11278 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011279 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011280
11281 return "cfxbr";
11282}
11283
florian55085f82012-11-21 00:36:55 +000011284static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011285s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
11286 UChar r1, UChar r2)
11287{
floriane75dafa2012-09-01 17:54:09 +000011288 if (! s390_host_has_fpext) {
11289 emulation_failure(EmFail_S390X_fpext);
11290 } else {
11291 IRTemp op = newTemp(Ity_F128);
11292 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011293 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011294
floriane75dafa2012-09-01 17:54:09 +000011295 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011296 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011297 mkexpr(op)));
11298 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011299 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011300 }
florian1c8f7ff2012-09-01 00:12:11 +000011301 return "clfxbr";
11302}
11303
11304
florian55085f82012-11-21 00:36:55 +000011305static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011306s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
11307 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011308{
11309 IRTemp op = newTemp(Ity_F128);
11310 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011311 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011312
11313 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011314 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011315 mkexpr(op)));
11316 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011317 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011318
11319 return "cgxbr";
11320}
11321
florian55085f82012-11-21 00:36:55 +000011322static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011323s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
11324 UChar r1, UChar r2)
11325{
floriane75dafa2012-09-01 17:54:09 +000011326 if (! s390_host_has_fpext) {
11327 emulation_failure(EmFail_S390X_fpext);
11328 } else {
11329 IRTemp op = newTemp(Ity_F128);
11330 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011331 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011332
floriane75dafa2012-09-01 17:54:09 +000011333 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011334 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011335 mkexpr(op)));
11336 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011337 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
11338 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011339 }
florian1c8f7ff2012-09-01 00:12:11 +000011340 return "clgxbr";
11341}
11342
florian55085f82012-11-21 00:36:55 +000011343static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011344s390_irgen_DXBR(UChar r1, UChar r2)
11345{
11346 IRTemp op1 = newTemp(Ity_F128);
11347 IRTemp op2 = newTemp(Ity_F128);
11348 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011349 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011350
11351 assign(op1, get_fpr_pair(r1));
11352 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011353 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011354 mkexpr(op2)));
11355 put_fpr_pair(r1, mkexpr(result));
11356
11357 return "dxbr";
11358}
11359
florian55085f82012-11-21 00:36:55 +000011360static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011361s390_irgen_LTXBR(UChar r1, UChar r2)
11362{
11363 IRTemp result = newTemp(Ity_F128);
11364
11365 assign(result, get_fpr_pair(r2));
11366 put_fpr_pair(r1, mkexpr(result));
11367 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11368
11369 return "ltxbr";
11370}
11371
florian55085f82012-11-21 00:36:55 +000011372static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011373s390_irgen_LCXBR(UChar r1, UChar r2)
11374{
11375 IRTemp result = newTemp(Ity_F128);
11376
11377 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
11378 put_fpr_pair(r1, mkexpr(result));
11379 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11380
11381 return "lcxbr";
11382}
11383
florian55085f82012-11-21 00:36:55 +000011384static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011385s390_irgen_LXDBR(UChar r1, UChar r2)
11386{
11387 IRTemp op = newTemp(Ity_F64);
11388
11389 assign(op, get_fpr_dw0(r2));
11390 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11391
11392 return "lxdbr";
11393}
11394
florian55085f82012-11-21 00:36:55 +000011395static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011396s390_irgen_LXEBR(UChar r1, UChar r2)
11397{
11398 IRTemp op = newTemp(Ity_F32);
11399
11400 assign(op, get_fpr_w0(r2));
11401 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11402
11403 return "lxebr";
11404}
11405
florian55085f82012-11-21 00:36:55 +000011406static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011407s390_irgen_LXDB(UChar r1, IRTemp op2addr)
11408{
11409 IRTemp op = newTemp(Ity_F64);
11410
11411 assign(op, load(Ity_F64, mkexpr(op2addr)));
11412 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11413
11414 return "lxdb";
11415}
11416
florian55085f82012-11-21 00:36:55 +000011417static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011418s390_irgen_LXEB(UChar r1, IRTemp op2addr)
11419{
11420 IRTemp op = newTemp(Ity_F32);
11421
11422 assign(op, load(Ity_F32, mkexpr(op2addr)));
11423 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11424
11425 return "lxeb";
11426}
11427
florian55085f82012-11-21 00:36:55 +000011428static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011429s390_irgen_LNEBR(UChar r1, UChar r2)
11430{
11431 IRTemp result = newTemp(Ity_F32);
11432
11433 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
11434 put_fpr_w0(r1, mkexpr(result));
11435 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11436
11437 return "lnebr";
11438}
11439
florian55085f82012-11-21 00:36:55 +000011440static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011441s390_irgen_LNDBR(UChar r1, UChar r2)
11442{
11443 IRTemp result = newTemp(Ity_F64);
11444
11445 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11446 put_fpr_dw0(r1, mkexpr(result));
11447 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11448
11449 return "lndbr";
11450}
11451
florian55085f82012-11-21 00:36:55 +000011452static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011453s390_irgen_LNXBR(UChar r1, UChar r2)
11454{
11455 IRTemp result = newTemp(Ity_F128);
11456
11457 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
11458 put_fpr_pair(r1, mkexpr(result));
11459 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11460
11461 return "lnxbr";
11462}
11463
florian55085f82012-11-21 00:36:55 +000011464static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011465s390_irgen_LPEBR(UChar r1, UChar r2)
11466{
11467 IRTemp result = newTemp(Ity_F32);
11468
11469 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
11470 put_fpr_w0(r1, mkexpr(result));
11471 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11472
11473 return "lpebr";
11474}
11475
florian55085f82012-11-21 00:36:55 +000011476static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011477s390_irgen_LPDBR(UChar r1, UChar r2)
11478{
11479 IRTemp result = newTemp(Ity_F64);
11480
11481 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11482 put_fpr_dw0(r1, mkexpr(result));
11483 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11484
11485 return "lpdbr";
11486}
11487
florian55085f82012-11-21 00:36:55 +000011488static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011489s390_irgen_LPXBR(UChar r1, UChar r2)
11490{
11491 IRTemp result = newTemp(Ity_F128);
11492
11493 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
11494 put_fpr_pair(r1, mkexpr(result));
11495 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11496
11497 return "lpxbr";
11498}
11499
florian55085f82012-11-21 00:36:55 +000011500static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011501s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
11502 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011503{
florian125e20d2012-10-07 15:42:37 +000011504 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011505 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011506 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011507 }
sewardj2019a972011-03-07 16:04:07 +000011508 IRTemp result = newTemp(Ity_F64);
11509
floriandb4fcaa2012-09-05 19:54:08 +000011510 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011511 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011512 put_fpr_dw0(r1, mkexpr(result));
11513
11514 return "ldxbr";
11515}
11516
florian55085f82012-11-21 00:36:55 +000011517static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011518s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11519 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011520{
florian125e20d2012-10-07 15:42:37 +000011521 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011522 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011523 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011524 }
sewardj2019a972011-03-07 16:04:07 +000011525 IRTemp result = newTemp(Ity_F32);
11526
floriandb4fcaa2012-09-05 19:54:08 +000011527 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011528 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011529 put_fpr_w0(r1, mkexpr(result));
11530
11531 return "lexbr";
11532}
11533
florian55085f82012-11-21 00:36:55 +000011534static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011535s390_irgen_MXBR(UChar r1, UChar r2)
11536{
11537 IRTemp op1 = newTemp(Ity_F128);
11538 IRTemp op2 = newTemp(Ity_F128);
11539 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011540 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011541
11542 assign(op1, get_fpr_pair(r1));
11543 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011544 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011545 mkexpr(op2)));
11546 put_fpr_pair(r1, mkexpr(result));
11547
11548 return "mxbr";
11549}
11550
florian55085f82012-11-21 00:36:55 +000011551static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011552s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11553{
florian125e20d2012-10-07 15:42:37 +000011554 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011555
floriandb4fcaa2012-09-05 19:54:08 +000011556 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011557 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011558
11559 return "maebr";
11560}
11561
florian55085f82012-11-21 00:36:55 +000011562static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011563s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11564{
florian125e20d2012-10-07 15:42:37 +000011565 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011566
floriandb4fcaa2012-09-05 19:54:08 +000011567 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011568 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011569
11570 return "madbr";
11571}
11572
florian55085f82012-11-21 00:36:55 +000011573static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011574s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11575{
11576 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011577 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011578
floriandb4fcaa2012-09-05 19:54:08 +000011579 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011580 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011581
11582 return "maeb";
11583}
11584
florian55085f82012-11-21 00:36:55 +000011585static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011586s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11587{
11588 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011589 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011590
floriandb4fcaa2012-09-05 19:54:08 +000011591 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011592 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011593
11594 return "madb";
11595}
11596
florian55085f82012-11-21 00:36:55 +000011597static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011598s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11599{
florian125e20d2012-10-07 15:42:37 +000011600 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011601
floriandb4fcaa2012-09-05 19:54:08 +000011602 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011603 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011604
11605 return "msebr";
11606}
11607
florian55085f82012-11-21 00:36:55 +000011608static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011609s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11610{
florian125e20d2012-10-07 15:42:37 +000011611 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011612
floriandb4fcaa2012-09-05 19:54:08 +000011613 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011614 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011615
11616 return "msdbr";
11617}
11618
florian55085f82012-11-21 00:36:55 +000011619static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011620s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11621{
11622 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011623 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011624
floriandb4fcaa2012-09-05 19:54:08 +000011625 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011626 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011627
11628 return "mseb";
11629}
11630
florian55085f82012-11-21 00:36:55 +000011631static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011632s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11633{
11634 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011635 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011636
floriandb4fcaa2012-09-05 19:54:08 +000011637 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011638 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011639
11640 return "msdb";
11641}
11642
florian55085f82012-11-21 00:36:55 +000011643static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011644s390_irgen_SQEBR(UChar r1, UChar r2)
11645{
11646 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011647 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011648
floriandb4fcaa2012-09-05 19:54:08 +000011649 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011650 put_fpr_w0(r1, mkexpr(result));
11651
11652 return "sqebr";
11653}
11654
florian55085f82012-11-21 00:36:55 +000011655static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011656s390_irgen_SQDBR(UChar r1, UChar r2)
11657{
11658 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011659 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011660
floriandb4fcaa2012-09-05 19:54:08 +000011661 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011662 put_fpr_dw0(r1, mkexpr(result));
11663
11664 return "sqdbr";
11665}
11666
florian55085f82012-11-21 00:36:55 +000011667static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011668s390_irgen_SQXBR(UChar r1, UChar r2)
11669{
11670 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011671 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011672
floriandb4fcaa2012-09-05 19:54:08 +000011673 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11674 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011675 put_fpr_pair(r1, mkexpr(result));
11676
11677 return "sqxbr";
11678}
11679
florian55085f82012-11-21 00:36:55 +000011680static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011681s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11682{
11683 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011684 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011685
11686 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011687 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011688
11689 return "sqeb";
11690}
11691
florian55085f82012-11-21 00:36:55 +000011692static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011693s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11694{
11695 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011696 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011697
11698 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011699 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011700
11701 return "sqdb";
11702}
11703
florian55085f82012-11-21 00:36:55 +000011704static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011705s390_irgen_SXBR(UChar r1, UChar r2)
11706{
11707 IRTemp op1 = newTemp(Ity_F128);
11708 IRTemp op2 = newTemp(Ity_F128);
11709 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011710 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011711
11712 assign(op1, get_fpr_pair(r1));
11713 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011714 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011715 mkexpr(op2)));
11716 put_fpr_pair(r1, mkexpr(result));
11717 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11718
11719 return "sxbr";
11720}
11721
florian55085f82012-11-21 00:36:55 +000011722static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011723s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11724{
11725 IRTemp value = newTemp(Ity_F32);
11726
11727 assign(value, get_fpr_w0(r1));
11728
11729 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11730
11731 return "tceb";
11732}
11733
florian55085f82012-11-21 00:36:55 +000011734static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011735s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11736{
11737 IRTemp value = newTemp(Ity_F64);
11738
11739 assign(value, get_fpr_dw0(r1));
11740
11741 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11742
11743 return "tcdb";
11744}
11745
florian55085f82012-11-21 00:36:55 +000011746static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011747s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11748{
11749 IRTemp value = newTemp(Ity_F128);
11750
11751 assign(value, get_fpr_pair(r1));
11752
11753 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11754
11755 return "tcxb";
11756}
11757
florian55085f82012-11-21 00:36:55 +000011758static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011759s390_irgen_LCDFR(UChar r1, UChar r2)
11760{
11761 IRTemp result = newTemp(Ity_F64);
11762
11763 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
11764 put_fpr_dw0(r1, mkexpr(result));
11765
11766 return "lcdfr";
11767}
11768
florian55085f82012-11-21 00:36:55 +000011769static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011770s390_irgen_LNDFR(UChar r1, UChar r2)
11771{
11772 IRTemp result = newTemp(Ity_F64);
11773
11774 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11775 put_fpr_dw0(r1, mkexpr(result));
11776
11777 return "lndfr";
11778}
11779
florian55085f82012-11-21 00:36:55 +000011780static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011781s390_irgen_LPDFR(UChar r1, UChar r2)
11782{
11783 IRTemp result = newTemp(Ity_F64);
11784
11785 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11786 put_fpr_dw0(r1, mkexpr(result));
11787
11788 return "lpdfr";
11789}
11790
florian55085f82012-11-21 00:36:55 +000011791static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011792s390_irgen_LDGR(UChar r1, UChar r2)
11793{
11794 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
11795
11796 return "ldgr";
11797}
11798
florian55085f82012-11-21 00:36:55 +000011799static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011800s390_irgen_LGDR(UChar r1, UChar r2)
11801{
11802 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
11803
11804 return "lgdr";
11805}
11806
11807
florian55085f82012-11-21 00:36:55 +000011808static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011809s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
11810{
11811 IRTemp sign = newTemp(Ity_I64);
11812 IRTemp value = newTemp(Ity_I64);
11813
11814 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
11815 mkU64(1ULL << 63)));
11816 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
11817 mkU64((1ULL << 63) - 1)));
11818 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
11819 mkexpr(sign))));
11820
11821 return "cpsdr";
11822}
11823
11824
sewardj2019a972011-03-07 16:04:07 +000011825static IRExpr *
11826s390_call_cvb(IRExpr *in)
11827{
11828 IRExpr **args, *call;
11829
11830 args = mkIRExprVec_1(in);
11831 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
11832 "s390_do_cvb", &s390_do_cvb, args);
11833
11834 /* Nothing is excluded from definedness checking. */
11835 call->Iex.CCall.cee->mcx_mask = 0;
11836
11837 return call;
11838}
11839
florian55085f82012-11-21 00:36:55 +000011840static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011841s390_irgen_CVB(UChar r1, IRTemp op2addr)
11842{
11843 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11844
11845 return "cvb";
11846}
11847
florian55085f82012-11-21 00:36:55 +000011848static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011849s390_irgen_CVBY(UChar r1, IRTemp op2addr)
11850{
11851 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
11852
11853 return "cvby";
11854}
11855
11856
sewardj2019a972011-03-07 16:04:07 +000011857static IRExpr *
11858s390_call_cvd(IRExpr *in)
11859{
11860 IRExpr **args, *call;
11861
11862 args = mkIRExprVec_1(in);
11863 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
11864 "s390_do_cvd", &s390_do_cvd, args);
11865
11866 /* Nothing is excluded from definedness checking. */
11867 call->Iex.CCall.cee->mcx_mask = 0;
11868
11869 return call;
11870}
11871
florian55085f82012-11-21 00:36:55 +000011872static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011873s390_irgen_CVD(UChar r1, IRTemp op2addr)
11874{
florian11b8ee82012-08-06 13:35:33 +000011875 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000011876
11877 return "cvd";
11878}
11879
florian55085f82012-11-21 00:36:55 +000011880static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011881s390_irgen_CVDY(UChar r1, IRTemp op2addr)
11882{
11883 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
11884
11885 return "cvdy";
11886}
11887
florian55085f82012-11-21 00:36:55 +000011888static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011889s390_irgen_FLOGR(UChar r1, UChar r2)
11890{
11891 IRTemp input = newTemp(Ity_I64);
11892 IRTemp not_zero = newTemp(Ity_I64);
11893 IRTemp tmpnum = newTemp(Ity_I64);
11894 IRTemp num = newTemp(Ity_I64);
11895 IRTemp shift_amount = newTemp(Ity_I8);
11896
11897 /* We use the "count leading zeroes" operator because the number of
11898 leading zeroes is identical with the bit position of the first '1' bit.
11899 However, that operator does not work when the input value is zero.
11900 Therefore, we set the LSB of the input value to 1 and use Clz64 on
11901 the modified value. If input == 0, then the result is 64. Otherwise,
11902 the result of Clz64 is what we want. */
11903
11904 assign(input, get_gpr_dw0(r2));
11905 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
11906 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
11907
11908 /* num = (input == 0) ? 64 : tmpnum */
11909 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
11910 /* == 0 */ mkU64(64),
11911 /* != 0 */ mkexpr(tmpnum)));
11912
11913 put_gpr_dw0(r1, mkexpr(num));
11914
11915 /* Set the leftmost '1' bit of the input value to zero. The general scheme
11916 is to first shift the input value by NUM + 1 bits to the left which
11917 causes the leftmost '1' bit to disappear. Then we shift logically to
11918 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
11919 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
11920 the width of the value-to-be-shifted, we need to special case
11921 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
11922 For both such INPUT values the result will be 0. */
11923
11924 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
11925 mkU64(1))));
11926
11927 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000011928 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
11929 /* == 0 || == 1*/ mkU64(0),
11930 /* otherwise */
11931 binop(Iop_Shr64,
11932 binop(Iop_Shl64, mkexpr(input),
11933 mkexpr(shift_amount)),
11934 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000011935
11936 /* Compare the original value as an unsigned integer with 0. */
11937 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
11938 mktemp(Ity_I64, mkU64(0)), False);
11939
11940 return "flogr";
11941}
11942
florian55085f82012-11-21 00:36:55 +000011943static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011944s390_irgen_STCK(IRTemp op2addr)
11945{
11946 IRDirty *d;
11947 IRTemp cc = newTemp(Ity_I64);
11948
11949 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
11950 &s390x_dirtyhelper_STCK,
11951 mkIRExprVec_1(mkexpr(op2addr)));
11952 d->mFx = Ifx_Write;
11953 d->mAddr = mkexpr(op2addr);
11954 d->mSize = 8;
11955 stmt(IRStmt_Dirty(d));
11956 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11957 mkexpr(cc), mkU64(0), mkU64(0));
11958 return "stck";
11959}
11960
florian55085f82012-11-21 00:36:55 +000011961static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011962s390_irgen_STCKF(IRTemp op2addr)
11963{
florianc5c669b2012-08-26 14:32:28 +000011964 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000011965 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000011966 } else {
11967 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000011968
florianc5c669b2012-08-26 14:32:28 +000011969 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
11970 &s390x_dirtyhelper_STCKF,
11971 mkIRExprVec_1(mkexpr(op2addr)));
11972 d->mFx = Ifx_Write;
11973 d->mAddr = mkexpr(op2addr);
11974 d->mSize = 8;
11975 stmt(IRStmt_Dirty(d));
11976 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11977 mkexpr(cc), mkU64(0), mkU64(0));
11978 }
sewardj1e5fea62011-05-17 16:18:36 +000011979 return "stckf";
11980}
11981
florian55085f82012-11-21 00:36:55 +000011982static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000011983s390_irgen_STCKE(IRTemp op2addr)
11984{
11985 IRDirty *d;
11986 IRTemp cc = newTemp(Ity_I64);
11987
11988 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
11989 &s390x_dirtyhelper_STCKE,
11990 mkIRExprVec_1(mkexpr(op2addr)));
11991 d->mFx = Ifx_Write;
11992 d->mAddr = mkexpr(op2addr);
11993 d->mSize = 16;
11994 stmt(IRStmt_Dirty(d));
11995 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
11996 mkexpr(cc), mkU64(0), mkU64(0));
11997 return "stcke";
11998}
11999
florian55085f82012-11-21 00:36:55 +000012000static const HChar *
florian933065d2011-07-11 01:48:02 +000012001s390_irgen_STFLE(IRTemp op2addr)
12002{
florian4e0083e2012-08-26 03:41:56 +000012003 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012004 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012005 return "stfle";
12006 }
12007
florian933065d2011-07-11 01:48:02 +000012008 IRDirty *d;
12009 IRTemp cc = newTemp(Ity_I64);
12010
12011 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12012 &s390x_dirtyhelper_STFLE,
12013 mkIRExprVec_1(mkexpr(op2addr)));
12014
12015 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
12016
sewardjc9069f22012-06-01 16:09:50 +000012017 d->nFxState = 1;
12018 vex_bzero(&d->fxState, sizeof(d->fxState));
12019
florian933065d2011-07-11 01:48:02 +000012020 d->fxState[0].fx = Ifx_Modify; /* read then write */
12021 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12022 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012023
12024 d->mAddr = mkexpr(op2addr);
12025 /* Pretend all double words are written */
12026 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12027 d->mFx = Ifx_Write;
12028
12029 stmt(IRStmt_Dirty(d));
12030
12031 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12032
12033 return "stfle";
12034}
12035
florian55085f82012-11-21 00:36:55 +000012036static const HChar *
floriana4384a32011-08-11 16:58:45 +000012037s390_irgen_CKSM(UChar r1,UChar r2)
12038{
12039 IRTemp addr = newTemp(Ity_I64);
12040 IRTemp op = newTemp(Ity_I32);
12041 IRTemp len = newTemp(Ity_I64);
12042 IRTemp oldval = newTemp(Ity_I32);
12043 IRTemp mask = newTemp(Ity_I32);
12044 IRTemp newop = newTemp(Ity_I32);
12045 IRTemp result = newTemp(Ity_I32);
12046 IRTemp result1 = newTemp(Ity_I32);
12047 IRTemp inc = newTemp(Ity_I64);
12048
12049 assign(oldval, get_gpr_w1(r1));
12050 assign(addr, get_gpr_dw0(r2));
12051 assign(len, get_gpr_dw0(r2+1));
12052
12053 /* Condition code is always zero. */
12054 s390_cc_set(0);
12055
12056 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012057 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012058
12059 /* Assiging the increment variable to adjust address and length
12060 later on. */
12061 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12062 mkexpr(len), mkU64(4)));
12063
12064 /* If length < 4 the final 4-byte 2nd operand value is computed by
12065 appending the remaining bytes to the right with 0. This is done
12066 by AND'ing the 4 bytes loaded from memory with an appropriate
12067 mask. If length >= 4, that mask is simply 0xffffffff. */
12068
12069 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12070 /* Mask computation when len < 4:
12071 0xffffffff << (32 - (len % 4)*8) */
12072 binop(Iop_Shl32, mkU32(0xffffffff),
12073 unop(Iop_32to8,
12074 binop(Iop_Sub32, mkU32(32),
12075 binop(Iop_Shl32,
12076 unop(Iop_64to32,
12077 binop(Iop_And64,
12078 mkexpr(len), mkU64(3))),
12079 mkU8(3))))),
12080 mkU32(0xffffffff)));
12081
12082 assign(op, load(Ity_I32, mkexpr(addr)));
12083 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12084 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12085
12086 /* Checking for carry */
12087 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12088 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12089 mkexpr(result)));
12090
12091 put_gpr_w1(r1, mkexpr(result1));
12092 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12093 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12094
florian6820ba52012-07-26 02:01:50 +000012095 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012096
12097 return "cksm";
12098}
12099
florian55085f82012-11-21 00:36:55 +000012100static const HChar *
florian9af37692012-01-15 21:01:16 +000012101s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12102{
12103 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12104 src_addr = newTemp(Ity_I64);
12105 des_addr = newTemp(Ity_I64);
12106 tab_addr = newTemp(Ity_I64);
12107 test_byte = newTemp(Ity_I8);
12108 src_len = newTemp(Ity_I64);
12109
12110 assign(src_addr, get_gpr_dw0(r2));
12111 assign(des_addr, get_gpr_dw0(r1));
12112 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012113 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012114 assign(test_byte, get_gpr_b7(0));
12115
12116 IRTemp op = newTemp(Ity_I8);
12117 IRTemp op1 = newTemp(Ity_I8);
12118 IRTemp result = newTemp(Ity_I64);
12119
12120 /* End of source string? We're done; proceed to next insn */
12121 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012122 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012123
12124 /* Load character from source string, index translation table and
12125 store translated character in op1. */
12126 assign(op, load(Ity_I8, mkexpr(src_addr)));
12127
12128 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12129 mkexpr(tab_addr)));
12130 assign(op1, load(Ity_I8, mkexpr(result)));
12131
12132 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12133 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012134 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000012135 }
12136 store(get_gpr_dw0(r1), mkexpr(op1));
12137
12138 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12139 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12140 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12141
florian6820ba52012-07-26 02:01:50 +000012142 iterate();
florian9af37692012-01-15 21:01:16 +000012143
12144 return "troo";
12145}
12146
florian55085f82012-11-21 00:36:55 +000012147static const HChar *
florian730448f2012-02-04 17:07:07 +000012148s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
12149{
12150 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12151 src_addr = newTemp(Ity_I64);
12152 des_addr = newTemp(Ity_I64);
12153 tab_addr = newTemp(Ity_I64);
12154 test_byte = newTemp(Ity_I8);
12155 src_len = newTemp(Ity_I64);
12156
12157 assign(src_addr, get_gpr_dw0(r2));
12158 assign(des_addr, get_gpr_dw0(r1));
12159 assign(tab_addr, get_gpr_dw0(1));
12160 assign(src_len, get_gpr_dw0(r1+1));
12161 assign(test_byte, get_gpr_b7(0));
12162
12163 IRTemp op = newTemp(Ity_I16);
12164 IRTemp op1 = newTemp(Ity_I8);
12165 IRTemp result = newTemp(Ity_I64);
12166
12167 /* End of source string? We're done; proceed to next insn */
12168 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012169 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012170
12171 /* Load character from source string, index translation table and
12172 store translated character in op1. */
12173 assign(op, load(Ity_I16, mkexpr(src_addr)));
12174
12175 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12176 mkexpr(tab_addr)));
12177
12178 assign(op1, load(Ity_I8, mkexpr(result)));
12179
12180 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12181 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012182 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012183 }
12184 store(get_gpr_dw0(r1), mkexpr(op1));
12185
12186 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12187 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12188 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12189
florian6820ba52012-07-26 02:01:50 +000012190 iterate();
florian730448f2012-02-04 17:07:07 +000012191
12192 return "trto";
12193}
12194
florian55085f82012-11-21 00:36:55 +000012195static const HChar *
florian730448f2012-02-04 17:07:07 +000012196s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
12197{
12198 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12199 src_addr = newTemp(Ity_I64);
12200 des_addr = newTemp(Ity_I64);
12201 tab_addr = newTemp(Ity_I64);
12202 test_byte = newTemp(Ity_I16);
12203 src_len = newTemp(Ity_I64);
12204
12205 assign(src_addr, get_gpr_dw0(r2));
12206 assign(des_addr, get_gpr_dw0(r1));
12207 assign(tab_addr, get_gpr_dw0(1));
12208 assign(src_len, get_gpr_dw0(r1+1));
12209 assign(test_byte, get_gpr_hw3(0));
12210
12211 IRTemp op = newTemp(Ity_I8);
12212 IRTemp op1 = newTemp(Ity_I16);
12213 IRTemp result = newTemp(Ity_I64);
12214
12215 /* End of source string? We're done; proceed to next insn */
12216 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012217 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012218
12219 /* Load character from source string, index translation table and
12220 store translated character in op1. */
12221 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12222
12223 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12224 mkexpr(tab_addr)));
12225 assign(op1, load(Ity_I16, mkexpr(result)));
12226
12227 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12228 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012229 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012230 }
12231 store(get_gpr_dw0(r1), mkexpr(op1));
12232
12233 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12234 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12235 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12236
florian6820ba52012-07-26 02:01:50 +000012237 iterate();
florian730448f2012-02-04 17:07:07 +000012238
12239 return "trot";
12240}
12241
florian55085f82012-11-21 00:36:55 +000012242static const HChar *
florian730448f2012-02-04 17:07:07 +000012243s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12244{
12245 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12246 src_addr = newTemp(Ity_I64);
12247 des_addr = newTemp(Ity_I64);
12248 tab_addr = newTemp(Ity_I64);
12249 test_byte = newTemp(Ity_I16);
12250 src_len = newTemp(Ity_I64);
12251
12252 assign(src_addr, get_gpr_dw0(r2));
12253 assign(des_addr, get_gpr_dw0(r1));
12254 assign(tab_addr, get_gpr_dw0(1));
12255 assign(src_len, get_gpr_dw0(r1+1));
12256 assign(test_byte, get_gpr_hw3(0));
12257
12258 IRTemp op = newTemp(Ity_I16);
12259 IRTemp op1 = newTemp(Ity_I16);
12260 IRTemp result = newTemp(Ity_I64);
12261
12262 /* End of source string? We're done; proceed to next insn */
12263 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012264 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012265
12266 /* Load character from source string, index translation table and
12267 store translated character in op1. */
12268 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12269
12270 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12271 mkexpr(tab_addr)));
12272 assign(op1, load(Ity_I16, mkexpr(result)));
12273
12274 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12275 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012276 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012277 }
12278
12279 store(get_gpr_dw0(r1), mkexpr(op1));
12280
12281 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12282 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12283 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12284
florian6820ba52012-07-26 02:01:50 +000012285 iterate();
florian730448f2012-02-04 17:07:07 +000012286
12287 return "trtt";
12288}
12289
florian55085f82012-11-21 00:36:55 +000012290static const HChar *
florian730448f2012-02-04 17:07:07 +000012291s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
12292{
florianf87d4fb2012-05-05 02:55:24 +000012293 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000012294
florianf87d4fb2012-05-05 02:55:24 +000012295 assign(len, mkU64(length));
12296 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000012297
12298 return "tr";
12299}
12300
florian55085f82012-11-21 00:36:55 +000012301static const HChar *
florian730448f2012-02-04 17:07:07 +000012302s390_irgen_TRE(UChar r1,UChar r2)
12303{
12304 IRTemp src_addr, tab_addr, src_len, test_byte;
12305 src_addr = newTemp(Ity_I64);
12306 tab_addr = newTemp(Ity_I64);
12307 src_len = newTemp(Ity_I64);
12308 test_byte = newTemp(Ity_I8);
12309
12310 assign(src_addr, get_gpr_dw0(r1));
12311 assign(src_len, get_gpr_dw0(r1+1));
12312 assign(tab_addr, get_gpr_dw0(r2));
12313 assign(test_byte, get_gpr_b7(0));
12314
12315 IRTemp op = newTemp(Ity_I8);
12316 IRTemp op1 = newTemp(Ity_I8);
12317 IRTemp result = newTemp(Ity_I64);
12318
12319 /* End of source string? We're done; proceed to next insn */
12320 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012321 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012322
12323 /* Load character from source string and compare with test byte */
12324 assign(op, load(Ity_I8, mkexpr(src_addr)));
12325
12326 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012327 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012328
12329 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12330 mkexpr(tab_addr)));
12331
12332 assign(op1, load(Ity_I8, mkexpr(result)));
12333
12334 store(get_gpr_dw0(r1), mkexpr(op1));
12335 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12336 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12337
florian6820ba52012-07-26 02:01:50 +000012338 iterate();
florian730448f2012-02-04 17:07:07 +000012339
12340 return "tre";
12341}
12342
floriana0100c92012-07-20 00:06:35 +000012343static IRExpr *
12344s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
12345{
12346 IRExpr **args, *call;
12347 args = mkIRExprVec_2(srcval, low_surrogate);
12348 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12349 "s390_do_cu21", &s390_do_cu21, args);
12350
12351 /* Nothing is excluded from definedness checking. */
12352 call->Iex.CCall.cee->mcx_mask = 0;
12353
12354 return call;
12355}
12356
florian55085f82012-11-21 00:36:55 +000012357static const HChar *
floriana0100c92012-07-20 00:06:35 +000012358s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
12359{
12360 IRTemp addr1 = newTemp(Ity_I64);
12361 IRTemp addr2 = newTemp(Ity_I64);
12362 IRTemp len1 = newTemp(Ity_I64);
12363 IRTemp len2 = newTemp(Ity_I64);
12364
12365 assign(addr1, get_gpr_dw0(r1));
12366 assign(addr2, get_gpr_dw0(r2));
12367 assign(len1, get_gpr_dw0(r1 + 1));
12368 assign(len2, get_gpr_dw0(r2 + 1));
12369
12370 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12371 there are less than 2 bytes left, then the 2nd operand is exhausted
12372 and we're done here. cc = 0 */
12373 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012374 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000012375
12376 /* There are at least two bytes there. Read them. */
12377 IRTemp srcval = newTemp(Ity_I32);
12378 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12379
12380 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12381 inside the interval [0xd800 - 0xdbff] */
12382 IRTemp is_high_surrogate = newTemp(Ity_I32);
12383 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12384 mkU32(1), mkU32(0));
12385 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12386 mkU32(1), mkU32(0));
12387 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12388
12389 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12390 then the 2nd operand is exhausted and we're done here. cc = 0 */
12391 IRExpr *not_enough_bytes =
12392 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12393
florian6820ba52012-07-26 02:01:50 +000012394 next_insn_if(binop(Iop_CmpEQ32,
12395 binop(Iop_And32, mkexpr(is_high_surrogate),
12396 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000012397
12398 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12399 surrogate, read the next two bytes (low surrogate). */
12400 IRTemp low_surrogate = newTemp(Ity_I32);
12401 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12402
12403 assign(low_surrogate,
12404 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12405 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12406 mkU32(0))); // any value is fine; it will not be used
12407
12408 /* Call the helper */
12409 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012410 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
12411 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000012412
12413 /* Before we can test whether the 1st operand is exhausted we need to
12414 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12415 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12416 IRExpr *invalid_low_surrogate =
12417 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12418
12419 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012420 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000012421 }
12422
12423 /* Now test whether the 1st operand is exhausted */
12424 IRTemp num_bytes = newTemp(Ity_I64);
12425 assign(num_bytes, binop(Iop_And64,
12426 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12427 mkU64(0xff)));
12428 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012429 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000012430
12431 /* Extract the bytes to be stored at addr1 */
12432 IRTemp data = newTemp(Ity_I64);
12433 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12434
12435 /* To store the bytes construct 4 dirty helper calls. The helper calls
12436 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12437 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012438 UInt i;
floriana0100c92012-07-20 00:06:35 +000012439 for (i = 1; i <= 4; ++i) {
12440 IRDirty *d;
12441
12442 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12443 &s390x_dirtyhelper_CUxy,
12444 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12445 mkexpr(num_bytes)));
12446 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12447 d->mFx = Ifx_Write;
12448 d->mAddr = mkexpr(addr1);
12449 d->mSize = i;
12450 stmt(IRStmt_Dirty(d));
12451 }
12452
12453 /* Update source address and length */
12454 IRTemp num_src_bytes = newTemp(Ity_I64);
12455 assign(num_src_bytes,
12456 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12457 mkU64(4), mkU64(2)));
12458 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12459 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12460
12461 /* Update destination address and length */
12462 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12463 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12464
florian6820ba52012-07-26 02:01:50 +000012465 iterate();
floriana0100c92012-07-20 00:06:35 +000012466
12467 return "cu21";
12468}
12469
florian2a415a12012-07-21 17:41:36 +000012470static IRExpr *
12471s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
12472{
12473 IRExpr **args, *call;
12474 args = mkIRExprVec_2(srcval, low_surrogate);
12475 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12476 "s390_do_cu24", &s390_do_cu24, args);
12477
12478 /* Nothing is excluded from definedness checking. */
12479 call->Iex.CCall.cee->mcx_mask = 0;
12480
12481 return call;
12482}
12483
florian55085f82012-11-21 00:36:55 +000012484static const HChar *
florian2a415a12012-07-21 17:41:36 +000012485s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
12486{
12487 IRTemp addr1 = newTemp(Ity_I64);
12488 IRTemp addr2 = newTemp(Ity_I64);
12489 IRTemp len1 = newTemp(Ity_I64);
12490 IRTemp len2 = newTemp(Ity_I64);
12491
12492 assign(addr1, get_gpr_dw0(r1));
12493 assign(addr2, get_gpr_dw0(r2));
12494 assign(len1, get_gpr_dw0(r1 + 1));
12495 assign(len2, get_gpr_dw0(r2 + 1));
12496
12497 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12498 there are less than 2 bytes left, then the 2nd operand is exhausted
12499 and we're done here. cc = 0 */
12500 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012501 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000012502
12503 /* There are at least two bytes there. Read them. */
12504 IRTemp srcval = newTemp(Ity_I32);
12505 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12506
12507 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12508 inside the interval [0xd800 - 0xdbff] */
12509 IRTemp is_high_surrogate = newTemp(Ity_I32);
12510 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12511 mkU32(1), mkU32(0));
12512 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12513 mkU32(1), mkU32(0));
12514 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12515
12516 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12517 then the 2nd operand is exhausted and we're done here. cc = 0 */
12518 IRExpr *not_enough_bytes =
12519 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12520
florian6820ba52012-07-26 02:01:50 +000012521 next_insn_if(binop(Iop_CmpEQ32,
12522 binop(Iop_And32, mkexpr(is_high_surrogate),
12523 not_enough_bytes),
12524 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012525
12526 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12527 surrogate, read the next two bytes (low surrogate). */
12528 IRTemp low_surrogate = newTemp(Ity_I32);
12529 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12530
12531 assign(low_surrogate,
12532 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12533 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12534 mkU32(0))); // any value is fine; it will not be used
12535
12536 /* Call the helper */
12537 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012538 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12539 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012540
12541 /* Before we can test whether the 1st operand is exhausted we need to
12542 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12543 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12544 IRExpr *invalid_low_surrogate =
12545 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12546
12547 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012548 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012549 }
12550
12551 /* Now test whether the 1st operand is exhausted */
12552 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012553 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012554
12555 /* Extract the bytes to be stored at addr1 */
12556 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12557
12558 store(mkexpr(addr1), data);
12559
12560 /* Update source address and length */
12561 IRTemp num_src_bytes = newTemp(Ity_I64);
12562 assign(num_src_bytes,
12563 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12564 mkU64(4), mkU64(2)));
12565 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12566 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12567
12568 /* Update destination address and length */
12569 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12570 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12571
florian6820ba52012-07-26 02:01:50 +000012572 iterate();
florian2a415a12012-07-21 17:41:36 +000012573
12574 return "cu24";
12575}
floriana4384a32011-08-11 16:58:45 +000012576
florian956194b2012-07-28 22:18:32 +000012577static IRExpr *
12578s390_call_cu42(IRExpr *srcval)
12579{
12580 IRExpr **args, *call;
12581 args = mkIRExprVec_1(srcval);
12582 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12583 "s390_do_cu42", &s390_do_cu42, args);
12584
12585 /* Nothing is excluded from definedness checking. */
12586 call->Iex.CCall.cee->mcx_mask = 0;
12587
12588 return call;
12589}
12590
florian55085f82012-11-21 00:36:55 +000012591static const HChar *
florian956194b2012-07-28 22:18:32 +000012592s390_irgen_CU42(UChar r1, UChar r2)
12593{
12594 IRTemp addr1 = newTemp(Ity_I64);
12595 IRTemp addr2 = newTemp(Ity_I64);
12596 IRTemp len1 = newTemp(Ity_I64);
12597 IRTemp len2 = newTemp(Ity_I64);
12598
12599 assign(addr1, get_gpr_dw0(r1));
12600 assign(addr2, get_gpr_dw0(r2));
12601 assign(len1, get_gpr_dw0(r1 + 1));
12602 assign(len2, get_gpr_dw0(r2 + 1));
12603
12604 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12605 there are less than 4 bytes left, then the 2nd operand is exhausted
12606 and we're done here. cc = 0 */
12607 s390_cc_set(0);
12608 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12609
12610 /* Read the 2nd operand. */
12611 IRTemp srcval = newTemp(Ity_I32);
12612 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12613
12614 /* Call the helper */
12615 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012616 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012617
12618 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12619 cc=2 outranks cc=1 (1st operand exhausted) */
12620 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12621
12622 s390_cc_set(2);
12623 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12624
12625 /* Now test whether the 1st operand is exhausted */
12626 IRTemp num_bytes = newTemp(Ity_I64);
12627 assign(num_bytes, binop(Iop_And64,
12628 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12629 mkU64(0xff)));
12630 s390_cc_set(1);
12631 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12632
12633 /* Extract the bytes to be stored at addr1 */
12634 IRTemp data = newTemp(Ity_I64);
12635 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12636
12637 /* To store the bytes construct 2 dirty helper calls. The helper calls
12638 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12639 that only one of them will be called at runtime. */
12640
12641 Int i;
12642 for (i = 2; i <= 4; ++i) {
12643 IRDirty *d;
12644
12645 if (i == 3) continue; // skip this one
12646
12647 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12648 &s390x_dirtyhelper_CUxy,
12649 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12650 mkexpr(num_bytes)));
12651 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12652 d->mFx = Ifx_Write;
12653 d->mAddr = mkexpr(addr1);
12654 d->mSize = i;
12655 stmt(IRStmt_Dirty(d));
12656 }
12657
12658 /* Update source address and length */
12659 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12660 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12661
12662 /* Update destination address and length */
12663 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12664 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12665
12666 iterate();
12667
12668 return "cu42";
12669}
12670
florian6d9b9b22012-08-03 18:35:39 +000012671static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012672s390_call_cu41(IRExpr *srcval)
12673{
12674 IRExpr **args, *call;
12675 args = mkIRExprVec_1(srcval);
12676 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12677 "s390_do_cu41", &s390_do_cu41, args);
12678
12679 /* Nothing is excluded from definedness checking. */
12680 call->Iex.CCall.cee->mcx_mask = 0;
12681
12682 return call;
12683}
12684
florian55085f82012-11-21 00:36:55 +000012685static const HChar *
florianaf2194f2012-08-06 00:07:54 +000012686s390_irgen_CU41(UChar r1, UChar r2)
12687{
12688 IRTemp addr1 = newTemp(Ity_I64);
12689 IRTemp addr2 = newTemp(Ity_I64);
12690 IRTemp len1 = newTemp(Ity_I64);
12691 IRTemp len2 = newTemp(Ity_I64);
12692
12693 assign(addr1, get_gpr_dw0(r1));
12694 assign(addr2, get_gpr_dw0(r2));
12695 assign(len1, get_gpr_dw0(r1 + 1));
12696 assign(len2, get_gpr_dw0(r2 + 1));
12697
12698 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12699 there are less than 4 bytes left, then the 2nd operand is exhausted
12700 and we're done here. cc = 0 */
12701 s390_cc_set(0);
12702 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12703
12704 /* Read the 2nd operand. */
12705 IRTemp srcval = newTemp(Ity_I32);
12706 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12707
12708 /* Call the helper */
12709 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012710 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012711
12712 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12713 cc=2 outranks cc=1 (1st operand exhausted) */
12714 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12715
12716 s390_cc_set(2);
12717 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12718
12719 /* Now test whether the 1st operand is exhausted */
12720 IRTemp num_bytes = newTemp(Ity_I64);
12721 assign(num_bytes, binop(Iop_And64,
12722 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12723 mkU64(0xff)));
12724 s390_cc_set(1);
12725 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12726
12727 /* Extract the bytes to be stored at addr1 */
12728 IRTemp data = newTemp(Ity_I64);
12729 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12730
12731 /* To store the bytes construct 4 dirty helper calls. The helper calls
12732 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12733 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012734 UInt i;
florianaf2194f2012-08-06 00:07:54 +000012735 for (i = 1; i <= 4; ++i) {
12736 IRDirty *d;
12737
12738 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12739 &s390x_dirtyhelper_CUxy,
12740 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12741 mkexpr(num_bytes)));
12742 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12743 d->mFx = Ifx_Write;
12744 d->mAddr = mkexpr(addr1);
12745 d->mSize = i;
12746 stmt(IRStmt_Dirty(d));
12747 }
12748
12749 /* Update source address and length */
12750 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12751 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12752
12753 /* Update destination address and length */
12754 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12755 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12756
12757 iterate();
12758
12759 return "cu41";
12760}
12761
12762static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000012763s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000012764{
12765 IRExpr **args, *call;
12766 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000012767 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
12768 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000012769
12770 /* Nothing is excluded from definedness checking. */
12771 call->Iex.CCall.cee->mcx_mask = 0;
12772
12773 return call;
12774}
12775
12776static IRExpr *
12777s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12778 IRExpr *byte4, IRExpr *stuff)
12779{
12780 IRExpr **args, *call;
12781 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12782 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12783 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
12784
12785 /* Nothing is excluded from definedness checking. */
12786 call->Iex.CCall.cee->mcx_mask = 0;
12787
12788 return call;
12789}
12790
florian3f8a96a2012-08-05 02:59:55 +000012791static IRExpr *
12792s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
12793 IRExpr *byte4, IRExpr *stuff)
12794{
12795 IRExpr **args, *call;
12796 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
12797 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12798 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
12799
12800 /* Nothing is excluded from definedness checking. */
12801 call->Iex.CCall.cee->mcx_mask = 0;
12802
12803 return call;
12804}
12805
12806static void
12807s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000012808{
12809 IRTemp addr1 = newTemp(Ity_I64);
12810 IRTemp addr2 = newTemp(Ity_I64);
12811 IRTemp len1 = newTemp(Ity_I64);
12812 IRTemp len2 = newTemp(Ity_I64);
12813
12814 assign(addr1, get_gpr_dw0(r1));
12815 assign(addr2, get_gpr_dw0(r2));
12816 assign(len1, get_gpr_dw0(r1 + 1));
12817 assign(len2, get_gpr_dw0(r2 + 1));
12818
12819 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
12820
12821 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
12822 there is less than 1 byte left, then the 2nd operand is exhausted
12823 and we're done here. cc = 0 */
12824 s390_cc_set(0);
12825 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
12826
12827 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000012828 IRTemp byte1 = newTemp(Ity_I64);
12829 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000012830
12831 /* Call the helper to get number of bytes and invalid byte indicator */
12832 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012833 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000012834 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000012835
12836 /* Check for invalid 1st byte */
12837 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
12838 s390_cc_set(2);
12839 next_insn_if(is_invalid);
12840
12841 /* How many bytes do we have to read? */
12842 IRTemp num_src_bytes = newTemp(Ity_I64);
12843 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
12844
12845 /* Now test whether the 2nd operand is exhausted */
12846 s390_cc_set(0);
12847 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
12848
12849 /* Read the remaining bytes */
12850 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
12851
12852 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
12853 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000012854 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012855 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
12856 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000012857 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012858 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
12859 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000012860 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000012861
12862 /* Call the helper to get the converted value and invalid byte indicator.
12863 We can pass at most 5 arguments; therefore some encoding is needed
12864 here */
12865 IRExpr *stuff = binop(Iop_Or64,
12866 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
12867 mkU64(extended_checking));
12868 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000012869
12870 if (is_cu12) {
12871 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
12872 byte4, stuff));
12873 } else {
12874 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
12875 byte4, stuff));
12876 }
florian6d9b9b22012-08-03 18:35:39 +000012877
12878 /* Check for invalid character */
12879 s390_cc_set(2);
12880 is_invalid = unop(Iop_64to1, mkexpr(retval2));
12881 next_insn_if(is_invalid);
12882
12883 /* Now test whether the 1st operand is exhausted */
12884 IRTemp num_bytes = newTemp(Ity_I64);
12885 assign(num_bytes, binop(Iop_And64,
12886 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
12887 mkU64(0xff)));
12888 s390_cc_set(1);
12889 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12890
12891 /* Extract the bytes to be stored at addr1 */
12892 IRTemp data = newTemp(Ity_I64);
12893 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
12894
florian3f8a96a2012-08-05 02:59:55 +000012895 if (is_cu12) {
12896 /* To store the bytes construct 2 dirty helper calls. The helper calls
12897 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12898 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000012899
florian3f8a96a2012-08-05 02:59:55 +000012900 Int i;
12901 for (i = 2; i <= 4; ++i) {
12902 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000012903
florian3f8a96a2012-08-05 02:59:55 +000012904 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000012905
florian3f8a96a2012-08-05 02:59:55 +000012906 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12907 &s390x_dirtyhelper_CUxy,
12908 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12909 mkexpr(num_bytes)));
12910 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12911 d->mFx = Ifx_Write;
12912 d->mAddr = mkexpr(addr1);
12913 d->mSize = i;
12914 stmt(IRStmt_Dirty(d));
12915 }
12916 } else {
12917 // cu14
12918 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000012919 }
12920
12921 /* Update source address and length */
12922 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12923 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12924
12925 /* Update destination address and length */
12926 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12927 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12928
12929 iterate();
florian3f8a96a2012-08-05 02:59:55 +000012930}
12931
florian55085f82012-11-21 00:36:55 +000012932static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012933s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
12934{
12935 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000012936
12937 return "cu12";
12938}
12939
florian55085f82012-11-21 00:36:55 +000012940static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000012941s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
12942{
12943 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
12944
12945 return "cu14";
12946}
12947
florian8c88cb62012-08-26 18:58:13 +000012948static IRExpr *
12949s390_call_ecag(IRExpr *op2addr)
12950{
12951 IRExpr **args, *call;
12952
12953 args = mkIRExprVec_1(op2addr);
12954 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12955 "s390_do_ecag", &s390_do_ecag, args);
12956
12957 /* Nothing is excluded from definedness checking. */
12958 call->Iex.CCall.cee->mcx_mask = 0;
12959
12960 return call;
12961}
12962
florian55085f82012-11-21 00:36:55 +000012963static const HChar *
floriand2129202012-09-01 20:01:39 +000012964s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000012965{
12966 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000012967 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000012968 } else {
12969 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
12970 }
12971
12972 return "ecag";
12973}
12974
12975
florianb7def222012-12-04 04:45:32 +000012976/* New insns are added here.
12977 If an insn is contingent on a facility being installed also
12978 check whether the list of supported facilities in function
12979 s390x_dirtyhelper_STFLE needs updating */
12980
sewardj2019a972011-03-07 16:04:07 +000012981/*------------------------------------------------------------*/
12982/*--- Build IR for special instructions ---*/
12983/*------------------------------------------------------------*/
12984
florianb4df7682011-07-05 02:09:01 +000012985static void
sewardj2019a972011-03-07 16:04:07 +000012986s390_irgen_client_request(void)
12987{
12988 if (0)
12989 vex_printf("%%R3 = client_request ( %%R2 )\n");
12990
florianf9e1ed72012-04-17 02:41:56 +000012991 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
12992 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000012993
florianf9e1ed72012-04-17 02:41:56 +000012994 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000012995 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000012996
12997 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000012998}
12999
florianb4df7682011-07-05 02:09:01 +000013000static void
sewardj2019a972011-03-07 16:04:07 +000013001s390_irgen_guest_NRADDR(void)
13002{
13003 if (0)
13004 vex_printf("%%R3 = guest_NRADDR\n");
13005
floriane88b3c92011-07-05 02:48:39 +000013006 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013007}
13008
florianb4df7682011-07-05 02:09:01 +000013009static void
sewardj2019a972011-03-07 16:04:07 +000013010s390_irgen_call_noredir(void)
13011{
florianf9e1ed72012-04-17 02:41:56 +000013012 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13013 + S390_SPECIAL_OP_SIZE;
13014
sewardj2019a972011-03-07 16:04:07 +000013015 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013016 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013017
13018 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013019 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013020
13021 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013022 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013023}
13024
13025/* Force proper alignment for the structures below. */
13026#pragma pack(1)
13027
13028
13029static s390_decode_t
13030s390_decode_2byte_and_irgen(UChar *bytes)
13031{
13032 typedef union {
13033 struct {
13034 unsigned int op : 16;
13035 } E;
13036 struct {
13037 unsigned int op : 8;
13038 unsigned int i : 8;
13039 } I;
13040 struct {
13041 unsigned int op : 8;
13042 unsigned int r1 : 4;
13043 unsigned int r2 : 4;
13044 } RR;
13045 } formats;
13046 union {
13047 formats fmt;
13048 UShort value;
13049 } ovl;
13050
13051 vassert(sizeof(formats) == 2);
13052
florianffbd84d2012-12-09 02:06:29 +000013053 ((UChar *)(&ovl.value))[0] = bytes[0];
13054 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013055
13056 switch (ovl.value & 0xffff) {
13057 case 0x0101: /* PR */ goto unimplemented;
13058 case 0x0102: /* UPT */ goto unimplemented;
13059 case 0x0104: /* PTFF */ goto unimplemented;
13060 case 0x0107: /* SCKPF */ goto unimplemented;
13061 case 0x010a: /* PFPO */ goto unimplemented;
13062 case 0x010b: /* TAM */ goto unimplemented;
13063 case 0x010c: /* SAM24 */ goto unimplemented;
13064 case 0x010d: /* SAM31 */ goto unimplemented;
13065 case 0x010e: /* SAM64 */ goto unimplemented;
13066 case 0x01ff: /* TRAP2 */ goto unimplemented;
13067 }
13068
13069 switch ((ovl.value & 0xff00) >> 8) {
13070 case 0x04: /* SPM */ goto unimplemented;
13071 case 0x05: /* BALR */ goto unimplemented;
13072 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13073 goto ok;
13074 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13075 goto ok;
13076 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13077 case 0x0b: /* BSM */ goto unimplemented;
13078 case 0x0c: /* BASSM */ goto unimplemented;
13079 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13080 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013081 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13082 goto ok;
13083 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13084 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013085 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13086 goto ok;
13087 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13088 goto ok;
13089 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13090 goto ok;
13091 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13092 goto ok;
13093 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13094 goto ok;
13095 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13096 goto ok;
13097 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13098 goto ok;
13099 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13100 goto ok;
13101 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13102 goto ok;
13103 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13104 goto ok;
13105 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13106 goto ok;
13107 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13108 goto ok;
13109 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13110 goto ok;
13111 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13112 goto ok;
13113 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13114 goto ok;
13115 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13116 goto ok;
13117 case 0x20: /* LPDR */ goto unimplemented;
13118 case 0x21: /* LNDR */ goto unimplemented;
13119 case 0x22: /* LTDR */ goto unimplemented;
13120 case 0x23: /* LCDR */ goto unimplemented;
13121 case 0x24: /* HDR */ goto unimplemented;
13122 case 0x25: /* LDXR */ goto unimplemented;
13123 case 0x26: /* MXR */ goto unimplemented;
13124 case 0x27: /* MXDR */ goto unimplemented;
13125 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13126 goto ok;
13127 case 0x29: /* CDR */ goto unimplemented;
13128 case 0x2a: /* ADR */ goto unimplemented;
13129 case 0x2b: /* SDR */ goto unimplemented;
13130 case 0x2c: /* MDR */ goto unimplemented;
13131 case 0x2d: /* DDR */ goto unimplemented;
13132 case 0x2e: /* AWR */ goto unimplemented;
13133 case 0x2f: /* SWR */ goto unimplemented;
13134 case 0x30: /* LPER */ goto unimplemented;
13135 case 0x31: /* LNER */ goto unimplemented;
13136 case 0x32: /* LTER */ goto unimplemented;
13137 case 0x33: /* LCER */ goto unimplemented;
13138 case 0x34: /* HER */ goto unimplemented;
13139 case 0x35: /* LEDR */ goto unimplemented;
13140 case 0x36: /* AXR */ goto unimplemented;
13141 case 0x37: /* SXR */ goto unimplemented;
13142 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13143 goto ok;
13144 case 0x39: /* CER */ goto unimplemented;
13145 case 0x3a: /* AER */ goto unimplemented;
13146 case 0x3b: /* SER */ goto unimplemented;
13147 case 0x3c: /* MDER */ goto unimplemented;
13148 case 0x3d: /* DER */ goto unimplemented;
13149 case 0x3e: /* AUR */ goto unimplemented;
13150 case 0x3f: /* SUR */ goto unimplemented;
13151 }
13152
13153 return S390_DECODE_UNKNOWN_INSN;
13154
13155ok:
13156 return S390_DECODE_OK;
13157
13158unimplemented:
13159 return S390_DECODE_UNIMPLEMENTED_INSN;
13160}
13161
13162static s390_decode_t
13163s390_decode_4byte_and_irgen(UChar *bytes)
13164{
13165 typedef union {
13166 struct {
13167 unsigned int op1 : 8;
13168 unsigned int r1 : 4;
13169 unsigned int op2 : 4;
13170 unsigned int i2 : 16;
13171 } RI;
13172 struct {
13173 unsigned int op : 16;
13174 unsigned int : 8;
13175 unsigned int r1 : 4;
13176 unsigned int r2 : 4;
13177 } RRE;
13178 struct {
13179 unsigned int op : 16;
13180 unsigned int r1 : 4;
13181 unsigned int : 4;
13182 unsigned int r3 : 4;
13183 unsigned int r2 : 4;
13184 } RRF;
13185 struct {
13186 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000013187 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000013188 unsigned int m4 : 4;
13189 unsigned int r1 : 4;
13190 unsigned int r2 : 4;
13191 } RRF2;
13192 struct {
13193 unsigned int op : 16;
13194 unsigned int r3 : 4;
13195 unsigned int : 4;
13196 unsigned int r1 : 4;
13197 unsigned int r2 : 4;
13198 } RRF3;
13199 struct {
13200 unsigned int op : 16;
13201 unsigned int r3 : 4;
13202 unsigned int : 4;
13203 unsigned int r1 : 4;
13204 unsigned int r2 : 4;
13205 } RRR;
13206 struct {
13207 unsigned int op : 16;
13208 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013209 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013210 unsigned int r1 : 4;
13211 unsigned int r2 : 4;
13212 } RRF4;
13213 struct {
floriane38f6412012-12-21 17:32:12 +000013214 unsigned int op : 16;
13215 unsigned int : 4;
13216 unsigned int m4 : 4;
13217 unsigned int r1 : 4;
13218 unsigned int r2 : 4;
13219 } RRF5;
13220 struct {
sewardj2019a972011-03-07 16:04:07 +000013221 unsigned int op : 8;
13222 unsigned int r1 : 4;
13223 unsigned int r3 : 4;
13224 unsigned int b2 : 4;
13225 unsigned int d2 : 12;
13226 } RS;
13227 struct {
13228 unsigned int op : 8;
13229 unsigned int r1 : 4;
13230 unsigned int r3 : 4;
13231 unsigned int i2 : 16;
13232 } RSI;
13233 struct {
13234 unsigned int op : 8;
13235 unsigned int r1 : 4;
13236 unsigned int x2 : 4;
13237 unsigned int b2 : 4;
13238 unsigned int d2 : 12;
13239 } RX;
13240 struct {
13241 unsigned int op : 16;
13242 unsigned int b2 : 4;
13243 unsigned int d2 : 12;
13244 } S;
13245 struct {
13246 unsigned int op : 8;
13247 unsigned int i2 : 8;
13248 unsigned int b1 : 4;
13249 unsigned int d1 : 12;
13250 } SI;
13251 } formats;
13252 union {
13253 formats fmt;
13254 UInt value;
13255 } ovl;
13256
13257 vassert(sizeof(formats) == 4);
13258
florianffbd84d2012-12-09 02:06:29 +000013259 ((UChar *)(&ovl.value))[0] = bytes[0];
13260 ((UChar *)(&ovl.value))[1] = bytes[1];
13261 ((UChar *)(&ovl.value))[2] = bytes[2];
13262 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013263
13264 switch ((ovl.value & 0xff0f0000) >> 16) {
13265 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13266 ovl.fmt.RI.i2); goto ok;
13267 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13268 ovl.fmt.RI.i2); goto ok;
13269 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
13270 ovl.fmt.RI.i2); goto ok;
13271 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
13272 ovl.fmt.RI.i2); goto ok;
13273 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
13274 ovl.fmt.RI.i2); goto ok;
13275 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
13276 ovl.fmt.RI.i2); goto ok;
13277 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
13278 ovl.fmt.RI.i2); goto ok;
13279 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
13280 ovl.fmt.RI.i2); goto ok;
13281 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
13282 ovl.fmt.RI.i2); goto ok;
13283 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
13284 ovl.fmt.RI.i2); goto ok;
13285 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
13286 ovl.fmt.RI.i2); goto ok;
13287 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
13288 ovl.fmt.RI.i2); goto ok;
13289 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
13290 ovl.fmt.RI.i2); goto ok;
13291 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
13292 ovl.fmt.RI.i2); goto ok;
13293 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
13294 ovl.fmt.RI.i2); goto ok;
13295 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
13296 ovl.fmt.RI.i2); goto ok;
13297 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
13298 ovl.fmt.RI.i2); goto ok;
13299 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
13300 ovl.fmt.RI.i2); goto ok;
13301 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
13302 ovl.fmt.RI.i2); goto ok;
13303 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
13304 ovl.fmt.RI.i2); goto ok;
13305 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13306 goto ok;
13307 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
13308 ovl.fmt.RI.i2); goto ok;
13309 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
13310 ovl.fmt.RI.i2); goto ok;
13311 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
13312 ovl.fmt.RI.i2); goto ok;
13313 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13314 goto ok;
13315 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
13316 ovl.fmt.RI.i2); goto ok;
13317 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13318 goto ok;
13319 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
13320 ovl.fmt.RI.i2); goto ok;
13321 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13322 goto ok;
13323 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
13324 ovl.fmt.RI.i2); goto ok;
13325 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13326 goto ok;
13327 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
13328 ovl.fmt.RI.i2); goto ok;
13329 }
13330
13331 switch ((ovl.value & 0xffff0000) >> 16) {
13332 case 0x8000: /* SSM */ goto unimplemented;
13333 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013334 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013335 case 0xb202: /* STIDP */ goto unimplemented;
13336 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013337 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
13338 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013339 case 0xb206: /* SCKC */ goto unimplemented;
13340 case 0xb207: /* STCKC */ goto unimplemented;
13341 case 0xb208: /* SPT */ goto unimplemented;
13342 case 0xb209: /* STPT */ goto unimplemented;
13343 case 0xb20a: /* SPKA */ goto unimplemented;
13344 case 0xb20b: /* IPK */ goto unimplemented;
13345 case 0xb20d: /* PTLB */ goto unimplemented;
13346 case 0xb210: /* SPX */ goto unimplemented;
13347 case 0xb211: /* STPX */ goto unimplemented;
13348 case 0xb212: /* STAP */ goto unimplemented;
13349 case 0xb214: /* SIE */ goto unimplemented;
13350 case 0xb218: /* PC */ goto unimplemented;
13351 case 0xb219: /* SAC */ goto unimplemented;
13352 case 0xb21a: /* CFC */ goto unimplemented;
13353 case 0xb221: /* IPTE */ goto unimplemented;
13354 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
13355 case 0xb223: /* IVSK */ goto unimplemented;
13356 case 0xb224: /* IAC */ goto unimplemented;
13357 case 0xb225: /* SSAR */ goto unimplemented;
13358 case 0xb226: /* EPAR */ goto unimplemented;
13359 case 0xb227: /* ESAR */ goto unimplemented;
13360 case 0xb228: /* PT */ goto unimplemented;
13361 case 0xb229: /* ISKE */ goto unimplemented;
13362 case 0xb22a: /* RRBE */ goto unimplemented;
13363 case 0xb22b: /* SSKE */ goto unimplemented;
13364 case 0xb22c: /* TB */ goto unimplemented;
13365 case 0xb22d: /* DXR */ goto unimplemented;
13366 case 0xb22e: /* PGIN */ goto unimplemented;
13367 case 0xb22f: /* PGOUT */ goto unimplemented;
13368 case 0xb230: /* CSCH */ goto unimplemented;
13369 case 0xb231: /* HSCH */ goto unimplemented;
13370 case 0xb232: /* MSCH */ goto unimplemented;
13371 case 0xb233: /* SSCH */ goto unimplemented;
13372 case 0xb234: /* STSCH */ goto unimplemented;
13373 case 0xb235: /* TSCH */ goto unimplemented;
13374 case 0xb236: /* TPI */ goto unimplemented;
13375 case 0xb237: /* SAL */ goto unimplemented;
13376 case 0xb238: /* RSCH */ goto unimplemented;
13377 case 0xb239: /* STCRW */ goto unimplemented;
13378 case 0xb23a: /* STCPS */ goto unimplemented;
13379 case 0xb23b: /* RCHP */ goto unimplemented;
13380 case 0xb23c: /* SCHM */ goto unimplemented;
13381 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000013382 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
13383 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013384 case 0xb244: /* SQDR */ goto unimplemented;
13385 case 0xb245: /* SQER */ goto unimplemented;
13386 case 0xb246: /* STURA */ goto unimplemented;
13387 case 0xb247: /* MSTA */ goto unimplemented;
13388 case 0xb248: /* PALB */ goto unimplemented;
13389 case 0xb249: /* EREG */ goto unimplemented;
13390 case 0xb24a: /* ESTA */ goto unimplemented;
13391 case 0xb24b: /* LURA */ goto unimplemented;
13392 case 0xb24c: /* TAR */ goto unimplemented;
13393 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
13394 ovl.fmt.RRE.r2); goto ok;
13395 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13396 goto ok;
13397 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13398 goto ok;
13399 case 0xb250: /* CSP */ goto unimplemented;
13400 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
13401 ovl.fmt.RRE.r2); goto ok;
13402 case 0xb254: /* MVPG */ goto unimplemented;
13403 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
13404 ovl.fmt.RRE.r2); goto ok;
13405 case 0xb257: /* CUSE */ goto unimplemented;
13406 case 0xb258: /* BSG */ goto unimplemented;
13407 case 0xb25a: /* BSA */ goto unimplemented;
13408 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
13409 ovl.fmt.RRE.r2); goto ok;
13410 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
13411 ovl.fmt.RRE.r2); goto ok;
13412 case 0xb263: /* CMPSC */ goto unimplemented;
13413 case 0xb274: /* SIGA */ goto unimplemented;
13414 case 0xb276: /* XSCH */ goto unimplemented;
13415 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013416 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 +000013417 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013418 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 +000013419 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013420 case 0xb280: /* LPP */ goto unimplemented;
13421 case 0xb284: /* LCCTL */ goto unimplemented;
13422 case 0xb285: /* LPCTL */ goto unimplemented;
13423 case 0xb286: /* QSI */ goto unimplemented;
13424 case 0xb287: /* LSCTL */ goto unimplemented;
13425 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013426 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
13427 goto ok;
13428 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13429 goto ok;
13430 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13431 goto ok;
florian730448f2012-02-04 17:07:07 +000013432 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 +000013433 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
13434 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13435 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000013436 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
13437 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13438 goto ok;
florian933065d2011-07-11 01:48:02 +000013439 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
13440 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013441 case 0xb2b1: /* STFL */ goto unimplemented;
13442 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000013443 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
13444 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013445 case 0xb2b9: /* SRNMT */ goto unimplemented;
13446 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013447 case 0xb2e0: /* SCCTR */ goto unimplemented;
13448 case 0xb2e1: /* SPCTR */ goto unimplemented;
13449 case 0xb2e4: /* ECCTR */ goto unimplemented;
13450 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013451 case 0xb2e8: /* PPA */ goto unimplemented;
13452 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013453 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013454 case 0xb2f8: /* TEND */ goto unimplemented;
13455 case 0xb2fa: /* NIAI */ goto unimplemented;
13456 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013457 case 0xb2ff: /* TRAP4 */ goto unimplemented;
13458 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
13459 ovl.fmt.RRE.r2); goto ok;
13460 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
13461 ovl.fmt.RRE.r2); goto ok;
13462 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
13463 ovl.fmt.RRE.r2); goto ok;
13464 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
13465 ovl.fmt.RRE.r2); goto ok;
13466 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
13467 ovl.fmt.RRE.r2); goto ok;
13468 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
13469 ovl.fmt.RRE.r2); goto ok;
13470 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
13471 ovl.fmt.RRE.r2); goto ok;
13472 case 0xb307: /* MXDBR */ goto unimplemented;
13473 case 0xb308: /* KEBR */ goto unimplemented;
13474 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
13475 ovl.fmt.RRE.r2); goto ok;
13476 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
13477 ovl.fmt.RRE.r2); goto ok;
13478 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
13479 ovl.fmt.RRE.r2); goto ok;
13480 case 0xb30c: /* MDEBR */ goto unimplemented;
13481 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
13482 ovl.fmt.RRE.r2); goto ok;
13483 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
13484 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13485 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
13486 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13487 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
13488 ovl.fmt.RRE.r2); goto ok;
13489 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
13490 ovl.fmt.RRE.r2); goto ok;
13491 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
13492 ovl.fmt.RRE.r2); goto ok;
13493 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
13494 ovl.fmt.RRE.r2); goto ok;
13495 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
13496 ovl.fmt.RRE.r2); goto ok;
13497 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
13498 ovl.fmt.RRE.r2); goto ok;
13499 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
13500 ovl.fmt.RRE.r2); goto ok;
13501 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
13502 ovl.fmt.RRE.r2); goto ok;
13503 case 0xb318: /* KDBR */ goto unimplemented;
13504 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
13505 ovl.fmt.RRE.r2); goto ok;
13506 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
13507 ovl.fmt.RRE.r2); goto ok;
13508 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
13509 ovl.fmt.RRE.r2); goto ok;
13510 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
13511 ovl.fmt.RRE.r2); goto ok;
13512 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
13513 ovl.fmt.RRE.r2); goto ok;
13514 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
13515 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13516 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
13517 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13518 case 0xb324: /* LDER */ goto unimplemented;
13519 case 0xb325: /* LXDR */ goto unimplemented;
13520 case 0xb326: /* LXER */ goto unimplemented;
13521 case 0xb32e: /* MAER */ goto unimplemented;
13522 case 0xb32f: /* MSER */ goto unimplemented;
13523 case 0xb336: /* SQXR */ goto unimplemented;
13524 case 0xb337: /* MEER */ goto unimplemented;
13525 case 0xb338: /* MAYLR */ goto unimplemented;
13526 case 0xb339: /* MYLR */ goto unimplemented;
13527 case 0xb33a: /* MAYR */ goto unimplemented;
13528 case 0xb33b: /* MYR */ goto unimplemented;
13529 case 0xb33c: /* MAYHR */ goto unimplemented;
13530 case 0xb33d: /* MYHR */ goto unimplemented;
13531 case 0xb33e: /* MADR */ goto unimplemented;
13532 case 0xb33f: /* MSDR */ goto unimplemented;
13533 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
13534 ovl.fmt.RRE.r2); goto ok;
13535 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
13536 ovl.fmt.RRE.r2); goto ok;
13537 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
13538 ovl.fmt.RRE.r2); goto ok;
13539 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
13540 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013541 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13542 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13543 ovl.fmt.RRF2.r2); goto ok;
13544 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13545 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13546 ovl.fmt.RRF2.r2); goto ok;
13547 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13548 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13549 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013550 case 0xb347: /* FIXBR */ goto unimplemented;
13551 case 0xb348: /* KXBR */ goto unimplemented;
13552 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13553 ovl.fmt.RRE.r2); goto ok;
13554 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13555 ovl.fmt.RRE.r2); goto ok;
13556 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13557 ovl.fmt.RRE.r2); goto ok;
13558 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13559 ovl.fmt.RRE.r2); goto ok;
13560 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13561 ovl.fmt.RRE.r2); goto ok;
13562 case 0xb350: /* TBEDR */ goto unimplemented;
13563 case 0xb351: /* TBDR */ goto unimplemented;
13564 case 0xb353: /* DIEBR */ goto unimplemented;
13565 case 0xb357: /* FIEBR */ goto unimplemented;
13566 case 0xb358: /* THDER */ goto unimplemented;
13567 case 0xb359: /* THDR */ goto unimplemented;
13568 case 0xb35b: /* DIDBR */ goto unimplemented;
13569 case 0xb35f: /* FIDBR */ goto unimplemented;
13570 case 0xb360: /* LPXR */ goto unimplemented;
13571 case 0xb361: /* LNXR */ goto unimplemented;
13572 case 0xb362: /* LTXR */ goto unimplemented;
13573 case 0xb363: /* LCXR */ goto unimplemented;
13574 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13575 ovl.fmt.RRE.r2); goto ok;
13576 case 0xb366: /* LEXR */ goto unimplemented;
13577 case 0xb367: /* FIXR */ goto unimplemented;
13578 case 0xb369: /* CXR */ goto unimplemented;
13579 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13580 ovl.fmt.RRE.r2); goto ok;
13581 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13582 ovl.fmt.RRE.r2); goto ok;
13583 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13584 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13585 goto ok;
13586 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13587 ovl.fmt.RRE.r2); goto ok;
13588 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13589 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13590 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13591 case 0xb377: /* FIER */ goto unimplemented;
13592 case 0xb37f: /* FIDR */ goto unimplemented;
13593 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13594 case 0xb385: /* SFASR */ goto unimplemented;
13595 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013596 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13597 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13598 ovl.fmt.RRF2.r2); goto ok;
13599 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13600 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13601 ovl.fmt.RRF2.r2); goto ok;
13602 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13603 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13604 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013605 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13606 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13607 ovl.fmt.RRF2.r2); goto ok;
13608 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13609 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13610 ovl.fmt.RRF2.r2); goto ok;
13611 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13612 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13613 ovl.fmt.RRF2.r2); goto ok;
13614 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13615 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13616 ovl.fmt.RRF2.r2); goto ok;
13617 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13618 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13619 ovl.fmt.RRF2.r2); goto ok;
13620 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13621 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13622 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013623 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13624 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13625 ovl.fmt.RRF2.r2); goto ok;
13626 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13627 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13628 ovl.fmt.RRF2.r2); goto ok;
13629 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13630 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13631 ovl.fmt.RRF2.r2); goto ok;
13632 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13633 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13634 ovl.fmt.RRF2.r2); goto ok;
13635 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13636 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13637 ovl.fmt.RRF2.r2); goto ok;
13638 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13639 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13640 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013641 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13642 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13643 ovl.fmt.RRF2.r2); goto ok;
13644 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13645 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13646 ovl.fmt.RRF2.r2); goto ok;
13647 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13648 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13649 ovl.fmt.RRF2.r2); goto ok;
13650 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13651 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13652 ovl.fmt.RRF2.r2); goto ok;
13653 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13654 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13655 ovl.fmt.RRF2.r2); goto ok;
13656 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13657 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13658 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013659 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13660 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13661 ovl.fmt.RRF2.r2); goto ok;
13662 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13663 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13664 ovl.fmt.RRF2.r2); goto ok;
13665 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13666 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13667 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013668 case 0xb3b4: /* CEFR */ goto unimplemented;
13669 case 0xb3b5: /* CDFR */ goto unimplemented;
13670 case 0xb3b6: /* CXFR */ goto unimplemented;
13671 case 0xb3b8: /* CFER */ goto unimplemented;
13672 case 0xb3b9: /* CFDR */ goto unimplemented;
13673 case 0xb3ba: /* CFXR */ goto unimplemented;
13674 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13675 ovl.fmt.RRE.r2); goto ok;
13676 case 0xb3c4: /* CEGR */ goto unimplemented;
13677 case 0xb3c5: /* CDGR */ goto unimplemented;
13678 case 0xb3c6: /* CXGR */ goto unimplemented;
13679 case 0xb3c8: /* CGER */ goto unimplemented;
13680 case 0xb3c9: /* CGDR */ goto unimplemented;
13681 case 0xb3ca: /* CGXR */ goto unimplemented;
13682 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13683 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013684 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13685 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13686 ovl.fmt.RRF4.r2); goto ok;
13687 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13688 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13689 ovl.fmt.RRF4.r2); goto ok;
13690 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13691 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13692 ovl.fmt.RRF4.r2); goto ok;
13693 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13694 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13695 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000013696 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
13697 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13698 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
13699 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13700 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013701 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13702 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013703 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013704 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
13705 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13706 ovl.fmt.RRF4.r2); goto ok;
13707 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
13708 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13709 ovl.fmt.RRF4.r2); goto ok;
13710 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
13711 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13712 ovl.fmt.RRF4.r2); goto ok;
13713 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
13714 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13715 ovl.fmt.RRF4.r2); goto ok;
13716 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
13717 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13718 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
13719 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13720 ovl.fmt.RRF2.r2); goto ok;
13721 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
13722 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013723 case 0xb3df: /* FIXTR */ goto unimplemented;
13724 case 0xb3e0: /* KDTR */ goto unimplemented;
13725 case 0xb3e1: /* CGDTR */ goto unimplemented;
13726 case 0xb3e2: /* CUDTR */ goto unimplemented;
13727 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013728 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
13729 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013730 case 0xb3e5: /* EEDTR */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000013731 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
13732 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013733 case 0xb3e8: /* KXTR */ goto unimplemented;
13734 case 0xb3e9: /* CGXTR */ goto unimplemented;
13735 case 0xb3ea: /* CUXTR */ goto unimplemented;
13736 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013737 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
13738 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013739 case 0xb3ed: /* EEXTR */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000013740 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
13741 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013742 case 0xb3f1: /* CDGTR */ goto unimplemented;
13743 case 0xb3f2: /* CDUTR */ goto unimplemented;
13744 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000013745 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
13746 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013747 case 0xb3f5: /* QADTR */ goto unimplemented;
13748 case 0xb3f6: /* IEDTR */ goto unimplemented;
13749 case 0xb3f7: /* RRDTR */ goto unimplemented;
13750 case 0xb3f9: /* CXGTR */ goto unimplemented;
13751 case 0xb3fa: /* CXUTR */ goto unimplemented;
13752 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000013753 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
13754 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013755 case 0xb3fd: /* QAXTR */ goto unimplemented;
13756 case 0xb3fe: /* IEXTR */ goto unimplemented;
13757 case 0xb3ff: /* RRXTR */ goto unimplemented;
13758 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13759 ovl.fmt.RRE.r2); goto ok;
13760 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13761 ovl.fmt.RRE.r2); goto ok;
13762 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
13763 ovl.fmt.RRE.r2); goto ok;
13764 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
13765 ovl.fmt.RRE.r2); goto ok;
13766 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
13767 ovl.fmt.RRE.r2); goto ok;
13768 case 0xb905: /* LURAG */ goto unimplemented;
13769 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
13770 ovl.fmt.RRE.r2); goto ok;
13771 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
13772 ovl.fmt.RRE.r2); goto ok;
13773 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
13774 ovl.fmt.RRE.r2); goto ok;
13775 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
13776 ovl.fmt.RRE.r2); goto ok;
13777 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
13778 ovl.fmt.RRE.r2); goto ok;
13779 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
13780 ovl.fmt.RRE.r2); goto ok;
13781 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
13782 ovl.fmt.RRE.r2); goto ok;
13783 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
13784 ovl.fmt.RRE.r2); goto ok;
13785 case 0xb90e: /* EREGG */ goto unimplemented;
13786 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
13787 ovl.fmt.RRE.r2); goto ok;
13788 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
13789 ovl.fmt.RRE.r2); goto ok;
13790 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
13791 ovl.fmt.RRE.r2); goto ok;
13792 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
13793 ovl.fmt.RRE.r2); goto ok;
13794 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
13795 ovl.fmt.RRE.r2); goto ok;
13796 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
13797 ovl.fmt.RRE.r2); goto ok;
13798 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
13799 ovl.fmt.RRE.r2); goto ok;
13800 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
13801 ovl.fmt.RRE.r2); goto ok;
13802 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
13803 ovl.fmt.RRE.r2); goto ok;
13804 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
13805 ovl.fmt.RRE.r2); goto ok;
13806 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
13807 ovl.fmt.RRE.r2); goto ok;
13808 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
13809 ovl.fmt.RRE.r2); goto ok;
13810 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
13811 ovl.fmt.RRE.r2); goto ok;
13812 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
13813 ovl.fmt.RRE.r2); goto ok;
13814 case 0xb91e: /* KMAC */ goto unimplemented;
13815 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
13816 ovl.fmt.RRE.r2); goto ok;
13817 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
13818 ovl.fmt.RRE.r2); goto ok;
13819 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
13820 ovl.fmt.RRE.r2); goto ok;
13821 case 0xb925: /* STURG */ goto unimplemented;
13822 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
13823 ovl.fmt.RRE.r2); goto ok;
13824 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
13825 ovl.fmt.RRE.r2); goto ok;
13826 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013827 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013828 case 0xb92b: /* KMO */ goto unimplemented;
13829 case 0xb92c: /* PCC */ goto unimplemented;
13830 case 0xb92d: /* KMCTR */ goto unimplemented;
13831 case 0xb92e: /* KM */ goto unimplemented;
13832 case 0xb92f: /* KMC */ goto unimplemented;
13833 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
13834 ovl.fmt.RRE.r2); goto ok;
13835 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
13836 ovl.fmt.RRE.r2); goto ok;
13837 case 0xb93e: /* KIMD */ goto unimplemented;
13838 case 0xb93f: /* KLMD */ goto unimplemented;
13839 case 0xb941: /* CFDTR */ goto unimplemented;
13840 case 0xb942: /* CLGDTR */ goto unimplemented;
13841 case 0xb943: /* CLFDTR */ goto unimplemented;
13842 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
13843 ovl.fmt.RRE.r2); goto ok;
13844 case 0xb949: /* CFXTR */ goto unimplemented;
13845 case 0xb94a: /* CLGXTR */ goto unimplemented;
13846 case 0xb94b: /* CLFXTR */ goto unimplemented;
13847 case 0xb951: /* CDFTR */ goto unimplemented;
13848 case 0xb952: /* CDLGTR */ goto unimplemented;
13849 case 0xb953: /* CDLFTR */ goto unimplemented;
13850 case 0xb959: /* CXFTR */ goto unimplemented;
13851 case 0xb95a: /* CXLGTR */ goto unimplemented;
13852 case 0xb95b: /* CXLFTR */ goto unimplemented;
13853 case 0xb960: /* CGRT */ goto unimplemented;
13854 case 0xb961: /* CLGRT */ goto unimplemented;
13855 case 0xb972: /* CRT */ goto unimplemented;
13856 case 0xb973: /* CLRT */ goto unimplemented;
13857 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
13858 ovl.fmt.RRE.r2); goto ok;
13859 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
13860 ovl.fmt.RRE.r2); goto ok;
13861 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
13862 ovl.fmt.RRE.r2); goto ok;
13863 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
13864 ovl.fmt.RRE.r2); goto ok;
13865 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
13866 ovl.fmt.RRE.r2); goto ok;
13867 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
13868 ovl.fmt.RRE.r2); goto ok;
13869 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
13870 ovl.fmt.RRE.r2); goto ok;
13871 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
13872 ovl.fmt.RRE.r2); goto ok;
13873 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
13874 ovl.fmt.RRE.r2); goto ok;
13875 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
13876 ovl.fmt.RRE.r2); goto ok;
13877 case 0xb98a: /* CSPG */ goto unimplemented;
13878 case 0xb98d: /* EPSW */ goto unimplemented;
13879 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013880 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000013881 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
13882 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13883 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
13884 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
13885 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
13886 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000013887 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
13888 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013889 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
13890 ovl.fmt.RRE.r2); goto ok;
13891 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
13892 ovl.fmt.RRE.r2); goto ok;
13893 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
13894 ovl.fmt.RRE.r2); goto ok;
13895 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
13896 ovl.fmt.RRE.r2); goto ok;
13897 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
13898 ovl.fmt.RRE.r2); goto ok;
13899 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
13900 ovl.fmt.RRE.r2); goto ok;
13901 case 0xb99a: /* EPAIR */ goto unimplemented;
13902 case 0xb99b: /* ESAIR */ goto unimplemented;
13903 case 0xb99d: /* ESEA */ goto unimplemented;
13904 case 0xb99e: /* PTI */ goto unimplemented;
13905 case 0xb99f: /* SSAIR */ goto unimplemented;
13906 case 0xb9a2: /* PTF */ goto unimplemented;
13907 case 0xb9aa: /* LPTEA */ goto unimplemented;
13908 case 0xb9ae: /* RRBM */ goto unimplemented;
13909 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000013910 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
13911 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13912 goto ok;
florian2a415a12012-07-21 17:41:36 +000013913 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
13914 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13915 goto ok;
florianaf2194f2012-08-06 00:07:54 +000013916 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
13917 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000013918 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
13919 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013920 case 0xb9bd: /* TRTRE */ goto unimplemented;
13921 case 0xb9be: /* SRSTU */ goto unimplemented;
13922 case 0xb9bf: /* TRTE */ goto unimplemented;
13923 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
13924 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13925 goto ok;
13926 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
13927 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13928 goto ok;
13929 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
13930 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13931 goto ok;
13932 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
13933 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13934 goto ok;
13935 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
13936 ovl.fmt.RRE.r2); goto ok;
13937 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
13938 ovl.fmt.RRE.r2); goto ok;
13939 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
13940 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13941 goto ok;
13942 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
13943 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13944 goto ok;
13945 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
13946 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13947 goto ok;
13948 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
13949 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13950 goto ok;
13951 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
13952 ovl.fmt.RRE.r2); goto ok;
13953 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
13954 ovl.fmt.RRE.r2); goto ok;
13955 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000013956 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
13957 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13958 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013959 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
13960 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13961 goto ok;
13962 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
13963 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13964 goto ok;
13965 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
13966 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13967 goto ok;
13968 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
13969 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13970 goto ok;
13971 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
13972 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13973 goto ok;
13974 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
13975 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13976 goto ok;
13977 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
13978 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13979 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000013980 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
13981 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
13982 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013983 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
13984 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13985 goto ok;
13986 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
13987 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13988 goto ok;
13989 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
13990 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13991 goto ok;
13992 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
13993 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13994 goto ok;
13995 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
13996 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
13997 goto ok;
13998 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
13999 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14000 goto ok;
14001 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14002 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14003 goto ok;
14004 }
14005
14006 switch ((ovl.value & 0xff000000) >> 24) {
14007 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14008 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14009 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14010 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14011 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14012 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14013 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14014 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14015 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14016 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14017 case 0x45: /* BAL */ goto unimplemented;
14018 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14019 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14020 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14021 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14022 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14023 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14024 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14025 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14026 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14027 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14028 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14029 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14030 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14031 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14032 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14033 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14034 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14035 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14036 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14037 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14038 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14039 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14040 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14041 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14042 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14043 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14044 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14045 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14046 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14047 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14048 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14049 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14050 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14051 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14052 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14053 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14054 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14055 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14056 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14057 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14058 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14059 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14060 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14061 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14062 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14063 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14064 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14065 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14066 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14067 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14068 case 0x67: /* MXD */ goto unimplemented;
14069 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14070 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14071 case 0x69: /* CD */ goto unimplemented;
14072 case 0x6a: /* AD */ goto unimplemented;
14073 case 0x6b: /* SD */ goto unimplemented;
14074 case 0x6c: /* MD */ goto unimplemented;
14075 case 0x6d: /* DD */ goto unimplemented;
14076 case 0x6e: /* AW */ goto unimplemented;
14077 case 0x6f: /* SW */ goto unimplemented;
14078 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14079 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14080 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14081 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14082 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14083 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14084 case 0x79: /* CE */ goto unimplemented;
14085 case 0x7a: /* AE */ goto unimplemented;
14086 case 0x7b: /* SE */ goto unimplemented;
14087 case 0x7c: /* MDE */ goto unimplemented;
14088 case 0x7d: /* DE */ goto unimplemented;
14089 case 0x7e: /* AU */ goto unimplemented;
14090 case 0x7f: /* SU */ goto unimplemented;
14091 case 0x83: /* DIAG */ goto unimplemented;
14092 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
14093 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14094 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
14095 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14096 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14097 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14098 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14099 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14100 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14101 ovl.fmt.RS.d2); goto ok;
14102 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14103 ovl.fmt.RS.d2); goto ok;
14104 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14105 ovl.fmt.RS.d2); goto ok;
14106 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14107 ovl.fmt.RS.d2); goto ok;
14108 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14109 ovl.fmt.RS.d2); goto ok;
14110 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14111 ovl.fmt.RS.d2); goto ok;
14112 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14113 ovl.fmt.RS.d2); goto ok;
14114 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14115 ovl.fmt.RS.d2); goto ok;
14116 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14117 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14118 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14119 ovl.fmt.SI.d1); goto ok;
14120 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14121 ovl.fmt.SI.d1); goto ok;
14122 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14123 ovl.fmt.SI.d1); goto ok;
14124 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14125 ovl.fmt.SI.d1); goto ok;
14126 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14127 ovl.fmt.SI.d1); goto ok;
14128 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14129 ovl.fmt.SI.d1); goto ok;
14130 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14131 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14132 case 0x99: /* TRACE */ goto unimplemented;
14133 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14134 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14135 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14136 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14137 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
14138 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14139 goto ok;
14140 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
14141 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14142 goto ok;
14143 case 0xac: /* STNSM */ goto unimplemented;
14144 case 0xad: /* STOSM */ goto unimplemented;
14145 case 0xae: /* SIGP */ goto unimplemented;
14146 case 0xaf: /* MC */ goto unimplemented;
14147 case 0xb1: /* LRA */ goto unimplemented;
14148 case 0xb6: /* STCTL */ goto unimplemented;
14149 case 0xb7: /* LCTL */ goto unimplemented;
14150 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14151 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014152 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14153 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014154 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14155 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14156 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14157 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14158 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14159 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14160 }
14161
14162 return S390_DECODE_UNKNOWN_INSN;
14163
14164ok:
14165 return S390_DECODE_OK;
14166
14167unimplemented:
14168 return S390_DECODE_UNIMPLEMENTED_INSN;
14169}
14170
14171static s390_decode_t
14172s390_decode_6byte_and_irgen(UChar *bytes)
14173{
14174 typedef union {
14175 struct {
14176 unsigned int op1 : 8;
14177 unsigned int r1 : 4;
14178 unsigned int r3 : 4;
14179 unsigned int i2 : 16;
14180 unsigned int : 8;
14181 unsigned int op2 : 8;
14182 } RIE;
14183 struct {
14184 unsigned int op1 : 8;
14185 unsigned int r1 : 4;
14186 unsigned int r2 : 4;
14187 unsigned int i3 : 8;
14188 unsigned int i4 : 8;
14189 unsigned int i5 : 8;
14190 unsigned int op2 : 8;
14191 } RIE_RRUUU;
14192 struct {
14193 unsigned int op1 : 8;
14194 unsigned int r1 : 4;
14195 unsigned int : 4;
14196 unsigned int i2 : 16;
14197 unsigned int m3 : 4;
14198 unsigned int : 4;
14199 unsigned int op2 : 8;
14200 } RIEv1;
14201 struct {
14202 unsigned int op1 : 8;
14203 unsigned int r1 : 4;
14204 unsigned int r2 : 4;
14205 unsigned int i4 : 16;
14206 unsigned int m3 : 4;
14207 unsigned int : 4;
14208 unsigned int op2 : 8;
14209 } RIE_RRPU;
14210 struct {
14211 unsigned int op1 : 8;
14212 unsigned int r1 : 4;
14213 unsigned int m3 : 4;
14214 unsigned int i4 : 16;
14215 unsigned int i2 : 8;
14216 unsigned int op2 : 8;
14217 } RIEv3;
14218 struct {
14219 unsigned int op1 : 8;
14220 unsigned int r1 : 4;
14221 unsigned int op2 : 4;
14222 unsigned int i2 : 32;
14223 } RIL;
14224 struct {
14225 unsigned int op1 : 8;
14226 unsigned int r1 : 4;
14227 unsigned int m3 : 4;
14228 unsigned int b4 : 4;
14229 unsigned int d4 : 12;
14230 unsigned int i2 : 8;
14231 unsigned int op2 : 8;
14232 } RIS;
14233 struct {
14234 unsigned int op1 : 8;
14235 unsigned int r1 : 4;
14236 unsigned int r2 : 4;
14237 unsigned int b4 : 4;
14238 unsigned int d4 : 12;
14239 unsigned int m3 : 4;
14240 unsigned int : 4;
14241 unsigned int op2 : 8;
14242 } RRS;
14243 struct {
14244 unsigned int op1 : 8;
14245 unsigned int l1 : 4;
14246 unsigned int : 4;
14247 unsigned int b1 : 4;
14248 unsigned int d1 : 12;
14249 unsigned int : 8;
14250 unsigned int op2 : 8;
14251 } RSL;
14252 struct {
14253 unsigned int op1 : 8;
14254 unsigned int r1 : 4;
14255 unsigned int r3 : 4;
14256 unsigned int b2 : 4;
14257 unsigned int dl2 : 12;
14258 unsigned int dh2 : 8;
14259 unsigned int op2 : 8;
14260 } RSY;
14261 struct {
14262 unsigned int op1 : 8;
14263 unsigned int r1 : 4;
14264 unsigned int x2 : 4;
14265 unsigned int b2 : 4;
14266 unsigned int d2 : 12;
14267 unsigned int : 8;
14268 unsigned int op2 : 8;
14269 } RXE;
14270 struct {
14271 unsigned int op1 : 8;
14272 unsigned int r3 : 4;
14273 unsigned int x2 : 4;
14274 unsigned int b2 : 4;
14275 unsigned int d2 : 12;
14276 unsigned int r1 : 4;
14277 unsigned int : 4;
14278 unsigned int op2 : 8;
14279 } RXF;
14280 struct {
14281 unsigned int op1 : 8;
14282 unsigned int r1 : 4;
14283 unsigned int x2 : 4;
14284 unsigned int b2 : 4;
14285 unsigned int dl2 : 12;
14286 unsigned int dh2 : 8;
14287 unsigned int op2 : 8;
14288 } RXY;
14289 struct {
14290 unsigned int op1 : 8;
14291 unsigned int i2 : 8;
14292 unsigned int b1 : 4;
14293 unsigned int dl1 : 12;
14294 unsigned int dh1 : 8;
14295 unsigned int op2 : 8;
14296 } SIY;
14297 struct {
14298 unsigned int op : 8;
14299 unsigned int l : 8;
14300 unsigned int b1 : 4;
14301 unsigned int d1 : 12;
14302 unsigned int b2 : 4;
14303 unsigned int d2 : 12;
14304 } SS;
14305 struct {
14306 unsigned int op : 8;
14307 unsigned int l1 : 4;
14308 unsigned int l2 : 4;
14309 unsigned int b1 : 4;
14310 unsigned int d1 : 12;
14311 unsigned int b2 : 4;
14312 unsigned int d2 : 12;
14313 } SS_LLRDRD;
14314 struct {
14315 unsigned int op : 8;
14316 unsigned int r1 : 4;
14317 unsigned int r3 : 4;
14318 unsigned int b2 : 4;
14319 unsigned int d2 : 12;
14320 unsigned int b4 : 4;
14321 unsigned int d4 : 12;
14322 } SS_RRRDRD2;
14323 struct {
14324 unsigned int op : 16;
14325 unsigned int b1 : 4;
14326 unsigned int d1 : 12;
14327 unsigned int b2 : 4;
14328 unsigned int d2 : 12;
14329 } SSE;
14330 struct {
14331 unsigned int op1 : 8;
14332 unsigned int r3 : 4;
14333 unsigned int op2 : 4;
14334 unsigned int b1 : 4;
14335 unsigned int d1 : 12;
14336 unsigned int b2 : 4;
14337 unsigned int d2 : 12;
14338 } SSF;
14339 struct {
14340 unsigned int op : 16;
14341 unsigned int b1 : 4;
14342 unsigned int d1 : 12;
14343 unsigned int i2 : 16;
14344 } SIL;
14345 } formats;
14346 union {
14347 formats fmt;
14348 ULong value;
14349 } ovl;
14350
14351 vassert(sizeof(formats) == 6);
14352
florianffbd84d2012-12-09 02:06:29 +000014353 ((UChar *)(&ovl.value))[0] = bytes[0];
14354 ((UChar *)(&ovl.value))[1] = bytes[1];
14355 ((UChar *)(&ovl.value))[2] = bytes[2];
14356 ((UChar *)(&ovl.value))[3] = bytes[3];
14357 ((UChar *)(&ovl.value))[4] = bytes[4];
14358 ((UChar *)(&ovl.value))[5] = bytes[5];
14359 ((UChar *)(&ovl.value))[6] = 0x0;
14360 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000014361
14362 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
14363 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
14364 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14365 ovl.fmt.RXY.dl2,
14366 ovl.fmt.RXY.dh2); goto ok;
14367 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
14368 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
14369 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14370 ovl.fmt.RXY.dl2,
14371 ovl.fmt.RXY.dh2); goto ok;
14372 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
14373 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14374 ovl.fmt.RXY.dl2,
14375 ovl.fmt.RXY.dh2); goto ok;
14376 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
14377 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14378 ovl.fmt.RXY.dl2,
14379 ovl.fmt.RXY.dh2); goto ok;
14380 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
14381 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14382 ovl.fmt.RXY.dl2,
14383 ovl.fmt.RXY.dh2); goto ok;
14384 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
14385 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14386 ovl.fmt.RXY.dl2,
14387 ovl.fmt.RXY.dh2); goto ok;
14388 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
14389 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14390 ovl.fmt.RXY.dl2,
14391 ovl.fmt.RXY.dh2); goto ok;
14392 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
14393 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14394 ovl.fmt.RXY.dl2,
14395 ovl.fmt.RXY.dh2); goto ok;
14396 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
14397 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14398 ovl.fmt.RXY.dl2,
14399 ovl.fmt.RXY.dh2); goto ok;
14400 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
14401 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
14402 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14403 ovl.fmt.RXY.dl2,
14404 ovl.fmt.RXY.dh2); goto ok;
14405 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
14406 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14407 ovl.fmt.RXY.dl2,
14408 ovl.fmt.RXY.dh2); goto ok;
14409 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
14410 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
14411 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14412 ovl.fmt.RXY.dl2,
14413 ovl.fmt.RXY.dh2); goto ok;
14414 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
14415 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14416 ovl.fmt.RXY.dl2,
14417 ovl.fmt.RXY.dh2); goto ok;
14418 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
14419 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14420 ovl.fmt.RXY.dl2,
14421 ovl.fmt.RXY.dh2); goto ok;
14422 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
14423 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14424 ovl.fmt.RXY.dl2,
14425 ovl.fmt.RXY.dh2); goto ok;
14426 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
14427 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14428 ovl.fmt.RXY.dl2,
14429 ovl.fmt.RXY.dh2); goto ok;
14430 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
14431 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14432 ovl.fmt.RXY.dl2,
14433 ovl.fmt.RXY.dh2); goto ok;
14434 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
14435 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14436 ovl.fmt.RXY.dl2,
14437 ovl.fmt.RXY.dh2); goto ok;
14438 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
14439 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14440 ovl.fmt.RXY.dl2,
14441 ovl.fmt.RXY.dh2); goto ok;
14442 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
14443 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14444 ovl.fmt.RXY.dl2,
14445 ovl.fmt.RXY.dh2); goto ok;
14446 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
14447 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14448 ovl.fmt.RXY.dl2,
14449 ovl.fmt.RXY.dh2); goto ok;
14450 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
14451 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14452 ovl.fmt.RXY.dl2,
14453 ovl.fmt.RXY.dh2); goto ok;
14454 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
14455 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14456 ovl.fmt.RXY.dl2,
14457 ovl.fmt.RXY.dh2); goto ok;
14458 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
14459 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14460 ovl.fmt.RXY.dl2,
14461 ovl.fmt.RXY.dh2); goto ok;
14462 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
14463 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14464 ovl.fmt.RXY.dl2,
14465 ovl.fmt.RXY.dh2); goto ok;
14466 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
14467 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14468 ovl.fmt.RXY.dl2,
14469 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014470 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014471 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
14472 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14473 ovl.fmt.RXY.dl2,
14474 ovl.fmt.RXY.dh2); goto ok;
14475 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
14476 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
14477 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14478 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14479 ovl.fmt.RXY.dh2); goto ok;
14480 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
14481 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14482 ovl.fmt.RXY.dl2,
14483 ovl.fmt.RXY.dh2); goto ok;
14484 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
14485 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14486 ovl.fmt.RXY.dl2,
14487 ovl.fmt.RXY.dh2); goto ok;
14488 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
14489 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14490 ovl.fmt.RXY.dl2,
14491 ovl.fmt.RXY.dh2); goto ok;
14492 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
14493 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14494 ovl.fmt.RXY.dl2,
14495 ovl.fmt.RXY.dh2); goto ok;
14496 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
14497 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14498 ovl.fmt.RXY.dl2,
14499 ovl.fmt.RXY.dh2); goto ok;
14500 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
14501 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14502 ovl.fmt.RXY.dl2,
14503 ovl.fmt.RXY.dh2); goto ok;
14504 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
14505 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14506 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14507 ovl.fmt.RXY.dh2); goto ok;
14508 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
14509 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14510 ovl.fmt.RXY.dl2,
14511 ovl.fmt.RXY.dh2); goto ok;
14512 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
14513 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14514 ovl.fmt.RXY.dl2,
14515 ovl.fmt.RXY.dh2); goto ok;
14516 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
14517 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14518 ovl.fmt.RXY.dl2,
14519 ovl.fmt.RXY.dh2); goto ok;
14520 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
14521 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14522 ovl.fmt.RXY.dl2,
14523 ovl.fmt.RXY.dh2); goto ok;
14524 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
14525 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14526 ovl.fmt.RXY.dl2,
14527 ovl.fmt.RXY.dh2); goto ok;
14528 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
14529 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14530 ovl.fmt.RXY.dl2,
14531 ovl.fmt.RXY.dh2); goto ok;
14532 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
14533 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14534 ovl.fmt.RXY.dl2,
14535 ovl.fmt.RXY.dh2); goto ok;
14536 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
14537 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14538 ovl.fmt.RXY.dl2,
14539 ovl.fmt.RXY.dh2); goto ok;
14540 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
14541 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14542 ovl.fmt.RXY.dl2,
14543 ovl.fmt.RXY.dh2); goto ok;
14544 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
14545 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14546 ovl.fmt.RXY.dl2,
14547 ovl.fmt.RXY.dh2); goto ok;
14548 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
14549 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14550 ovl.fmt.RXY.dl2,
14551 ovl.fmt.RXY.dh2); goto ok;
14552 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
14553 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14554 ovl.fmt.RXY.dl2,
14555 ovl.fmt.RXY.dh2); goto ok;
14556 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
14557 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14558 ovl.fmt.RXY.dl2,
14559 ovl.fmt.RXY.dh2); goto ok;
14560 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
14561 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14562 ovl.fmt.RXY.dl2,
14563 ovl.fmt.RXY.dh2); goto ok;
14564 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
14565 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14566 ovl.fmt.RXY.dl2,
14567 ovl.fmt.RXY.dh2); goto ok;
14568 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
14569 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14570 ovl.fmt.RXY.dl2,
14571 ovl.fmt.RXY.dh2); goto ok;
14572 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
14573 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14574 ovl.fmt.RXY.dl2,
14575 ovl.fmt.RXY.dh2); goto ok;
14576 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
14577 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14578 ovl.fmt.RXY.dl2,
14579 ovl.fmt.RXY.dh2); goto ok;
14580 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
14581 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14582 ovl.fmt.RXY.dl2,
14583 ovl.fmt.RXY.dh2); goto ok;
14584 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
14585 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14586 ovl.fmt.RXY.dl2,
14587 ovl.fmt.RXY.dh2); goto ok;
14588 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
14589 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14590 ovl.fmt.RXY.dl2,
14591 ovl.fmt.RXY.dh2); goto ok;
14592 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
14593 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14594 ovl.fmt.RXY.dl2,
14595 ovl.fmt.RXY.dh2); goto ok;
14596 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
14597 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14598 ovl.fmt.RXY.dl2,
14599 ovl.fmt.RXY.dh2); goto ok;
14600 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
14601 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14602 ovl.fmt.RXY.dl2,
14603 ovl.fmt.RXY.dh2); goto ok;
14604 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
14605 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14606 ovl.fmt.RXY.dl2,
14607 ovl.fmt.RXY.dh2); goto ok;
14608 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
14609 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14610 ovl.fmt.RXY.dl2,
14611 ovl.fmt.RXY.dh2); goto ok;
14612 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
14613 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14614 ovl.fmt.RXY.dl2,
14615 ovl.fmt.RXY.dh2); goto ok;
14616 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
14617 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14618 ovl.fmt.RXY.dl2,
14619 ovl.fmt.RXY.dh2); goto ok;
14620 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
14621 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14622 ovl.fmt.RXY.dl2,
14623 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014624 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014625 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
14626 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14627 ovl.fmt.RXY.dl2,
14628 ovl.fmt.RXY.dh2); goto ok;
14629 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14630 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14631 ovl.fmt.RXY.dl2,
14632 ovl.fmt.RXY.dh2); goto ok;
14633 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14634 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14635 ovl.fmt.RXY.dl2,
14636 ovl.fmt.RXY.dh2); goto ok;
14637 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14638 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14639 ovl.fmt.RXY.dl2,
14640 ovl.fmt.RXY.dh2); goto ok;
14641 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14642 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14643 ovl.fmt.RXY.dl2,
14644 ovl.fmt.RXY.dh2); goto ok;
14645 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14646 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14647 ovl.fmt.RXY.dl2,
14648 ovl.fmt.RXY.dh2); goto ok;
14649 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14650 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14651 ovl.fmt.RXY.dl2,
14652 ovl.fmt.RXY.dh2); goto ok;
14653 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
14654 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14655 ovl.fmt.RXY.dl2,
14656 ovl.fmt.RXY.dh2); goto ok;
14657 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
14658 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14659 ovl.fmt.RXY.dl2,
14660 ovl.fmt.RXY.dh2); goto ok;
14661 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
14662 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14663 ovl.fmt.RXY.dl2,
14664 ovl.fmt.RXY.dh2); goto ok;
14665 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
14666 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14667 ovl.fmt.RXY.dl2,
14668 ovl.fmt.RXY.dh2); goto ok;
14669 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
14670 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14671 ovl.fmt.RXY.dl2,
14672 ovl.fmt.RXY.dh2); goto ok;
14673 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
14674 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14675 ovl.fmt.RXY.dl2,
14676 ovl.fmt.RXY.dh2); goto ok;
14677 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
14678 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14679 ovl.fmt.RXY.dl2,
14680 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014681 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
14682 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
14683 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014684 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
14685 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14686 ovl.fmt.RXY.dl2,
14687 ovl.fmt.RXY.dh2); goto ok;
14688 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
14689 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14690 ovl.fmt.RXY.dl2,
14691 ovl.fmt.RXY.dh2); goto ok;
14692 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
14693 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14694 ovl.fmt.RXY.dl2,
14695 ovl.fmt.RXY.dh2); goto ok;
14696 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
14697 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14698 ovl.fmt.RXY.dl2,
14699 ovl.fmt.RXY.dh2); goto ok;
14700 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
14701 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14702 ovl.fmt.RXY.dl2,
14703 ovl.fmt.RXY.dh2); goto ok;
14704 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
14705 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14706 ovl.fmt.RXY.dl2,
14707 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014708 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014709 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
14710 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14711 ovl.fmt.RXY.dl2,
14712 ovl.fmt.RXY.dh2); goto ok;
14713 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
14714 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14715 ovl.fmt.RXY.dl2,
14716 ovl.fmt.RXY.dh2); goto ok;
14717 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
14718 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14719 ovl.fmt.RXY.dl2,
14720 ovl.fmt.RXY.dh2); goto ok;
14721 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
14722 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14723 ovl.fmt.RXY.dl2,
14724 ovl.fmt.RXY.dh2); goto ok;
14725 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14726 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14727 ovl.fmt.RSY.dl2,
14728 ovl.fmt.RSY.dh2); goto ok;
14729 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14730 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14731 ovl.fmt.RSY.dl2,
14732 ovl.fmt.RSY.dh2); goto ok;
14733 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14734 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14735 ovl.fmt.RSY.dl2,
14736 ovl.fmt.RSY.dh2); goto ok;
14737 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14738 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14739 ovl.fmt.RSY.dl2,
14740 ovl.fmt.RSY.dh2); goto ok;
14741 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
14742 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14743 ovl.fmt.RSY.dl2,
14744 ovl.fmt.RSY.dh2); goto ok;
14745 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
14746 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
14747 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14748 ovl.fmt.RSY.dl2,
14749 ovl.fmt.RSY.dh2); goto ok;
14750 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
14751 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14752 ovl.fmt.RSY.dl2,
14753 ovl.fmt.RSY.dh2); goto ok;
14754 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
14755 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14756 ovl.fmt.RSY.dl2,
14757 ovl.fmt.RSY.dh2); goto ok;
14758 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
14759 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14760 ovl.fmt.RSY.dl2,
14761 ovl.fmt.RSY.dh2); goto ok;
14762 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
14763 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14764 ovl.fmt.RSY.dl2,
14765 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014766 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014767 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
14768 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14769 ovl.fmt.RSY.dl2,
14770 ovl.fmt.RSY.dh2); goto ok;
14771 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
14772 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
14773 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14774 ovl.fmt.RSY.dl2,
14775 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014776 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014777 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
14778 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14779 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14780 ovl.fmt.RSY.dh2); goto ok;
14781 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
14782 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14783 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14784 ovl.fmt.RSY.dh2); goto ok;
14785 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
14786 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
14787 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14788 ovl.fmt.RSY.dl2,
14789 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014790 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
14791 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14792 ovl.fmt.RSY.dl2,
14793 ovl.fmt.RSY.dh2); goto ok;
14794 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
14795 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14796 ovl.fmt.RSY.dl2,
14797 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014798 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
14799 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14800 ovl.fmt.RSY.dl2,
14801 ovl.fmt.RSY.dh2); goto ok;
14802 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
14803 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14804 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14805 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000014806 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
14807 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14808 ovl.fmt.RSY.dl2,
14809 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014810 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
14811 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14812 ovl.fmt.SIY.dh1); goto ok;
14813 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
14814 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14815 ovl.fmt.SIY.dh1); goto ok;
14816 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
14817 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14818 ovl.fmt.SIY.dh1); goto ok;
14819 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
14820 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14821 ovl.fmt.SIY.dh1); goto ok;
14822 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
14823 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14824 ovl.fmt.SIY.dh1); goto ok;
14825 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
14826 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14827 ovl.fmt.SIY.dh1); goto ok;
14828 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
14829 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14830 ovl.fmt.SIY.dh1); goto ok;
14831 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
14832 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14833 ovl.fmt.SIY.dh1); goto ok;
14834 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
14835 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14836 ovl.fmt.SIY.dh1); goto ok;
14837 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
14838 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
14839 ovl.fmt.SIY.dh1); goto ok;
14840 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
14841 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14842 ovl.fmt.RSY.dl2,
14843 ovl.fmt.RSY.dh2); goto ok;
14844 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
14845 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14846 ovl.fmt.RSY.dl2,
14847 ovl.fmt.RSY.dh2); goto ok;
14848 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
14849 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
14850 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
14851 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14852 ovl.fmt.RSY.dl2,
14853 ovl.fmt.RSY.dh2); goto ok;
14854 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
14855 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14856 ovl.fmt.RSY.dl2,
14857 ovl.fmt.RSY.dh2); goto ok;
14858 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
14859 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14860 ovl.fmt.RSY.dl2,
14861 ovl.fmt.RSY.dh2); goto ok;
14862 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
14863 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14864 ovl.fmt.RSY.dl2,
14865 ovl.fmt.RSY.dh2); goto ok;
14866 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
14867 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14868 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14869 ovl.fmt.RSY.dh2); goto ok;
14870 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
14871 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
14872 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14873 ovl.fmt.RSY.dl2,
14874 ovl.fmt.RSY.dh2); goto ok;
14875 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
14876 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14877 ovl.fmt.RSY.dl2,
14878 ovl.fmt.RSY.dh2); goto ok;
14879 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
14880 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14881 ovl.fmt.RSY.dl2,
14882 ovl.fmt.RSY.dh2); goto ok;
14883 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
14884 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14885 ovl.fmt.RSY.dl2,
14886 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014887 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
14888 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14889 ovl.fmt.RSY.dl2,
14890 ovl.fmt.RSY.dh2,
14891 S390_XMNM_LOCG); goto ok;
14892 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
14893 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14894 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14895 ovl.fmt.RSY.dh2,
14896 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014897 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
14898 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14899 ovl.fmt.RSY.dl2,
14900 ovl.fmt.RSY.dh2); goto ok;
14901 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
14902 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14903 ovl.fmt.RSY.dl2,
14904 ovl.fmt.RSY.dh2); goto ok;
14905 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
14906 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14907 ovl.fmt.RSY.dl2,
14908 ovl.fmt.RSY.dh2); goto ok;
14909 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
14910 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14911 ovl.fmt.RSY.dl2,
14912 ovl.fmt.RSY.dh2); goto ok;
14913 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
14914 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
14915 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
14916 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014917 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
14918 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14919 ovl.fmt.RSY.dl2,
14920 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
14921 goto ok;
14922 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
14923 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14924 ovl.fmt.RSY.dl2,
14925 ovl.fmt.RSY.dh2,
14926 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014927 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
14928 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14929 ovl.fmt.RSY.dl2,
14930 ovl.fmt.RSY.dh2); goto ok;
14931 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
14932 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14933 ovl.fmt.RSY.dl2,
14934 ovl.fmt.RSY.dh2); goto ok;
14935 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
14936 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14937 ovl.fmt.RSY.dl2,
14938 ovl.fmt.RSY.dh2); goto ok;
14939 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
14940 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14941 ovl.fmt.RSY.dl2,
14942 ovl.fmt.RSY.dh2); goto ok;
14943 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
14944 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14945 ovl.fmt.RSY.dl2,
14946 ovl.fmt.RSY.dh2); goto ok;
14947 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
14948 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14949 goto ok;
14950 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
14951 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
14952 goto ok;
14953 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
14954 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
14955 ovl.fmt.RIE_RRUUU.r1,
14956 ovl.fmt.RIE_RRUUU.r2,
14957 ovl.fmt.RIE_RRUUU.i3,
14958 ovl.fmt.RIE_RRUUU.i4,
14959 ovl.fmt.RIE_RRUUU.i5);
14960 goto ok;
14961 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
14962 ovl.fmt.RIE_RRUUU.r1,
14963 ovl.fmt.RIE_RRUUU.r2,
14964 ovl.fmt.RIE_RRUUU.i3,
14965 ovl.fmt.RIE_RRUUU.i4,
14966 ovl.fmt.RIE_RRUUU.i5);
14967 goto ok;
14968 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
14969 ovl.fmt.RIE_RRUUU.r1,
14970 ovl.fmt.RIE_RRUUU.r2,
14971 ovl.fmt.RIE_RRUUU.i3,
14972 ovl.fmt.RIE_RRUUU.i4,
14973 ovl.fmt.RIE_RRUUU.i5);
14974 goto ok;
14975 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
14976 ovl.fmt.RIE_RRUUU.r1,
14977 ovl.fmt.RIE_RRUUU.r2,
14978 ovl.fmt.RIE_RRUUU.i3,
14979 ovl.fmt.RIE_RRUUU.i4,
14980 ovl.fmt.RIE_RRUUU.i5);
14981 goto ok;
florian2289cd42012-12-05 04:23:42 +000014982 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014983 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
14984 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
14985 ovl.fmt.RIE_RRPU.r1,
14986 ovl.fmt.RIE_RRPU.r2,
14987 ovl.fmt.RIE_RRPU.i4,
14988 ovl.fmt.RIE_RRPU.m3); goto ok;
14989 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
14990 ovl.fmt.RIE_RRPU.r1,
14991 ovl.fmt.RIE_RRPU.r2,
14992 ovl.fmt.RIE_RRPU.i4,
14993 ovl.fmt.RIE_RRPU.m3); goto ok;
14994 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
14995 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
14996 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
14997 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
14998 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
14999 ovl.fmt.RIE_RRPU.r1,
15000 ovl.fmt.RIE_RRPU.r2,
15001 ovl.fmt.RIE_RRPU.i4,
15002 ovl.fmt.RIE_RRPU.m3); goto ok;
15003 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15004 ovl.fmt.RIE_RRPU.r1,
15005 ovl.fmt.RIE_RRPU.r2,
15006 ovl.fmt.RIE_RRPU.i4,
15007 ovl.fmt.RIE_RRPU.m3); goto ok;
15008 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15009 ovl.fmt.RIEv3.r1,
15010 ovl.fmt.RIEv3.m3,
15011 ovl.fmt.RIEv3.i4,
15012 ovl.fmt.RIEv3.i2); goto ok;
15013 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15014 ovl.fmt.RIEv3.r1,
15015 ovl.fmt.RIEv3.m3,
15016 ovl.fmt.RIEv3.i4,
15017 ovl.fmt.RIEv3.i2); goto ok;
15018 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15019 ovl.fmt.RIEv3.r1,
15020 ovl.fmt.RIEv3.m3,
15021 ovl.fmt.RIEv3.i4,
15022 ovl.fmt.RIEv3.i2); goto ok;
15023 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15024 ovl.fmt.RIEv3.r1,
15025 ovl.fmt.RIEv3.m3,
15026 ovl.fmt.RIEv3.i4,
15027 ovl.fmt.RIEv3.i2); goto ok;
15028 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15029 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15030 goto ok;
15031 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15032 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15033 ovl.fmt.RIE.i2); goto ok;
15034 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15035 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15036 ovl.fmt.RIE.i2); goto ok;
15037 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15038 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15039 ovl.fmt.RIE.i2); goto ok;
15040 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15041 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15042 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15043 goto ok;
15044 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15045 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15046 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15047 goto ok;
15048 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15049 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15050 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15051 goto ok;
15052 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15053 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15054 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15055 goto ok;
15056 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15057 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15058 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15059 ovl.fmt.RIS.i2); goto ok;
15060 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15061 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15062 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15063 ovl.fmt.RIS.i2); goto ok;
15064 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15065 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15066 ovl.fmt.RIS.d4,
15067 ovl.fmt.RIS.i2); goto ok;
15068 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15069 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15070 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15071 ovl.fmt.RIS.i2); goto ok;
15072 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15073 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15074 ovl.fmt.RXE.d2); goto ok;
15075 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15076 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15077 ovl.fmt.RXE.d2); goto ok;
15078 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15079 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15080 ovl.fmt.RXE.d2); goto ok;
15081 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15082 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15083 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15084 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15085 ovl.fmt.RXE.d2); goto ok;
15086 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15087 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15088 ovl.fmt.RXE.d2); goto ok;
15089 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
15090 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15091 ovl.fmt.RXE.d2); goto ok;
15092 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
15093 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
15094 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15095 ovl.fmt.RXE.d2); goto ok;
15096 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
15097 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15098 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15099 ovl.fmt.RXF.r1); goto ok;
15100 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
15101 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15102 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15103 ovl.fmt.RXF.r1); goto ok;
15104 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
15105 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15106 ovl.fmt.RXE.d2); goto ok;
15107 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
15108 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15109 ovl.fmt.RXE.d2); goto ok;
15110 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
15111 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15112 ovl.fmt.RXE.d2); goto ok;
15113 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
15114 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15115 ovl.fmt.RXE.d2); goto ok;
15116 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
15117 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15118 ovl.fmt.RXE.d2); goto ok;
15119 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
15120 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15121 ovl.fmt.RXE.d2); goto ok;
15122 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
15123 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
15124 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15125 ovl.fmt.RXE.d2); goto ok;
15126 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
15127 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15128 ovl.fmt.RXE.d2); goto ok;
15129 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
15130 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15131 ovl.fmt.RXE.d2); goto ok;
15132 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
15133 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15134 ovl.fmt.RXE.d2); goto ok;
15135 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
15136 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15137 ovl.fmt.RXE.d2); goto ok;
15138 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
15139 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15140 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15141 ovl.fmt.RXF.r1); goto ok;
15142 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
15143 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15144 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15145 ovl.fmt.RXF.r1); goto ok;
15146 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
15147 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
15148 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
15149 case 0xed000000002eULL: /* MAE */ goto unimplemented;
15150 case 0xed000000002fULL: /* MSE */ goto unimplemented;
15151 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
15152 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
15153 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
15154 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
15155 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
15156 case 0xed000000003aULL: /* MAY */ goto unimplemented;
15157 case 0xed000000003bULL: /* MY */ goto unimplemented;
15158 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
15159 case 0xed000000003dULL: /* MYH */ goto unimplemented;
15160 case 0xed000000003eULL: /* MAD */ goto unimplemented;
15161 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000015162 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
15163 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15164 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15165 ovl.fmt.RXF.r1); goto ok;
15166 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
15167 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15168 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15169 ovl.fmt.RXF.r1); goto ok;
15170 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
15171 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15172 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15173 ovl.fmt.RXF.r1); goto ok;
15174 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
15175 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15176 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15177 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000015178 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
15179 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15180 ovl.fmt.RXE.d2); goto ok;
15181 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
15182 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15183 ovl.fmt.RXE.d2); goto ok;
15184 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
15185 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15186 ovl.fmt.RXE.d2); goto ok;
15187 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
15188 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15189 ovl.fmt.RXE.d2); goto ok;
15190 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
15191 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15192 ovl.fmt.RXE.d2); goto ok;
15193 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
15194 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15195 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015196 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
15197 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15198 ovl.fmt.RXY.dl2,
15199 ovl.fmt.RXY.dh2); goto ok;
15200 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
15201 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15202 ovl.fmt.RXY.dl2,
15203 ovl.fmt.RXY.dh2); goto ok;
15204 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
15205 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15206 ovl.fmt.RXY.dl2,
15207 ovl.fmt.RXY.dh2); goto ok;
15208 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
15209 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15210 ovl.fmt.RXY.dl2,
15211 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015212 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
15213 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
15214 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
15215 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015216 }
15217
15218 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
15219 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
15220 ovl.fmt.RIL.i2); goto ok;
15221 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
15222 ovl.fmt.RIL.i2); goto ok;
15223 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
15224 ovl.fmt.RIL.i2); goto ok;
15225 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
15226 ovl.fmt.RIL.i2); goto ok;
15227 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
15228 ovl.fmt.RIL.i2); goto ok;
15229 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
15230 ovl.fmt.RIL.i2); goto ok;
15231 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
15232 ovl.fmt.RIL.i2); goto ok;
15233 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
15234 ovl.fmt.RIL.i2); goto ok;
15235 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
15236 ovl.fmt.RIL.i2); goto ok;
15237 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
15238 ovl.fmt.RIL.i2); goto ok;
15239 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
15240 ovl.fmt.RIL.i2); goto ok;
15241 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
15242 ovl.fmt.RIL.i2); goto ok;
15243 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
15244 ovl.fmt.RIL.i2); goto ok;
15245 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
15246 ovl.fmt.RIL.i2); goto ok;
15247 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
15248 ovl.fmt.RIL.i2); goto ok;
15249 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
15250 ovl.fmt.RIL.i2); goto ok;
15251 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
15252 ovl.fmt.RIL.i2); goto ok;
15253 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
15254 ovl.fmt.RIL.i2); goto ok;
15255 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
15256 ovl.fmt.RIL.i2); goto ok;
15257 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
15258 ovl.fmt.RIL.i2); goto ok;
15259 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
15260 ovl.fmt.RIL.i2); goto ok;
15261 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
15262 ovl.fmt.RIL.i2); goto ok;
15263 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
15264 ovl.fmt.RIL.i2); goto ok;
15265 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
15266 ovl.fmt.RIL.i2); goto ok;
15267 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
15268 ovl.fmt.RIL.i2); goto ok;
15269 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
15270 ovl.fmt.RIL.i2); goto ok;
15271 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
15272 ovl.fmt.RIL.i2); goto ok;
15273 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
15274 ovl.fmt.RIL.i2); goto ok;
15275 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
15276 ovl.fmt.RIL.i2); goto ok;
15277 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
15278 ovl.fmt.RIL.i2); goto ok;
15279 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
15280 ovl.fmt.RIL.i2); goto ok;
15281 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
15282 ovl.fmt.RIL.i2); goto ok;
15283 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
15284 ovl.fmt.RIL.i2); goto ok;
15285 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
15286 ovl.fmt.RIL.i2); goto ok;
15287 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
15288 ovl.fmt.RIL.i2); goto ok;
15289 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
15290 ovl.fmt.RIL.i2); goto ok;
15291 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
15292 ovl.fmt.RIL.i2); goto ok;
15293 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
15294 ovl.fmt.RIL.i2); goto ok;
15295 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
15296 ovl.fmt.RIL.i2); goto ok;
15297 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
15298 ovl.fmt.RIL.i2); goto ok;
15299 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
15300 ovl.fmt.RIL.i2); goto ok;
15301 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
15302 ovl.fmt.RIL.i2); goto ok;
15303 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
15304 ovl.fmt.RIL.i2); goto ok;
15305 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
15306 ovl.fmt.RIL.i2); goto ok;
15307 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
15308 ovl.fmt.RIL.i2); goto ok;
15309 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
15310 ovl.fmt.RIL.i2); goto ok;
15311 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
15312 ovl.fmt.RIL.i2); goto ok;
15313 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
15314 ovl.fmt.RIL.i2); goto ok;
15315 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
15316 ovl.fmt.RIL.i2); goto ok;
15317 case 0xc800ULL: /* MVCOS */ goto unimplemented;
15318 case 0xc801ULL: /* ECTG */ goto unimplemented;
15319 case 0xc802ULL: /* CSST */ goto unimplemented;
15320 case 0xc804ULL: /* LPD */ goto unimplemented;
15321 case 0xc805ULL: /* LPDG */ goto unimplemented;
15322 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
15323 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
15324 ovl.fmt.RIL.i2); goto ok;
15325 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
15326 ovl.fmt.RIL.i2); goto ok;
15327 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
15328 ovl.fmt.RIL.i2); goto ok;
15329 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
15330 ovl.fmt.RIL.i2); goto ok;
15331 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
15332 ovl.fmt.RIL.i2); goto ok;
15333 }
15334
15335 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000015336 case 0xc5ULL: /* BPRP */ goto unimplemented;
15337 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015338 case 0xd0ULL: /* TRTR */ goto unimplemented;
15339 case 0xd1ULL: /* MVN */ goto unimplemented;
15340 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
15341 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15342 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15343 case 0xd3ULL: /* MVZ */ goto unimplemented;
15344 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
15345 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15346 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15347 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
15348 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15349 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15350 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
15351 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15352 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000015353 case 0xd7ULL:
15354 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
15355 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
15356 else
15357 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
15358 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15359 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
15360 goto ok;
sewardj2019a972011-03-07 16:04:07 +000015361 case 0xd9ULL: /* MVCK */ goto unimplemented;
15362 case 0xdaULL: /* MVCP */ goto unimplemented;
15363 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015364 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
15365 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15366 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015367 case 0xddULL: /* TRT */ goto unimplemented;
15368 case 0xdeULL: /* ED */ goto unimplemented;
15369 case 0xdfULL: /* EDMK */ goto unimplemented;
15370 case 0xe1ULL: /* PKU */ goto unimplemented;
15371 case 0xe2ULL: /* UNPKU */ goto unimplemented;
15372 case 0xe8ULL: /* MVCIN */ goto unimplemented;
15373 case 0xe9ULL: /* PKA */ goto unimplemented;
15374 case 0xeaULL: /* UNPKA */ goto unimplemented;
15375 case 0xeeULL: /* PLO */ goto unimplemented;
15376 case 0xefULL: /* LMD */ goto unimplemented;
15377 case 0xf0ULL: /* SRP */ goto unimplemented;
15378 case 0xf1ULL: /* MVO */ goto unimplemented;
15379 case 0xf2ULL: /* PACK */ goto unimplemented;
15380 case 0xf3ULL: /* UNPK */ goto unimplemented;
15381 case 0xf8ULL: /* ZAP */ goto unimplemented;
15382 case 0xf9ULL: /* CP */ goto unimplemented;
15383 case 0xfaULL: /* AP */ goto unimplemented;
15384 case 0xfbULL: /* SP */ goto unimplemented;
15385 case 0xfcULL: /* MP */ goto unimplemented;
15386 case 0xfdULL: /* DP */ goto unimplemented;
15387 }
15388
15389 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
15390 case 0xe500ULL: /* LASP */ goto unimplemented;
15391 case 0xe501ULL: /* TPROT */ goto unimplemented;
15392 case 0xe502ULL: /* STRAG */ goto unimplemented;
15393 case 0xe50eULL: /* MVCSK */ goto unimplemented;
15394 case 0xe50fULL: /* MVCDK */ goto unimplemented;
15395 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
15396 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15397 goto ok;
15398 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
15399 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15400 goto ok;
15401 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
15402 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15403 goto ok;
15404 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
15405 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15406 goto ok;
15407 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
15408 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15409 goto ok;
15410 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
15411 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15412 goto ok;
15413 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
15414 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15415 goto ok;
15416 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
15417 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15418 goto ok;
15419 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
15420 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15421 goto ok;
florian2289cd42012-12-05 04:23:42 +000015422 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
15423 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015424 }
15425
15426 return S390_DECODE_UNKNOWN_INSN;
15427
15428ok:
15429 return S390_DECODE_OK;
15430
15431unimplemented:
15432 return S390_DECODE_UNIMPLEMENTED_INSN;
15433}
15434
15435/* Handle "special" instructions. */
15436static s390_decode_t
15437s390_decode_special_and_irgen(UChar *bytes)
15438{
15439 s390_decode_t status = S390_DECODE_OK;
15440
15441 /* Got a "Special" instruction preamble. Which one is it? */
15442 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
15443 s390_irgen_client_request();
15444 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
15445 s390_irgen_guest_NRADDR();
15446 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
15447 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000015448 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
15449 vex_inject_ir(irsb, Iend_BE);
15450
15451 /* Invalidate the current insn. The reason is that the IRop we're
15452 injecting here can change. In which case the translation has to
15453 be redone. For ease of handling, we simply invalidate all the
15454 time. */
15455 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
15456 mkU64(guest_IA_curr_instr)));
15457 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
15458 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
15459 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
15460 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
15461
15462 put_IA(mkaddr_expr(guest_IA_next_instr));
15463 dis_res->whatNext = Dis_StopHere;
15464 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000015465 } else {
15466 /* We don't know what it is. */
15467 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
15468 }
15469
15470 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15471
15472 return status;
15473}
15474
15475
15476/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000015477static UInt
sewardj2019a972011-03-07 16:04:07 +000015478s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
15479{
15480 s390_decode_t status;
15481
15482 dis_res = dres;
15483
15484 /* Spot the 8-byte preamble: 18ff lr r15,r15
15485 1811 lr r1,r1
15486 1822 lr r2,r2
15487 1833 lr r3,r3 */
15488 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
15489 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
15490 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
15491
15492 /* Handle special instruction that follows that preamble. */
15493 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000015494
15495 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15496 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15497
15498 status =
15499 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000015500 } else {
15501 /* Handle normal instructions. */
15502 switch (insn_length) {
15503 case 2:
15504 status = s390_decode_2byte_and_irgen(bytes);
15505 break;
15506
15507 case 4:
15508 status = s390_decode_4byte_and_irgen(bytes);
15509 break;
15510
15511 case 6:
15512 status = s390_decode_6byte_and_irgen(bytes);
15513 break;
15514
15515 default:
15516 status = S390_DECODE_ERROR;
15517 break;
15518 }
15519 }
florian5fcbba22011-07-27 20:40:22 +000015520 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000015521 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
15522 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000015523 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000015524 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000015525 }
15526
15527 if (status == S390_DECODE_OK) return insn_length; /* OK */
15528
15529 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000015530 if (sigill_diag) {
15531 vex_printf("vex s390->IR: ");
15532 switch (status) {
15533 case S390_DECODE_UNKNOWN_INSN:
15534 vex_printf("unknown insn: ");
15535 break;
sewardj2019a972011-03-07 16:04:07 +000015536
sewardj442e51a2012-12-06 18:08:04 +000015537 case S390_DECODE_UNIMPLEMENTED_INSN:
15538 vex_printf("unimplemented insn: ");
15539 break;
sewardj2019a972011-03-07 16:04:07 +000015540
sewardj442e51a2012-12-06 18:08:04 +000015541 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
15542 vex_printf("unimplemented special insn: ");
15543 break;
sewardj2019a972011-03-07 16:04:07 +000015544
sewardj442e51a2012-12-06 18:08:04 +000015545 default:
15546 case S390_DECODE_ERROR:
15547 vex_printf("decoding error: ");
15548 break;
15549 }
15550
15551 vex_printf("%02x%02x", bytes[0], bytes[1]);
15552 if (insn_length > 2) {
15553 vex_printf(" %02x%02x", bytes[2], bytes[3]);
15554 }
15555 if (insn_length > 4) {
15556 vex_printf(" %02x%02x", bytes[4], bytes[5]);
15557 }
15558 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000015559 }
15560
sewardj2019a972011-03-07 16:04:07 +000015561 return 0; /* Failed */
15562}
15563
15564
sewardj2019a972011-03-07 16:04:07 +000015565/* Disassemble a single instruction INSN into IR. */
15566static DisResult
florian420c5012011-07-22 02:12:28 +000015567disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000015568{
15569 UChar byte;
15570 UInt insn_length;
15571 DisResult dres;
15572
15573 /* ---------------------------------------------------- */
15574 /* --- Compute instruction length -- */
15575 /* ---------------------------------------------------- */
15576
15577 /* Get the first byte of the insn. */
15578 byte = insn[0];
15579
15580 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
15581 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
15582 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
15583
15584 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15585
15586 /* ---------------------------------------------------- */
15587 /* --- Initialise the DisResult data -- */
15588 /* ---------------------------------------------------- */
15589 dres.whatNext = Dis_Continue;
15590 dres.len = insn_length;
15591 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000015592 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000015593
floriana99f20e2011-07-17 14:16:41 +000015594 /* fixs390: consider chasing of conditional jumps */
15595
sewardj2019a972011-03-07 16:04:07 +000015596 /* Normal and special instruction handling starts here. */
15597 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
15598 /* All decode failures end up here. The decoder has already issued an
15599 error message.
15600 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000015601 not been executed, and (is currently) the next to be executed.
15602 The insn address in the guest state needs to be set to
15603 guest_IA_curr_instr, otherwise the complaint will report an
15604 incorrect address. */
15605 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000015606
florian8844a632012-04-13 04:04:06 +000015607 dres.whatNext = Dis_StopHere;
15608 dres.jk_StopHere = Ijk_NoDecode;
15609 dres.continueAt = 0;
15610 dres.len = 0;
15611 } else {
15612 /* Decode success */
15613 switch (dres.whatNext) {
15614 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015615 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015616 break;
15617 case Dis_ResteerU:
15618 case Dis_ResteerC:
15619 put_IA(mkaddr_expr(dres.continueAt));
15620 break;
15621 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000015622 if (dres.jk_StopHere == Ijk_EmWarn ||
15623 dres.jk_StopHere == Ijk_EmFail) {
15624 /* We assume here, that emulation warnings are not given for
15625 insns that transfer control. There is no good way to
15626 do that. */
15627 put_IA(mkaddr_expr(guest_IA_next_instr));
15628 }
florian8844a632012-04-13 04:04:06 +000015629 break;
15630 default:
15631 vassert(0);
15632 }
sewardj2019a972011-03-07 16:04:07 +000015633 }
15634
15635 return dres;
15636}
15637
15638
15639/*------------------------------------------------------------*/
15640/*--- Top-level fn ---*/
15641/*------------------------------------------------------------*/
15642
15643/* Disassemble a single instruction into IR. The instruction
15644 is located in host memory at &guest_code[delta]. */
15645
15646DisResult
15647disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015648 Bool (*resteerOkFn)(void *, Addr64),
15649 Bool resteerCisOk,
15650 void *callback_opaque,
15651 UChar *guest_code,
15652 Long delta,
15653 Addr64 guest_IP,
15654 VexArch guest_arch,
15655 VexArchInfo *archinfo,
15656 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000015657 Bool host_bigendian,
15658 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000015659{
15660 vassert(guest_arch == VexArchS390X);
15661
15662 /* The instruction decoder requires a big-endian machine. */
15663 vassert(host_bigendian == True);
15664
15665 /* Set globals (see top of this file) */
15666 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015667 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015668 resteer_fn = resteerOkFn;
15669 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000015670 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000015671
florian420c5012011-07-22 02:12:28 +000015672 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015673}
15674
15675/*---------------------------------------------------------------*/
15676/*--- end guest_s390_toIR.c ---*/
15677/*---------------------------------------------------------------*/