blob: 4a5013b34137aa122ca8b32818ab2c760d40f75c [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
sewardj89ae8472013-10-18 14:12:58 +000011 Copyright IBM Corp. 2010-2013
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
florian99dd03e2013-01-29 03:56:06 +0000243 return IRExpr_ITE(condition, iftrue, iffalse);
sewardj2019a972011-03-07 16:04:07 +0000244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
sewardj05f5e012014-05-04 10:52:11 +0000420 stmt(IRStmt_Exit(condition, Ijk_InvalICache,
421 IRConst_U64(guest_IA_curr_instr),
florian6820ba52012-07-26 02:01:50 +0000422 S390X_GUEST_OFFSET(guest_IA)));
423}
424
425/* Convenience function to yield to thread scheduler */
426static void
427yield_if(IRExpr *condition)
428{
429 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
430 S390X_GUEST_OFFSET(guest_IA)));
431}
432
sewardj2019a972011-03-07 16:04:07 +0000433static __inline__ IRExpr *get_fpr_dw0(UInt);
434static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000435static __inline__ IRExpr *get_dpr_dw0(UInt);
436static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000437
438/* Read a floating point register pair and combine their contents into a
439 128-bit value */
440static IRExpr *
441get_fpr_pair(UInt archreg)
442{
443 IRExpr *high = get_fpr_dw0(archreg);
444 IRExpr *low = get_fpr_dw0(archreg + 2);
445
446 return binop(Iop_F64HLtoF128, high, low);
447}
448
449/* Write a 128-bit floating point value into a register pair. */
450static void
451put_fpr_pair(UInt archreg, IRExpr *expr)
452{
453 IRExpr *high = unop(Iop_F128HItoF64, expr);
454 IRExpr *low = unop(Iop_F128LOtoF64, expr);
455
456 put_fpr_dw0(archreg, high);
457 put_fpr_dw0(archreg + 2, low);
458}
459
floriane38f6412012-12-21 17:32:12 +0000460/* Read a floating point register pair cointaining DFP value
461 and combine their contents into a 128-bit value */
462
463static IRExpr *
464get_dpr_pair(UInt archreg)
465{
466 IRExpr *high = get_dpr_dw0(archreg);
467 IRExpr *low = get_dpr_dw0(archreg + 2);
468
469 return binop(Iop_D64HLtoD128, high, low);
470}
471
472/* Write a 128-bit decimal floating point value into a register pair. */
473static void
474put_dpr_pair(UInt archreg, IRExpr *expr)
475{
476 IRExpr *high = unop(Iop_D128HItoD64, expr);
477 IRExpr *low = unop(Iop_D128LOtoD64, expr);
478
479 put_dpr_dw0(archreg, high);
480 put_dpr_dw0(archreg + 2, low);
481}
482
floriane75dafa2012-09-01 17:54:09 +0000483/* Terminate the current IRSB with an emulation failure. */
484static void
485emulation_failure(VexEmNote fail_kind)
486{
487 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000488 dis_res->whatNext = Dis_StopHere;
489 dis_res->jk_StopHere = Ijk_EmFail;
490}
sewardj2019a972011-03-07 16:04:07 +0000491
florian4b8efad2012-09-02 18:07:08 +0000492/* Terminate the current IRSB with an emulation warning. */
493static void
494emulation_warning(VexEmNote warn_kind)
495{
496 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
497 dis_res->whatNext = Dis_StopHere;
498 dis_res->jk_StopHere = Ijk_EmWarn;
499}
500
sewardj2019a972011-03-07 16:04:07 +0000501/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000502/*--- IR Debugging aids. ---*/
503/*------------------------------------------------------------*/
504#if 0
505
506static ULong
507s390_do_print(HChar *text, ULong value)
508{
509 vex_printf("%s %llu\n", text, value);
510 return 0;
511}
512
513static void
514s390_print(HChar *text, IRExpr *value)
515{
516 IRDirty *d;
517
518 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
519 mkIRExprVec_2(mkU64((ULong)text), value));
520 stmt(IRStmt_Dirty(d));
521}
522#endif
523
524
525/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000526/*--- Build the flags thunk. ---*/
527/*------------------------------------------------------------*/
528
529/* Completely fill the flags thunk. We're always filling all fields.
530 Apparently, that is better for redundant PUT elimination. */
531static void
532s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
533{
534 UInt op_off, dep1_off, dep2_off, ndep_off;
535
florian428dfdd2012-03-27 03:09:49 +0000536 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
537 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
538 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
539 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000540
541 stmt(IRStmt_Put(op_off, op));
542 stmt(IRStmt_Put(dep1_off, dep1));
543 stmt(IRStmt_Put(dep2_off, dep2));
544 stmt(IRStmt_Put(ndep_off, ndep));
545}
546
547
548/* Create an expression for V and widen the result to 64 bit. */
549static IRExpr *
550s390_cc_widen(IRTemp v, Bool sign_extend)
551{
552 IRExpr *expr;
553
554 expr = mkexpr(v);
555
556 switch (typeOfIRTemp(irsb->tyenv, v)) {
557 case Ity_I64:
558 break;
559 case Ity_I32:
560 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
561 break;
562 case Ity_I16:
563 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
564 break;
565 case Ity_I8:
566 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
567 break;
568 default:
569 vpanic("s390_cc_widen");
570 }
571
572 return expr;
573}
574
575static void
576s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
577{
578 IRExpr *op, *dep1, *dep2, *ndep;
579
580 op = mkU64(opc);
581 dep1 = s390_cc_widen(d1, sign_extend);
582 dep2 = mkU64(0);
583 ndep = mkU64(0);
584
585 s390_cc_thunk_fill(op, dep1, dep2, ndep);
586}
587
588
589static void
590s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
591{
592 IRExpr *op, *dep1, *dep2, *ndep;
593
594 op = mkU64(opc);
595 dep1 = s390_cc_widen(d1, sign_extend);
596 dep2 = s390_cc_widen(d2, sign_extend);
597 ndep = mkU64(0);
598
599 s390_cc_thunk_fill(op, dep1, dep2, ndep);
600}
601
602
603/* memcheck believes that the NDEP field in the flags thunk is always
604 defined. But for some flag computations (e.g. add with carry) that is
605 just not true. We therefore need to convey to memcheck that the value
606 of the ndep field does matter and therefore we make the DEP2 field
607 depend on it:
608
609 DEP2 = original_DEP2 ^ NDEP
610
611 In s390_calculate_cc we exploit that (a^b)^b == a
612 I.e. we xor the DEP2 value with the NDEP value to recover the
613 original_DEP2 value. */
614static void
615s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
616{
617 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
618
619 op = mkU64(opc);
620 dep1 = s390_cc_widen(d1, sign_extend);
621 dep2 = s390_cc_widen(d2, sign_extend);
622 ndep = s390_cc_widen(nd, sign_extend);
623
624 dep2x = binop(Iop_Xor64, dep2, ndep);
625
626 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
627}
628
629
630/* Write one floating point value into the flags thunk */
631static void
632s390_cc_thunk_put1f(UInt opc, IRTemp d1)
633{
634 IRExpr *op, *dep1, *dep2, *ndep;
635
florianbafb8262013-05-31 15:41:55 +0000636 /* Make the CC_DEP1 slot appear completely defined.
637 Otherwise, assigning a 32-bit value will cause memcheck
638 to trigger an undefinedness error.
639 */
640 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
641 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
642 stmt(IRStmt_Put(dep1_off, mkU64(0)));
643 }
sewardj2019a972011-03-07 16:04:07 +0000644 op = mkU64(opc);
645 dep1 = mkexpr(d1);
646 dep2 = mkU64(0);
647 ndep = mkU64(0);
648
649 s390_cc_thunk_fill(op, dep1, dep2, ndep);
650}
651
652
653/* Write a floating point value and an integer into the flags thunk. The
654 integer value is zero-extended first. */
655static void
656s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
657{
658 IRExpr *op, *dep1, *dep2, *ndep;
659
florianbafb8262013-05-31 15:41:55 +0000660 /* Make the CC_DEP1 slot appear completely defined.
661 Otherwise, assigning a 32-bit value will cause memcheck
662 to trigger an undefinedness error.
663 */
664 if (sizeofIRType(typeOfIRTemp(irsb->tyenv, d1)) == 4) {
665 UInt dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
666 stmt(IRStmt_Put(dep1_off, mkU64(0)));
667 }
sewardj2019a972011-03-07 16:04:07 +0000668 op = mkU64(opc);
669 dep1 = mkexpr(d1);
670 dep2 = s390_cc_widen(d2, False);
671 ndep = mkU64(0);
672
673 s390_cc_thunk_fill(op, dep1, dep2, ndep);
674}
675
676
677/* Write a 128-bit floating point value into the flags thunk. This is
678 done by splitting the value into two 64-bits values. */
679static void
680s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
681{
682 IRExpr *op, *hi, *lo, *ndep;
683
684 op = mkU64(opc);
685 hi = unop(Iop_F128HItoF64, mkexpr(d1));
686 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
687 ndep = mkU64(0);
688
689 s390_cc_thunk_fill(op, hi, lo, ndep);
690}
691
692
693/* Write a 128-bit floating point value and an integer into the flags thunk.
694 The integer value is zero-extended first. */
695static void
696s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
697{
698 IRExpr *op, *hi, *lo, *lox, *ndep;
699
700 op = mkU64(opc);
701 hi = unop(Iop_F128HItoF64, mkexpr(d1));
702 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
703 ndep = s390_cc_widen(nd, False);
704
705 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
706
707 s390_cc_thunk_fill(op, hi, lox, ndep);
708}
709
710
floriane38f6412012-12-21 17:32:12 +0000711/* Write a 128-bit decimal floating point value into the flags thunk.
712 This is done by splitting the value into two 64-bits values. */
713static void
714s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
715{
716 IRExpr *op, *hi, *lo, *ndep;
717
718 op = mkU64(opc);
719 hi = unop(Iop_D128HItoD64, mkexpr(d1));
720 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
721 ndep = mkU64(0);
722
723 s390_cc_thunk_fill(op, hi, lo, ndep);
724}
725
726
floriance9e3db2012-12-27 20:14:03 +0000727/* Write a 128-bit decimal floating point value and an integer into the flags
728 thunk. The integer value is zero-extended first. */
729static void
730s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
731{
732 IRExpr *op, *hi, *lo, *lox, *ndep;
733
734 op = mkU64(opc);
735 hi = unop(Iop_D128HItoD64, mkexpr(d1));
736 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
737 ndep = s390_cc_widen(nd, False);
738
739 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
740
741 s390_cc_thunk_fill(op, hi, lox, ndep);
742}
743
744
sewardj2019a972011-03-07 16:04:07 +0000745static void
746s390_cc_set(UInt val)
747{
748 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
749 mkU64(val), mkU64(0), mkU64(0));
750}
751
752/* Build IR to calculate the condition code from flags thunk.
753 Returns an expression of type Ity_I32 */
754static IRExpr *
755s390_call_calculate_cc(void)
756{
757 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
758
florian428dfdd2012-03-27 03:09:49 +0000759 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
760 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
761 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
762 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000763
764 args = mkIRExprVec_4(op, dep1, dep2, ndep);
765 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
766 "s390_calculate_cc", &s390_calculate_cc, args);
767
768 /* Exclude OP and NDEP from definedness checking. We're only
769 interested in DEP1 and DEP2. */
770 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
771
772 return call;
773}
774
775/* Build IR to calculate the internal condition code for a "compare and branch"
776 insn. Returns an expression of type Ity_I32 */
777static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000778s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000779{
florianff9613f2012-05-12 15:26:44 +0000780 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000781
florianff9613f2012-05-12 15:26:44 +0000782 switch (opc) {
783 case S390_CC_OP_SIGNED_COMPARE:
784 dep1 = s390_cc_widen(op1, True);
785 dep2 = s390_cc_widen(op2, True);
786 break;
787
788 case S390_CC_OP_UNSIGNED_COMPARE:
789 dep1 = s390_cc_widen(op1, False);
790 dep2 = s390_cc_widen(op2, False);
791 break;
792
793 default:
794 vpanic("s390_call_calculate_icc");
795 }
796
797 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000798 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000799
florianff9613f2012-05-12 15:26:44 +0000800 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000801 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000802 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000803
florianff9613f2012-05-12 15:26:44 +0000804 /* Exclude the requested condition, OP and NDEP from definedness
805 checking. We're only interested in DEP1 and DEP2. */
806 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000807
808 return call;
809}
810
811/* Build IR to calculate the condition code from flags thunk.
812 Returns an expression of type Ity_I32 */
813static IRExpr *
814s390_call_calculate_cond(UInt m)
815{
816 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
817
818 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000819 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
820 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
821 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
822 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000823
824 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
825 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
826 "s390_calculate_cond", &s390_calculate_cond, args);
827
828 /* Exclude the requested condition, OP and NDEP from definedness
829 checking. We're only interested in DEP1 and DEP2. */
830 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
831
832 return call;
833}
834
835#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
836#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
837#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
838#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
839#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
840#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
841#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
842 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
843#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
844 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000845
846
sewardj2019a972011-03-07 16:04:07 +0000847
848
849/*------------------------------------------------------------*/
850/*--- Guest register access ---*/
851/*------------------------------------------------------------*/
852
853
854/*------------------------------------------------------------*/
855/*--- ar registers ---*/
856/*------------------------------------------------------------*/
857
858/* Return the guest state offset of a ar register. */
859static UInt
860ar_offset(UInt archreg)
861{
862 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000863 S390X_GUEST_OFFSET(guest_a0),
864 S390X_GUEST_OFFSET(guest_a1),
865 S390X_GUEST_OFFSET(guest_a2),
866 S390X_GUEST_OFFSET(guest_a3),
867 S390X_GUEST_OFFSET(guest_a4),
868 S390X_GUEST_OFFSET(guest_a5),
869 S390X_GUEST_OFFSET(guest_a6),
870 S390X_GUEST_OFFSET(guest_a7),
871 S390X_GUEST_OFFSET(guest_a8),
872 S390X_GUEST_OFFSET(guest_a9),
873 S390X_GUEST_OFFSET(guest_a10),
874 S390X_GUEST_OFFSET(guest_a11),
875 S390X_GUEST_OFFSET(guest_a12),
876 S390X_GUEST_OFFSET(guest_a13),
877 S390X_GUEST_OFFSET(guest_a14),
878 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000879 };
880
881 vassert(archreg < 16);
882
883 return offset[archreg];
884}
885
886
887/* Return the guest state offset of word #0 of a ar register. */
888static __inline__ UInt
889ar_w0_offset(UInt archreg)
890{
891 return ar_offset(archreg) + 0;
892}
893
894/* Write word #0 of a ar to the guest state. */
895static __inline__ void
896put_ar_w0(UInt archreg, IRExpr *expr)
897{
898 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
899
900 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
901}
902
903/* Read word #0 of a ar register. */
904static __inline__ IRExpr *
905get_ar_w0(UInt archreg)
906{
907 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
908}
909
910
911/*------------------------------------------------------------*/
912/*--- fpr registers ---*/
913/*------------------------------------------------------------*/
914
915/* Return the guest state offset of a fpr register. */
916static UInt
917fpr_offset(UInt archreg)
918{
919 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000920 S390X_GUEST_OFFSET(guest_f0),
921 S390X_GUEST_OFFSET(guest_f1),
922 S390X_GUEST_OFFSET(guest_f2),
923 S390X_GUEST_OFFSET(guest_f3),
924 S390X_GUEST_OFFSET(guest_f4),
925 S390X_GUEST_OFFSET(guest_f5),
926 S390X_GUEST_OFFSET(guest_f6),
927 S390X_GUEST_OFFSET(guest_f7),
928 S390X_GUEST_OFFSET(guest_f8),
929 S390X_GUEST_OFFSET(guest_f9),
930 S390X_GUEST_OFFSET(guest_f10),
931 S390X_GUEST_OFFSET(guest_f11),
932 S390X_GUEST_OFFSET(guest_f12),
933 S390X_GUEST_OFFSET(guest_f13),
934 S390X_GUEST_OFFSET(guest_f14),
935 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000936 };
937
938 vassert(archreg < 16);
939
940 return offset[archreg];
941}
942
943
944/* Return the guest state offset of word #0 of a fpr register. */
945static __inline__ UInt
946fpr_w0_offset(UInt archreg)
947{
948 return fpr_offset(archreg) + 0;
949}
950
951/* Write word #0 of a fpr to the guest state. */
952static __inline__ void
953put_fpr_w0(UInt archreg, IRExpr *expr)
954{
955 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
956
957 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
958}
959
960/* Read word #0 of a fpr register. */
961static __inline__ IRExpr *
962get_fpr_w0(UInt archreg)
963{
964 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
965}
966
967/* Return the guest state offset of double word #0 of a fpr register. */
968static __inline__ UInt
969fpr_dw0_offset(UInt archreg)
970{
971 return fpr_offset(archreg) + 0;
972}
973
974/* Write double word #0 of a fpr to the guest state. */
975static __inline__ void
976put_fpr_dw0(UInt archreg, IRExpr *expr)
977{
978 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
979
980 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
981}
982
983/* Read double word #0 of a fpr register. */
984static __inline__ IRExpr *
985get_fpr_dw0(UInt archreg)
986{
987 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
988}
989
floriane38f6412012-12-21 17:32:12 +0000990/* Write word #0 of a dpr to the guest state. */
991static __inline__ void
992put_dpr_w0(UInt archreg, IRExpr *expr)
993{
994 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
995
996 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
997}
998
999/* Read word #0 of a dpr register. */
1000static __inline__ IRExpr *
1001get_dpr_w0(UInt archreg)
1002{
1003 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
1004}
1005
florian12390202012-11-10 22:34:14 +00001006/* Write double word #0 of a fpr containg DFP value to the guest state. */
1007static __inline__ void
1008put_dpr_dw0(UInt archreg, IRExpr *expr)
1009{
1010 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
1011
1012 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
1013}
1014
1015/* Read double word #0 of a fpr register containing DFP value. */
1016static __inline__ IRExpr *
1017get_dpr_dw0(UInt archreg)
1018{
1019 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1020}
sewardj2019a972011-03-07 16:04:07 +00001021
1022/*------------------------------------------------------------*/
1023/*--- gpr registers ---*/
1024/*------------------------------------------------------------*/
1025
1026/* Return the guest state offset of a gpr register. */
1027static UInt
1028gpr_offset(UInt archreg)
1029{
1030 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001031 S390X_GUEST_OFFSET(guest_r0),
1032 S390X_GUEST_OFFSET(guest_r1),
1033 S390X_GUEST_OFFSET(guest_r2),
1034 S390X_GUEST_OFFSET(guest_r3),
1035 S390X_GUEST_OFFSET(guest_r4),
1036 S390X_GUEST_OFFSET(guest_r5),
1037 S390X_GUEST_OFFSET(guest_r6),
1038 S390X_GUEST_OFFSET(guest_r7),
1039 S390X_GUEST_OFFSET(guest_r8),
1040 S390X_GUEST_OFFSET(guest_r9),
1041 S390X_GUEST_OFFSET(guest_r10),
1042 S390X_GUEST_OFFSET(guest_r11),
1043 S390X_GUEST_OFFSET(guest_r12),
1044 S390X_GUEST_OFFSET(guest_r13),
1045 S390X_GUEST_OFFSET(guest_r14),
1046 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001047 };
1048
1049 vassert(archreg < 16);
1050
1051 return offset[archreg];
1052}
1053
1054
1055/* Return the guest state offset of word #0 of a gpr register. */
1056static __inline__ UInt
1057gpr_w0_offset(UInt archreg)
1058{
1059 return gpr_offset(archreg) + 0;
1060}
1061
1062/* Write word #0 of a gpr to the guest state. */
1063static __inline__ void
1064put_gpr_w0(UInt archreg, IRExpr *expr)
1065{
1066 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1067
1068 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1069}
1070
1071/* Read word #0 of a gpr register. */
1072static __inline__ IRExpr *
1073get_gpr_w0(UInt archreg)
1074{
1075 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1076}
1077
1078/* Return the guest state offset of double word #0 of a gpr register. */
1079static __inline__ UInt
1080gpr_dw0_offset(UInt archreg)
1081{
1082 return gpr_offset(archreg) + 0;
1083}
1084
1085/* Write double word #0 of a gpr to the guest state. */
1086static __inline__ void
1087put_gpr_dw0(UInt archreg, IRExpr *expr)
1088{
1089 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1090
1091 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1092}
1093
1094/* Read double word #0 of a gpr register. */
1095static __inline__ IRExpr *
1096get_gpr_dw0(UInt archreg)
1097{
1098 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1099}
1100
1101/* Return the guest state offset of half word #1 of a gpr register. */
1102static __inline__ UInt
1103gpr_hw1_offset(UInt archreg)
1104{
1105 return gpr_offset(archreg) + 2;
1106}
1107
1108/* Write half word #1 of a gpr to the guest state. */
1109static __inline__ void
1110put_gpr_hw1(UInt archreg, IRExpr *expr)
1111{
1112 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1113
1114 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1115}
1116
1117/* Read half word #1 of a gpr register. */
1118static __inline__ IRExpr *
1119get_gpr_hw1(UInt archreg)
1120{
1121 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1122}
1123
1124/* Return the guest state offset of byte #6 of a gpr register. */
1125static __inline__ UInt
1126gpr_b6_offset(UInt archreg)
1127{
1128 return gpr_offset(archreg) + 6;
1129}
1130
1131/* Write byte #6 of a gpr to the guest state. */
1132static __inline__ void
1133put_gpr_b6(UInt archreg, IRExpr *expr)
1134{
1135 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1136
1137 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1138}
1139
1140/* Read byte #6 of a gpr register. */
1141static __inline__ IRExpr *
1142get_gpr_b6(UInt archreg)
1143{
1144 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1145}
1146
1147/* Return the guest state offset of byte #3 of a gpr register. */
1148static __inline__ UInt
1149gpr_b3_offset(UInt archreg)
1150{
1151 return gpr_offset(archreg) + 3;
1152}
1153
1154/* Write byte #3 of a gpr to the guest state. */
1155static __inline__ void
1156put_gpr_b3(UInt archreg, IRExpr *expr)
1157{
1158 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1159
1160 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1161}
1162
1163/* Read byte #3 of a gpr register. */
1164static __inline__ IRExpr *
1165get_gpr_b3(UInt archreg)
1166{
1167 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1168}
1169
1170/* Return the guest state offset of byte #0 of a gpr register. */
1171static __inline__ UInt
1172gpr_b0_offset(UInt archreg)
1173{
1174 return gpr_offset(archreg) + 0;
1175}
1176
1177/* Write byte #0 of a gpr to the guest state. */
1178static __inline__ void
1179put_gpr_b0(UInt archreg, IRExpr *expr)
1180{
1181 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1182
1183 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1184}
1185
1186/* Read byte #0 of a gpr register. */
1187static __inline__ IRExpr *
1188get_gpr_b0(UInt archreg)
1189{
1190 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1191}
1192
1193/* Return the guest state offset of word #1 of a gpr register. */
1194static __inline__ UInt
1195gpr_w1_offset(UInt archreg)
1196{
1197 return gpr_offset(archreg) + 4;
1198}
1199
1200/* Write word #1 of a gpr to the guest state. */
1201static __inline__ void
1202put_gpr_w1(UInt archreg, IRExpr *expr)
1203{
1204 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1205
1206 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1207}
1208
1209/* Read word #1 of a gpr register. */
1210static __inline__ IRExpr *
1211get_gpr_w1(UInt archreg)
1212{
1213 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1214}
1215
1216/* Return the guest state offset of half word #3 of a gpr register. */
1217static __inline__ UInt
1218gpr_hw3_offset(UInt archreg)
1219{
1220 return gpr_offset(archreg) + 6;
1221}
1222
1223/* Write half word #3 of a gpr to the guest state. */
1224static __inline__ void
1225put_gpr_hw3(UInt archreg, IRExpr *expr)
1226{
1227 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1228
1229 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1230}
1231
1232/* Read half word #3 of a gpr register. */
1233static __inline__ IRExpr *
1234get_gpr_hw3(UInt archreg)
1235{
1236 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1237}
1238
1239/* Return the guest state offset of byte #7 of a gpr register. */
1240static __inline__ UInt
1241gpr_b7_offset(UInt archreg)
1242{
1243 return gpr_offset(archreg) + 7;
1244}
1245
1246/* Write byte #7 of a gpr to the guest state. */
1247static __inline__ void
1248put_gpr_b7(UInt archreg, IRExpr *expr)
1249{
1250 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1251
1252 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1253}
1254
1255/* Read byte #7 of a gpr register. */
1256static __inline__ IRExpr *
1257get_gpr_b7(UInt archreg)
1258{
1259 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1260}
1261
1262/* Return the guest state offset of half word #0 of a gpr register. */
1263static __inline__ UInt
1264gpr_hw0_offset(UInt archreg)
1265{
1266 return gpr_offset(archreg) + 0;
1267}
1268
1269/* Write half word #0 of a gpr to the guest state. */
1270static __inline__ void
1271put_gpr_hw0(UInt archreg, IRExpr *expr)
1272{
1273 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1274
1275 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1276}
1277
1278/* Read half word #0 of a gpr register. */
1279static __inline__ IRExpr *
1280get_gpr_hw0(UInt archreg)
1281{
1282 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1283}
1284
1285/* Return the guest state offset of byte #4 of a gpr register. */
1286static __inline__ UInt
1287gpr_b4_offset(UInt archreg)
1288{
1289 return gpr_offset(archreg) + 4;
1290}
1291
1292/* Write byte #4 of a gpr to the guest state. */
1293static __inline__ void
1294put_gpr_b4(UInt archreg, IRExpr *expr)
1295{
1296 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1297
1298 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1299}
1300
1301/* Read byte #4 of a gpr register. */
1302static __inline__ IRExpr *
1303get_gpr_b4(UInt archreg)
1304{
1305 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1306}
1307
1308/* Return the guest state offset of byte #1 of a gpr register. */
1309static __inline__ UInt
1310gpr_b1_offset(UInt archreg)
1311{
1312 return gpr_offset(archreg) + 1;
1313}
1314
1315/* Write byte #1 of a gpr to the guest state. */
1316static __inline__ void
1317put_gpr_b1(UInt archreg, IRExpr *expr)
1318{
1319 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1320
1321 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1322}
1323
1324/* Read byte #1 of a gpr register. */
1325static __inline__ IRExpr *
1326get_gpr_b1(UInt archreg)
1327{
1328 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1329}
1330
1331/* Return the guest state offset of half word #2 of a gpr register. */
1332static __inline__ UInt
1333gpr_hw2_offset(UInt archreg)
1334{
1335 return gpr_offset(archreg) + 4;
1336}
1337
1338/* Write half word #2 of a gpr to the guest state. */
1339static __inline__ void
1340put_gpr_hw2(UInt archreg, IRExpr *expr)
1341{
1342 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1343
1344 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1345}
1346
1347/* Read half word #2 of a gpr register. */
1348static __inline__ IRExpr *
1349get_gpr_hw2(UInt archreg)
1350{
1351 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1352}
1353
1354/* Return the guest state offset of byte #5 of a gpr register. */
1355static __inline__ UInt
1356gpr_b5_offset(UInt archreg)
1357{
1358 return gpr_offset(archreg) + 5;
1359}
1360
1361/* Write byte #5 of a gpr to the guest state. */
1362static __inline__ void
1363put_gpr_b5(UInt archreg, IRExpr *expr)
1364{
1365 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1366
1367 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1368}
1369
1370/* Read byte #5 of a gpr register. */
1371static __inline__ IRExpr *
1372get_gpr_b5(UInt archreg)
1373{
1374 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1375}
1376
1377/* Return the guest state offset of byte #2 of a gpr register. */
1378static __inline__ UInt
1379gpr_b2_offset(UInt archreg)
1380{
1381 return gpr_offset(archreg) + 2;
1382}
1383
1384/* Write byte #2 of a gpr to the guest state. */
1385static __inline__ void
1386put_gpr_b2(UInt archreg, IRExpr *expr)
1387{
1388 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1389
1390 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1391}
1392
1393/* Read byte #2 of a gpr register. */
1394static __inline__ IRExpr *
1395get_gpr_b2(UInt archreg)
1396{
1397 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1398}
1399
1400/* Return the guest state offset of the counter register. */
1401static UInt
1402counter_offset(void)
1403{
floriane88b3c92011-07-05 02:48:39 +00001404 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001405}
1406
1407/* Return the guest state offset of double word #0 of the counter register. */
1408static __inline__ UInt
1409counter_dw0_offset(void)
1410{
1411 return counter_offset() + 0;
1412}
1413
1414/* Write double word #0 of the counter to the guest state. */
1415static __inline__ void
1416put_counter_dw0(IRExpr *expr)
1417{
1418 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1419
1420 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1421}
1422
1423/* Read double word #0 of the counter register. */
1424static __inline__ IRExpr *
1425get_counter_dw0(void)
1426{
1427 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1428}
1429
1430/* Return the guest state offset of word #0 of the counter register. */
1431static __inline__ UInt
1432counter_w0_offset(void)
1433{
1434 return counter_offset() + 0;
1435}
1436
1437/* Return the guest state offset of word #1 of the counter register. */
1438static __inline__ UInt
1439counter_w1_offset(void)
1440{
1441 return counter_offset() + 4;
1442}
1443
1444/* Write word #0 of the counter to the guest state. */
1445static __inline__ void
1446put_counter_w0(IRExpr *expr)
1447{
1448 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1449
1450 stmt(IRStmt_Put(counter_w0_offset(), expr));
1451}
1452
1453/* Read word #0 of the counter register. */
1454static __inline__ IRExpr *
1455get_counter_w0(void)
1456{
1457 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1458}
1459
1460/* Write word #1 of the counter to the guest state. */
1461static __inline__ void
1462put_counter_w1(IRExpr *expr)
1463{
1464 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1465
1466 stmt(IRStmt_Put(counter_w1_offset(), expr));
1467}
1468
1469/* Read word #1 of the counter register. */
1470static __inline__ IRExpr *
1471get_counter_w1(void)
1472{
1473 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1474}
1475
1476/* Return the guest state offset of the fpc register. */
1477static UInt
1478fpc_offset(void)
1479{
floriane88b3c92011-07-05 02:48:39 +00001480 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001481}
1482
1483/* Return the guest state offset of word #0 of the fpc register. */
1484static __inline__ UInt
1485fpc_w0_offset(void)
1486{
1487 return fpc_offset() + 0;
1488}
1489
1490/* Write word #0 of the fpc to the guest state. */
1491static __inline__ void
1492put_fpc_w0(IRExpr *expr)
1493{
1494 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1495
1496 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1497}
1498
1499/* Read word #0 of the fpc register. */
1500static __inline__ IRExpr *
1501get_fpc_w0(void)
1502{
1503 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1504}
1505
1506
1507/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001508/*--- Rounding modes ---*/
1509/*------------------------------------------------------------*/
1510
florian125e20d2012-10-07 15:42:37 +00001511/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001512 IRRoundingMode:
1513
1514 rounding mode | s390 | IR
1515 -------------------------
1516 to nearest | 00 | 00
1517 to zero | 01 | 11
1518 to +infinity | 10 | 10
1519 to -infinity | 11 | 01
1520
1521 So: IR = (4 - s390) & 3
1522*/
1523static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001524get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001525{
1526 IRTemp fpc_bits = newTemp(Ity_I32);
1527
1528 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1529 Prior to that bits [30:31] contained the bfp rounding mode with
1530 bit 29 being unused and having a value of 0. So we can always
1531 extract the least significant 3 bits. */
1532 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1533
1534 /* fixs390:
1535
1536
1537 if (! s390_host_has_fpext && rounding_mode > 3) {
1538 emulation warning @ runtime and
1539 set fpc to round nearest
1540 }
1541 */
1542
1543 /* For now silently adjust an unsupported rounding mode to "nearest" */
1544 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1545 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001546 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001547
1548 // rm_IR = (4 - rm_s390) & 3;
1549 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1550}
1551
1552/* Encode the s390 rounding mode as it appears in the m3 field of certain
1553 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1554 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1555 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1556 considers the default rounding mode (4.3.3). */
1557static IRTemp
1558encode_bfp_rounding_mode(UChar mode)
1559{
1560 IRExpr *rm;
1561
1562 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001563 case S390_BFP_ROUND_PER_FPC:
1564 rm = get_bfp_rounding_mode_from_fpc();
1565 break;
1566 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1567 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1568 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1569 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1570 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1571 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001572 default:
1573 vpanic("encode_bfp_rounding_mode");
1574 }
1575
1576 return mktemp(Ity_I32, rm);
1577}
1578
florianc8e4f562012-10-27 16:19:31 +00001579/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1580 IRRoundingMode:
1581
1582 rounding mode | s390 | IR
1583 ------------------------------------------------
1584 to nearest, ties to even | 000 | 000
1585 to zero | 001 | 011
1586 to +infinity | 010 | 010
1587 to -infinity | 011 | 001
1588 to nearest, ties away from 0 | 100 | 100
1589 to nearest, ties toward 0 | 101 | 111
1590 to away from 0 | 110 | 110
1591 to prepare for shorter precision | 111 | 101
1592
1593 So: IR = (s390 ^ ((s390 << 1) & 2))
1594*/
florianc8e4f562012-10-27 16:19:31 +00001595static IRExpr *
1596get_dfp_rounding_mode_from_fpc(void)
1597{
1598 IRTemp fpc_bits = newTemp(Ity_I32);
1599
1600 /* The dfp rounding mode is stored in bits [25:27].
1601 extract the bits at 25:27 and right shift 4 times. */
1602 assign(fpc_bits, binop(Iop_Shr32,
1603 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1604 mkU8(4)));
1605
1606 IRExpr *rm_s390 = mkexpr(fpc_bits);
1607 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1608
1609 return binop(Iop_Xor32, rm_s390,
1610 binop( Iop_And32,
1611 binop(Iop_Shl32, rm_s390, mkU8(1)),
1612 mkU32(2)));
1613}
1614
1615/* Encode the s390 rounding mode as it appears in the m3 field of certain
1616 instructions to VEX's IRRoundingMode. */
1617static IRTemp
1618encode_dfp_rounding_mode(UChar mode)
1619{
1620 IRExpr *rm;
1621
1622 switch (mode) {
1623 case S390_DFP_ROUND_PER_FPC_0:
1624 case S390_DFP_ROUND_PER_FPC_2:
1625 rm = get_dfp_rounding_mode_from_fpc(); break;
1626 case S390_DFP_ROUND_NEAREST_EVEN_4:
1627 case S390_DFP_ROUND_NEAREST_EVEN_8:
florian79e5a482013-06-06 19:12:46 +00001628 rm = mkU32(Irrm_NEAREST); break;
florianc8e4f562012-10-27 16:19:31 +00001629 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1630 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
florian79e5a482013-06-06 19:12:46 +00001631 rm = mkU32(Irrm_NEAREST_TIE_AWAY_0); break;
florianc8e4f562012-10-27 16:19:31 +00001632 case S390_DFP_ROUND_PREPARE_SHORT_3:
1633 case S390_DFP_ROUND_PREPARE_SHORT_15:
florian79e5a482013-06-06 19:12:46 +00001634 rm = mkU32(Irrm_PREPARE_SHORTER); break;
florianc8e4f562012-10-27 16:19:31 +00001635 case S390_DFP_ROUND_ZERO_5:
1636 case S390_DFP_ROUND_ZERO_9:
florian79e5a482013-06-06 19:12:46 +00001637 rm = mkU32(Irrm_ZERO ); break;
florianc8e4f562012-10-27 16:19:31 +00001638 case S390_DFP_ROUND_POSINF_6:
1639 case S390_DFP_ROUND_POSINF_10:
florian79e5a482013-06-06 19:12:46 +00001640 rm = mkU32(Irrm_PosINF); break;
florianc8e4f562012-10-27 16:19:31 +00001641 case S390_DFP_ROUND_NEGINF_7:
1642 case S390_DFP_ROUND_NEGINF_11:
florian79e5a482013-06-06 19:12:46 +00001643 rm = mkU32(Irrm_NegINF); break;
florianc8e4f562012-10-27 16:19:31 +00001644 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
florian79e5a482013-06-06 19:12:46 +00001645 rm = mkU32(Irrm_NEAREST_TIE_TOWARD_0); break;
florianc8e4f562012-10-27 16:19:31 +00001646 case S390_DFP_ROUND_AWAY_0:
florian79e5a482013-06-06 19:12:46 +00001647 rm = mkU32(Irrm_AWAY_FROM_ZERO); break;
florianc8e4f562012-10-27 16:19:31 +00001648 default:
1649 vpanic("encode_dfp_rounding_mode");
1650 }
1651
1652 return mktemp(Ity_I32, rm);
1653}
florian12390202012-11-10 22:34:14 +00001654
florianc8e4f562012-10-27 16:19:31 +00001655
florian2c74d242012-09-12 19:38:42 +00001656/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001657/*--- Condition code helpers ---*/
1658/*------------------------------------------------------------*/
1659
1660/* The result of a Iop_CmpFxx operation is a condition code. It is
1661 encoded using the values defined in type IRCmpFxxResult.
1662 Before we can store the condition code into the guest state (or do
1663 anything else with it for that matter) we need to convert it to
1664 the encoding that s390 uses. This is what this function does.
1665
1666 s390 VEX b6 b2 b0 cc.1 cc.0
1667 0 0x40 EQ 1 0 0 0 0
1668 1 0x01 LT 0 0 1 0 1
1669 2 0x00 GT 0 0 0 1 0
1670 3 0x45 Unordered 1 1 1 1 1
1671
1672 The following bits from the VEX encoding are interesting:
1673 b0, b2, b6 with b0 being the LSB. We observe:
1674
1675 cc.0 = b0;
1676 cc.1 = b2 | (~b0 & ~b6)
1677
1678 with cc being the s390 condition code.
1679*/
1680static IRExpr *
1681convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1682{
1683 IRTemp cc0 = newTemp(Ity_I32);
1684 IRTemp cc1 = newTemp(Ity_I32);
1685 IRTemp b0 = newTemp(Ity_I32);
1686 IRTemp b2 = newTemp(Ity_I32);
1687 IRTemp b6 = newTemp(Ity_I32);
1688
1689 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1690 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1691 mkU32(1)));
1692 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1693 mkU32(1)));
1694
1695 assign(cc0, mkexpr(b0));
1696 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1697 binop(Iop_And32,
1698 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1699 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1700 )));
1701
1702 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1703}
1704
1705
1706/* The result of a Iop_CmpDxx operation is a condition code. It is
1707 encoded using the values defined in type IRCmpDxxResult.
1708 Before we can store the condition code into the guest state (or do
1709 anything else with it for that matter) we need to convert it to
1710 the encoding that s390 uses. This is what this function does. */
1711static IRExpr *
1712convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1713{
1714 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1715 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001716 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001717}
1718
1719
1720/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001721/*--- Build IR for formats ---*/
1722/*------------------------------------------------------------*/
1723static void
florian55085f82012-11-21 00:36:55 +00001724s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001725 UChar i)
1726{
florian55085f82012-11-21 00:36:55 +00001727 const HChar *mnm = irgen(i);
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(ENC2(MNM, UINT), mnm, i);
1731}
1732
1733static void
florian78d5ef72013-05-11 15:02:58 +00001734s390_format_E(const HChar *(*irgen)(void))
1735{
1736 const HChar *mnm = irgen();
1737
1738 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
1739 s390_disasm(ENC1(MNM), mnm);
1740}
1741
1742static void
florian55085f82012-11-21 00:36:55 +00001743s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001744 UChar r1, UShort i2)
1745{
1746 irgen(r1, i2);
1747}
1748
1749static void
florian55085f82012-11-21 00:36:55 +00001750s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001751 UChar r1, UShort i2)
1752{
florian55085f82012-11-21 00:36:55 +00001753 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001754
sewardj7ee97522011-05-09 21:45:04 +00001755 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001756 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1757}
1758
1759static void
florian55085f82012-11-21 00:36:55 +00001760s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001761 UChar r1, UShort i2)
1762{
florian55085f82012-11-21 00:36:55 +00001763 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001764
sewardj7ee97522011-05-09 21:45:04 +00001765 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001766 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1767}
1768
1769static void
florian55085f82012-11-21 00:36:55 +00001770s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001771 UChar r1, UShort i2)
1772{
florian55085f82012-11-21 00:36:55 +00001773 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001774
sewardj7ee97522011-05-09 21:45:04 +00001775 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001776 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1777}
1778
1779static void
florian55085f82012-11-21 00:36:55 +00001780s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001781 UChar r1, UChar r3, UShort i2)
1782{
florian55085f82012-11-21 00:36:55 +00001783 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001784
sewardj7ee97522011-05-09 21:45:04 +00001785 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001786 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1787}
1788
1789static void
florian55085f82012-11-21 00:36:55 +00001790s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001791 UChar r1, UChar r3, UShort i2)
1792{
florian55085f82012-11-21 00:36:55 +00001793 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001794
sewardj7ee97522011-05-09 21:45:04 +00001795 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001796 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1797}
1798
1799static void
florian55085f82012-11-21 00:36:55 +00001800s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1801 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001802 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1803{
florian55085f82012-11-21 00:36:55 +00001804 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001805
sewardj7ee97522011-05-09 21:45:04 +00001806 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001807 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1808 i5);
1809}
1810
1811static void
florian55085f82012-11-21 00:36:55 +00001812s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1813 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001814 UChar r1, UChar r2, UShort i4, UChar m3)
1815{
florian55085f82012-11-21 00:36:55 +00001816 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001817
sewardj7ee97522011-05-09 21:45:04 +00001818 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001819 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1820 r2, m3, (Int)(Short)i4);
1821}
1822
1823static void
florian55085f82012-11-21 00:36:55 +00001824s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1825 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001826 UChar r1, UChar m3, UShort i4, UChar i2)
1827{
florian55085f82012-11-21 00:36:55 +00001828 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001829
sewardj7ee97522011-05-09 21:45:04 +00001830 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001831 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1832 r1, i2, m3, (Int)(Short)i4);
1833}
1834
1835static void
florian55085f82012-11-21 00:36:55 +00001836s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1837 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001838 UChar r1, UChar m3, UShort i4, UChar i2)
1839{
florian55085f82012-11-21 00:36:55 +00001840 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001841
sewardj7ee97522011-05-09 21:45:04 +00001842 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001843 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1844 (Int)(Char)i2, m3, (Int)(Short)i4);
1845}
1846
1847static void
florian55085f82012-11-21 00:36:55 +00001848s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001849 UChar r1, UInt i2)
1850{
1851 irgen(r1, i2);
1852}
1853
1854static void
florian55085f82012-11-21 00:36:55 +00001855s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001856 UChar r1, UInt i2)
1857{
florian55085f82012-11-21 00:36:55 +00001858 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001859
sewardj7ee97522011-05-09 21:45:04 +00001860 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001861 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1862}
1863
1864static void
florian55085f82012-11-21 00:36:55 +00001865s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001866 UChar r1, UInt i2)
1867{
florian55085f82012-11-21 00:36:55 +00001868 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001869
sewardj7ee97522011-05-09 21:45:04 +00001870 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001871 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1872}
1873
1874static void
florian55085f82012-11-21 00:36:55 +00001875s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001876 UChar r1, UInt i2)
1877{
florian55085f82012-11-21 00:36:55 +00001878 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001879
sewardj7ee97522011-05-09 21:45:04 +00001880 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001881 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1882}
1883
1884static void
florian55085f82012-11-21 00:36:55 +00001885s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001886 UChar r1, UInt i2)
1887{
florian55085f82012-11-21 00:36:55 +00001888 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001889
sewardj7ee97522011-05-09 21:45:04 +00001890 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001891 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1892}
1893
1894static void
florian55085f82012-11-21 00:36:55 +00001895s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001896 IRTemp op4addr),
1897 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1898{
florian55085f82012-11-21 00:36:55 +00001899 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001900 IRTemp op4addr = newTemp(Ity_I64);
1901
1902 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1903 mkU64(0)));
1904
1905 mnm = irgen(r1, m3, i2, op4addr);
1906
sewardj7ee97522011-05-09 21:45:04 +00001907 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001908 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1909 (Int)(Char)i2, m3, d4, 0, b4);
1910}
1911
1912static void
florian55085f82012-11-21 00:36:55 +00001913s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001914 IRTemp op4addr),
1915 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1916{
florian55085f82012-11-21 00:36:55 +00001917 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001918 IRTemp op4addr = newTemp(Ity_I64);
1919
1920 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1921 mkU64(0)));
1922
1923 mnm = irgen(r1, m3, i2, op4addr);
1924
sewardj7ee97522011-05-09 21:45:04 +00001925 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001926 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1927 i2, m3, d4, 0, b4);
1928}
1929
1930static void
florian55085f82012-11-21 00:36:55 +00001931s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001932 UChar r1, UChar r2)
1933{
1934 irgen(r1, r2);
1935}
1936
1937static void
florian55085f82012-11-21 00:36:55 +00001938s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001939 UChar r1, UChar r2)
1940{
florian55085f82012-11-21 00:36:55 +00001941 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001942
sewardj7ee97522011-05-09 21:45:04 +00001943 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001944 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1945}
1946
1947static void
florian55085f82012-11-21 00:36:55 +00001948s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001949 UChar r1, UChar r2)
1950{
florian55085f82012-11-21 00:36:55 +00001951 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001952
sewardj7ee97522011-05-09 21:45:04 +00001953 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001954 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1955}
1956
1957static void
florian55085f82012-11-21 00:36:55 +00001958s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001959 UChar r1, UChar r2)
1960{
1961 irgen(r1, r2);
1962}
1963
1964static void
florian55085f82012-11-21 00:36:55 +00001965s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001966 UChar r1, UChar r2)
1967{
florian55085f82012-11-21 00:36:55 +00001968 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001969
sewardj7ee97522011-05-09 21:45:04 +00001970 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001971 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1972}
1973
1974static void
florian55085f82012-11-21 00:36:55 +00001975s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001976 UChar r1, UChar r2)
1977{
florian55085f82012-11-21 00:36:55 +00001978 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001979
sewardj7ee97522011-05-09 21:45:04 +00001980 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001981 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1982}
1983
1984static void
florian55085f82012-11-21 00:36:55 +00001985s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001986 UChar r1, UChar r2)
1987{
florian55085f82012-11-21 00:36:55 +00001988 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001989
sewardj7ee97522011-05-09 21:45:04 +00001990 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001991 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1992}
1993
1994static void
florian55085f82012-11-21 00:36:55 +00001995s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001996 UChar r1, UChar r2)
1997{
florian55085f82012-11-21 00:36:55 +00001998 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001999
sewardj7ee97522011-05-09 21:45:04 +00002000 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002001 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
2002}
2003
2004static void
florian55085f82012-11-21 00:36:55 +00002005s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002006 UChar r1)
2007{
florian55085f82012-11-21 00:36:55 +00002008 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002009
sewardj7ee97522011-05-09 21:45:04 +00002010 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002011 s390_disasm(ENC2(MNM, GPR), mnm, r1);
2012}
2013
2014static void
florian55085f82012-11-21 00:36:55 +00002015s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00002016 UChar r1)
2017{
florian55085f82012-11-21 00:36:55 +00002018 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00002019
sewardj7ee97522011-05-09 21:45:04 +00002020 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002021 s390_disasm(ENC2(MNM, FPR), mnm, r1);
2022}
2023
2024static void
florian55085f82012-11-21 00:36:55 +00002025s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002026 UChar m3, UChar r1, UChar r2)
2027{
florian55085f82012-11-21 00:36:55 +00002028 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002029
2030 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002031 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002032}
2033
2034static void
florian55085f82012-11-21 00:36:55 +00002035s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002036 UChar r1, UChar r3, UChar r2)
2037{
florian55085f82012-11-21 00:36:55 +00002038 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002039
sewardj7ee97522011-05-09 21:45:04 +00002040 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002041 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2042}
2043
2044static void
florian5c539732013-02-14 14:27:12 +00002045s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2046 UChar r3, UChar r1, UChar r2)
2047{
2048 const HChar *mnm = irgen(r3, r1, r2);
2049
2050 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2051 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2052}
2053
2054static void
florian55085f82012-11-21 00:36:55 +00002055s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2056 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002057 UChar m3, UChar m4, UChar r1, UChar r2)
2058{
florian55085f82012-11-21 00:36:55 +00002059 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002060
2061 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2062 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2063}
2064
2065static void
floriane38f6412012-12-21 17:32:12 +00002066s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2067 UChar m4, UChar r1, UChar r2)
2068{
2069 const HChar *mnm = irgen(m4, r1, r2);
2070
2071 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2072 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2073}
2074
2075static void
florian55085f82012-11-21 00:36:55 +00002076s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2077 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002078 UChar m3, UChar m4, UChar r1, UChar r2)
2079{
florian55085f82012-11-21 00:36:55 +00002080 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002081
2082 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2083 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2084}
2085
2086static void
florian55085f82012-11-21 00:36:55 +00002087s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2088 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002089 UChar m3, UChar m4, UChar r1, UChar r2)
2090{
florian55085f82012-11-21 00:36:55 +00002091 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002092
2093 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2094 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2095}
2096
2097
2098static void
florian55085f82012-11-21 00:36:55 +00002099s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002100 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2101{
2102 irgen(m3, r1, r2);
2103
sewardj7ee97522011-05-09 21:45:04 +00002104 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002105 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2106}
2107
2108static void
florian55085f82012-11-21 00:36:55 +00002109s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002110 UChar r3, UChar r1, UChar r2)
2111{
florian55085f82012-11-21 00:36:55 +00002112 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002113
sewardj7ee97522011-05-09 21:45:04 +00002114 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002115 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2116}
2117
2118static void
florian5c539732013-02-14 14:27:12 +00002119s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2120 UChar r3, UChar m4, UChar r1, UChar r2)
2121{
2122 const HChar *mnm = irgen(r3, m4, r1, r2);
2123
2124 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2125 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2126}
2127
2128static void
2129s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2130 UChar r3, UChar m4, UChar r1, UChar r2)
2131{
2132 const HChar *mnm = irgen(r3, m4, r1, r2);
2133
2134 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2135 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2136}
2137
2138static void
florian55085f82012-11-21 00:36:55 +00002139s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002140 UChar r3, UChar m4, UChar r1, UChar r2)
2141{
florian55085f82012-11-21 00:36:55 +00002142 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002143
2144 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2145 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2146}
2147
2148static void
florian55085f82012-11-21 00:36:55 +00002149s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002150 UChar r3, UChar r1, UChar r2)
2151{
florian55085f82012-11-21 00:36:55 +00002152 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002153
sewardj7ee97522011-05-09 21:45:04 +00002154 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002155 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2156}
2157
2158static void
florian55085f82012-11-21 00:36:55 +00002159s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2160 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002161 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2162{
florian55085f82012-11-21 00:36:55 +00002163 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002164 IRTemp op4addr = newTemp(Ity_I64);
2165
2166 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2167 mkU64(0)));
2168
2169 mnm = irgen(r1, r2, m3, op4addr);
2170
sewardj7ee97522011-05-09 21:45:04 +00002171 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002172 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2173 r2, m3, d4, 0, b4);
2174}
2175
2176static void
florian55085f82012-11-21 00:36:55 +00002177s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002178 UChar r1, UChar b2, UShort d2)
2179{
florian55085f82012-11-21 00:36:55 +00002180 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002181 IRTemp op2addr = newTemp(Ity_I64);
2182
2183 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2184 mkU64(0)));
2185
2186 mnm = irgen(r1, op2addr);
2187
sewardj7ee97522011-05-09 21:45:04 +00002188 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002189 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2190}
2191
2192static void
florian55085f82012-11-21 00:36:55 +00002193s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002194 UChar r1, UChar r3, UChar b2, UShort d2)
2195{
florian55085f82012-11-21 00:36:55 +00002196 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002197 IRTemp op2addr = newTemp(Ity_I64);
2198
2199 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2200 mkU64(0)));
2201
2202 mnm = irgen(r1, r3, op2addr);
2203
sewardj7ee97522011-05-09 21:45:04 +00002204 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002205 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2206}
2207
2208static void
florian55085f82012-11-21 00:36:55 +00002209s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002210 UChar r1, UChar r3, UChar b2, UShort d2)
2211{
florian55085f82012-11-21 00:36:55 +00002212 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002213 IRTemp op2addr = newTemp(Ity_I64);
2214
2215 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2216 mkU64(0)));
2217
2218 mnm = irgen(r1, r3, op2addr);
2219
sewardj7ee97522011-05-09 21:45:04 +00002220 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002221 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2222}
2223
2224static void
florian55085f82012-11-21 00:36:55 +00002225s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002226 UChar r1, UChar r3, UChar b2, UShort d2)
2227{
florian55085f82012-11-21 00:36:55 +00002228 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002229 IRTemp op2addr = newTemp(Ity_I64);
2230
2231 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2232 mkU64(0)));
2233
2234 mnm = irgen(r1, r3, op2addr);
2235
sewardj7ee97522011-05-09 21:45:04 +00002236 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002237 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2238}
2239
2240static void
florian55085f82012-11-21 00:36:55 +00002241s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002242 UChar r1, UChar r3, UShort i2)
2243{
florian55085f82012-11-21 00:36:55 +00002244 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002245
sewardj7ee97522011-05-09 21:45:04 +00002246 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002247 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2248}
2249
2250static void
florian55085f82012-11-21 00:36:55 +00002251s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002252 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2253{
florian55085f82012-11-21 00:36:55 +00002254 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002255 IRTemp op2addr = newTemp(Ity_I64);
2256 IRTemp d2 = newTemp(Ity_I64);
2257
2258 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 mnm = irgen(r1, r3, op2addr);
2263
sewardj7ee97522011-05-09 21:45:04 +00002264 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002265 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2266}
2267
2268static void
florian55085f82012-11-21 00:36:55 +00002269s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002270 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2271{
florian55085f82012-11-21 00:36:55 +00002272 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002273 IRTemp op2addr = newTemp(Ity_I64);
2274 IRTemp d2 = newTemp(Ity_I64);
2275
2276 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2277 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2278 mkU64(0)));
2279
2280 mnm = irgen(r1, r3, op2addr);
2281
sewardj7ee97522011-05-09 21:45:04 +00002282 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002283 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2284}
2285
2286static void
florian55085f82012-11-21 00:36:55 +00002287s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002288 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2289{
florian55085f82012-11-21 00:36:55 +00002290 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002291 IRTemp op2addr = newTemp(Ity_I64);
2292 IRTemp d2 = newTemp(Ity_I64);
2293
2294 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2295 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2296 mkU64(0)));
2297
2298 mnm = irgen(r1, r3, op2addr);
2299
sewardj7ee97522011-05-09 21:45:04 +00002300 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002301 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2302}
2303
2304static void
florian55085f82012-11-21 00:36:55 +00002305s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002306 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2307 Int xmnm_kind)
2308{
2309 IRTemp op2addr = newTemp(Ity_I64);
2310 IRTemp d2 = newTemp(Ity_I64);
2311
florian6820ba52012-07-26 02:01:50 +00002312 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2313
sewardjd7bde722011-04-05 13:19:33 +00002314 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2315 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2316 mkU64(0)));
2317
2318 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002319
2320 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002321
sewardj7ee97522011-05-09 21:45:04 +00002322 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002323 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2324}
2325
2326static void
florian55085f82012-11-21 00:36:55 +00002327s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002328 IRTemp op2addr),
2329 UChar r1, UChar x2, UChar b2, UShort d2)
2330{
2331 IRTemp op2addr = newTemp(Ity_I64);
2332
2333 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2334 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2335 mkU64(0)));
2336
2337 irgen(r1, x2, b2, d2, op2addr);
2338}
2339
2340static void
florian55085f82012-11-21 00:36:55 +00002341s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002342 UChar r1, UChar x2, UChar b2, UShort d2)
2343{
florian55085f82012-11-21 00:36:55 +00002344 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002345 IRTemp op2addr = newTemp(Ity_I64);
2346
2347 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2348 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2349 mkU64(0)));
2350
2351 mnm = irgen(r1, op2addr);
2352
sewardj7ee97522011-05-09 21:45:04 +00002353 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002354 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2355}
2356
2357static void
florian55085f82012-11-21 00:36:55 +00002358s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002359 UChar r1, UChar x2, UChar b2, UShort d2)
2360{
florian55085f82012-11-21 00:36:55 +00002361 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002362 IRTemp op2addr = newTemp(Ity_I64);
2363
2364 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2365 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2366 mkU64(0)));
2367
2368 mnm = irgen(r1, op2addr);
2369
sewardj7ee97522011-05-09 21:45:04 +00002370 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002371 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2372}
2373
2374static void
florian55085f82012-11-21 00:36:55 +00002375s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002376 UChar r1, UChar x2, UChar b2, UShort d2)
2377{
florian55085f82012-11-21 00:36:55 +00002378 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002379 IRTemp op2addr = newTemp(Ity_I64);
2380
2381 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2382 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2383 mkU64(0)));
2384
2385 mnm = irgen(r1, op2addr);
2386
sewardj7ee97522011-05-09 21:45:04 +00002387 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002388 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2389}
2390
2391static void
florian55085f82012-11-21 00:36:55 +00002392s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002393 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2394{
florian55085f82012-11-21 00:36:55 +00002395 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002396 IRTemp op2addr = newTemp(Ity_I64);
2397
2398 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2399 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2400 mkU64(0)));
2401
2402 mnm = irgen(r3, op2addr, r1);
2403
sewardj7ee97522011-05-09 21:45:04 +00002404 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002405 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2406}
2407
2408static void
florian55085f82012-11-21 00:36:55 +00002409s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002410 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2411{
florian55085f82012-11-21 00:36:55 +00002412 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002413 IRTemp op2addr = newTemp(Ity_I64);
2414 IRTemp d2 = newTemp(Ity_I64);
2415
2416 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2417 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2418 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2419 mkU64(0)));
2420
2421 mnm = irgen(r1, op2addr);
2422
sewardj7ee97522011-05-09 21:45:04 +00002423 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002424 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2425}
2426
2427static void
florian55085f82012-11-21 00:36:55 +00002428s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002429 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2430{
florian55085f82012-11-21 00:36:55 +00002431 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002432 IRTemp op2addr = newTemp(Ity_I64);
2433 IRTemp d2 = newTemp(Ity_I64);
2434
2435 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2436 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2437 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2438 mkU64(0)));
2439
2440 mnm = irgen(r1, op2addr);
2441
sewardj7ee97522011-05-09 21:45:04 +00002442 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002443 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2444}
2445
2446static void
florian55085f82012-11-21 00:36:55 +00002447s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002448 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2449{
florian55085f82012-11-21 00:36:55 +00002450 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002451 IRTemp op2addr = newTemp(Ity_I64);
2452 IRTemp d2 = newTemp(Ity_I64);
2453
2454 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2455 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2456 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2457 mkU64(0)));
2458
2459 mnm = irgen();
2460
sewardj7ee97522011-05-09 21:45:04 +00002461 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002462 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2463}
2464
2465static void
florian55085f82012-11-21 00:36:55 +00002466s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002467 UChar b2, UShort d2)
2468{
florian55085f82012-11-21 00:36:55 +00002469 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002470 IRTemp op2addr = newTemp(Ity_I64);
2471
2472 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2473 mkU64(0)));
2474
2475 mnm = irgen(op2addr);
2476
sewardj7ee97522011-05-09 21:45:04 +00002477 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002478 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2479}
2480
2481static void
florian55085f82012-11-21 00:36:55 +00002482s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002483 UChar i2, UChar b1, UShort d1)
2484{
florian55085f82012-11-21 00:36:55 +00002485 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002486 IRTemp op1addr = newTemp(Ity_I64);
2487
2488 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2489 mkU64(0)));
2490
2491 mnm = irgen(i2, op1addr);
2492
sewardj7ee97522011-05-09 21:45:04 +00002493 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002494 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2495}
2496
2497static void
florian55085f82012-11-21 00:36:55 +00002498s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002499 UChar i2, UChar b1, UShort dl1, UChar dh1)
2500{
florian55085f82012-11-21 00:36:55 +00002501 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002502 IRTemp op1addr = newTemp(Ity_I64);
2503 IRTemp d1 = newTemp(Ity_I64);
2504
2505 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2506 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2507 mkU64(0)));
2508
2509 mnm = irgen(i2, op1addr);
2510
sewardj7ee97522011-05-09 21:45:04 +00002511 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002512 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2513}
2514
2515static void
florian55085f82012-11-21 00:36:55 +00002516s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002517 UChar i2, UChar b1, UShort dl1, UChar dh1)
2518{
florian55085f82012-11-21 00:36:55 +00002519 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002520 IRTemp op1addr = newTemp(Ity_I64);
2521 IRTemp d1 = newTemp(Ity_I64);
2522
2523 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2524 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2525 mkU64(0)));
2526
2527 mnm = irgen(i2, op1addr);
2528
sewardj7ee97522011-05-09 21:45:04 +00002529 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002530 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2531}
2532
2533static void
florian55085f82012-11-21 00:36:55 +00002534s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002535 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2536{
florian55085f82012-11-21 00:36:55 +00002537 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002538 IRTemp op1addr = newTemp(Ity_I64);
2539 IRTemp op2addr = newTemp(Ity_I64);
2540
2541 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2542 mkU64(0)));
2543 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2544 mkU64(0)));
2545
2546 mnm = irgen(l, op1addr, op2addr);
2547
sewardj7ee97522011-05-09 21:45:04 +00002548 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002549 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2550}
2551
2552static void
florian55085f82012-11-21 00:36:55 +00002553s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002554 UChar b1, UShort d1, UShort i2)
2555{
florian55085f82012-11-21 00:36:55 +00002556 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002557 IRTemp op1addr = newTemp(Ity_I64);
2558
2559 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2560 mkU64(0)));
2561
2562 mnm = irgen(i2, op1addr);
2563
sewardj7ee97522011-05-09 21:45:04 +00002564 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002565 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2566}
2567
2568static void
florian55085f82012-11-21 00:36:55 +00002569s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002570 UChar b1, UShort d1, UShort i2)
2571{
florian55085f82012-11-21 00:36:55 +00002572 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002573 IRTemp op1addr = newTemp(Ity_I64);
2574
2575 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2576 mkU64(0)));
2577
2578 mnm = irgen(i2, op1addr);
2579
sewardj7ee97522011-05-09 21:45:04 +00002580 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002581 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2582}
2583
2584
2585
2586/*------------------------------------------------------------*/
2587/*--- Build IR for opcodes ---*/
2588/*------------------------------------------------------------*/
2589
florian55085f82012-11-21 00:36:55 +00002590static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002591s390_irgen_AR(UChar r1, UChar r2)
2592{
2593 IRTemp op1 = newTemp(Ity_I32);
2594 IRTemp op2 = newTemp(Ity_I32);
2595 IRTemp result = newTemp(Ity_I32);
2596
2597 assign(op1, get_gpr_w1(r1));
2598 assign(op2, get_gpr_w1(r2));
2599 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2600 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2601 put_gpr_w1(r1, mkexpr(result));
2602
2603 return "ar";
2604}
2605
florian55085f82012-11-21 00:36:55 +00002606static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002607s390_irgen_AGR(UChar r1, UChar r2)
2608{
2609 IRTemp op1 = newTemp(Ity_I64);
2610 IRTemp op2 = newTemp(Ity_I64);
2611 IRTemp result = newTemp(Ity_I64);
2612
2613 assign(op1, get_gpr_dw0(r1));
2614 assign(op2, get_gpr_dw0(r2));
2615 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2616 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2617 put_gpr_dw0(r1, mkexpr(result));
2618
2619 return "agr";
2620}
2621
florian55085f82012-11-21 00:36:55 +00002622static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002623s390_irgen_AGFR(UChar r1, UChar r2)
2624{
2625 IRTemp op1 = newTemp(Ity_I64);
2626 IRTemp op2 = newTemp(Ity_I64);
2627 IRTemp result = newTemp(Ity_I64);
2628
2629 assign(op1, get_gpr_dw0(r1));
2630 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2631 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2632 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2633 put_gpr_dw0(r1, mkexpr(result));
2634
2635 return "agfr";
2636}
2637
florian55085f82012-11-21 00:36:55 +00002638static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002639s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2640{
2641 IRTemp op2 = newTemp(Ity_I32);
2642 IRTemp op3 = newTemp(Ity_I32);
2643 IRTemp result = newTemp(Ity_I32);
2644
2645 assign(op2, get_gpr_w1(r2));
2646 assign(op3, get_gpr_w1(r3));
2647 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2648 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2649 put_gpr_w1(r1, mkexpr(result));
2650
2651 return "ark";
2652}
2653
florian55085f82012-11-21 00:36:55 +00002654static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002655s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2656{
2657 IRTemp op2 = newTemp(Ity_I64);
2658 IRTemp op3 = newTemp(Ity_I64);
2659 IRTemp result = newTemp(Ity_I64);
2660
2661 assign(op2, get_gpr_dw0(r2));
2662 assign(op3, get_gpr_dw0(r3));
2663 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2664 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2665 put_gpr_dw0(r1, mkexpr(result));
2666
2667 return "agrk";
2668}
2669
florian55085f82012-11-21 00:36:55 +00002670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002671s390_irgen_A(UChar r1, IRTemp op2addr)
2672{
2673 IRTemp op1 = newTemp(Ity_I32);
2674 IRTemp op2 = newTemp(Ity_I32);
2675 IRTemp result = newTemp(Ity_I32);
2676
2677 assign(op1, get_gpr_w1(r1));
2678 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2679 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2680 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2681 put_gpr_w1(r1, mkexpr(result));
2682
2683 return "a";
2684}
2685
florian55085f82012-11-21 00:36:55 +00002686static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002687s390_irgen_AY(UChar r1, IRTemp op2addr)
2688{
2689 IRTemp op1 = newTemp(Ity_I32);
2690 IRTemp op2 = newTemp(Ity_I32);
2691 IRTemp result = newTemp(Ity_I32);
2692
2693 assign(op1, get_gpr_w1(r1));
2694 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2695 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2696 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2697 put_gpr_w1(r1, mkexpr(result));
2698
2699 return "ay";
2700}
2701
florian55085f82012-11-21 00:36:55 +00002702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002703s390_irgen_AG(UChar r1, IRTemp op2addr)
2704{
2705 IRTemp op1 = newTemp(Ity_I64);
2706 IRTemp op2 = newTemp(Ity_I64);
2707 IRTemp result = newTemp(Ity_I64);
2708
2709 assign(op1, get_gpr_dw0(r1));
2710 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2711 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2712 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2713 put_gpr_dw0(r1, mkexpr(result));
2714
2715 return "ag";
2716}
2717
florian55085f82012-11-21 00:36:55 +00002718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002719s390_irgen_AGF(UChar r1, IRTemp op2addr)
2720{
2721 IRTemp op1 = newTemp(Ity_I64);
2722 IRTemp op2 = newTemp(Ity_I64);
2723 IRTemp result = newTemp(Ity_I64);
2724
2725 assign(op1, get_gpr_dw0(r1));
2726 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2727 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2728 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2729 put_gpr_dw0(r1, mkexpr(result));
2730
2731 return "agf";
2732}
2733
florian55085f82012-11-21 00:36:55 +00002734static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002735s390_irgen_AFI(UChar r1, UInt i2)
2736{
2737 IRTemp op1 = newTemp(Ity_I32);
2738 Int op2;
2739 IRTemp result = newTemp(Ity_I32);
2740
2741 assign(op1, get_gpr_w1(r1));
2742 op2 = (Int)i2;
2743 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2744 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2745 mkU32((UInt)op2)));
2746 put_gpr_w1(r1, mkexpr(result));
2747
2748 return "afi";
2749}
2750
florian55085f82012-11-21 00:36:55 +00002751static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002752s390_irgen_AGFI(UChar r1, UInt i2)
2753{
2754 IRTemp op1 = newTemp(Ity_I64);
2755 Long op2;
2756 IRTemp result = newTemp(Ity_I64);
2757
2758 assign(op1, get_gpr_dw0(r1));
2759 op2 = (Long)(Int)i2;
2760 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2761 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2762 mkU64((ULong)op2)));
2763 put_gpr_dw0(r1, mkexpr(result));
2764
2765 return "agfi";
2766}
2767
florian55085f82012-11-21 00:36:55 +00002768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002769s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2770{
2771 Int op2;
2772 IRTemp op3 = newTemp(Ity_I32);
2773 IRTemp result = newTemp(Ity_I32);
2774
2775 op2 = (Int)(Short)i2;
2776 assign(op3, get_gpr_w1(r3));
2777 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2778 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2779 op2)), op3);
2780 put_gpr_w1(r1, mkexpr(result));
2781
2782 return "ahik";
2783}
2784
florian55085f82012-11-21 00:36:55 +00002785static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002786s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2787{
2788 Long op2;
2789 IRTemp op3 = newTemp(Ity_I64);
2790 IRTemp result = newTemp(Ity_I64);
2791
2792 op2 = (Long)(Short)i2;
2793 assign(op3, get_gpr_dw0(r3));
2794 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2795 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2796 op2)), op3);
2797 put_gpr_dw0(r1, mkexpr(result));
2798
2799 return "aghik";
2800}
2801
florian55085f82012-11-21 00:36:55 +00002802static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002803s390_irgen_ASI(UChar i2, IRTemp op1addr)
2804{
2805 IRTemp op1 = newTemp(Ity_I32);
2806 Int op2;
2807 IRTemp result = newTemp(Ity_I32);
2808
2809 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2810 op2 = (Int)(Char)i2;
2811 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2812 store(mkexpr(op1addr), mkexpr(result));
2813 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2814 mkU32((UInt)op2)));
2815
2816 return "asi";
2817}
2818
florian55085f82012-11-21 00:36:55 +00002819static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002820s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2821{
2822 IRTemp op1 = newTemp(Ity_I64);
2823 Long op2;
2824 IRTemp result = newTemp(Ity_I64);
2825
2826 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2827 op2 = (Long)(Char)i2;
2828 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2829 store(mkexpr(op1addr), mkexpr(result));
2830 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2831 mkU64((ULong)op2)));
2832
2833 return "agsi";
2834}
2835
florian55085f82012-11-21 00:36:55 +00002836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002837s390_irgen_AH(UChar r1, IRTemp op2addr)
2838{
2839 IRTemp op1 = newTemp(Ity_I32);
2840 IRTemp op2 = newTemp(Ity_I32);
2841 IRTemp result = newTemp(Ity_I32);
2842
2843 assign(op1, get_gpr_w1(r1));
2844 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2845 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2846 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2847 put_gpr_w1(r1, mkexpr(result));
2848
2849 return "ah";
2850}
2851
florian55085f82012-11-21 00:36:55 +00002852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002853s390_irgen_AHY(UChar r1, IRTemp op2addr)
2854{
2855 IRTemp op1 = newTemp(Ity_I32);
2856 IRTemp op2 = newTemp(Ity_I32);
2857 IRTemp result = newTemp(Ity_I32);
2858
2859 assign(op1, get_gpr_w1(r1));
2860 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2861 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2862 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2863 put_gpr_w1(r1, mkexpr(result));
2864
2865 return "ahy";
2866}
2867
florian55085f82012-11-21 00:36:55 +00002868static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002869s390_irgen_AHI(UChar r1, UShort i2)
2870{
2871 IRTemp op1 = newTemp(Ity_I32);
2872 Int op2;
2873 IRTemp result = newTemp(Ity_I32);
2874
2875 assign(op1, get_gpr_w1(r1));
2876 op2 = (Int)(Short)i2;
2877 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2878 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2879 mkU32((UInt)op2)));
2880 put_gpr_w1(r1, mkexpr(result));
2881
2882 return "ahi";
2883}
2884
florian55085f82012-11-21 00:36:55 +00002885static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002886s390_irgen_AGHI(UChar r1, UShort i2)
2887{
2888 IRTemp op1 = newTemp(Ity_I64);
2889 Long op2;
2890 IRTemp result = newTemp(Ity_I64);
2891
2892 assign(op1, get_gpr_dw0(r1));
2893 op2 = (Long)(Short)i2;
2894 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2895 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2896 mkU64((ULong)op2)));
2897 put_gpr_dw0(r1, mkexpr(result));
2898
2899 return "aghi";
2900}
2901
florian55085f82012-11-21 00:36:55 +00002902static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002903s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2904{
2905 IRTemp op2 = newTemp(Ity_I32);
2906 IRTemp op3 = newTemp(Ity_I32);
2907 IRTemp result = newTemp(Ity_I32);
2908
2909 assign(op2, get_gpr_w0(r2));
2910 assign(op3, get_gpr_w0(r3));
2911 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2912 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2913 put_gpr_w0(r1, mkexpr(result));
2914
2915 return "ahhhr";
2916}
2917
florian55085f82012-11-21 00:36:55 +00002918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002919s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2920{
2921 IRTemp op2 = newTemp(Ity_I32);
2922 IRTemp op3 = newTemp(Ity_I32);
2923 IRTemp result = newTemp(Ity_I32);
2924
2925 assign(op2, get_gpr_w0(r2));
2926 assign(op3, get_gpr_w1(r3));
2927 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2928 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2929 put_gpr_w0(r1, mkexpr(result));
2930
2931 return "ahhlr";
2932}
2933
florian55085f82012-11-21 00:36:55 +00002934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002935s390_irgen_AIH(UChar r1, UInt i2)
2936{
2937 IRTemp op1 = newTemp(Ity_I32);
2938 Int op2;
2939 IRTemp result = newTemp(Ity_I32);
2940
2941 assign(op1, get_gpr_w0(r1));
2942 op2 = (Int)i2;
2943 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2944 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2945 mkU32((UInt)op2)));
2946 put_gpr_w0(r1, mkexpr(result));
2947
2948 return "aih";
2949}
2950
florian55085f82012-11-21 00:36:55 +00002951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002952s390_irgen_ALR(UChar r1, UChar r2)
2953{
2954 IRTemp op1 = newTemp(Ity_I32);
2955 IRTemp op2 = newTemp(Ity_I32);
2956 IRTemp result = newTemp(Ity_I32);
2957
2958 assign(op1, get_gpr_w1(r1));
2959 assign(op2, get_gpr_w1(r2));
2960 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2961 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2962 put_gpr_w1(r1, mkexpr(result));
2963
2964 return "alr";
2965}
2966
florian55085f82012-11-21 00:36:55 +00002967static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002968s390_irgen_ALGR(UChar r1, UChar r2)
2969{
2970 IRTemp op1 = newTemp(Ity_I64);
2971 IRTemp op2 = newTemp(Ity_I64);
2972 IRTemp result = newTemp(Ity_I64);
2973
2974 assign(op1, get_gpr_dw0(r1));
2975 assign(op2, get_gpr_dw0(r2));
2976 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2977 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2978 put_gpr_dw0(r1, mkexpr(result));
2979
2980 return "algr";
2981}
2982
florian55085f82012-11-21 00:36:55 +00002983static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002984s390_irgen_ALGFR(UChar r1, UChar r2)
2985{
2986 IRTemp op1 = newTemp(Ity_I64);
2987 IRTemp op2 = newTemp(Ity_I64);
2988 IRTemp result = newTemp(Ity_I64);
2989
2990 assign(op1, get_gpr_dw0(r1));
2991 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2992 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2993 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2994 put_gpr_dw0(r1, mkexpr(result));
2995
2996 return "algfr";
2997}
2998
florian55085f82012-11-21 00:36:55 +00002999static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003000s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
3001{
3002 IRTemp op2 = newTemp(Ity_I32);
3003 IRTemp op3 = newTemp(Ity_I32);
3004 IRTemp result = newTemp(Ity_I32);
3005
3006 assign(op2, get_gpr_w1(r2));
3007 assign(op3, get_gpr_w1(r3));
3008 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3009 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3010 put_gpr_w1(r1, mkexpr(result));
3011
3012 return "alrk";
3013}
3014
florian55085f82012-11-21 00:36:55 +00003015static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003016s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
3017{
3018 IRTemp op2 = newTemp(Ity_I64);
3019 IRTemp op3 = newTemp(Ity_I64);
3020 IRTemp result = newTemp(Ity_I64);
3021
3022 assign(op2, get_gpr_dw0(r2));
3023 assign(op3, get_gpr_dw0(r3));
3024 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
3025 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3026 put_gpr_dw0(r1, mkexpr(result));
3027
3028 return "algrk";
3029}
3030
florian55085f82012-11-21 00:36:55 +00003031static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003032s390_irgen_AL(UChar r1, IRTemp op2addr)
3033{
3034 IRTemp op1 = newTemp(Ity_I32);
3035 IRTemp op2 = newTemp(Ity_I32);
3036 IRTemp result = newTemp(Ity_I32);
3037
3038 assign(op1, get_gpr_w1(r1));
3039 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3040 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3041 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3042 put_gpr_w1(r1, mkexpr(result));
3043
3044 return "al";
3045}
3046
florian55085f82012-11-21 00:36:55 +00003047static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003048s390_irgen_ALY(UChar r1, IRTemp op2addr)
3049{
3050 IRTemp op1 = newTemp(Ity_I32);
3051 IRTemp op2 = newTemp(Ity_I32);
3052 IRTemp result = newTemp(Ity_I32);
3053
3054 assign(op1, get_gpr_w1(r1));
3055 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3056 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3057 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3058 put_gpr_w1(r1, mkexpr(result));
3059
3060 return "aly";
3061}
3062
florian55085f82012-11-21 00:36:55 +00003063static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003064s390_irgen_ALG(UChar r1, IRTemp op2addr)
3065{
3066 IRTemp op1 = newTemp(Ity_I64);
3067 IRTemp op2 = newTemp(Ity_I64);
3068 IRTemp result = newTemp(Ity_I64);
3069
3070 assign(op1, get_gpr_dw0(r1));
3071 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3072 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3073 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3074 put_gpr_dw0(r1, mkexpr(result));
3075
3076 return "alg";
3077}
3078
florian55085f82012-11-21 00:36:55 +00003079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003080s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3081{
3082 IRTemp op1 = newTemp(Ity_I64);
3083 IRTemp op2 = newTemp(Ity_I64);
3084 IRTemp result = newTemp(Ity_I64);
3085
3086 assign(op1, get_gpr_dw0(r1));
3087 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3088 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3089 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3090 put_gpr_dw0(r1, mkexpr(result));
3091
3092 return "algf";
3093}
3094
florian55085f82012-11-21 00:36:55 +00003095static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003096s390_irgen_ALFI(UChar r1, UInt i2)
3097{
3098 IRTemp op1 = newTemp(Ity_I32);
3099 UInt op2;
3100 IRTemp result = newTemp(Ity_I32);
3101
3102 assign(op1, get_gpr_w1(r1));
3103 op2 = i2;
3104 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3105 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3106 mkU32(op2)));
3107 put_gpr_w1(r1, mkexpr(result));
3108
3109 return "alfi";
3110}
3111
florian55085f82012-11-21 00:36:55 +00003112static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003113s390_irgen_ALGFI(UChar r1, UInt i2)
3114{
3115 IRTemp op1 = newTemp(Ity_I64);
3116 ULong op2;
3117 IRTemp result = newTemp(Ity_I64);
3118
3119 assign(op1, get_gpr_dw0(r1));
3120 op2 = (ULong)i2;
3121 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3122 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3123 mkU64(op2)));
3124 put_gpr_dw0(r1, mkexpr(result));
3125
3126 return "algfi";
3127}
3128
florian55085f82012-11-21 00:36:55 +00003129static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003130s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3131{
3132 IRTemp op2 = newTemp(Ity_I32);
3133 IRTemp op3 = newTemp(Ity_I32);
3134 IRTemp result = newTemp(Ity_I32);
3135
3136 assign(op2, get_gpr_w0(r2));
3137 assign(op3, get_gpr_w0(r3));
3138 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3139 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3140 put_gpr_w0(r1, mkexpr(result));
3141
3142 return "alhhhr";
3143}
3144
florian55085f82012-11-21 00:36:55 +00003145static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003146s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3147{
3148 IRTemp op2 = newTemp(Ity_I32);
3149 IRTemp op3 = newTemp(Ity_I32);
3150 IRTemp result = newTemp(Ity_I32);
3151
3152 assign(op2, get_gpr_w0(r2));
3153 assign(op3, get_gpr_w1(r3));
3154 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3155 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3156 put_gpr_w0(r1, mkexpr(result));
3157
3158 return "alhhlr";
3159}
3160
florian55085f82012-11-21 00:36:55 +00003161static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003162s390_irgen_ALCR(UChar r1, UChar r2)
3163{
3164 IRTemp op1 = newTemp(Ity_I32);
3165 IRTemp op2 = newTemp(Ity_I32);
3166 IRTemp result = newTemp(Ity_I32);
3167 IRTemp carry_in = newTemp(Ity_I32);
3168
3169 assign(op1, get_gpr_w1(r1));
3170 assign(op2, get_gpr_w1(r2));
3171 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3172 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3173 mkexpr(carry_in)));
3174 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3175 put_gpr_w1(r1, mkexpr(result));
3176
3177 return "alcr";
3178}
3179
florian55085f82012-11-21 00:36:55 +00003180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003181s390_irgen_ALCGR(UChar r1, UChar r2)
3182{
3183 IRTemp op1 = newTemp(Ity_I64);
3184 IRTemp op2 = newTemp(Ity_I64);
3185 IRTemp result = newTemp(Ity_I64);
3186 IRTemp carry_in = newTemp(Ity_I64);
3187
3188 assign(op1, get_gpr_dw0(r1));
3189 assign(op2, get_gpr_dw0(r2));
3190 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3191 mkU8(1))));
3192 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3193 mkexpr(carry_in)));
3194 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3195 put_gpr_dw0(r1, mkexpr(result));
3196
3197 return "alcgr";
3198}
3199
florian55085f82012-11-21 00:36:55 +00003200static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003201s390_irgen_ALC(UChar r1, IRTemp op2addr)
3202{
3203 IRTemp op1 = newTemp(Ity_I32);
3204 IRTemp op2 = newTemp(Ity_I32);
3205 IRTemp result = newTemp(Ity_I32);
3206 IRTemp carry_in = newTemp(Ity_I32);
3207
3208 assign(op1, get_gpr_w1(r1));
3209 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3210 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3211 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3212 mkexpr(carry_in)));
3213 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3214 put_gpr_w1(r1, mkexpr(result));
3215
3216 return "alc";
3217}
3218
florian55085f82012-11-21 00:36:55 +00003219static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003220s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3221{
3222 IRTemp op1 = newTemp(Ity_I64);
3223 IRTemp op2 = newTemp(Ity_I64);
3224 IRTemp result = newTemp(Ity_I64);
3225 IRTemp carry_in = newTemp(Ity_I64);
3226
3227 assign(op1, get_gpr_dw0(r1));
3228 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3229 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3230 mkU8(1))));
3231 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3232 mkexpr(carry_in)));
3233 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3234 put_gpr_dw0(r1, mkexpr(result));
3235
3236 return "alcg";
3237}
3238
florian55085f82012-11-21 00:36:55 +00003239static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003240s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3241{
3242 IRTemp op1 = newTemp(Ity_I32);
3243 UInt op2;
3244 IRTemp result = newTemp(Ity_I32);
3245
3246 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3247 op2 = (UInt)(Int)(Char)i2;
3248 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3249 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3250 mkU32(op2)));
3251 store(mkexpr(op1addr), mkexpr(result));
3252
3253 return "alsi";
3254}
3255
florian55085f82012-11-21 00:36:55 +00003256static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003257s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3258{
3259 IRTemp op1 = newTemp(Ity_I64);
3260 ULong op2;
3261 IRTemp result = newTemp(Ity_I64);
3262
3263 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3264 op2 = (ULong)(Long)(Char)i2;
3265 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3266 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3267 mkU64(op2)));
3268 store(mkexpr(op1addr), mkexpr(result));
3269
3270 return "algsi";
3271}
3272
florian55085f82012-11-21 00:36:55 +00003273static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003274s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3275{
3276 UInt op2;
3277 IRTemp op3 = newTemp(Ity_I32);
3278 IRTemp result = newTemp(Ity_I32);
3279
3280 op2 = (UInt)(Int)(Short)i2;
3281 assign(op3, get_gpr_w1(r3));
3282 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3283 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3284 op3);
3285 put_gpr_w1(r1, mkexpr(result));
3286
3287 return "alhsik";
3288}
3289
florian55085f82012-11-21 00:36:55 +00003290static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003291s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3292{
3293 ULong op2;
3294 IRTemp op3 = newTemp(Ity_I64);
3295 IRTemp result = newTemp(Ity_I64);
3296
3297 op2 = (ULong)(Long)(Short)i2;
3298 assign(op3, get_gpr_dw0(r3));
3299 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3300 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3301 op3);
3302 put_gpr_dw0(r1, mkexpr(result));
3303
3304 return "alghsik";
3305}
3306
florian55085f82012-11-21 00:36:55 +00003307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003308s390_irgen_ALSIH(UChar r1, UInt i2)
3309{
3310 IRTemp op1 = newTemp(Ity_I32);
3311 UInt op2;
3312 IRTemp result = newTemp(Ity_I32);
3313
3314 assign(op1, get_gpr_w0(r1));
3315 op2 = i2;
3316 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3317 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3318 mkU32(op2)));
3319 put_gpr_w0(r1, mkexpr(result));
3320
3321 return "alsih";
3322}
3323
florian55085f82012-11-21 00:36:55 +00003324static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003325s390_irgen_ALSIHN(UChar r1, UInt i2)
3326{
3327 IRTemp op1 = newTemp(Ity_I32);
3328 UInt op2;
3329 IRTemp result = newTemp(Ity_I32);
3330
3331 assign(op1, get_gpr_w0(r1));
3332 op2 = i2;
3333 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3334 put_gpr_w0(r1, mkexpr(result));
3335
3336 return "alsihn";
3337}
3338
florian55085f82012-11-21 00:36:55 +00003339static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003340s390_irgen_NR(UChar r1, UChar r2)
3341{
3342 IRTemp op1 = newTemp(Ity_I32);
3343 IRTemp op2 = newTemp(Ity_I32);
3344 IRTemp result = newTemp(Ity_I32);
3345
3346 assign(op1, get_gpr_w1(r1));
3347 assign(op2, get_gpr_w1(r2));
3348 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3349 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3350 put_gpr_w1(r1, mkexpr(result));
3351
3352 return "nr";
3353}
3354
florian55085f82012-11-21 00:36:55 +00003355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003356s390_irgen_NGR(UChar r1, UChar r2)
3357{
3358 IRTemp op1 = newTemp(Ity_I64);
3359 IRTemp op2 = newTemp(Ity_I64);
3360 IRTemp result = newTemp(Ity_I64);
3361
3362 assign(op1, get_gpr_dw0(r1));
3363 assign(op2, get_gpr_dw0(r2));
3364 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3365 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3366 put_gpr_dw0(r1, mkexpr(result));
3367
3368 return "ngr";
3369}
3370
florian55085f82012-11-21 00:36:55 +00003371static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003372s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3373{
3374 IRTemp op2 = newTemp(Ity_I32);
3375 IRTemp op3 = newTemp(Ity_I32);
3376 IRTemp result = newTemp(Ity_I32);
3377
3378 assign(op2, get_gpr_w1(r2));
3379 assign(op3, get_gpr_w1(r3));
3380 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3381 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3382 put_gpr_w1(r1, mkexpr(result));
3383
3384 return "nrk";
3385}
3386
florian55085f82012-11-21 00:36:55 +00003387static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003388s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3389{
3390 IRTemp op2 = newTemp(Ity_I64);
3391 IRTemp op3 = newTemp(Ity_I64);
3392 IRTemp result = newTemp(Ity_I64);
3393
3394 assign(op2, get_gpr_dw0(r2));
3395 assign(op3, get_gpr_dw0(r3));
3396 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3397 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3398 put_gpr_dw0(r1, mkexpr(result));
3399
3400 return "ngrk";
3401}
3402
florian55085f82012-11-21 00:36:55 +00003403static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003404s390_irgen_N(UChar r1, IRTemp op2addr)
3405{
3406 IRTemp op1 = newTemp(Ity_I32);
3407 IRTemp op2 = newTemp(Ity_I32);
3408 IRTemp result = newTemp(Ity_I32);
3409
3410 assign(op1, get_gpr_w1(r1));
3411 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3412 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3413 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3414 put_gpr_w1(r1, mkexpr(result));
3415
3416 return "n";
3417}
3418
florian55085f82012-11-21 00:36:55 +00003419static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003420s390_irgen_NY(UChar r1, IRTemp op2addr)
3421{
3422 IRTemp op1 = newTemp(Ity_I32);
3423 IRTemp op2 = newTemp(Ity_I32);
3424 IRTemp result = newTemp(Ity_I32);
3425
3426 assign(op1, get_gpr_w1(r1));
3427 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3428 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3429 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3430 put_gpr_w1(r1, mkexpr(result));
3431
3432 return "ny";
3433}
3434
florian55085f82012-11-21 00:36:55 +00003435static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003436s390_irgen_NG(UChar r1, IRTemp op2addr)
3437{
3438 IRTemp op1 = newTemp(Ity_I64);
3439 IRTemp op2 = newTemp(Ity_I64);
3440 IRTemp result = newTemp(Ity_I64);
3441
3442 assign(op1, get_gpr_dw0(r1));
3443 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3444 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3445 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3446 put_gpr_dw0(r1, mkexpr(result));
3447
3448 return "ng";
3449}
3450
florian55085f82012-11-21 00:36:55 +00003451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003452s390_irgen_NI(UChar i2, IRTemp op1addr)
3453{
3454 IRTemp op1 = newTemp(Ity_I8);
3455 UChar op2;
3456 IRTemp result = newTemp(Ity_I8);
3457
3458 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3459 op2 = i2;
3460 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3461 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3462 store(mkexpr(op1addr), mkexpr(result));
3463
3464 return "ni";
3465}
3466
florian55085f82012-11-21 00:36:55 +00003467static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003468s390_irgen_NIY(UChar i2, IRTemp op1addr)
3469{
3470 IRTemp op1 = newTemp(Ity_I8);
3471 UChar op2;
3472 IRTemp result = newTemp(Ity_I8);
3473
3474 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3475 op2 = i2;
3476 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3477 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3478 store(mkexpr(op1addr), mkexpr(result));
3479
3480 return "niy";
3481}
3482
florian55085f82012-11-21 00:36:55 +00003483static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003484s390_irgen_NIHF(UChar r1, UInt i2)
3485{
3486 IRTemp op1 = newTemp(Ity_I32);
3487 UInt op2;
3488 IRTemp result = newTemp(Ity_I32);
3489
3490 assign(op1, get_gpr_w0(r1));
3491 op2 = i2;
3492 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3493 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3494 put_gpr_w0(r1, mkexpr(result));
3495
3496 return "nihf";
3497}
3498
florian55085f82012-11-21 00:36:55 +00003499static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003500s390_irgen_NIHH(UChar r1, UShort i2)
3501{
3502 IRTemp op1 = newTemp(Ity_I16);
3503 UShort op2;
3504 IRTemp result = newTemp(Ity_I16);
3505
3506 assign(op1, get_gpr_hw0(r1));
3507 op2 = i2;
3508 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3509 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3510 put_gpr_hw0(r1, mkexpr(result));
3511
3512 return "nihh";
3513}
3514
florian55085f82012-11-21 00:36:55 +00003515static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003516s390_irgen_NIHL(UChar r1, UShort i2)
3517{
3518 IRTemp op1 = newTemp(Ity_I16);
3519 UShort op2;
3520 IRTemp result = newTemp(Ity_I16);
3521
3522 assign(op1, get_gpr_hw1(r1));
3523 op2 = i2;
3524 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3525 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3526 put_gpr_hw1(r1, mkexpr(result));
3527
3528 return "nihl";
3529}
3530
florian55085f82012-11-21 00:36:55 +00003531static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003532s390_irgen_NILF(UChar r1, UInt i2)
3533{
3534 IRTemp op1 = newTemp(Ity_I32);
3535 UInt op2;
3536 IRTemp result = newTemp(Ity_I32);
3537
3538 assign(op1, get_gpr_w1(r1));
3539 op2 = i2;
3540 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3541 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3542 put_gpr_w1(r1, mkexpr(result));
3543
3544 return "nilf";
3545}
3546
florian55085f82012-11-21 00:36:55 +00003547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003548s390_irgen_NILH(UChar r1, UShort i2)
3549{
3550 IRTemp op1 = newTemp(Ity_I16);
3551 UShort op2;
3552 IRTemp result = newTemp(Ity_I16);
3553
3554 assign(op1, get_gpr_hw2(r1));
3555 op2 = i2;
3556 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3557 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3558 put_gpr_hw2(r1, mkexpr(result));
3559
3560 return "nilh";
3561}
3562
florian55085f82012-11-21 00:36:55 +00003563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003564s390_irgen_NILL(UChar r1, UShort i2)
3565{
3566 IRTemp op1 = newTemp(Ity_I16);
3567 UShort op2;
3568 IRTemp result = newTemp(Ity_I16);
3569
3570 assign(op1, get_gpr_hw3(r1));
3571 op2 = i2;
3572 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3573 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3574 put_gpr_hw3(r1, mkexpr(result));
3575
3576 return "nill";
3577}
3578
florian55085f82012-11-21 00:36:55 +00003579static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003580s390_irgen_BASR(UChar r1, UChar r2)
3581{
3582 IRTemp target = newTemp(Ity_I64);
3583
3584 if (r2 == 0) {
3585 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3586 } else {
3587 if (r1 != r2) {
3588 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3589 call_function(get_gpr_dw0(r2));
3590 } else {
3591 assign(target, get_gpr_dw0(r2));
3592 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3593 call_function(mkexpr(target));
3594 }
3595 }
3596
3597 return "basr";
3598}
3599
florian55085f82012-11-21 00:36:55 +00003600static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003601s390_irgen_BAS(UChar r1, IRTemp op2addr)
3602{
3603 IRTemp target = newTemp(Ity_I64);
3604
3605 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3606 assign(target, mkexpr(op2addr));
3607 call_function(mkexpr(target));
3608
3609 return "bas";
3610}
3611
florian55085f82012-11-21 00:36:55 +00003612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003613s390_irgen_BCR(UChar r1, UChar r2)
3614{
3615 IRTemp cond = newTemp(Ity_I32);
3616
sewardja52e37e2011-04-28 18:48:06 +00003617 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3618 stmt(IRStmt_MBE(Imbe_Fence));
3619 }
3620
sewardj2019a972011-03-07 16:04:07 +00003621 if ((r2 == 0) || (r1 == 0)) {
3622 } else {
3623 if (r1 == 15) {
3624 return_from_function(get_gpr_dw0(r2));
3625 } else {
3626 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003627 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3628 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003629 }
3630 }
sewardj7ee97522011-05-09 21:45:04 +00003631 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003632 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3633
3634 return "bcr";
3635}
3636
florian55085f82012-11-21 00:36:55 +00003637static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003638s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3639{
3640 IRTemp cond = newTemp(Ity_I32);
3641
3642 if (r1 == 0) {
3643 } else {
3644 if (r1 == 15) {
3645 always_goto(mkexpr(op2addr));
3646 } else {
3647 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003648 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3649 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003650 }
3651 }
sewardj7ee97522011-05-09 21:45:04 +00003652 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003653 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3654
3655 return "bc";
3656}
3657
florian55085f82012-11-21 00:36:55 +00003658static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003659s390_irgen_BCTR(UChar r1, UChar r2)
3660{
3661 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3662 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003663 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3664 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003665 }
3666
3667 return "bctr";
3668}
3669
florian55085f82012-11-21 00:36:55 +00003670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003671s390_irgen_BCTGR(UChar r1, UChar r2)
3672{
3673 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3674 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003675 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3676 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003677 }
3678
3679 return "bctgr";
3680}
3681
florian55085f82012-11-21 00:36:55 +00003682static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003683s390_irgen_BCT(UChar r1, IRTemp op2addr)
3684{
3685 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003686 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3687 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003688
3689 return "bct";
3690}
3691
florian55085f82012-11-21 00:36:55 +00003692static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003693s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3694{
3695 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003696 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3697 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003698
3699 return "bctg";
3700}
3701
florian55085f82012-11-21 00:36:55 +00003702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003703s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3704{
3705 IRTemp value = newTemp(Ity_I32);
3706
3707 assign(value, get_gpr_w1(r3 | 1));
3708 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003709 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3710 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003711
3712 return "bxh";
3713}
3714
florian55085f82012-11-21 00:36:55 +00003715static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003716s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3717{
3718 IRTemp value = newTemp(Ity_I64);
3719
3720 assign(value, get_gpr_dw0(r3 | 1));
3721 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003722 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3723 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003724
3725 return "bxhg";
3726}
3727
florian55085f82012-11-21 00:36:55 +00003728static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003729s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3730{
3731 IRTemp value = newTemp(Ity_I32);
3732
3733 assign(value, get_gpr_w1(r3 | 1));
3734 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003735 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3736 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003737
3738 return "bxle";
3739}
3740
florian55085f82012-11-21 00:36:55 +00003741static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003742s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3743{
3744 IRTemp value = newTemp(Ity_I64);
3745
3746 assign(value, get_gpr_dw0(r3 | 1));
3747 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003748 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3749 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003750
3751 return "bxleg";
3752}
3753
florian55085f82012-11-21 00:36:55 +00003754static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003755s390_irgen_BRAS(UChar r1, UShort i2)
3756{
3757 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003758 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003759
3760 return "bras";
3761}
3762
florian55085f82012-11-21 00:36:55 +00003763static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003764s390_irgen_BRASL(UChar r1, UInt i2)
3765{
3766 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003767 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003768
3769 return "brasl";
3770}
3771
florian55085f82012-11-21 00:36:55 +00003772static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003773s390_irgen_BRC(UChar r1, UShort i2)
3774{
3775 IRTemp cond = newTemp(Ity_I32);
3776
3777 if (r1 == 0) {
3778 } else {
3779 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003780 always_goto_and_chase(
3781 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003782 } else {
3783 assign(cond, s390_call_calculate_cond(r1));
3784 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3785 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3786
3787 }
3788 }
sewardj7ee97522011-05-09 21:45:04 +00003789 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003790 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3791
3792 return "brc";
3793}
3794
florian55085f82012-11-21 00:36:55 +00003795static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003796s390_irgen_BRCL(UChar r1, UInt i2)
3797{
3798 IRTemp cond = newTemp(Ity_I32);
3799
3800 if (r1 == 0) {
3801 } else {
3802 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003803 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003804 } else {
3805 assign(cond, s390_call_calculate_cond(r1));
3806 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3807 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3808 }
3809 }
sewardj7ee97522011-05-09 21:45:04 +00003810 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003811 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3812
3813 return "brcl";
3814}
3815
florian55085f82012-11-21 00:36:55 +00003816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003817s390_irgen_BRCT(UChar r1, UShort i2)
3818{
3819 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3820 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3821 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3822
3823 return "brct";
3824}
3825
florian55085f82012-11-21 00:36:55 +00003826static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003827s390_irgen_BRCTG(UChar r1, UShort i2)
3828{
3829 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3830 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3831 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3832
3833 return "brctg";
3834}
3835
florian55085f82012-11-21 00:36:55 +00003836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003837s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3838{
3839 IRTemp value = newTemp(Ity_I32);
3840
3841 assign(value, get_gpr_w1(r3 | 1));
3842 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3843 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3844 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3845
3846 return "brxh";
3847}
3848
florian55085f82012-11-21 00:36:55 +00003849static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003850s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3851{
3852 IRTemp value = newTemp(Ity_I64);
3853
3854 assign(value, get_gpr_dw0(r3 | 1));
3855 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3856 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3857 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3858
3859 return "brxhg";
3860}
3861
florian55085f82012-11-21 00:36:55 +00003862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003863s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3864{
3865 IRTemp value = newTemp(Ity_I32);
3866
3867 assign(value, get_gpr_w1(r3 | 1));
3868 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3869 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3870 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3871
3872 return "brxle";
3873}
3874
florian55085f82012-11-21 00:36:55 +00003875static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003876s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3877{
3878 IRTemp value = newTemp(Ity_I64);
3879
3880 assign(value, get_gpr_dw0(r3 | 1));
3881 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3882 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3883 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3884
3885 return "brxlg";
3886}
3887
florian55085f82012-11-21 00:36:55 +00003888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003889s390_irgen_CR(UChar r1, UChar r2)
3890{
3891 IRTemp op1 = newTemp(Ity_I32);
3892 IRTemp op2 = newTemp(Ity_I32);
3893
3894 assign(op1, get_gpr_w1(r1));
3895 assign(op2, get_gpr_w1(r2));
3896 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3897
3898 return "cr";
3899}
3900
florian55085f82012-11-21 00:36:55 +00003901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003902s390_irgen_CGR(UChar r1, UChar r2)
3903{
3904 IRTemp op1 = newTemp(Ity_I64);
3905 IRTemp op2 = newTemp(Ity_I64);
3906
3907 assign(op1, get_gpr_dw0(r1));
3908 assign(op2, get_gpr_dw0(r2));
3909 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3910
3911 return "cgr";
3912}
3913
florian55085f82012-11-21 00:36:55 +00003914static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003915s390_irgen_CGFR(UChar r1, UChar r2)
3916{
3917 IRTemp op1 = newTemp(Ity_I64);
3918 IRTemp op2 = newTemp(Ity_I64);
3919
3920 assign(op1, get_gpr_dw0(r1));
3921 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3922 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3923
3924 return "cgfr";
3925}
3926
florian55085f82012-11-21 00:36:55 +00003927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003928s390_irgen_C(UChar r1, IRTemp op2addr)
3929{
3930 IRTemp op1 = newTemp(Ity_I32);
3931 IRTemp op2 = newTemp(Ity_I32);
3932
3933 assign(op1, get_gpr_w1(r1));
3934 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3935 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3936
3937 return "c";
3938}
3939
florian55085f82012-11-21 00:36:55 +00003940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003941s390_irgen_CY(UChar r1, IRTemp op2addr)
3942{
3943 IRTemp op1 = newTemp(Ity_I32);
3944 IRTemp op2 = newTemp(Ity_I32);
3945
3946 assign(op1, get_gpr_w1(r1));
3947 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3948 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3949
3950 return "cy";
3951}
3952
florian55085f82012-11-21 00:36:55 +00003953static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003954s390_irgen_CG(UChar r1, IRTemp op2addr)
3955{
3956 IRTemp op1 = newTemp(Ity_I64);
3957 IRTemp op2 = newTemp(Ity_I64);
3958
3959 assign(op1, get_gpr_dw0(r1));
3960 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3961 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3962
3963 return "cg";
3964}
3965
florian55085f82012-11-21 00:36:55 +00003966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003967s390_irgen_CGF(UChar r1, IRTemp op2addr)
3968{
3969 IRTemp op1 = newTemp(Ity_I64);
3970 IRTemp op2 = newTemp(Ity_I64);
3971
3972 assign(op1, get_gpr_dw0(r1));
3973 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3974 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3975
3976 return "cgf";
3977}
3978
florian55085f82012-11-21 00:36:55 +00003979static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003980s390_irgen_CFI(UChar r1, UInt i2)
3981{
3982 IRTemp op1 = newTemp(Ity_I32);
3983 Int op2;
3984
3985 assign(op1, get_gpr_w1(r1));
3986 op2 = (Int)i2;
3987 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3988 mkU32((UInt)op2)));
3989
3990 return "cfi";
3991}
3992
florian55085f82012-11-21 00:36:55 +00003993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003994s390_irgen_CGFI(UChar r1, UInt i2)
3995{
3996 IRTemp op1 = newTemp(Ity_I64);
3997 Long op2;
3998
3999 assign(op1, get_gpr_dw0(r1));
4000 op2 = (Long)(Int)i2;
4001 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4002 mkU64((ULong)op2)));
4003
4004 return "cgfi";
4005}
4006
florian55085f82012-11-21 00:36:55 +00004007static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004008s390_irgen_CRL(UChar r1, UInt i2)
4009{
4010 IRTemp op1 = newTemp(Ity_I32);
4011 IRTemp op2 = newTemp(Ity_I32);
4012
4013 assign(op1, get_gpr_w1(r1));
4014 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4015 i2 << 1))));
4016 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4017
4018 return "crl";
4019}
4020
florian55085f82012-11-21 00:36:55 +00004021static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004022s390_irgen_CGRL(UChar r1, UInt i2)
4023{
4024 IRTemp op1 = newTemp(Ity_I64);
4025 IRTemp op2 = newTemp(Ity_I64);
4026
4027 assign(op1, get_gpr_dw0(r1));
4028 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4029 i2 << 1))));
4030 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4031
4032 return "cgrl";
4033}
4034
florian55085f82012-11-21 00:36:55 +00004035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004036s390_irgen_CGFRL(UChar r1, UInt i2)
4037{
4038 IRTemp op1 = newTemp(Ity_I64);
4039 IRTemp op2 = newTemp(Ity_I64);
4040
4041 assign(op1, get_gpr_dw0(r1));
4042 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4043 ((ULong)(Long)(Int)i2 << 1)))));
4044 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4045
4046 return "cgfrl";
4047}
4048
florian55085f82012-11-21 00:36:55 +00004049static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004050s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4051{
4052 IRTemp op1 = newTemp(Ity_I32);
4053 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004054 IRTemp cond = newTemp(Ity_I32);
4055
4056 if (m3 == 0) {
4057 } else {
4058 if (m3 == 14) {
4059 always_goto(mkexpr(op4addr));
4060 } else {
4061 assign(op1, get_gpr_w1(r1));
4062 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004063 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4064 op1, op2));
florianf321da72012-07-21 20:32:57 +00004065 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4066 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004067 }
4068 }
4069
4070 return "crb";
4071}
4072
florian55085f82012-11-21 00:36:55 +00004073static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004074s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4075{
4076 IRTemp op1 = newTemp(Ity_I64);
4077 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004078 IRTemp cond = newTemp(Ity_I32);
4079
4080 if (m3 == 0) {
4081 } else {
4082 if (m3 == 14) {
4083 always_goto(mkexpr(op4addr));
4084 } else {
4085 assign(op1, get_gpr_dw0(r1));
4086 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004087 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4088 op1, op2));
florianf321da72012-07-21 20:32:57 +00004089 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4090 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004091 }
4092 }
4093
4094 return "cgrb";
4095}
4096
florian55085f82012-11-21 00:36:55 +00004097static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004098s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4099{
4100 IRTemp op1 = newTemp(Ity_I32);
4101 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004102 IRTemp cond = newTemp(Ity_I32);
4103
4104 if (m3 == 0) {
4105 } else {
4106 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004107 always_goto_and_chase(
4108 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004109 } else {
4110 assign(op1, get_gpr_w1(r1));
4111 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004112 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4113 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004114 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4115 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4116
4117 }
4118 }
4119
4120 return "crj";
4121}
4122
florian55085f82012-11-21 00:36:55 +00004123static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004124s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4125{
4126 IRTemp op1 = newTemp(Ity_I64);
4127 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004128 IRTemp cond = newTemp(Ity_I32);
4129
4130 if (m3 == 0) {
4131 } else {
4132 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004133 always_goto_and_chase(
4134 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004135 } else {
4136 assign(op1, get_gpr_dw0(r1));
4137 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004138 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4139 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004140 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4141 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4142
4143 }
4144 }
4145
4146 return "cgrj";
4147}
4148
florian55085f82012-11-21 00:36:55 +00004149static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004150s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4151{
4152 IRTemp op1 = newTemp(Ity_I32);
4153 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004154 IRTemp cond = newTemp(Ity_I32);
4155
4156 if (m3 == 0) {
4157 } else {
4158 if (m3 == 14) {
4159 always_goto(mkexpr(op4addr));
4160 } else {
4161 assign(op1, get_gpr_w1(r1));
4162 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004163 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4164 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004165 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4166 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004167 }
4168 }
4169
4170 return "cib";
4171}
4172
florian55085f82012-11-21 00:36:55 +00004173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004174s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4175{
4176 IRTemp op1 = newTemp(Ity_I64);
4177 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004178 IRTemp cond = newTemp(Ity_I32);
4179
4180 if (m3 == 0) {
4181 } else {
4182 if (m3 == 14) {
4183 always_goto(mkexpr(op4addr));
4184 } else {
4185 assign(op1, get_gpr_dw0(r1));
4186 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004187 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4188 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004189 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4190 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004191 }
4192 }
4193
4194 return "cgib";
4195}
4196
florian55085f82012-11-21 00:36:55 +00004197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004198s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4199{
4200 IRTemp op1 = newTemp(Ity_I32);
4201 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004202 IRTemp cond = newTemp(Ity_I32);
4203
4204 if (m3 == 0) {
4205 } else {
4206 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004207 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004208 } else {
4209 assign(op1, get_gpr_w1(r1));
4210 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004211 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4212 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004213 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4214 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4215
4216 }
4217 }
4218
4219 return "cij";
4220}
4221
florian55085f82012-11-21 00:36:55 +00004222static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004223s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4224{
4225 IRTemp op1 = newTemp(Ity_I64);
4226 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004227 IRTemp cond = newTemp(Ity_I32);
4228
4229 if (m3 == 0) {
4230 } else {
4231 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004232 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004233 } else {
4234 assign(op1, get_gpr_dw0(r1));
4235 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004236 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4237 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004238 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4239 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4240
4241 }
4242 }
4243
4244 return "cgij";
4245}
4246
florian55085f82012-11-21 00:36:55 +00004247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004248s390_irgen_CH(UChar r1, IRTemp op2addr)
4249{
4250 IRTemp op1 = newTemp(Ity_I32);
4251 IRTemp op2 = newTemp(Ity_I32);
4252
4253 assign(op1, get_gpr_w1(r1));
4254 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4255 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4256
4257 return "ch";
4258}
4259
florian55085f82012-11-21 00:36:55 +00004260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004261s390_irgen_CHY(UChar r1, IRTemp op2addr)
4262{
4263 IRTemp op1 = newTemp(Ity_I32);
4264 IRTemp op2 = newTemp(Ity_I32);
4265
4266 assign(op1, get_gpr_w1(r1));
4267 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4268 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4269
4270 return "chy";
4271}
4272
florian55085f82012-11-21 00:36:55 +00004273static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004274s390_irgen_CGH(UChar r1, IRTemp op2addr)
4275{
4276 IRTemp op1 = newTemp(Ity_I64);
4277 IRTemp op2 = newTemp(Ity_I64);
4278
4279 assign(op1, get_gpr_dw0(r1));
4280 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4281 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4282
4283 return "cgh";
4284}
4285
florian55085f82012-11-21 00:36:55 +00004286static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004287s390_irgen_CHI(UChar r1, UShort i2)
4288{
4289 IRTemp op1 = newTemp(Ity_I32);
4290 Int op2;
4291
4292 assign(op1, get_gpr_w1(r1));
4293 op2 = (Int)(Short)i2;
4294 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4295 mkU32((UInt)op2)));
4296
4297 return "chi";
4298}
4299
florian55085f82012-11-21 00:36:55 +00004300static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004301s390_irgen_CGHI(UChar r1, UShort i2)
4302{
4303 IRTemp op1 = newTemp(Ity_I64);
4304 Long op2;
4305
4306 assign(op1, get_gpr_dw0(r1));
4307 op2 = (Long)(Short)i2;
4308 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4309 mkU64((ULong)op2)));
4310
4311 return "cghi";
4312}
4313
florian55085f82012-11-21 00:36:55 +00004314static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004315s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4316{
4317 IRTemp op1 = newTemp(Ity_I16);
4318 Short op2;
4319
4320 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4321 op2 = (Short)i2;
4322 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4323 mkU16((UShort)op2)));
4324
4325 return "chhsi";
4326}
4327
florian55085f82012-11-21 00:36:55 +00004328static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004329s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4330{
4331 IRTemp op1 = newTemp(Ity_I32);
4332 Int op2;
4333
4334 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4335 op2 = (Int)(Short)i2;
4336 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4337 mkU32((UInt)op2)));
4338
4339 return "chsi";
4340}
4341
florian55085f82012-11-21 00:36:55 +00004342static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004343s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4344{
4345 IRTemp op1 = newTemp(Ity_I64);
4346 Long op2;
4347
4348 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4349 op2 = (Long)(Short)i2;
4350 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4351 mkU64((ULong)op2)));
4352
4353 return "cghsi";
4354}
4355
florian55085f82012-11-21 00:36:55 +00004356static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004357s390_irgen_CHRL(UChar r1, UInt i2)
4358{
4359 IRTemp op1 = newTemp(Ity_I32);
4360 IRTemp op2 = newTemp(Ity_I32);
4361
4362 assign(op1, get_gpr_w1(r1));
4363 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4364 ((ULong)(Long)(Int)i2 << 1)))));
4365 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4366
4367 return "chrl";
4368}
4369
florian55085f82012-11-21 00:36:55 +00004370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004371s390_irgen_CGHRL(UChar r1, UInt i2)
4372{
4373 IRTemp op1 = newTemp(Ity_I64);
4374 IRTemp op2 = newTemp(Ity_I64);
4375
4376 assign(op1, get_gpr_dw0(r1));
4377 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4378 ((ULong)(Long)(Int)i2 << 1)))));
4379 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4380
4381 return "cghrl";
4382}
4383
florian55085f82012-11-21 00:36:55 +00004384static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004385s390_irgen_CHHR(UChar r1, UChar r2)
4386{
4387 IRTemp op1 = newTemp(Ity_I32);
4388 IRTemp op2 = newTemp(Ity_I32);
4389
4390 assign(op1, get_gpr_w0(r1));
4391 assign(op2, get_gpr_w0(r2));
4392 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4393
4394 return "chhr";
4395}
4396
florian55085f82012-11-21 00:36:55 +00004397static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004398s390_irgen_CHLR(UChar r1, UChar r2)
4399{
4400 IRTemp op1 = newTemp(Ity_I32);
4401 IRTemp op2 = newTemp(Ity_I32);
4402
4403 assign(op1, get_gpr_w0(r1));
4404 assign(op2, get_gpr_w1(r2));
4405 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4406
4407 return "chlr";
4408}
4409
florian55085f82012-11-21 00:36:55 +00004410static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004411s390_irgen_CHF(UChar r1, IRTemp op2addr)
4412{
4413 IRTemp op1 = newTemp(Ity_I32);
4414 IRTemp op2 = newTemp(Ity_I32);
4415
4416 assign(op1, get_gpr_w0(r1));
4417 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4418 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4419
4420 return "chf";
4421}
4422
florian55085f82012-11-21 00:36:55 +00004423static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004424s390_irgen_CIH(UChar r1, UInt i2)
4425{
4426 IRTemp op1 = newTemp(Ity_I32);
4427 Int op2;
4428
4429 assign(op1, get_gpr_w0(r1));
4430 op2 = (Int)i2;
4431 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4432 mkU32((UInt)op2)));
4433
4434 return "cih";
4435}
4436
florian55085f82012-11-21 00:36:55 +00004437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004438s390_irgen_CLR(UChar r1, UChar r2)
4439{
4440 IRTemp op1 = newTemp(Ity_I32);
4441 IRTemp op2 = newTemp(Ity_I32);
4442
4443 assign(op1, get_gpr_w1(r1));
4444 assign(op2, get_gpr_w1(r2));
4445 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4446
4447 return "clr";
4448}
4449
florian55085f82012-11-21 00:36:55 +00004450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004451s390_irgen_CLGR(UChar r1, UChar r2)
4452{
4453 IRTemp op1 = newTemp(Ity_I64);
4454 IRTemp op2 = newTemp(Ity_I64);
4455
4456 assign(op1, get_gpr_dw0(r1));
4457 assign(op2, get_gpr_dw0(r2));
4458 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4459
4460 return "clgr";
4461}
4462
florian55085f82012-11-21 00:36:55 +00004463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004464s390_irgen_CLGFR(UChar r1, UChar r2)
4465{
4466 IRTemp op1 = newTemp(Ity_I64);
4467 IRTemp op2 = newTemp(Ity_I64);
4468
4469 assign(op1, get_gpr_dw0(r1));
4470 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4471 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4472
4473 return "clgfr";
4474}
4475
florian55085f82012-11-21 00:36:55 +00004476static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004477s390_irgen_CL(UChar r1, IRTemp op2addr)
4478{
4479 IRTemp op1 = newTemp(Ity_I32);
4480 IRTemp op2 = newTemp(Ity_I32);
4481
4482 assign(op1, get_gpr_w1(r1));
4483 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4484 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4485
4486 return "cl";
4487}
4488
florian55085f82012-11-21 00:36:55 +00004489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004490s390_irgen_CLY(UChar r1, IRTemp op2addr)
4491{
4492 IRTemp op1 = newTemp(Ity_I32);
4493 IRTemp op2 = newTemp(Ity_I32);
4494
4495 assign(op1, get_gpr_w1(r1));
4496 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4497 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4498
4499 return "cly";
4500}
4501
florian55085f82012-11-21 00:36:55 +00004502static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004503s390_irgen_CLG(UChar r1, IRTemp op2addr)
4504{
4505 IRTemp op1 = newTemp(Ity_I64);
4506 IRTemp op2 = newTemp(Ity_I64);
4507
4508 assign(op1, get_gpr_dw0(r1));
4509 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4510 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4511
4512 return "clg";
4513}
4514
florian55085f82012-11-21 00:36:55 +00004515static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004516s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4517{
4518 IRTemp op1 = newTemp(Ity_I64);
4519 IRTemp op2 = newTemp(Ity_I64);
4520
4521 assign(op1, get_gpr_dw0(r1));
4522 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4523 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4524
4525 return "clgf";
4526}
4527
florian55085f82012-11-21 00:36:55 +00004528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004529s390_irgen_CLFI(UChar r1, UInt i2)
4530{
4531 IRTemp op1 = newTemp(Ity_I32);
4532 UInt op2;
4533
4534 assign(op1, get_gpr_w1(r1));
4535 op2 = i2;
4536 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4537 mkU32(op2)));
4538
4539 return "clfi";
4540}
4541
florian55085f82012-11-21 00:36:55 +00004542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004543s390_irgen_CLGFI(UChar r1, UInt i2)
4544{
4545 IRTemp op1 = newTemp(Ity_I64);
4546 ULong op2;
4547
4548 assign(op1, get_gpr_dw0(r1));
4549 op2 = (ULong)i2;
4550 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4551 mkU64(op2)));
4552
4553 return "clgfi";
4554}
4555
florian55085f82012-11-21 00:36:55 +00004556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004557s390_irgen_CLI(UChar i2, IRTemp op1addr)
4558{
4559 IRTemp op1 = newTemp(Ity_I8);
4560 UChar op2;
4561
4562 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4563 op2 = i2;
4564 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4565 mkU8(op2)));
4566
4567 return "cli";
4568}
4569
florian55085f82012-11-21 00:36:55 +00004570static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004571s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4572{
4573 IRTemp op1 = newTemp(Ity_I8);
4574 UChar op2;
4575
4576 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4577 op2 = i2;
4578 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4579 mkU8(op2)));
4580
4581 return "cliy";
4582}
4583
florian55085f82012-11-21 00:36:55 +00004584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004585s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4586{
4587 IRTemp op1 = newTemp(Ity_I32);
4588 UInt op2;
4589
4590 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4591 op2 = (UInt)i2;
4592 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4593 mkU32(op2)));
4594
4595 return "clfhsi";
4596}
4597
florian55085f82012-11-21 00:36:55 +00004598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004599s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4600{
4601 IRTemp op1 = newTemp(Ity_I64);
4602 ULong op2;
4603
4604 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4605 op2 = (ULong)i2;
4606 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4607 mkU64(op2)));
4608
4609 return "clghsi";
4610}
4611
florian55085f82012-11-21 00:36:55 +00004612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004613s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4614{
4615 IRTemp op1 = newTemp(Ity_I16);
4616 UShort op2;
4617
4618 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4619 op2 = i2;
4620 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4621 mkU16(op2)));
4622
4623 return "clhhsi";
4624}
4625
florian55085f82012-11-21 00:36:55 +00004626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004627s390_irgen_CLRL(UChar r1, UInt i2)
4628{
4629 IRTemp op1 = newTemp(Ity_I32);
4630 IRTemp op2 = newTemp(Ity_I32);
4631
4632 assign(op1, get_gpr_w1(r1));
4633 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4634 i2 << 1))));
4635 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4636
4637 return "clrl";
4638}
4639
florian55085f82012-11-21 00:36:55 +00004640static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004641s390_irgen_CLGRL(UChar r1, UInt i2)
4642{
4643 IRTemp op1 = newTemp(Ity_I64);
4644 IRTemp op2 = newTemp(Ity_I64);
4645
4646 assign(op1, get_gpr_dw0(r1));
4647 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4648 i2 << 1))));
4649 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4650
4651 return "clgrl";
4652}
4653
florian55085f82012-11-21 00:36:55 +00004654static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004655s390_irgen_CLGFRL(UChar r1, UInt i2)
4656{
4657 IRTemp op1 = newTemp(Ity_I64);
4658 IRTemp op2 = newTemp(Ity_I64);
4659
4660 assign(op1, get_gpr_dw0(r1));
4661 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4662 ((ULong)(Long)(Int)i2 << 1)))));
4663 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4664
4665 return "clgfrl";
4666}
4667
florian55085f82012-11-21 00:36:55 +00004668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004669s390_irgen_CLHRL(UChar r1, UInt i2)
4670{
4671 IRTemp op1 = newTemp(Ity_I32);
4672 IRTemp op2 = newTemp(Ity_I32);
4673
4674 assign(op1, get_gpr_w1(r1));
4675 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4676 ((ULong)(Long)(Int)i2 << 1)))));
4677 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4678
4679 return "clhrl";
4680}
4681
florian55085f82012-11-21 00:36:55 +00004682static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004683s390_irgen_CLGHRL(UChar r1, UInt i2)
4684{
4685 IRTemp op1 = newTemp(Ity_I64);
4686 IRTemp op2 = newTemp(Ity_I64);
4687
4688 assign(op1, get_gpr_dw0(r1));
4689 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4690 ((ULong)(Long)(Int)i2 << 1)))));
4691 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4692
4693 return "clghrl";
4694}
4695
florian55085f82012-11-21 00:36:55 +00004696static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004697s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4698{
4699 IRTemp op1 = newTemp(Ity_I32);
4700 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004701 IRTemp cond = newTemp(Ity_I32);
4702
4703 if (m3 == 0) {
4704 } else {
4705 if (m3 == 14) {
4706 always_goto(mkexpr(op4addr));
4707 } else {
4708 assign(op1, get_gpr_w1(r1));
4709 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004710 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4711 op1, op2));
florianf321da72012-07-21 20:32:57 +00004712 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4713 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004714 }
4715 }
4716
4717 return "clrb";
4718}
4719
florian55085f82012-11-21 00:36:55 +00004720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004721s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4722{
4723 IRTemp op1 = newTemp(Ity_I64);
4724 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004725 IRTemp cond = newTemp(Ity_I32);
4726
4727 if (m3 == 0) {
4728 } else {
4729 if (m3 == 14) {
4730 always_goto(mkexpr(op4addr));
4731 } else {
4732 assign(op1, get_gpr_dw0(r1));
4733 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004734 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4735 op1, op2));
florianf321da72012-07-21 20:32:57 +00004736 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4737 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004738 }
4739 }
4740
4741 return "clgrb";
4742}
4743
florian55085f82012-11-21 00:36:55 +00004744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004745s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4746{
4747 IRTemp op1 = newTemp(Ity_I32);
4748 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004749 IRTemp cond = newTemp(Ity_I32);
4750
4751 if (m3 == 0) {
4752 } else {
4753 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004754 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004755 } else {
4756 assign(op1, get_gpr_w1(r1));
4757 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004758 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4759 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004760 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4761 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4762
4763 }
4764 }
4765
4766 return "clrj";
4767}
4768
florian55085f82012-11-21 00:36:55 +00004769static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004770s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4771{
4772 IRTemp op1 = newTemp(Ity_I64);
4773 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004774 IRTemp cond = newTemp(Ity_I32);
4775
4776 if (m3 == 0) {
4777 } else {
4778 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004779 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004780 } else {
4781 assign(op1, get_gpr_dw0(r1));
4782 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004783 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4784 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004785 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4786 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4787
4788 }
4789 }
4790
4791 return "clgrj";
4792}
4793
florian55085f82012-11-21 00:36:55 +00004794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004795s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4796{
4797 IRTemp op1 = newTemp(Ity_I32);
4798 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004799 IRTemp cond = newTemp(Ity_I32);
4800
4801 if (m3 == 0) {
4802 } else {
4803 if (m3 == 14) {
4804 always_goto(mkexpr(op4addr));
4805 } else {
4806 assign(op1, get_gpr_w1(r1));
4807 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004808 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4809 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004810 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4811 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004812 }
4813 }
4814
4815 return "clib";
4816}
4817
florian55085f82012-11-21 00:36:55 +00004818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004819s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4820{
4821 IRTemp op1 = newTemp(Ity_I64);
4822 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004823 IRTemp cond = newTemp(Ity_I32);
4824
4825 if (m3 == 0) {
4826 } else {
4827 if (m3 == 14) {
4828 always_goto(mkexpr(op4addr));
4829 } else {
4830 assign(op1, get_gpr_dw0(r1));
4831 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004832 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4833 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004834 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4835 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004836 }
4837 }
4838
4839 return "clgib";
4840}
4841
florian55085f82012-11-21 00:36:55 +00004842static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004843s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4844{
4845 IRTemp op1 = newTemp(Ity_I32);
4846 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004847 IRTemp cond = newTemp(Ity_I32);
4848
4849 if (m3 == 0) {
4850 } else {
4851 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004852 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004853 } else {
4854 assign(op1, get_gpr_w1(r1));
4855 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004856 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4857 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004858 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4859 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4860
4861 }
4862 }
4863
4864 return "clij";
4865}
4866
florian55085f82012-11-21 00:36:55 +00004867static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004868s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4869{
4870 IRTemp op1 = newTemp(Ity_I64);
4871 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004872 IRTemp cond = newTemp(Ity_I32);
4873
4874 if (m3 == 0) {
4875 } else {
4876 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004877 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004878 } else {
4879 assign(op1, get_gpr_dw0(r1));
4880 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004881 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4882 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004883 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4884 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4885
4886 }
4887 }
4888
4889 return "clgij";
4890}
4891
florian55085f82012-11-21 00:36:55 +00004892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004893s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4894{
4895 IRTemp op1 = newTemp(Ity_I32);
4896 IRTemp op2 = newTemp(Ity_I32);
4897 IRTemp b0 = newTemp(Ity_I32);
4898 IRTemp b1 = newTemp(Ity_I32);
4899 IRTemp b2 = newTemp(Ity_I32);
4900 IRTemp b3 = newTemp(Ity_I32);
4901 IRTemp c0 = newTemp(Ity_I32);
4902 IRTemp c1 = newTemp(Ity_I32);
4903 IRTemp c2 = newTemp(Ity_I32);
4904 IRTemp c3 = newTemp(Ity_I32);
4905 UChar n;
4906
4907 n = 0;
4908 if ((r3 & 8) != 0) {
4909 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4910 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4911 n = n + 1;
4912 } else {
4913 assign(b0, mkU32(0));
4914 assign(c0, mkU32(0));
4915 }
4916 if ((r3 & 4) != 0) {
4917 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4918 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4919 mkU64(n)))));
4920 n = n + 1;
4921 } else {
4922 assign(b1, mkU32(0));
4923 assign(c1, mkU32(0));
4924 }
4925 if ((r3 & 2) != 0) {
4926 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4927 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4928 mkU64(n)))));
4929 n = n + 1;
4930 } else {
4931 assign(b2, mkU32(0));
4932 assign(c2, mkU32(0));
4933 }
4934 if ((r3 & 1) != 0) {
4935 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4936 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4937 mkU64(n)))));
4938 n = n + 1;
4939 } else {
4940 assign(b3, mkU32(0));
4941 assign(c3, mkU32(0));
4942 }
4943 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4944 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4945 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4946 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4947 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4948 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4949 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4950
4951 return "clm";
4952}
4953
florian55085f82012-11-21 00:36:55 +00004954static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004955s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4956{
4957 IRTemp op1 = newTemp(Ity_I32);
4958 IRTemp op2 = newTemp(Ity_I32);
4959 IRTemp b0 = newTemp(Ity_I32);
4960 IRTemp b1 = newTemp(Ity_I32);
4961 IRTemp b2 = newTemp(Ity_I32);
4962 IRTemp b3 = newTemp(Ity_I32);
4963 IRTemp c0 = newTemp(Ity_I32);
4964 IRTemp c1 = newTemp(Ity_I32);
4965 IRTemp c2 = newTemp(Ity_I32);
4966 IRTemp c3 = newTemp(Ity_I32);
4967 UChar n;
4968
4969 n = 0;
4970 if ((r3 & 8) != 0) {
4971 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4972 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4973 n = n + 1;
4974 } else {
4975 assign(b0, mkU32(0));
4976 assign(c0, mkU32(0));
4977 }
4978 if ((r3 & 4) != 0) {
4979 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4980 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4981 mkU64(n)))));
4982 n = n + 1;
4983 } else {
4984 assign(b1, mkU32(0));
4985 assign(c1, mkU32(0));
4986 }
4987 if ((r3 & 2) != 0) {
4988 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4989 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4990 mkU64(n)))));
4991 n = n + 1;
4992 } else {
4993 assign(b2, mkU32(0));
4994 assign(c2, mkU32(0));
4995 }
4996 if ((r3 & 1) != 0) {
4997 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4998 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4999 mkU64(n)))));
5000 n = n + 1;
5001 } else {
5002 assign(b3, mkU32(0));
5003 assign(c3, mkU32(0));
5004 }
5005 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5006 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5007 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5008 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5009 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5010 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5011 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5012
5013 return "clmy";
5014}
5015
florian55085f82012-11-21 00:36:55 +00005016static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005017s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
5018{
5019 IRTemp op1 = newTemp(Ity_I32);
5020 IRTemp op2 = newTemp(Ity_I32);
5021 IRTemp b0 = newTemp(Ity_I32);
5022 IRTemp b1 = newTemp(Ity_I32);
5023 IRTemp b2 = newTemp(Ity_I32);
5024 IRTemp b3 = newTemp(Ity_I32);
5025 IRTemp c0 = newTemp(Ity_I32);
5026 IRTemp c1 = newTemp(Ity_I32);
5027 IRTemp c2 = newTemp(Ity_I32);
5028 IRTemp c3 = newTemp(Ity_I32);
5029 UChar n;
5030
5031 n = 0;
5032 if ((r3 & 8) != 0) {
5033 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5034 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5035 n = n + 1;
5036 } else {
5037 assign(b0, mkU32(0));
5038 assign(c0, mkU32(0));
5039 }
5040 if ((r3 & 4) != 0) {
5041 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5042 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5043 mkU64(n)))));
5044 n = n + 1;
5045 } else {
5046 assign(b1, mkU32(0));
5047 assign(c1, mkU32(0));
5048 }
5049 if ((r3 & 2) != 0) {
5050 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5051 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5052 mkU64(n)))));
5053 n = n + 1;
5054 } else {
5055 assign(b2, mkU32(0));
5056 assign(c2, mkU32(0));
5057 }
5058 if ((r3 & 1) != 0) {
5059 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5060 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5061 mkU64(n)))));
5062 n = n + 1;
5063 } else {
5064 assign(b3, mkU32(0));
5065 assign(c3, mkU32(0));
5066 }
5067 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5068 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5069 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5070 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5071 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5072 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5073 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5074
5075 return "clmh";
5076}
5077
florian55085f82012-11-21 00:36:55 +00005078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005079s390_irgen_CLHHR(UChar r1, UChar r2)
5080{
5081 IRTemp op1 = newTemp(Ity_I32);
5082 IRTemp op2 = newTemp(Ity_I32);
5083
5084 assign(op1, get_gpr_w0(r1));
5085 assign(op2, get_gpr_w0(r2));
5086 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5087
5088 return "clhhr";
5089}
5090
florian55085f82012-11-21 00:36:55 +00005091static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005092s390_irgen_CLHLR(UChar r1, UChar r2)
5093{
5094 IRTemp op1 = newTemp(Ity_I32);
5095 IRTemp op2 = newTemp(Ity_I32);
5096
5097 assign(op1, get_gpr_w0(r1));
5098 assign(op2, get_gpr_w1(r2));
5099 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5100
5101 return "clhlr";
5102}
5103
florian55085f82012-11-21 00:36:55 +00005104static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005105s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5106{
5107 IRTemp op1 = newTemp(Ity_I32);
5108 IRTemp op2 = newTemp(Ity_I32);
5109
5110 assign(op1, get_gpr_w0(r1));
5111 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5112 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5113
5114 return "clhf";
5115}
5116
florian55085f82012-11-21 00:36:55 +00005117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005118s390_irgen_CLIH(UChar r1, UInt i2)
5119{
5120 IRTemp op1 = newTemp(Ity_I32);
5121 UInt op2;
5122
5123 assign(op1, get_gpr_w0(r1));
5124 op2 = i2;
5125 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5126 mkU32(op2)));
5127
5128 return "clih";
5129}
5130
florian55085f82012-11-21 00:36:55 +00005131static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005132s390_irgen_CPYA(UChar r1, UChar r2)
5133{
5134 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005135 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005136 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5137
5138 return "cpya";
5139}
5140
florian55085f82012-11-21 00:36:55 +00005141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005142s390_irgen_XR(UChar r1, UChar r2)
5143{
5144 IRTemp op1 = newTemp(Ity_I32);
5145 IRTemp op2 = newTemp(Ity_I32);
5146 IRTemp result = newTemp(Ity_I32);
5147
5148 if (r1 == r2) {
5149 assign(result, mkU32(0));
5150 } else {
5151 assign(op1, get_gpr_w1(r1));
5152 assign(op2, get_gpr_w1(r2));
5153 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5154 }
5155 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5156 put_gpr_w1(r1, mkexpr(result));
5157
5158 return "xr";
5159}
5160
florian55085f82012-11-21 00:36:55 +00005161static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005162s390_irgen_XGR(UChar r1, UChar r2)
5163{
5164 IRTemp op1 = newTemp(Ity_I64);
5165 IRTemp op2 = newTemp(Ity_I64);
5166 IRTemp result = newTemp(Ity_I64);
5167
5168 if (r1 == r2) {
5169 assign(result, mkU64(0));
5170 } else {
5171 assign(op1, get_gpr_dw0(r1));
5172 assign(op2, get_gpr_dw0(r2));
5173 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5174 }
5175 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5176 put_gpr_dw0(r1, mkexpr(result));
5177
5178 return "xgr";
5179}
5180
florian55085f82012-11-21 00:36:55 +00005181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005182s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5183{
5184 IRTemp op2 = newTemp(Ity_I32);
5185 IRTemp op3 = newTemp(Ity_I32);
5186 IRTemp result = newTemp(Ity_I32);
5187
5188 assign(op2, get_gpr_w1(r2));
5189 assign(op3, get_gpr_w1(r3));
5190 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5191 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5192 put_gpr_w1(r1, mkexpr(result));
5193
5194 return "xrk";
5195}
5196
florian55085f82012-11-21 00:36:55 +00005197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005198s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5199{
5200 IRTemp op2 = newTemp(Ity_I64);
5201 IRTemp op3 = newTemp(Ity_I64);
5202 IRTemp result = newTemp(Ity_I64);
5203
5204 assign(op2, get_gpr_dw0(r2));
5205 assign(op3, get_gpr_dw0(r3));
5206 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5207 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5208 put_gpr_dw0(r1, mkexpr(result));
5209
5210 return "xgrk";
5211}
5212
florian55085f82012-11-21 00:36:55 +00005213static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005214s390_irgen_X(UChar r1, IRTemp op2addr)
5215{
5216 IRTemp op1 = newTemp(Ity_I32);
5217 IRTemp op2 = newTemp(Ity_I32);
5218 IRTemp result = newTemp(Ity_I32);
5219
5220 assign(op1, get_gpr_w1(r1));
5221 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5222 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5223 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5224 put_gpr_w1(r1, mkexpr(result));
5225
5226 return "x";
5227}
5228
florian55085f82012-11-21 00:36:55 +00005229static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005230s390_irgen_XY(UChar r1, IRTemp op2addr)
5231{
5232 IRTemp op1 = newTemp(Ity_I32);
5233 IRTemp op2 = newTemp(Ity_I32);
5234 IRTemp result = newTemp(Ity_I32);
5235
5236 assign(op1, get_gpr_w1(r1));
5237 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5238 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5239 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5240 put_gpr_w1(r1, mkexpr(result));
5241
5242 return "xy";
5243}
5244
florian55085f82012-11-21 00:36:55 +00005245static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005246s390_irgen_XG(UChar r1, IRTemp op2addr)
5247{
5248 IRTemp op1 = newTemp(Ity_I64);
5249 IRTemp op2 = newTemp(Ity_I64);
5250 IRTemp result = newTemp(Ity_I64);
5251
5252 assign(op1, get_gpr_dw0(r1));
5253 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5254 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5255 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5256 put_gpr_dw0(r1, mkexpr(result));
5257
5258 return "xg";
5259}
5260
florian55085f82012-11-21 00:36:55 +00005261static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005262s390_irgen_XI(UChar i2, IRTemp op1addr)
5263{
5264 IRTemp op1 = newTemp(Ity_I8);
5265 UChar op2;
5266 IRTemp result = newTemp(Ity_I8);
5267
5268 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5269 op2 = i2;
5270 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5271 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5272 store(mkexpr(op1addr), mkexpr(result));
5273
5274 return "xi";
5275}
5276
florian55085f82012-11-21 00:36:55 +00005277static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005278s390_irgen_XIY(UChar i2, IRTemp op1addr)
5279{
5280 IRTemp op1 = newTemp(Ity_I8);
5281 UChar op2;
5282 IRTemp result = newTemp(Ity_I8);
5283
5284 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5285 op2 = i2;
5286 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5287 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5288 store(mkexpr(op1addr), mkexpr(result));
5289
5290 return "xiy";
5291}
5292
florian55085f82012-11-21 00:36:55 +00005293static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005294s390_irgen_XIHF(UChar r1, UInt i2)
5295{
5296 IRTemp op1 = newTemp(Ity_I32);
5297 UInt op2;
5298 IRTemp result = newTemp(Ity_I32);
5299
5300 assign(op1, get_gpr_w0(r1));
5301 op2 = i2;
5302 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5303 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5304 put_gpr_w0(r1, mkexpr(result));
5305
5306 return "xihf";
5307}
5308
florian55085f82012-11-21 00:36:55 +00005309static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005310s390_irgen_XILF(UChar r1, UInt i2)
5311{
5312 IRTemp op1 = newTemp(Ity_I32);
5313 UInt op2;
5314 IRTemp result = newTemp(Ity_I32);
5315
5316 assign(op1, get_gpr_w1(r1));
5317 op2 = i2;
5318 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5319 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5320 put_gpr_w1(r1, mkexpr(result));
5321
5322 return "xilf";
5323}
5324
florian55085f82012-11-21 00:36:55 +00005325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005326s390_irgen_EAR(UChar r1, UChar r2)
5327{
5328 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005329 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005330 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5331
5332 return "ear";
5333}
5334
florian55085f82012-11-21 00:36:55 +00005335static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005336s390_irgen_IC(UChar r1, IRTemp op2addr)
5337{
5338 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5339
5340 return "ic";
5341}
5342
florian55085f82012-11-21 00:36:55 +00005343static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005344s390_irgen_ICY(UChar r1, IRTemp op2addr)
5345{
5346 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5347
5348 return "icy";
5349}
5350
florian55085f82012-11-21 00:36:55 +00005351static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005352s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5353{
5354 UChar n;
5355 IRTemp result = newTemp(Ity_I32);
5356 UInt mask;
5357
5358 n = 0;
5359 mask = (UInt)r3;
5360 if ((mask & 8) != 0) {
5361 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5362 n = n + 1;
5363 }
5364 if ((mask & 4) != 0) {
5365 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5366
5367 n = n + 1;
5368 }
5369 if ((mask & 2) != 0) {
5370 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5371
5372 n = n + 1;
5373 }
5374 if ((mask & 1) != 0) {
5375 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5376
5377 n = n + 1;
5378 }
5379 assign(result, get_gpr_w1(r1));
5380 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5381 mkU32(mask)));
5382
5383 return "icm";
5384}
5385
florian55085f82012-11-21 00:36:55 +00005386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005387s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5388{
5389 UChar n;
5390 IRTemp result = newTemp(Ity_I32);
5391 UInt mask;
5392
5393 n = 0;
5394 mask = (UInt)r3;
5395 if ((mask & 8) != 0) {
5396 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5397 n = n + 1;
5398 }
5399 if ((mask & 4) != 0) {
5400 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5401
5402 n = n + 1;
5403 }
5404 if ((mask & 2) != 0) {
5405 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5406
5407 n = n + 1;
5408 }
5409 if ((mask & 1) != 0) {
5410 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5411
5412 n = n + 1;
5413 }
5414 assign(result, get_gpr_w1(r1));
5415 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5416 mkU32(mask)));
5417
5418 return "icmy";
5419}
5420
florian55085f82012-11-21 00:36:55 +00005421static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005422s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5423{
5424 UChar n;
5425 IRTemp result = newTemp(Ity_I32);
5426 UInt mask;
5427
5428 n = 0;
5429 mask = (UInt)r3;
5430 if ((mask & 8) != 0) {
5431 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5432 n = n + 1;
5433 }
5434 if ((mask & 4) != 0) {
5435 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5436
5437 n = n + 1;
5438 }
5439 if ((mask & 2) != 0) {
5440 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5441
5442 n = n + 1;
5443 }
5444 if ((mask & 1) != 0) {
5445 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5446
5447 n = n + 1;
5448 }
5449 assign(result, get_gpr_w0(r1));
5450 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5451 mkU32(mask)));
5452
5453 return "icmh";
5454}
5455
florian55085f82012-11-21 00:36:55 +00005456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005457s390_irgen_IIHF(UChar r1, UInt i2)
5458{
5459 put_gpr_w0(r1, mkU32(i2));
5460
5461 return "iihf";
5462}
5463
florian55085f82012-11-21 00:36:55 +00005464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005465s390_irgen_IIHH(UChar r1, UShort i2)
5466{
5467 put_gpr_hw0(r1, mkU16(i2));
5468
5469 return "iihh";
5470}
5471
florian55085f82012-11-21 00:36:55 +00005472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005473s390_irgen_IIHL(UChar r1, UShort i2)
5474{
5475 put_gpr_hw1(r1, mkU16(i2));
5476
5477 return "iihl";
5478}
5479
florian55085f82012-11-21 00:36:55 +00005480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005481s390_irgen_IILF(UChar r1, UInt i2)
5482{
5483 put_gpr_w1(r1, mkU32(i2));
5484
5485 return "iilf";
5486}
5487
florian55085f82012-11-21 00:36:55 +00005488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005489s390_irgen_IILH(UChar r1, UShort i2)
5490{
5491 put_gpr_hw2(r1, mkU16(i2));
5492
5493 return "iilh";
5494}
5495
florian55085f82012-11-21 00:36:55 +00005496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005497s390_irgen_IILL(UChar r1, UShort i2)
5498{
5499 put_gpr_hw3(r1, mkU16(i2));
5500
5501 return "iill";
5502}
5503
florian55085f82012-11-21 00:36:55 +00005504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005505s390_irgen_LR(UChar r1, UChar r2)
5506{
5507 put_gpr_w1(r1, get_gpr_w1(r2));
5508
5509 return "lr";
5510}
5511
florian55085f82012-11-21 00:36:55 +00005512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005513s390_irgen_LGR(UChar r1, UChar r2)
5514{
5515 put_gpr_dw0(r1, get_gpr_dw0(r2));
5516
5517 return "lgr";
5518}
5519
florian55085f82012-11-21 00:36:55 +00005520static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005521s390_irgen_LGFR(UChar r1, UChar r2)
5522{
5523 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5524
5525 return "lgfr";
5526}
5527
florian55085f82012-11-21 00:36:55 +00005528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005529s390_irgen_L(UChar r1, IRTemp op2addr)
5530{
5531 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5532
5533 return "l";
5534}
5535
florian55085f82012-11-21 00:36:55 +00005536static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005537s390_irgen_LY(UChar r1, IRTemp op2addr)
5538{
5539 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5540
5541 return "ly";
5542}
5543
florian55085f82012-11-21 00:36:55 +00005544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005545s390_irgen_LG(UChar r1, IRTemp op2addr)
5546{
5547 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5548
5549 return "lg";
5550}
5551
florian55085f82012-11-21 00:36:55 +00005552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005553s390_irgen_LGF(UChar r1, IRTemp op2addr)
5554{
5555 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5556
5557 return "lgf";
5558}
5559
florian55085f82012-11-21 00:36:55 +00005560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005561s390_irgen_LGFI(UChar r1, UInt i2)
5562{
5563 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5564
5565 return "lgfi";
5566}
5567
florian55085f82012-11-21 00:36:55 +00005568static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005569s390_irgen_LRL(UChar r1, UInt i2)
5570{
5571 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5572 i2 << 1))));
5573
5574 return "lrl";
5575}
5576
florian55085f82012-11-21 00:36:55 +00005577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005578s390_irgen_LGRL(UChar r1, UInt i2)
5579{
5580 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5581 i2 << 1))));
5582
5583 return "lgrl";
5584}
5585
florian55085f82012-11-21 00:36:55 +00005586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005587s390_irgen_LGFRL(UChar r1, UInt i2)
5588{
5589 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5590 ((ULong)(Long)(Int)i2 << 1)))));
5591
5592 return "lgfrl";
5593}
5594
florian55085f82012-11-21 00:36:55 +00005595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005596s390_irgen_LA(UChar r1, IRTemp op2addr)
5597{
5598 put_gpr_dw0(r1, mkexpr(op2addr));
5599
5600 return "la";
5601}
5602
florian55085f82012-11-21 00:36:55 +00005603static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005604s390_irgen_LAY(UChar r1, IRTemp op2addr)
5605{
5606 put_gpr_dw0(r1, mkexpr(op2addr));
5607
5608 return "lay";
5609}
5610
florian55085f82012-11-21 00:36:55 +00005611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005612s390_irgen_LAE(UChar r1, IRTemp op2addr)
5613{
5614 put_gpr_dw0(r1, mkexpr(op2addr));
5615
5616 return "lae";
5617}
5618
florian55085f82012-11-21 00:36:55 +00005619static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005620s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5621{
5622 put_gpr_dw0(r1, mkexpr(op2addr));
5623
5624 return "laey";
5625}
5626
florian55085f82012-11-21 00:36:55 +00005627static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005628s390_irgen_LARL(UChar r1, UInt i2)
5629{
5630 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5631
5632 return "larl";
5633}
5634
floriana265ee72012-12-02 20:58:17 +00005635/* The IR representation of LAA and friends is an approximation of what
5636 happens natively. Essentially a loop containing a compare-and-swap is
5637 constructed which will iterate until the CAS succeeds. As a consequence,
5638 instrumenters may see more memory accesses than happen natively. See also
5639 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005640static void
5641s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005642{
floriana265ee72012-12-02 20:58:17 +00005643 IRCAS *cas;
5644 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005645 IRTemp op2 = newTemp(Ity_I32);
5646 IRTemp op3 = newTemp(Ity_I32);
5647 IRTemp result = newTemp(Ity_I32);
5648
5649 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5650 assign(op3, get_gpr_w1(r3));
5651 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005652
5653 /* Place the addition of second operand and third operand at the
5654 second-operand location everytime */
5655 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5656 Iend_BE, mkexpr(op2addr),
5657 NULL, mkexpr(op2), /* expected value */
5658 NULL, mkexpr(result) /* new value */);
5659 stmt(IRStmt_CAS(cas));
5660
florianffc94012012-12-02 21:31:15 +00005661 /* Set CC according to 32-bit addition */
5662 if (is_signed) {
5663 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5664 } else {
5665 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5666 }
floriana265ee72012-12-02 20:58:17 +00005667
5668 /* If old_mem contains the expected value, then the CAS succeeded.
5669 Otherwise, it did not */
5670 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5671 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005672}
5673
5674static void
5675s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5676{
5677 IRCAS *cas;
5678 IRTemp old_mem = newTemp(Ity_I64);
5679 IRTemp op2 = newTemp(Ity_I64);
5680 IRTemp op3 = newTemp(Ity_I64);
5681 IRTemp result = newTemp(Ity_I64);
5682
5683 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5684 assign(op3, get_gpr_dw0(r3));
5685 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5686
5687 /* Place the addition of second operand and third operand at the
5688 second-operand location everytime */
5689 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5690 Iend_BE, mkexpr(op2addr),
5691 NULL, mkexpr(op2), /* expected value */
5692 NULL, mkexpr(result) /* new value */);
5693 stmt(IRStmt_CAS(cas));
5694
5695 /* Set CC according to 64-bit addition */
5696 if (is_signed) {
5697 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5698 } else {
5699 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5700 }
5701
5702 /* If old_mem contains the expected value, then the CAS succeeded.
5703 Otherwise, it did not */
5704 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5705 put_gpr_dw0(r1, mkexpr(old_mem));
5706}
5707
5708static void
5709s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5710{
5711 IRCAS *cas;
5712 IRTemp old_mem = newTemp(Ity_I32);
5713 IRTemp op2 = newTemp(Ity_I32);
5714 IRTemp op3 = newTemp(Ity_I32);
5715 IRTemp result = newTemp(Ity_I32);
5716
5717 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5718 assign(op3, get_gpr_w1(r3));
5719 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5720
5721 /* Place the addition of second operand and third operand at the
5722 second-operand location everytime */
5723 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5724 Iend_BE, mkexpr(op2addr),
5725 NULL, mkexpr(op2), /* expected value */
5726 NULL, mkexpr(result) /* new value */);
5727 stmt(IRStmt_CAS(cas));
5728
5729 /* Set CC according to bitwise operation */
5730 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5731
5732 /* If old_mem contains the expected value, then the CAS succeeded.
5733 Otherwise, it did not */
5734 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5735 put_gpr_w1(r1, mkexpr(old_mem));
5736}
5737
5738static void
5739s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5740{
5741 IRCAS *cas;
5742 IRTemp old_mem = newTemp(Ity_I64);
5743 IRTemp op2 = newTemp(Ity_I64);
5744 IRTemp op3 = newTemp(Ity_I64);
5745 IRTemp result = newTemp(Ity_I64);
5746
5747 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5748 assign(op3, get_gpr_dw0(r3));
5749 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5750
5751 /* Place the addition of second operand and third operand at the
5752 second-operand location everytime */
5753 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5754 Iend_BE, mkexpr(op2addr),
5755 NULL, mkexpr(op2), /* expected value */
5756 NULL, mkexpr(result) /* new value */);
5757 stmt(IRStmt_CAS(cas));
5758
5759 /* Set CC according to bitwise operation */
5760 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5761
5762 /* If old_mem contains the expected value, then the CAS succeeded.
5763 Otherwise, it did not */
5764 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5765 put_gpr_dw0(r1, mkexpr(old_mem));
5766}
5767
5768static const HChar *
5769s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5770{
5771 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005772
5773 return "laa";
5774}
5775
florian55085f82012-11-21 00:36:55 +00005776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005777s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5778{
florianffc94012012-12-02 21:31:15 +00005779 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005780
5781 return "laag";
5782}
5783
florian55085f82012-11-21 00:36:55 +00005784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005785s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5786{
florianffc94012012-12-02 21:31:15 +00005787 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005788
5789 return "laal";
5790}
5791
florian55085f82012-11-21 00:36:55 +00005792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005793s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5794{
florianffc94012012-12-02 21:31:15 +00005795 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005796
5797 return "laalg";
5798}
5799
florian55085f82012-11-21 00:36:55 +00005800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005801s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5802{
florianffc94012012-12-02 21:31:15 +00005803 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005804
5805 return "lan";
5806}
5807
florian55085f82012-11-21 00:36:55 +00005808static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005809s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5810{
florianffc94012012-12-02 21:31:15 +00005811 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005812
5813 return "lang";
5814}
5815
florian55085f82012-11-21 00:36:55 +00005816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005817s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5818{
florianffc94012012-12-02 21:31:15 +00005819 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005820
5821 return "lax";
5822}
5823
florian55085f82012-11-21 00:36:55 +00005824static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005825s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5826{
florianffc94012012-12-02 21:31:15 +00005827 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005828
5829 return "laxg";
5830}
5831
florian55085f82012-11-21 00:36:55 +00005832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005833s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5834{
florianffc94012012-12-02 21:31:15 +00005835 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005836
5837 return "lao";
5838}
5839
florian55085f82012-11-21 00:36:55 +00005840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005841s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5842{
florianffc94012012-12-02 21:31:15 +00005843 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005844
5845 return "laog";
5846}
5847
florian55085f82012-11-21 00:36:55 +00005848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005849s390_irgen_LTR(UChar r1, UChar r2)
5850{
5851 IRTemp op2 = newTemp(Ity_I32);
5852
5853 assign(op2, get_gpr_w1(r2));
5854 put_gpr_w1(r1, mkexpr(op2));
5855 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5856
5857 return "ltr";
5858}
5859
florian55085f82012-11-21 00:36:55 +00005860static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005861s390_irgen_LTGR(UChar r1, UChar r2)
5862{
5863 IRTemp op2 = newTemp(Ity_I64);
5864
5865 assign(op2, get_gpr_dw0(r2));
5866 put_gpr_dw0(r1, mkexpr(op2));
5867 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5868
5869 return "ltgr";
5870}
5871
florian55085f82012-11-21 00:36:55 +00005872static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005873s390_irgen_LTGFR(UChar r1, UChar r2)
5874{
5875 IRTemp op2 = newTemp(Ity_I64);
5876
5877 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5878 put_gpr_dw0(r1, mkexpr(op2));
5879 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5880
5881 return "ltgfr";
5882}
5883
florian55085f82012-11-21 00:36:55 +00005884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005885s390_irgen_LT(UChar r1, IRTemp op2addr)
5886{
5887 IRTemp op2 = newTemp(Ity_I32);
5888
5889 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5890 put_gpr_w1(r1, mkexpr(op2));
5891 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5892
5893 return "lt";
5894}
5895
florian55085f82012-11-21 00:36:55 +00005896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005897s390_irgen_LTG(UChar r1, IRTemp op2addr)
5898{
5899 IRTemp op2 = newTemp(Ity_I64);
5900
5901 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5902 put_gpr_dw0(r1, mkexpr(op2));
5903 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5904
5905 return "ltg";
5906}
5907
florian55085f82012-11-21 00:36:55 +00005908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005909s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5910{
5911 IRTemp op2 = newTemp(Ity_I64);
5912
5913 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5914 put_gpr_dw0(r1, mkexpr(op2));
5915 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5916
5917 return "ltgf";
5918}
5919
florian55085f82012-11-21 00:36:55 +00005920static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005921s390_irgen_LBR(UChar r1, UChar r2)
5922{
5923 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5924
5925 return "lbr";
5926}
5927
florian55085f82012-11-21 00:36:55 +00005928static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005929s390_irgen_LGBR(UChar r1, UChar r2)
5930{
5931 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5932
5933 return "lgbr";
5934}
5935
florian55085f82012-11-21 00:36:55 +00005936static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005937s390_irgen_LB(UChar r1, IRTemp op2addr)
5938{
5939 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5940
5941 return "lb";
5942}
5943
florian55085f82012-11-21 00:36:55 +00005944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005945s390_irgen_LGB(UChar r1, IRTemp op2addr)
5946{
5947 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5948
5949 return "lgb";
5950}
5951
florian55085f82012-11-21 00:36:55 +00005952static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005953s390_irgen_LBH(UChar r1, IRTemp op2addr)
5954{
5955 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5956
5957 return "lbh";
5958}
5959
florian55085f82012-11-21 00:36:55 +00005960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005961s390_irgen_LCR(UChar r1, UChar r2)
5962{
5963 Int op1;
5964 IRTemp op2 = newTemp(Ity_I32);
5965 IRTemp result = newTemp(Ity_I32);
5966
5967 op1 = 0;
5968 assign(op2, get_gpr_w1(r2));
5969 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5970 put_gpr_w1(r1, mkexpr(result));
5971 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5972 op1)), op2);
5973
5974 return "lcr";
5975}
5976
florian55085f82012-11-21 00:36:55 +00005977static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005978s390_irgen_LCGR(UChar r1, UChar r2)
5979{
5980 Long op1;
5981 IRTemp op2 = newTemp(Ity_I64);
5982 IRTemp result = newTemp(Ity_I64);
5983
5984 op1 = 0ULL;
5985 assign(op2, get_gpr_dw0(r2));
5986 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5987 put_gpr_dw0(r1, mkexpr(result));
5988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5989 op1)), op2);
5990
5991 return "lcgr";
5992}
5993
florian55085f82012-11-21 00:36:55 +00005994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005995s390_irgen_LCGFR(UChar r1, UChar r2)
5996{
5997 Long op1;
5998 IRTemp op2 = newTemp(Ity_I64);
5999 IRTemp result = newTemp(Ity_I64);
6000
6001 op1 = 0ULL;
6002 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6003 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
6004 put_gpr_dw0(r1, mkexpr(result));
6005 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
6006 op1)), op2);
6007
6008 return "lcgfr";
6009}
6010
florian55085f82012-11-21 00:36:55 +00006011static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006012s390_irgen_LHR(UChar r1, UChar r2)
6013{
6014 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
6015
6016 return "lhr";
6017}
6018
florian55085f82012-11-21 00:36:55 +00006019static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006020s390_irgen_LGHR(UChar r1, UChar r2)
6021{
6022 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
6023
6024 return "lghr";
6025}
6026
florian55085f82012-11-21 00:36:55 +00006027static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006028s390_irgen_LH(UChar r1, IRTemp op2addr)
6029{
6030 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6031
6032 return "lh";
6033}
6034
florian55085f82012-11-21 00:36:55 +00006035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006036s390_irgen_LHY(UChar r1, IRTemp op2addr)
6037{
6038 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6039
6040 return "lhy";
6041}
6042
florian55085f82012-11-21 00:36:55 +00006043static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006044s390_irgen_LGH(UChar r1, IRTemp op2addr)
6045{
6046 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6047
6048 return "lgh";
6049}
6050
florian55085f82012-11-21 00:36:55 +00006051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006052s390_irgen_LHI(UChar r1, UShort i2)
6053{
6054 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6055
6056 return "lhi";
6057}
6058
florian55085f82012-11-21 00:36:55 +00006059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006060s390_irgen_LGHI(UChar r1, UShort i2)
6061{
6062 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6063
6064 return "lghi";
6065}
6066
florian55085f82012-11-21 00:36:55 +00006067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006068s390_irgen_LHRL(UChar r1, UInt i2)
6069{
6070 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6071 ((ULong)(Long)(Int)i2 << 1)))));
6072
6073 return "lhrl";
6074}
6075
florian55085f82012-11-21 00:36:55 +00006076static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006077s390_irgen_LGHRL(UChar r1, UInt i2)
6078{
6079 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6080 ((ULong)(Long)(Int)i2 << 1)))));
6081
6082 return "lghrl";
6083}
6084
florian55085f82012-11-21 00:36:55 +00006085static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006086s390_irgen_LHH(UChar r1, IRTemp op2addr)
6087{
6088 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6089
6090 return "lhh";
6091}
6092
florian55085f82012-11-21 00:36:55 +00006093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006094s390_irgen_LFH(UChar r1, IRTemp op2addr)
6095{
6096 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6097
6098 return "lfh";
6099}
6100
florian55085f82012-11-21 00:36:55 +00006101static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006102s390_irgen_LLGFR(UChar r1, UChar r2)
6103{
6104 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6105
6106 return "llgfr";
6107}
6108
florian55085f82012-11-21 00:36:55 +00006109static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006110s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6111{
6112 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6113
6114 return "llgf";
6115}
6116
florian55085f82012-11-21 00:36:55 +00006117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006118s390_irgen_LLGFRL(UChar r1, UInt i2)
6119{
6120 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6121 ((ULong)(Long)(Int)i2 << 1)))));
6122
6123 return "llgfrl";
6124}
6125
florian55085f82012-11-21 00:36:55 +00006126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006127s390_irgen_LLCR(UChar r1, UChar r2)
6128{
6129 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6130
6131 return "llcr";
6132}
6133
florian55085f82012-11-21 00:36:55 +00006134static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006135s390_irgen_LLGCR(UChar r1, UChar r2)
6136{
6137 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6138
6139 return "llgcr";
6140}
6141
florian55085f82012-11-21 00:36:55 +00006142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006143s390_irgen_LLC(UChar r1, IRTemp op2addr)
6144{
6145 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6146
6147 return "llc";
6148}
6149
florian55085f82012-11-21 00:36:55 +00006150static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006151s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6152{
6153 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6154
6155 return "llgc";
6156}
6157
florian55085f82012-11-21 00:36:55 +00006158static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006159s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6160{
6161 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6162
6163 return "llch";
6164}
6165
florian55085f82012-11-21 00:36:55 +00006166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006167s390_irgen_LLHR(UChar r1, UChar r2)
6168{
6169 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6170
6171 return "llhr";
6172}
6173
florian55085f82012-11-21 00:36:55 +00006174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006175s390_irgen_LLGHR(UChar r1, UChar r2)
6176{
6177 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6178
6179 return "llghr";
6180}
6181
florian55085f82012-11-21 00:36:55 +00006182static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006183s390_irgen_LLH(UChar r1, IRTemp op2addr)
6184{
6185 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6186
6187 return "llh";
6188}
6189
florian55085f82012-11-21 00:36:55 +00006190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006191s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6192{
6193 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6194
6195 return "llgh";
6196}
6197
florian55085f82012-11-21 00:36:55 +00006198static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006199s390_irgen_LLHRL(UChar r1, UInt i2)
6200{
6201 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6202 ((ULong)(Long)(Int)i2 << 1)))));
6203
6204 return "llhrl";
6205}
6206
florian55085f82012-11-21 00:36:55 +00006207static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006208s390_irgen_LLGHRL(UChar r1, UInt i2)
6209{
6210 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6211 ((ULong)(Long)(Int)i2 << 1)))));
6212
6213 return "llghrl";
6214}
6215
florian55085f82012-11-21 00:36:55 +00006216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006217s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6218{
6219 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6220
6221 return "llhh";
6222}
6223
florian55085f82012-11-21 00:36:55 +00006224static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006225s390_irgen_LLIHF(UChar r1, UInt i2)
6226{
6227 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6228
6229 return "llihf";
6230}
6231
florian55085f82012-11-21 00:36:55 +00006232static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006233s390_irgen_LLIHH(UChar r1, UShort i2)
6234{
6235 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6236
6237 return "llihh";
6238}
6239
florian55085f82012-11-21 00:36:55 +00006240static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006241s390_irgen_LLIHL(UChar r1, UShort i2)
6242{
6243 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6244
6245 return "llihl";
6246}
6247
florian55085f82012-11-21 00:36:55 +00006248static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006249s390_irgen_LLILF(UChar r1, UInt i2)
6250{
6251 put_gpr_dw0(r1, mkU64(i2));
6252
6253 return "llilf";
6254}
6255
florian55085f82012-11-21 00:36:55 +00006256static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006257s390_irgen_LLILH(UChar r1, UShort i2)
6258{
6259 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6260
6261 return "llilh";
6262}
6263
florian55085f82012-11-21 00:36:55 +00006264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006265s390_irgen_LLILL(UChar r1, UShort i2)
6266{
6267 put_gpr_dw0(r1, mkU64(i2));
6268
6269 return "llill";
6270}
6271
florian55085f82012-11-21 00:36:55 +00006272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006273s390_irgen_LLGTR(UChar r1, UChar r2)
6274{
6275 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6276 mkU32(2147483647))));
6277
6278 return "llgtr";
6279}
6280
florian55085f82012-11-21 00:36:55 +00006281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006282s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6283{
6284 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6285 mkexpr(op2addr)), mkU32(2147483647))));
6286
6287 return "llgt";
6288}
6289
florian55085f82012-11-21 00:36:55 +00006290static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006291s390_irgen_LNR(UChar r1, UChar r2)
6292{
6293 IRTemp op2 = newTemp(Ity_I32);
6294 IRTemp result = newTemp(Ity_I32);
6295
6296 assign(op2, get_gpr_w1(r2));
6297 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6298 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6299 put_gpr_w1(r1, mkexpr(result));
6300 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6301
6302 return "lnr";
6303}
6304
florian55085f82012-11-21 00:36:55 +00006305static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006306s390_irgen_LNGR(UChar r1, UChar r2)
6307{
6308 IRTemp op2 = newTemp(Ity_I64);
6309 IRTemp result = newTemp(Ity_I64);
6310
6311 assign(op2, get_gpr_dw0(r2));
6312 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6313 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6314 put_gpr_dw0(r1, mkexpr(result));
6315 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6316
6317 return "lngr";
6318}
6319
florian55085f82012-11-21 00:36:55 +00006320static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006321s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6322{
6323 IRTemp op2 = newTemp(Ity_I64);
6324 IRTemp result = newTemp(Ity_I64);
6325
6326 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6327 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6328 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6329 put_gpr_dw0(r1, mkexpr(result));
6330 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6331
6332 return "lngfr";
6333}
6334
florian55085f82012-11-21 00:36:55 +00006335static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006336s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6337{
florian6820ba52012-07-26 02:01:50 +00006338 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006339 put_gpr_w1(r1, get_gpr_w1(r2));
6340
6341 return "locr";
6342}
6343
florian55085f82012-11-21 00:36:55 +00006344static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006345s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6346{
florian6820ba52012-07-26 02:01:50 +00006347 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006348 put_gpr_dw0(r1, get_gpr_dw0(r2));
6349
6350 return "locgr";
6351}
6352
florian55085f82012-11-21 00:36:55 +00006353static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006354s390_irgen_LOC(UChar r1, IRTemp op2addr)
6355{
6356 /* condition is checked in format handler */
6357 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6358
6359 return "loc";
6360}
6361
florian55085f82012-11-21 00:36:55 +00006362static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006363s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6364{
6365 /* condition is checked in format handler */
6366 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6367
6368 return "locg";
6369}
6370
florian55085f82012-11-21 00:36:55 +00006371static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006372s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6373{
6374 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6375 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6376 ));
6377
6378 return "lpq";
6379}
6380
florian55085f82012-11-21 00:36:55 +00006381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006382s390_irgen_LPR(UChar r1, UChar r2)
6383{
6384 IRTemp op2 = newTemp(Ity_I32);
6385 IRTemp result = newTemp(Ity_I32);
6386
6387 assign(op2, get_gpr_w1(r2));
6388 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6389 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6390 put_gpr_w1(r1, mkexpr(result));
6391 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6392
6393 return "lpr";
6394}
6395
florian55085f82012-11-21 00:36:55 +00006396static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006397s390_irgen_LPGR(UChar r1, UChar r2)
6398{
6399 IRTemp op2 = newTemp(Ity_I64);
6400 IRTemp result = newTemp(Ity_I64);
6401
6402 assign(op2, get_gpr_dw0(r2));
6403 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6404 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6405 put_gpr_dw0(r1, mkexpr(result));
6406 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6407
6408 return "lpgr";
6409}
6410
florian55085f82012-11-21 00:36:55 +00006411static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006412s390_irgen_LPGFR(UChar r1, UChar r2)
6413{
6414 IRTemp op2 = newTemp(Ity_I64);
6415 IRTemp result = newTemp(Ity_I64);
6416
6417 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6418 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6419 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6420 put_gpr_dw0(r1, mkexpr(result));
6421 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6422
6423 return "lpgfr";
6424}
6425
florian55085f82012-11-21 00:36:55 +00006426static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006427s390_irgen_LRVR(UChar r1, UChar r2)
6428{
6429 IRTemp b0 = newTemp(Ity_I8);
6430 IRTemp b1 = newTemp(Ity_I8);
6431 IRTemp b2 = newTemp(Ity_I8);
6432 IRTemp b3 = newTemp(Ity_I8);
6433
6434 assign(b3, get_gpr_b7(r2));
6435 assign(b2, get_gpr_b6(r2));
6436 assign(b1, get_gpr_b5(r2));
6437 assign(b0, get_gpr_b4(r2));
6438 put_gpr_b4(r1, mkexpr(b3));
6439 put_gpr_b5(r1, mkexpr(b2));
6440 put_gpr_b6(r1, mkexpr(b1));
6441 put_gpr_b7(r1, mkexpr(b0));
6442
6443 return "lrvr";
6444}
6445
florian55085f82012-11-21 00:36:55 +00006446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006447s390_irgen_LRVGR(UChar r1, UChar r2)
6448{
6449 IRTemp b0 = newTemp(Ity_I8);
6450 IRTemp b1 = newTemp(Ity_I8);
6451 IRTemp b2 = newTemp(Ity_I8);
6452 IRTemp b3 = newTemp(Ity_I8);
6453 IRTemp b4 = newTemp(Ity_I8);
6454 IRTemp b5 = newTemp(Ity_I8);
6455 IRTemp b6 = newTemp(Ity_I8);
6456 IRTemp b7 = newTemp(Ity_I8);
6457
6458 assign(b7, get_gpr_b7(r2));
6459 assign(b6, get_gpr_b6(r2));
6460 assign(b5, get_gpr_b5(r2));
6461 assign(b4, get_gpr_b4(r2));
6462 assign(b3, get_gpr_b3(r2));
6463 assign(b2, get_gpr_b2(r2));
6464 assign(b1, get_gpr_b1(r2));
6465 assign(b0, get_gpr_b0(r2));
6466 put_gpr_b0(r1, mkexpr(b7));
6467 put_gpr_b1(r1, mkexpr(b6));
6468 put_gpr_b2(r1, mkexpr(b5));
6469 put_gpr_b3(r1, mkexpr(b4));
6470 put_gpr_b4(r1, mkexpr(b3));
6471 put_gpr_b5(r1, mkexpr(b2));
6472 put_gpr_b6(r1, mkexpr(b1));
6473 put_gpr_b7(r1, mkexpr(b0));
6474
6475 return "lrvgr";
6476}
6477
florian55085f82012-11-21 00:36:55 +00006478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006479s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6480{
6481 IRTemp op2 = newTemp(Ity_I16);
6482
6483 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6484 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6485 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6486
6487 return "lrvh";
6488}
6489
florian55085f82012-11-21 00:36:55 +00006490static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006491s390_irgen_LRV(UChar r1, IRTemp op2addr)
6492{
6493 IRTemp op2 = newTemp(Ity_I32);
6494
6495 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6496 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6497 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6498 mkU8(8)), mkU32(255))));
6499 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6500 mkU8(16)), mkU32(255))));
6501 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6502 mkU8(24)), mkU32(255))));
6503
6504 return "lrv";
6505}
6506
florian55085f82012-11-21 00:36:55 +00006507static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006508s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6509{
6510 IRTemp op2 = newTemp(Ity_I64);
6511
6512 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6513 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6514 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6515 mkU8(8)), mkU64(255))));
6516 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6517 mkU8(16)), mkU64(255))));
6518 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6519 mkU8(24)), mkU64(255))));
6520 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6521 mkU8(32)), mkU64(255))));
6522 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6523 mkU8(40)), mkU64(255))));
6524 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6525 mkU8(48)), mkU64(255))));
6526 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6527 mkU8(56)), mkU64(255))));
6528
6529 return "lrvg";
6530}
6531
florian55085f82012-11-21 00:36:55 +00006532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006533s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6534{
6535 store(mkexpr(op1addr), mkU16(i2));
6536
6537 return "mvhhi";
6538}
6539
florian55085f82012-11-21 00:36:55 +00006540static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006541s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6542{
6543 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6544
6545 return "mvhi";
6546}
6547
florian55085f82012-11-21 00:36:55 +00006548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006549s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6550{
6551 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6552
6553 return "mvghi";
6554}
6555
florian55085f82012-11-21 00:36:55 +00006556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006557s390_irgen_MVI(UChar i2, IRTemp op1addr)
6558{
6559 store(mkexpr(op1addr), mkU8(i2));
6560
6561 return "mvi";
6562}
6563
florian55085f82012-11-21 00:36:55 +00006564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006565s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6566{
6567 store(mkexpr(op1addr), mkU8(i2));
6568
6569 return "mviy";
6570}
6571
florian55085f82012-11-21 00:36:55 +00006572static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006573s390_irgen_MR(UChar r1, UChar r2)
6574{
6575 IRTemp op1 = newTemp(Ity_I32);
6576 IRTemp op2 = newTemp(Ity_I32);
6577 IRTemp result = newTemp(Ity_I64);
6578
6579 assign(op1, get_gpr_w1(r1 + 1));
6580 assign(op2, get_gpr_w1(r2));
6581 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6582 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6583 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6584
6585 return "mr";
6586}
6587
florian55085f82012-11-21 00:36:55 +00006588static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006589s390_irgen_M(UChar r1, IRTemp op2addr)
6590{
6591 IRTemp op1 = newTemp(Ity_I32);
6592 IRTemp op2 = newTemp(Ity_I32);
6593 IRTemp result = newTemp(Ity_I64);
6594
6595 assign(op1, get_gpr_w1(r1 + 1));
6596 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6597 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6598 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6599 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6600
6601 return "m";
6602}
6603
florian55085f82012-11-21 00:36:55 +00006604static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006605s390_irgen_MFY(UChar r1, IRTemp op2addr)
6606{
6607 IRTemp op1 = newTemp(Ity_I32);
6608 IRTemp op2 = newTemp(Ity_I32);
6609 IRTemp result = newTemp(Ity_I64);
6610
6611 assign(op1, get_gpr_w1(r1 + 1));
6612 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6613 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6614 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6615 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6616
6617 return "mfy";
6618}
6619
florian55085f82012-11-21 00:36:55 +00006620static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006621s390_irgen_MH(UChar r1, IRTemp op2addr)
6622{
6623 IRTemp op1 = newTemp(Ity_I32);
6624 IRTemp op2 = newTemp(Ity_I16);
6625 IRTemp result = newTemp(Ity_I64);
6626
6627 assign(op1, get_gpr_w1(r1));
6628 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6629 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6630 ));
6631 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6632
6633 return "mh";
6634}
6635
florian55085f82012-11-21 00:36:55 +00006636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006637s390_irgen_MHY(UChar r1, IRTemp op2addr)
6638{
6639 IRTemp op1 = newTemp(Ity_I32);
6640 IRTemp op2 = newTemp(Ity_I16);
6641 IRTemp result = newTemp(Ity_I64);
6642
6643 assign(op1, get_gpr_w1(r1));
6644 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6645 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6646 ));
6647 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6648
6649 return "mhy";
6650}
6651
florian55085f82012-11-21 00:36:55 +00006652static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006653s390_irgen_MHI(UChar r1, UShort i2)
6654{
6655 IRTemp op1 = newTemp(Ity_I32);
6656 Short op2;
6657 IRTemp result = newTemp(Ity_I64);
6658
6659 assign(op1, get_gpr_w1(r1));
6660 op2 = (Short)i2;
6661 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6662 mkU16((UShort)op2))));
6663 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6664
6665 return "mhi";
6666}
6667
florian55085f82012-11-21 00:36:55 +00006668static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006669s390_irgen_MGHI(UChar r1, UShort i2)
6670{
6671 IRTemp op1 = newTemp(Ity_I64);
6672 Short op2;
6673 IRTemp result = newTemp(Ity_I128);
6674
6675 assign(op1, get_gpr_dw0(r1));
6676 op2 = (Short)i2;
6677 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6678 mkU16((UShort)op2))));
6679 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6680
6681 return "mghi";
6682}
6683
florian55085f82012-11-21 00:36:55 +00006684static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006685s390_irgen_MLR(UChar r1, UChar r2)
6686{
6687 IRTemp op1 = newTemp(Ity_I32);
6688 IRTemp op2 = newTemp(Ity_I32);
6689 IRTemp result = newTemp(Ity_I64);
6690
6691 assign(op1, get_gpr_w1(r1 + 1));
6692 assign(op2, get_gpr_w1(r2));
6693 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6694 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6695 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6696
6697 return "mlr";
6698}
6699
florian55085f82012-11-21 00:36:55 +00006700static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006701s390_irgen_MLGR(UChar r1, UChar r2)
6702{
6703 IRTemp op1 = newTemp(Ity_I64);
6704 IRTemp op2 = newTemp(Ity_I64);
6705 IRTemp result = newTemp(Ity_I128);
6706
6707 assign(op1, get_gpr_dw0(r1 + 1));
6708 assign(op2, get_gpr_dw0(r2));
6709 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6710 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6711 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6712
6713 return "mlgr";
6714}
6715
florian55085f82012-11-21 00:36:55 +00006716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006717s390_irgen_ML(UChar r1, IRTemp op2addr)
6718{
6719 IRTemp op1 = newTemp(Ity_I32);
6720 IRTemp op2 = newTemp(Ity_I32);
6721 IRTemp result = newTemp(Ity_I64);
6722
6723 assign(op1, get_gpr_w1(r1 + 1));
6724 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6725 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6726 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6727 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6728
6729 return "ml";
6730}
6731
florian55085f82012-11-21 00:36:55 +00006732static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006733s390_irgen_MLG(UChar r1, IRTemp op2addr)
6734{
6735 IRTemp op1 = newTemp(Ity_I64);
6736 IRTemp op2 = newTemp(Ity_I64);
6737 IRTemp result = newTemp(Ity_I128);
6738
6739 assign(op1, get_gpr_dw0(r1 + 1));
6740 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6741 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6742 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6743 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6744
6745 return "mlg";
6746}
6747
florian55085f82012-11-21 00:36:55 +00006748static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006749s390_irgen_MSR(UChar r1, UChar r2)
6750{
6751 IRTemp op1 = newTemp(Ity_I32);
6752 IRTemp op2 = newTemp(Ity_I32);
6753 IRTemp result = newTemp(Ity_I64);
6754
6755 assign(op1, get_gpr_w1(r1));
6756 assign(op2, get_gpr_w1(r2));
6757 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6758 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6759
6760 return "msr";
6761}
6762
florian55085f82012-11-21 00:36:55 +00006763static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006764s390_irgen_MSGR(UChar r1, UChar r2)
6765{
6766 IRTemp op1 = newTemp(Ity_I64);
6767 IRTemp op2 = newTemp(Ity_I64);
6768 IRTemp result = newTemp(Ity_I128);
6769
6770 assign(op1, get_gpr_dw0(r1));
6771 assign(op2, get_gpr_dw0(r2));
6772 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6773 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6774
6775 return "msgr";
6776}
6777
florian55085f82012-11-21 00:36:55 +00006778static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006779s390_irgen_MSGFR(UChar r1, UChar r2)
6780{
6781 IRTemp op1 = newTemp(Ity_I64);
6782 IRTemp op2 = newTemp(Ity_I32);
6783 IRTemp result = newTemp(Ity_I128);
6784
6785 assign(op1, get_gpr_dw0(r1));
6786 assign(op2, get_gpr_w1(r2));
6787 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6788 ));
6789 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6790
6791 return "msgfr";
6792}
6793
florian55085f82012-11-21 00:36:55 +00006794static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006795s390_irgen_MS(UChar r1, IRTemp op2addr)
6796{
6797 IRTemp op1 = newTemp(Ity_I32);
6798 IRTemp op2 = newTemp(Ity_I32);
6799 IRTemp result = newTemp(Ity_I64);
6800
6801 assign(op1, get_gpr_w1(r1));
6802 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6803 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6804 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6805
6806 return "ms";
6807}
6808
florian55085f82012-11-21 00:36:55 +00006809static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006810s390_irgen_MSY(UChar r1, IRTemp op2addr)
6811{
6812 IRTemp op1 = newTemp(Ity_I32);
6813 IRTemp op2 = newTemp(Ity_I32);
6814 IRTemp result = newTemp(Ity_I64);
6815
6816 assign(op1, get_gpr_w1(r1));
6817 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6818 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6819 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6820
6821 return "msy";
6822}
6823
florian55085f82012-11-21 00:36:55 +00006824static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006825s390_irgen_MSG(UChar r1, IRTemp op2addr)
6826{
6827 IRTemp op1 = newTemp(Ity_I64);
6828 IRTemp op2 = newTemp(Ity_I64);
6829 IRTemp result = newTemp(Ity_I128);
6830
6831 assign(op1, get_gpr_dw0(r1));
6832 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6833 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6834 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6835
6836 return "msg";
6837}
6838
florian55085f82012-11-21 00:36:55 +00006839static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006840s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6841{
6842 IRTemp op1 = newTemp(Ity_I64);
6843 IRTemp op2 = newTemp(Ity_I32);
6844 IRTemp result = newTemp(Ity_I128);
6845
6846 assign(op1, get_gpr_dw0(r1));
6847 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6848 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6849 ));
6850 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6851
6852 return "msgf";
6853}
6854
florian55085f82012-11-21 00:36:55 +00006855static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006856s390_irgen_MSFI(UChar r1, UInt i2)
6857{
6858 IRTemp op1 = newTemp(Ity_I32);
6859 Int op2;
6860 IRTemp result = newTemp(Ity_I64);
6861
6862 assign(op1, get_gpr_w1(r1));
6863 op2 = (Int)i2;
6864 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6865 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6866
6867 return "msfi";
6868}
6869
florian55085f82012-11-21 00:36:55 +00006870static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006871s390_irgen_MSGFI(UChar r1, UInt i2)
6872{
6873 IRTemp op1 = newTemp(Ity_I64);
6874 Int op2;
6875 IRTemp result = newTemp(Ity_I128);
6876
6877 assign(op1, get_gpr_dw0(r1));
6878 op2 = (Int)i2;
6879 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6880 op2))));
6881 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6882
6883 return "msgfi";
6884}
6885
florian55085f82012-11-21 00:36:55 +00006886static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006887s390_irgen_OR(UChar r1, UChar r2)
6888{
6889 IRTemp op1 = newTemp(Ity_I32);
6890 IRTemp op2 = newTemp(Ity_I32);
6891 IRTemp result = newTemp(Ity_I32);
6892
6893 assign(op1, get_gpr_w1(r1));
6894 assign(op2, get_gpr_w1(r2));
6895 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6896 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6897 put_gpr_w1(r1, mkexpr(result));
6898
6899 return "or";
6900}
6901
florian55085f82012-11-21 00:36:55 +00006902static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006903s390_irgen_OGR(UChar r1, UChar r2)
6904{
6905 IRTemp op1 = newTemp(Ity_I64);
6906 IRTemp op2 = newTemp(Ity_I64);
6907 IRTemp result = newTemp(Ity_I64);
6908
6909 assign(op1, get_gpr_dw0(r1));
6910 assign(op2, get_gpr_dw0(r2));
6911 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6912 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6913 put_gpr_dw0(r1, mkexpr(result));
6914
6915 return "ogr";
6916}
6917
florian55085f82012-11-21 00:36:55 +00006918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006919s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6920{
6921 IRTemp op2 = newTemp(Ity_I32);
6922 IRTemp op3 = newTemp(Ity_I32);
6923 IRTemp result = newTemp(Ity_I32);
6924
6925 assign(op2, get_gpr_w1(r2));
6926 assign(op3, get_gpr_w1(r3));
6927 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6928 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6929 put_gpr_w1(r1, mkexpr(result));
6930
6931 return "ork";
6932}
6933
florian55085f82012-11-21 00:36:55 +00006934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006935s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6936{
6937 IRTemp op2 = newTemp(Ity_I64);
6938 IRTemp op3 = newTemp(Ity_I64);
6939 IRTemp result = newTemp(Ity_I64);
6940
6941 assign(op2, get_gpr_dw0(r2));
6942 assign(op3, get_gpr_dw0(r3));
6943 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6944 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6945 put_gpr_dw0(r1, mkexpr(result));
6946
6947 return "ogrk";
6948}
6949
florian55085f82012-11-21 00:36:55 +00006950static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006951s390_irgen_O(UChar r1, IRTemp op2addr)
6952{
6953 IRTemp op1 = newTemp(Ity_I32);
6954 IRTemp op2 = newTemp(Ity_I32);
6955 IRTemp result = newTemp(Ity_I32);
6956
6957 assign(op1, get_gpr_w1(r1));
6958 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6959 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6960 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6961 put_gpr_w1(r1, mkexpr(result));
6962
6963 return "o";
6964}
6965
florian55085f82012-11-21 00:36:55 +00006966static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006967s390_irgen_OY(UChar r1, IRTemp op2addr)
6968{
6969 IRTemp op1 = newTemp(Ity_I32);
6970 IRTemp op2 = newTemp(Ity_I32);
6971 IRTemp result = newTemp(Ity_I32);
6972
6973 assign(op1, get_gpr_w1(r1));
6974 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6975 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6976 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6977 put_gpr_w1(r1, mkexpr(result));
6978
6979 return "oy";
6980}
6981
florian55085f82012-11-21 00:36:55 +00006982static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006983s390_irgen_OG(UChar r1, IRTemp op2addr)
6984{
6985 IRTemp op1 = newTemp(Ity_I64);
6986 IRTemp op2 = newTemp(Ity_I64);
6987 IRTemp result = newTemp(Ity_I64);
6988
6989 assign(op1, get_gpr_dw0(r1));
6990 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6991 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6992 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6993 put_gpr_dw0(r1, mkexpr(result));
6994
6995 return "og";
6996}
6997
florian55085f82012-11-21 00:36:55 +00006998static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006999s390_irgen_OI(UChar i2, IRTemp op1addr)
7000{
7001 IRTemp op1 = newTemp(Ity_I8);
7002 UChar op2;
7003 IRTemp result = newTemp(Ity_I8);
7004
7005 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7006 op2 = i2;
7007 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7008 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7009 store(mkexpr(op1addr), mkexpr(result));
7010
7011 return "oi";
7012}
7013
florian55085f82012-11-21 00:36:55 +00007014static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007015s390_irgen_OIY(UChar i2, IRTemp op1addr)
7016{
7017 IRTemp op1 = newTemp(Ity_I8);
7018 UChar op2;
7019 IRTemp result = newTemp(Ity_I8);
7020
7021 assign(op1, load(Ity_I8, mkexpr(op1addr)));
7022 op2 = i2;
7023 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
7024 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7025 store(mkexpr(op1addr), mkexpr(result));
7026
7027 return "oiy";
7028}
7029
florian55085f82012-11-21 00:36:55 +00007030static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007031s390_irgen_OIHF(UChar r1, UInt i2)
7032{
7033 IRTemp op1 = newTemp(Ity_I32);
7034 UInt op2;
7035 IRTemp result = newTemp(Ity_I32);
7036
7037 assign(op1, get_gpr_w0(r1));
7038 op2 = i2;
7039 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7040 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7041 put_gpr_w0(r1, mkexpr(result));
7042
7043 return "oihf";
7044}
7045
florian55085f82012-11-21 00:36:55 +00007046static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007047s390_irgen_OIHH(UChar r1, UShort i2)
7048{
7049 IRTemp op1 = newTemp(Ity_I16);
7050 UShort op2;
7051 IRTemp result = newTemp(Ity_I16);
7052
7053 assign(op1, get_gpr_hw0(r1));
7054 op2 = i2;
7055 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7056 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7057 put_gpr_hw0(r1, mkexpr(result));
7058
7059 return "oihh";
7060}
7061
florian55085f82012-11-21 00:36:55 +00007062static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007063s390_irgen_OIHL(UChar r1, UShort i2)
7064{
7065 IRTemp op1 = newTemp(Ity_I16);
7066 UShort op2;
7067 IRTemp result = newTemp(Ity_I16);
7068
7069 assign(op1, get_gpr_hw1(r1));
7070 op2 = i2;
7071 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7072 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7073 put_gpr_hw1(r1, mkexpr(result));
7074
7075 return "oihl";
7076}
7077
florian55085f82012-11-21 00:36:55 +00007078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007079s390_irgen_OILF(UChar r1, UInt i2)
7080{
7081 IRTemp op1 = newTemp(Ity_I32);
7082 UInt op2;
7083 IRTemp result = newTemp(Ity_I32);
7084
7085 assign(op1, get_gpr_w1(r1));
7086 op2 = i2;
7087 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7088 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7089 put_gpr_w1(r1, mkexpr(result));
7090
7091 return "oilf";
7092}
7093
florian55085f82012-11-21 00:36:55 +00007094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007095s390_irgen_OILH(UChar r1, UShort i2)
7096{
7097 IRTemp op1 = newTemp(Ity_I16);
7098 UShort op2;
7099 IRTemp result = newTemp(Ity_I16);
7100
7101 assign(op1, get_gpr_hw2(r1));
7102 op2 = i2;
7103 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7104 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7105 put_gpr_hw2(r1, mkexpr(result));
7106
7107 return "oilh";
7108}
7109
florian55085f82012-11-21 00:36:55 +00007110static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007111s390_irgen_OILL(UChar r1, UShort i2)
7112{
7113 IRTemp op1 = newTemp(Ity_I16);
7114 UShort op2;
7115 IRTemp result = newTemp(Ity_I16);
7116
7117 assign(op1, get_gpr_hw3(r1));
7118 op2 = i2;
7119 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7120 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7121 put_gpr_hw3(r1, mkexpr(result));
7122
7123 return "oill";
7124}
7125
florian55085f82012-11-21 00:36:55 +00007126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007127s390_irgen_PFD(void)
7128{
7129
7130 return "pfd";
7131}
7132
florian55085f82012-11-21 00:36:55 +00007133static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007134s390_irgen_PFDRL(void)
7135{
7136
7137 return "pfdrl";
7138}
7139
florian78d5ef72013-05-11 15:02:58 +00007140static IRExpr *
7141get_rounding_mode_from_gr0(void)
7142{
7143 IRTemp rm_bits = newTemp(Ity_I32);
7144 IRExpr *s390rm;
7145 IRExpr *irrm;
7146
7147 vassert(s390_host_has_pfpo);
7148 /* The dfp/bfp rounding mode is stored in bits [60:63] of GR 0
7149 when PFPO insn is called. So, extract the bits at [60:63] */
7150 assign(rm_bits, binop(Iop_And32, get_gpr_w1(0), mkU32(0xf)));
7151 s390rm = mkexpr(rm_bits);
7152 irrm = mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x1)),
7153 mkexpr(encode_bfp_rounding_mode( S390_BFP_ROUND_PER_FPC)),
7154 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x8)),
7155 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEAREST_EVEN_8)),
7156 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0x9)),
7157 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_ZERO_9)),
7158 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xa)),
7159 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_POSINF_10)),
7160 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xb)),
7161 mkexpr(encode_dfp_rounding_mode(S390_DFP_ROUND_NEGINF_11)),
7162 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xc)),
7163 mkexpr(encode_dfp_rounding_mode(
7164 S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12)),
7165 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xd)),
7166 mkexpr(encode_dfp_rounding_mode(
7167 S390_DFP_ROUND_NEAREST_TIE_TOWARD_0)),
7168 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xe)),
7169 mkexpr(encode_dfp_rounding_mode(
7170 S390_DFP_ROUND_AWAY_0)),
7171 mkite(binop(Iop_CmpEQ32, s390rm, mkU32(0xf)),
7172 mkexpr(encode_dfp_rounding_mode(
7173 S390_DFP_ROUND_PREPARE_SHORT_15)),
7174 /* if rounding mode is 0 or invalid (2-7)
7175 set S390_DFP_ROUND_PER_FPC_0 */
7176 mkexpr(encode_dfp_rounding_mode(
7177 S390_DFP_ROUND_PER_FPC_0)))))))))));
7178
7179 return irrm;
7180}
7181
7182static IRExpr *
7183s390_call_pfpo_helper(IRExpr *gr0)
7184{
7185 IRExpr **args, *call;
7186
7187 args = mkIRExprVec_1(gr0);
7188 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
7189 "s390_do_pfpo", &s390_do_pfpo, args);
7190 /* Nothing is excluded from definedness checking. */
7191 call->Iex.CCall.cee->mcx_mask = 0;
7192
7193 return call;
7194}
7195
7196static const HChar *
7197s390_irgen_PFPO(void)
7198{
7199 IRTemp gr0 = newTemp(Ity_I32); /* word 1 [32:63] of GR 0 */
7200 IRTemp test_bit = newTemp(Ity_I32); /* bit 32 of GR 0 - test validity */
7201 IRTemp fn = newTemp(Ity_I32); /* [33:55] of GR 0 - function code */
7202 IRTemp ef = newTemp(Ity_I32); /* Emulation Failure */
florian7ab421d2013-06-17 21:03:56 +00007203 IRTemp src1 = newTemp(Ity_F32);
7204 IRTemp dst1 = newTemp(Ity_D32);
7205 IRTemp src2 = newTemp(Ity_F32);
7206 IRTemp dst2 = newTemp(Ity_D64);
7207 IRTemp src3 = newTemp(Ity_F32);
florian78d5ef72013-05-11 15:02:58 +00007208 IRTemp dst3 = newTemp(Ity_D128);
florian7ab421d2013-06-17 21:03:56 +00007209 IRTemp src4 = newTemp(Ity_F64);
7210 IRTemp dst4 = newTemp(Ity_D32);
7211 IRTemp src5 = newTemp(Ity_F64);
7212 IRTemp dst5 = newTemp(Ity_D64);
7213 IRTemp src6 = newTemp(Ity_F64);
7214 IRTemp dst6 = newTemp(Ity_D128);
7215 IRTemp src7 = newTemp(Ity_F128);
7216 IRTemp dst7 = newTemp(Ity_D32);
7217 IRTemp src8 = newTemp(Ity_F128);
7218 IRTemp dst8 = newTemp(Ity_D64);
7219 IRTemp src9 = newTemp(Ity_F128);
7220 IRTemp dst9 = newTemp(Ity_D128);
7221 IRTemp src10 = newTemp(Ity_D32);
7222 IRTemp dst10 = newTemp(Ity_F32);
7223 IRTemp src11 = newTemp(Ity_D32);
7224 IRTemp dst11 = newTemp(Ity_F64);
7225 IRTemp src12 = newTemp(Ity_D32);
7226 IRTemp dst12 = newTemp(Ity_F128);
7227 IRTemp src13 = newTemp(Ity_D64);
7228 IRTemp dst13 = newTemp(Ity_F32);
7229 IRTemp src14 = newTemp(Ity_D64);
7230 IRTemp dst14 = newTemp(Ity_F64);
7231 IRTemp src15 = newTemp(Ity_D64);
7232 IRTemp dst15 = newTemp(Ity_F128);
7233 IRTemp src16 = newTemp(Ity_D128);
7234 IRTemp dst16 = newTemp(Ity_F32);
7235 IRTemp src17 = newTemp(Ity_D128);
7236 IRTemp dst17 = newTemp(Ity_F64);
7237 IRTemp src18 = newTemp(Ity_D128);
7238 IRTemp dst18 = newTemp(Ity_F128);
florian78d5ef72013-05-11 15:02:58 +00007239 IRExpr *irrm;
7240
7241 vassert(s390_host_has_pfpo);
7242
7243 assign(gr0, get_gpr_w1(0));
7244 /* get function code */
7245 assign(fn, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(8)),
7246 mkU32(0x7fffff)));
7247 /* get validity test bit */
7248 assign(test_bit, binop(Iop_And32, binop(Iop_Shr32, mkexpr(gr0), mkU8(31)),
7249 mkU32(0x1)));
7250 irrm = get_rounding_mode_from_gr0();
7251
7252 /* test_bit is 1 */
florian7ab421d2013-06-17 21:03:56 +00007253 assign(src1, get_fpr_w0(4)); /* get source from FPR 4,6 */
florian78d5ef72013-05-11 15:02:58 +00007254 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src1, gr0);
7255
7256 /* Return code set in GR1 is usually 0. Non-zero value is set only
7257 when exceptions are raised. See Programming Notes point 5 in the
7258 instrcution description of pfpo in POP. Since valgrind does not
7259 model exception, it might be safe to just set 0 to GR 1. */
7260 put_gpr_w1(1, mkU32(0x0));
7261 next_insn_if(binop(Iop_CmpEQ32, mkexpr(test_bit), mkU32(0x1)));
7262
7263 /* Check validity of function code in GR 0 */
7264 assign(ef, s390_call_pfpo_helper(unop(Iop_32Uto64, mkexpr(gr0))));
7265
7266 /* fixs390: Function emulation_failure can be used if it takes argument as
7267 IRExpr * instead of VexEmNote. */
7268 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkexpr(ef)));
7269 dis_res->whatNext = Dis_StopHere;
7270 dis_res->jk_StopHere = Ijk_EmFail;
7271
7272 stmt(
7273 IRStmt_Exit(
7274 binop(Iop_CmpNE32, mkexpr(ef), mkU32(EmNote_NONE)),
7275 Ijk_EmFail,
7276 IRConst_U64(guest_IA_next_instr),
7277 S390X_GUEST_OFFSET(guest_IA)
7278 )
7279 );
7280
florian7ab421d2013-06-17 21:03:56 +00007281 /* F32 -> D32 */
florian78d5ef72013-05-11 15:02:58 +00007282 /* get source from FPR 4,6 - already set in src1 */
florian7ab421d2013-06-17 21:03:56 +00007283 assign(dst1, binop(Iop_F32toD32, irrm, mkexpr(src1)));
7284 put_dpr_w0(0, mkexpr(dst1)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007285 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007286 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src1, gr0);
7287 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D32)));
florian78d5ef72013-05-11 15:02:58 +00007288
florian7ab421d2013-06-17 21:03:56 +00007289 /* F32 -> D64 */
7290 assign(src2, get_fpr_w0(4)); /* get source from FPR 4,6 */
7291 assign(dst2, binop(Iop_F32toD64, irrm, mkexpr(src2)));
7292 put_dpr_dw0(0, mkexpr(dst2)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007293 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007294 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src2, gr0);
7295 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007296
florian7ab421d2013-06-17 21:03:56 +00007297 /* F32 -> D128 */
7298 assign(src3, get_fpr_w0(4)); /* get source from FPR 4,6 */
7299 assign(dst3, binop(Iop_F32toD128, irrm, mkexpr(src3)));
florian78d5ef72013-05-11 15:02:58 +00007300 put_dpr_pair(0, mkexpr(dst3)); /* put the result in FPR 0,2 */
7301 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007302 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src3, gr0);
7303 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F32_TO_D128)));
7304
7305 /* F64 -> D32 */
7306 assign(src4, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7307 assign(dst4, binop(Iop_F64toD32, irrm, mkexpr(src4)));
7308 put_dpr_w0(0, mkexpr(dst4)); /* put the result in FPR 0,2 */
7309 put_gpr_w1(1, mkU32(0x0));
7310 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src4, gr0);
7311 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D32)));
7312
7313 /* F64 -> D64 */
7314 assign(src5, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7315 assign(dst5, binop(Iop_F64toD64, irrm, mkexpr(src5)));
7316 put_dpr_dw0(0, mkexpr(dst5)); /* put the result in FPR 0,2 */
7317 put_gpr_w1(1, mkU32(0x0));
7318 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src5, gr0);
7319 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D64)));
7320
7321 /* F64 -> D128 */
7322 assign(src6, get_fpr_dw0(4)); /* get source from FPR 4,6 */
7323 assign(dst6, binop(Iop_F64toD128, irrm, mkexpr(src6)));
7324 put_dpr_pair(0, mkexpr(dst6)); /* put the result in FPR 0,2 */
7325 put_gpr_w1(1, mkU32(0x0));
7326 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src6, gr0);
florian78d5ef72013-05-11 15:02:58 +00007327 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F64_TO_D128)));
7328
florian7ab421d2013-06-17 21:03:56 +00007329 /* F128 -> D32 */
7330 assign(src7, get_fpr_pair(4)); /* get source from FPR 4,6 */
7331 assign(dst7, binop(Iop_F128toD32, irrm, mkexpr(src7)));
7332 put_dpr_w0(0, mkexpr(dst7)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007333 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007334 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src7, gr0);
7335 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D32)));
7336
7337 /* F128 -> D64 */
7338 assign(src8, get_fpr_pair(4)); /* get source from FPR 4,6 */
7339 assign(dst8, binop(Iop_F128toD64, irrm, mkexpr(src8)));
7340 put_dpr_dw0(0, mkexpr(dst8)); /* put the result in FPR 0,2 */
7341 put_gpr_w1(1, mkU32(0x0));
7342 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src8, gr0);
7343 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D64)));
florian78d5ef72013-05-11 15:02:58 +00007344
7345 /* F128 -> D128 */
florian7ab421d2013-06-17 21:03:56 +00007346 assign(src9, get_fpr_pair(4)); /* get source from FPR 4,6 */
7347 assign(dst9, binop(Iop_F128toD128, irrm, mkexpr(src9)));
7348 put_dpr_pair(0, mkexpr(dst9)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007349 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007350 s390_cc_thunk_put1f128Z(S390_CC_OP_PFPO_128, src9, gr0);
florian78d5ef72013-05-11 15:02:58 +00007351 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_F128_TO_D128)));
7352
florian7ab421d2013-06-17 21:03:56 +00007353 /* D32 -> F32 */
7354 assign(src10, get_dpr_w0(4)); /* get source from FPR 4,6 */
7355 assign(dst10, binop(Iop_D32toF32, irrm, mkexpr(src10)));
7356 put_fpr_w0(0, mkexpr(dst10)); /* put the result in FPR 0,2 */
florian78d5ef72013-05-11 15:02:58 +00007357 put_gpr_w1(1, mkU32(0x0));
florian7ab421d2013-06-17 21:03:56 +00007358 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src10, gr0);
7359 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F32)));
7360
7361 /* D32 -> F64 */
7362 assign(src11, get_dpr_w0(4)); /* get source from FPR 4,6 */
7363 assign(dst11, binop(Iop_D32toF64, irrm, mkexpr(src11)));
7364 put_fpr_dw0(0, mkexpr(dst11)); /* put the result in FPR 0,2 */
7365 put_gpr_w1(1, mkU32(0x0));
7366 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src11, gr0);
7367 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F64)));
7368
7369 /* D32 -> F128 */
7370 assign(src12, get_dpr_w0(4)); /* get source from FPR 4,6 */
7371 assign(dst12, binop(Iop_D32toF128, irrm, mkexpr(src12)));
7372 put_fpr_pair(0, mkexpr(dst12)); /* put the result in FPR 0,2 */
7373 put_gpr_w1(1, mkU32(0x0));
7374 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_32, src12, gr0);
7375 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D32_TO_F128)));
7376
7377 /* D64 -> F32 */
7378 assign(src13, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7379 assign(dst13, binop(Iop_D64toF32, irrm, mkexpr(src13)));
7380 put_fpr_w0(0, mkexpr(dst13)); /* put the result in FPR 0,2 */
7381 put_gpr_w1(1, mkU32(0x0));
7382 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src13, gr0);
7383 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F32)));
7384
7385 /* D64 -> F64 */
7386 assign(src14, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7387 assign(dst14, binop(Iop_D64toF64, irrm, mkexpr(src14)));
7388 put_fpr_dw0(0, mkexpr(dst14)); /* put the result in FPR 0,2 */
7389 put_gpr_w1(1, mkU32(0x0));
7390 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src14, gr0);
7391 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F64)));
7392
7393 /* D64 -> F128 */
7394 assign(src15, get_dpr_dw0(4)); /* get source from FPR 4,6 */
7395 assign(dst15, binop(Iop_D64toF128, irrm, mkexpr(src15)));
7396 put_fpr_pair(0, mkexpr(dst15)); /* put the result in FPR 0,2 */
7397 put_gpr_w1(1, mkU32(0x0));
7398 s390_cc_thunk_putFZ(S390_CC_OP_PFPO_64, src15, gr0);
7399 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D64_TO_F128)));
7400
7401 /* D128 -> F32 */
7402 assign(src16, get_dpr_pair(4)); /* get source from FPR 4,6 */
7403 assign(dst16, binop(Iop_D128toF32, irrm, mkexpr(src16)));
7404 put_fpr_w0(0, mkexpr(dst16)); /* put the result in FPR 0,2 */
7405 put_gpr_w1(1, mkU32(0x0));
7406 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src16, gr0);
7407 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F32)));
7408
7409 /* D128 -> F64 */
7410 assign(src17, get_dpr_pair(4)); /* get source from FPR 4,6 */
7411 assign(dst17, binop(Iop_D128toF64, irrm, mkexpr(src17)));
7412 put_fpr_dw0(0, mkexpr(dst17)); /* put the result in FPR 0,2 */
7413 put_gpr_w1(1, mkU32(0x0));
7414 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src17, gr0);
7415 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F64)));
7416
7417 /* D128 -> F128 */
7418 assign(src18, get_dpr_pair(4)); /* get source from FPR 4,6 */
7419 assign(dst18, binop(Iop_D128toF128, irrm, mkexpr(src18)));
7420 put_fpr_pair(0, mkexpr(dst18)); /* put the result in FPR 0,2 */
7421 put_gpr_w1(1, mkU32(0x0));
7422 s390_cc_thunk_put1d128Z(S390_CC_OP_PFPO_128, src18, gr0);
florian78d5ef72013-05-11 15:02:58 +00007423 next_insn_if(binop(Iop_CmpEQ32, mkexpr(fn), mkU32(S390_PFPO_D128_TO_F128)));
7424
7425 return "pfpo";
7426}
7427
florian55085f82012-11-21 00:36:55 +00007428static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007429s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7430{
7431 IRTemp amount = newTemp(Ity_I64);
7432 IRTemp op = newTemp(Ity_I32);
7433
7434 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7435 assign(op, get_gpr_w1(r3));
7436 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7437 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7438 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7439
7440 return "rll";
7441}
7442
florian55085f82012-11-21 00:36:55 +00007443static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007444s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7445{
7446 IRTemp amount = newTemp(Ity_I64);
7447 IRTemp op = newTemp(Ity_I64);
7448
7449 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7450 assign(op, get_gpr_dw0(r3));
7451 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7452 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7453 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7454
7455 return "rllg";
7456}
7457
florian55085f82012-11-21 00:36:55 +00007458static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007459s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7460{
7461 UChar from;
7462 UChar to;
7463 UChar rot;
7464 UChar t_bit;
7465 ULong mask;
7466 ULong maskc;
7467 IRTemp result = newTemp(Ity_I64);
7468 IRTemp op2 = newTemp(Ity_I64);
7469
7470 from = i3 & 63;
7471 to = i4 & 63;
7472 rot = i5 & 63;
7473 t_bit = i3 & 128;
7474 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7475 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7476 mkU8(64 - rot))));
7477 if (from <= to) {
7478 mask = ~0ULL;
7479 mask = (mask >> from) & (mask << (63 - to));
7480 maskc = ~mask;
7481 } else {
7482 maskc = ~0ULL;
7483 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7484 mask = ~maskc;
7485 }
7486 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7487 ), mkU64(mask)));
7488 if (t_bit == 0) {
7489 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7490 mkU64(maskc)), mkexpr(result)));
7491 }
7492 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7493
7494 return "rnsbg";
7495}
7496
florian55085f82012-11-21 00:36:55 +00007497static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007498s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7499{
7500 UChar from;
7501 UChar to;
7502 UChar rot;
7503 UChar t_bit;
7504 ULong mask;
7505 ULong maskc;
7506 IRTemp result = newTemp(Ity_I64);
7507 IRTemp op2 = newTemp(Ity_I64);
7508
7509 from = i3 & 63;
7510 to = i4 & 63;
7511 rot = i5 & 63;
7512 t_bit = i3 & 128;
7513 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7514 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7515 mkU8(64 - rot))));
7516 if (from <= to) {
7517 mask = ~0ULL;
7518 mask = (mask >> from) & (mask << (63 - to));
7519 maskc = ~mask;
7520 } else {
7521 maskc = ~0ULL;
7522 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7523 mask = ~maskc;
7524 }
7525 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7526 ), mkU64(mask)));
7527 if (t_bit == 0) {
7528 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7529 mkU64(maskc)), mkexpr(result)));
7530 }
7531 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7532
7533 return "rxsbg";
7534}
7535
florian55085f82012-11-21 00:36:55 +00007536static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007537s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7538{
7539 UChar from;
7540 UChar to;
7541 UChar rot;
7542 UChar t_bit;
7543 ULong mask;
7544 ULong maskc;
7545 IRTemp result = newTemp(Ity_I64);
7546 IRTemp op2 = newTemp(Ity_I64);
7547
7548 from = i3 & 63;
7549 to = i4 & 63;
7550 rot = i5 & 63;
7551 t_bit = i3 & 128;
7552 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7553 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7554 mkU8(64 - rot))));
7555 if (from <= to) {
7556 mask = ~0ULL;
7557 mask = (mask >> from) & (mask << (63 - to));
7558 maskc = ~mask;
7559 } else {
7560 maskc = ~0ULL;
7561 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7562 mask = ~maskc;
7563 }
7564 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7565 ), mkU64(mask)));
7566 if (t_bit == 0) {
7567 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7568 mkU64(maskc)), mkexpr(result)));
7569 }
7570 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7571
7572 return "rosbg";
7573}
7574
florian55085f82012-11-21 00:36:55 +00007575static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007576s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7577{
7578 UChar from;
7579 UChar to;
7580 UChar rot;
7581 UChar z_bit;
7582 ULong mask;
7583 ULong maskc;
7584 IRTemp op2 = newTemp(Ity_I64);
7585 IRTemp result = newTemp(Ity_I64);
7586
7587 from = i3 & 63;
7588 to = i4 & 63;
7589 rot = i5 & 63;
7590 z_bit = i4 & 128;
7591 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7592 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7593 mkU8(64 - rot))));
7594 if (from <= to) {
7595 mask = ~0ULL;
7596 mask = (mask >> from) & (mask << (63 - to));
7597 maskc = ~mask;
7598 } else {
7599 maskc = ~0ULL;
7600 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7601 mask = ~maskc;
7602 }
7603 if (z_bit == 0) {
7604 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7605 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7606 } else {
7607 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7608 }
7609 assign(result, get_gpr_dw0(r1));
cborntrae03b6002013-11-07 21:37:28 +00007610 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
sewardj2019a972011-03-07 16:04:07 +00007611
7612 return "risbg";
7613}
7614
florian55085f82012-11-21 00:36:55 +00007615static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007616s390_irgen_SAR(UChar r1, UChar r2)
7617{
7618 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007619 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007620 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7621
7622 return "sar";
7623}
7624
florian55085f82012-11-21 00:36:55 +00007625static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007626s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7627{
7628 IRTemp p1 = newTemp(Ity_I64);
7629 IRTemp p2 = newTemp(Ity_I64);
7630 IRTemp op = newTemp(Ity_I64);
7631 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007632 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007633 IRTemp shift_amount = newTemp(Ity_I64);
7634
7635 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7636 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7637 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7638 ));
7639 sign_mask = 1ULL << 63;
7640 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7641 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007642 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7643 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007644 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7645 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7646 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7647
7648 return "slda";
7649}
7650
florian55085f82012-11-21 00:36:55 +00007651static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007652s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7653{
7654 IRTemp p1 = newTemp(Ity_I64);
7655 IRTemp p2 = newTemp(Ity_I64);
7656 IRTemp result = newTemp(Ity_I64);
7657
7658 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7659 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7660 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7661 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7662 mkexpr(op2addr), mkU64(63)))));
7663 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7664 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7665
7666 return "sldl";
7667}
7668
florian55085f82012-11-21 00:36:55 +00007669static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007670s390_irgen_SLA(UChar r1, IRTemp op2addr)
7671{
7672 IRTemp uop = newTemp(Ity_I32);
7673 IRTemp result = newTemp(Ity_I32);
7674 UInt sign_mask;
7675 IRTemp shift_amount = newTemp(Ity_I64);
7676 IRTemp op = newTemp(Ity_I32);
7677
7678 assign(op, get_gpr_w1(r1));
7679 assign(uop, get_gpr_w1(r1));
7680 sign_mask = 2147483648U;
7681 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7682 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7683 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7684 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7685 put_gpr_w1(r1, mkexpr(result));
7686 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7687
7688 return "sla";
7689}
7690
florian55085f82012-11-21 00:36:55 +00007691static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007692s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7693{
7694 IRTemp uop = newTemp(Ity_I32);
7695 IRTemp result = newTemp(Ity_I32);
7696 UInt sign_mask;
7697 IRTemp shift_amount = newTemp(Ity_I64);
7698 IRTemp op = newTemp(Ity_I32);
7699
7700 assign(op, get_gpr_w1(r3));
7701 assign(uop, get_gpr_w1(r3));
7702 sign_mask = 2147483648U;
7703 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7704 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7705 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7706 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7707 put_gpr_w1(r1, mkexpr(result));
7708 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7709
7710 return "slak";
7711}
7712
florian55085f82012-11-21 00:36:55 +00007713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007714s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7715{
7716 IRTemp uop = newTemp(Ity_I64);
7717 IRTemp result = newTemp(Ity_I64);
7718 ULong sign_mask;
7719 IRTemp shift_amount = newTemp(Ity_I64);
7720 IRTemp op = newTemp(Ity_I64);
7721
7722 assign(op, get_gpr_dw0(r3));
7723 assign(uop, get_gpr_dw0(r3));
7724 sign_mask = 9223372036854775808ULL;
7725 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7726 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7727 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7728 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7729 put_gpr_dw0(r1, mkexpr(result));
7730 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7731
7732 return "slag";
7733}
7734
florian55085f82012-11-21 00:36:55 +00007735static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007736s390_irgen_SLL(UChar r1, IRTemp op2addr)
7737{
7738 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7739 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7740
7741 return "sll";
7742}
7743
florian55085f82012-11-21 00:36:55 +00007744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007745s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7746{
7747 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7748 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7749
7750 return "sllk";
7751}
7752
florian55085f82012-11-21 00:36:55 +00007753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007754s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7755{
7756 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7757 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7758
7759 return "sllg";
7760}
7761
florian55085f82012-11-21 00:36:55 +00007762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007763s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7764{
7765 IRTemp p1 = newTemp(Ity_I64);
7766 IRTemp p2 = newTemp(Ity_I64);
7767 IRTemp result = newTemp(Ity_I64);
7768
7769 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7770 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7771 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7772 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7773 mkexpr(op2addr), mkU64(63)))));
7774 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7775 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7776 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7777
7778 return "srda";
7779}
7780
florian55085f82012-11-21 00:36:55 +00007781static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007782s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7783{
7784 IRTemp p1 = newTemp(Ity_I64);
7785 IRTemp p2 = newTemp(Ity_I64);
7786 IRTemp result = newTemp(Ity_I64);
7787
7788 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7789 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7790 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7791 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7792 mkexpr(op2addr), mkU64(63)))));
7793 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7794 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7795
7796 return "srdl";
7797}
7798
florian55085f82012-11-21 00:36:55 +00007799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007800s390_irgen_SRA(UChar r1, IRTemp op2addr)
7801{
7802 IRTemp result = newTemp(Ity_I32);
7803 IRTemp op = newTemp(Ity_I32);
7804
7805 assign(op, get_gpr_w1(r1));
7806 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7807 mkexpr(op2addr), mkU64(63)))));
7808 put_gpr_w1(r1, mkexpr(result));
7809 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7810
7811 return "sra";
7812}
7813
florian55085f82012-11-21 00:36:55 +00007814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007815s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7816{
7817 IRTemp result = newTemp(Ity_I32);
7818 IRTemp op = newTemp(Ity_I32);
7819
7820 assign(op, get_gpr_w1(r3));
7821 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7822 mkexpr(op2addr), mkU64(63)))));
7823 put_gpr_w1(r1, mkexpr(result));
7824 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7825
7826 return "srak";
7827}
7828
florian55085f82012-11-21 00:36:55 +00007829static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007830s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7831{
7832 IRTemp result = newTemp(Ity_I64);
7833 IRTemp op = newTemp(Ity_I64);
7834
7835 assign(op, get_gpr_dw0(r3));
7836 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7837 mkexpr(op2addr), mkU64(63)))));
7838 put_gpr_dw0(r1, mkexpr(result));
7839 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7840
7841 return "srag";
7842}
7843
florian55085f82012-11-21 00:36:55 +00007844static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007845s390_irgen_SRL(UChar r1, IRTemp op2addr)
7846{
7847 IRTemp op = newTemp(Ity_I32);
7848
7849 assign(op, get_gpr_w1(r1));
7850 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7851 mkexpr(op2addr), mkU64(63)))));
7852
7853 return "srl";
7854}
7855
florian55085f82012-11-21 00:36:55 +00007856static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007857s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7858{
7859 IRTemp op = newTemp(Ity_I32);
7860
7861 assign(op, get_gpr_w1(r3));
7862 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7863 mkexpr(op2addr), mkU64(63)))));
7864
7865 return "srlk";
7866}
7867
florian55085f82012-11-21 00:36:55 +00007868static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007869s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7870{
7871 IRTemp op = newTemp(Ity_I64);
7872
7873 assign(op, get_gpr_dw0(r3));
7874 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7875 mkexpr(op2addr), mkU64(63)))));
7876
7877 return "srlg";
7878}
7879
florian55085f82012-11-21 00:36:55 +00007880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007881s390_irgen_ST(UChar r1, IRTemp op2addr)
7882{
7883 store(mkexpr(op2addr), get_gpr_w1(r1));
7884
7885 return "st";
7886}
7887
florian55085f82012-11-21 00:36:55 +00007888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007889s390_irgen_STY(UChar r1, IRTemp op2addr)
7890{
7891 store(mkexpr(op2addr), get_gpr_w1(r1));
7892
7893 return "sty";
7894}
7895
florian55085f82012-11-21 00:36:55 +00007896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007897s390_irgen_STG(UChar r1, IRTemp op2addr)
7898{
7899 store(mkexpr(op2addr), get_gpr_dw0(r1));
7900
7901 return "stg";
7902}
7903
florian55085f82012-11-21 00:36:55 +00007904static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007905s390_irgen_STRL(UChar r1, UInt i2)
7906{
7907 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7908 get_gpr_w1(r1));
7909
7910 return "strl";
7911}
7912
florian55085f82012-11-21 00:36:55 +00007913static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007914s390_irgen_STGRL(UChar r1, UInt i2)
7915{
7916 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7917 get_gpr_dw0(r1));
7918
7919 return "stgrl";
7920}
7921
florian55085f82012-11-21 00:36:55 +00007922static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007923s390_irgen_STC(UChar r1, IRTemp op2addr)
7924{
7925 store(mkexpr(op2addr), get_gpr_b7(r1));
7926
7927 return "stc";
7928}
7929
florian55085f82012-11-21 00:36:55 +00007930static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007931s390_irgen_STCY(UChar r1, IRTemp op2addr)
7932{
7933 store(mkexpr(op2addr), get_gpr_b7(r1));
7934
7935 return "stcy";
7936}
7937
florian55085f82012-11-21 00:36:55 +00007938static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007939s390_irgen_STCH(UChar r1, IRTemp op2addr)
7940{
7941 store(mkexpr(op2addr), get_gpr_b3(r1));
7942
7943 return "stch";
7944}
7945
florian55085f82012-11-21 00:36:55 +00007946static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007947s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7948{
7949 UChar mask;
7950 UChar n;
7951
7952 mask = (UChar)r3;
7953 n = 0;
7954 if ((mask & 8) != 0) {
7955 store(mkexpr(op2addr), get_gpr_b4(r1));
7956 n = n + 1;
7957 }
7958 if ((mask & 4) != 0) {
7959 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7960 n = n + 1;
7961 }
7962 if ((mask & 2) != 0) {
7963 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7964 n = n + 1;
7965 }
7966 if ((mask & 1) != 0) {
7967 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7968 }
7969
7970 return "stcm";
7971}
7972
florian55085f82012-11-21 00:36:55 +00007973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007974s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7975{
7976 UChar mask;
7977 UChar n;
7978
7979 mask = (UChar)r3;
7980 n = 0;
7981 if ((mask & 8) != 0) {
7982 store(mkexpr(op2addr), get_gpr_b4(r1));
7983 n = n + 1;
7984 }
7985 if ((mask & 4) != 0) {
7986 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7987 n = n + 1;
7988 }
7989 if ((mask & 2) != 0) {
7990 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7991 n = n + 1;
7992 }
7993 if ((mask & 1) != 0) {
7994 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7995 }
7996
7997 return "stcmy";
7998}
7999
florian55085f82012-11-21 00:36:55 +00008000static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008001s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
8002{
8003 UChar mask;
8004 UChar n;
8005
8006 mask = (UChar)r3;
8007 n = 0;
8008 if ((mask & 8) != 0) {
8009 store(mkexpr(op2addr), get_gpr_b0(r1));
8010 n = n + 1;
8011 }
8012 if ((mask & 4) != 0) {
8013 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
8014 n = n + 1;
8015 }
8016 if ((mask & 2) != 0) {
8017 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
8018 n = n + 1;
8019 }
8020 if ((mask & 1) != 0) {
8021 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
8022 }
8023
8024 return "stcmh";
8025}
8026
florian55085f82012-11-21 00:36:55 +00008027static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008028s390_irgen_STH(UChar r1, IRTemp op2addr)
8029{
8030 store(mkexpr(op2addr), get_gpr_hw3(r1));
8031
8032 return "sth";
8033}
8034
florian55085f82012-11-21 00:36:55 +00008035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008036s390_irgen_STHY(UChar r1, IRTemp op2addr)
8037{
8038 store(mkexpr(op2addr), get_gpr_hw3(r1));
8039
8040 return "sthy";
8041}
8042
florian55085f82012-11-21 00:36:55 +00008043static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008044s390_irgen_STHRL(UChar r1, UInt i2)
8045{
8046 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
8047 get_gpr_hw3(r1));
8048
8049 return "sthrl";
8050}
8051
florian55085f82012-11-21 00:36:55 +00008052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008053s390_irgen_STHH(UChar r1, IRTemp op2addr)
8054{
8055 store(mkexpr(op2addr), get_gpr_hw1(r1));
8056
8057 return "sthh";
8058}
8059
florian55085f82012-11-21 00:36:55 +00008060static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008061s390_irgen_STFH(UChar r1, IRTemp op2addr)
8062{
8063 store(mkexpr(op2addr), get_gpr_w0(r1));
8064
8065 return "stfh";
8066}
8067
florian55085f82012-11-21 00:36:55 +00008068static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008069s390_irgen_STOC(UChar r1, IRTemp op2addr)
8070{
8071 /* condition is checked in format handler */
8072 store(mkexpr(op2addr), get_gpr_w1(r1));
8073
8074 return "stoc";
8075}
8076
florian55085f82012-11-21 00:36:55 +00008077static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00008078s390_irgen_STOCG(UChar r1, IRTemp op2addr)
8079{
8080 /* condition is checked in format handler */
8081 store(mkexpr(op2addr), get_gpr_dw0(r1));
8082
8083 return "stocg";
8084}
8085
florian55085f82012-11-21 00:36:55 +00008086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008087s390_irgen_STPQ(UChar r1, IRTemp op2addr)
8088{
8089 store(mkexpr(op2addr), get_gpr_dw0(r1));
8090 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
8091
8092 return "stpq";
8093}
8094
florian55085f82012-11-21 00:36:55 +00008095static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008096s390_irgen_STRVH(UChar r1, IRTemp op2addr)
8097{
8098 store(mkexpr(op2addr), get_gpr_b7(r1));
8099 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8100
8101 return "strvh";
8102}
8103
florian55085f82012-11-21 00:36:55 +00008104static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008105s390_irgen_STRV(UChar r1, IRTemp op2addr)
8106{
8107 store(mkexpr(op2addr), get_gpr_b7(r1));
8108 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8109 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8110 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8111
8112 return "strv";
8113}
8114
florian55085f82012-11-21 00:36:55 +00008115static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008116s390_irgen_STRVG(UChar r1, IRTemp op2addr)
8117{
8118 store(mkexpr(op2addr), get_gpr_b7(r1));
8119 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
8120 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
8121 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
8122 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
8123 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
8124 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
8125 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
8126
8127 return "strvg";
8128}
8129
florian55085f82012-11-21 00:36:55 +00008130static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008131s390_irgen_SR(UChar r1, UChar r2)
8132{
8133 IRTemp op1 = newTemp(Ity_I32);
8134 IRTemp op2 = newTemp(Ity_I32);
8135 IRTemp result = newTemp(Ity_I32);
8136
8137 assign(op1, get_gpr_w1(r1));
8138 assign(op2, get_gpr_w1(r2));
8139 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8140 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8141 put_gpr_w1(r1, mkexpr(result));
8142
8143 return "sr";
8144}
8145
florian55085f82012-11-21 00:36:55 +00008146static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008147s390_irgen_SGR(UChar r1, UChar r2)
8148{
8149 IRTemp op1 = newTemp(Ity_I64);
8150 IRTemp op2 = newTemp(Ity_I64);
8151 IRTemp result = newTemp(Ity_I64);
8152
8153 assign(op1, get_gpr_dw0(r1));
8154 assign(op2, get_gpr_dw0(r2));
8155 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8156 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8157 put_gpr_dw0(r1, mkexpr(result));
8158
8159 return "sgr";
8160}
8161
florian55085f82012-11-21 00:36:55 +00008162static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008163s390_irgen_SGFR(UChar r1, UChar r2)
8164{
8165 IRTemp op1 = newTemp(Ity_I64);
8166 IRTemp op2 = newTemp(Ity_I64);
8167 IRTemp result = newTemp(Ity_I64);
8168
8169 assign(op1, get_gpr_dw0(r1));
8170 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
8171 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8172 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8173 put_gpr_dw0(r1, mkexpr(result));
8174
8175 return "sgfr";
8176}
8177
florian55085f82012-11-21 00:36:55 +00008178static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008179s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
8180{
8181 IRTemp op2 = newTemp(Ity_I32);
8182 IRTemp op3 = newTemp(Ity_I32);
8183 IRTemp result = newTemp(Ity_I32);
8184
8185 assign(op2, get_gpr_w1(r2));
8186 assign(op3, get_gpr_w1(r3));
8187 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8188 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8189 put_gpr_w1(r1, mkexpr(result));
8190
8191 return "srk";
8192}
8193
florian55085f82012-11-21 00:36:55 +00008194static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008195s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
8196{
8197 IRTemp op2 = newTemp(Ity_I64);
8198 IRTemp op3 = newTemp(Ity_I64);
8199 IRTemp result = newTemp(Ity_I64);
8200
8201 assign(op2, get_gpr_dw0(r2));
8202 assign(op3, get_gpr_dw0(r3));
8203 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8204 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
8205 put_gpr_dw0(r1, mkexpr(result));
8206
8207 return "sgrk";
8208}
8209
florian55085f82012-11-21 00:36:55 +00008210static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008211s390_irgen_S(UChar r1, IRTemp op2addr)
8212{
8213 IRTemp op1 = newTemp(Ity_I32);
8214 IRTemp op2 = newTemp(Ity_I32);
8215 IRTemp result = newTemp(Ity_I32);
8216
8217 assign(op1, get_gpr_w1(r1));
8218 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8219 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8220 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8221 put_gpr_w1(r1, mkexpr(result));
8222
8223 return "s";
8224}
8225
florian55085f82012-11-21 00:36:55 +00008226static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008227s390_irgen_SY(UChar r1, IRTemp op2addr)
8228{
8229 IRTemp op1 = newTemp(Ity_I32);
8230 IRTemp op2 = newTemp(Ity_I32);
8231 IRTemp result = newTemp(Ity_I32);
8232
8233 assign(op1, get_gpr_w1(r1));
8234 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8235 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8236 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8237 put_gpr_w1(r1, mkexpr(result));
8238
8239 return "sy";
8240}
8241
florian55085f82012-11-21 00:36:55 +00008242static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008243s390_irgen_SG(UChar r1, IRTemp op2addr)
8244{
8245 IRTemp op1 = newTemp(Ity_I64);
8246 IRTemp op2 = newTemp(Ity_I64);
8247 IRTemp result = newTemp(Ity_I64);
8248
8249 assign(op1, get_gpr_dw0(r1));
8250 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8251 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8252 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8253 put_gpr_dw0(r1, mkexpr(result));
8254
8255 return "sg";
8256}
8257
florian55085f82012-11-21 00:36:55 +00008258static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008259s390_irgen_SGF(UChar r1, IRTemp op2addr)
8260{
8261 IRTemp op1 = newTemp(Ity_I64);
8262 IRTemp op2 = newTemp(Ity_I64);
8263 IRTemp result = newTemp(Ity_I64);
8264
8265 assign(op1, get_gpr_dw0(r1));
8266 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
8267 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8268 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
8269 put_gpr_dw0(r1, mkexpr(result));
8270
8271 return "sgf";
8272}
8273
florian55085f82012-11-21 00:36:55 +00008274static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008275s390_irgen_SH(UChar r1, IRTemp op2addr)
8276{
8277 IRTemp op1 = newTemp(Ity_I32);
8278 IRTemp op2 = newTemp(Ity_I32);
8279 IRTemp result = newTemp(Ity_I32);
8280
8281 assign(op1, get_gpr_w1(r1));
8282 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8283 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8284 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8285 put_gpr_w1(r1, mkexpr(result));
8286
8287 return "sh";
8288}
8289
florian55085f82012-11-21 00:36:55 +00008290static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008291s390_irgen_SHY(UChar r1, IRTemp op2addr)
8292{
8293 IRTemp op1 = newTemp(Ity_I32);
8294 IRTemp op2 = newTemp(Ity_I32);
8295 IRTemp result = newTemp(Ity_I32);
8296
8297 assign(op1, get_gpr_w1(r1));
8298 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
8299 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8300 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
8301 put_gpr_w1(r1, mkexpr(result));
8302
8303 return "shy";
8304}
8305
florian55085f82012-11-21 00:36:55 +00008306static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008307s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8308{
8309 IRTemp op2 = newTemp(Ity_I32);
8310 IRTemp op3 = newTemp(Ity_I32);
8311 IRTemp result = newTemp(Ity_I32);
8312
8313 assign(op2, get_gpr_w0(r1));
8314 assign(op3, get_gpr_w0(r2));
8315 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8316 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8317 put_gpr_w0(r1, mkexpr(result));
8318
8319 return "shhhr";
8320}
8321
florian55085f82012-11-21 00:36:55 +00008322static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008323s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8324{
8325 IRTemp op2 = newTemp(Ity_I32);
8326 IRTemp op3 = newTemp(Ity_I32);
8327 IRTemp result = newTemp(Ity_I32);
8328
8329 assign(op2, get_gpr_w0(r1));
8330 assign(op3, get_gpr_w1(r2));
8331 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8332 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8333 put_gpr_w0(r1, mkexpr(result));
8334
8335 return "shhlr";
8336}
8337
florian55085f82012-11-21 00:36:55 +00008338static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008339s390_irgen_SLR(UChar r1, UChar r2)
8340{
8341 IRTemp op1 = newTemp(Ity_I32);
8342 IRTemp op2 = newTemp(Ity_I32);
8343 IRTemp result = newTemp(Ity_I32);
8344
8345 assign(op1, get_gpr_w1(r1));
8346 assign(op2, get_gpr_w1(r2));
8347 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8348 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8349 put_gpr_w1(r1, mkexpr(result));
8350
8351 return "slr";
8352}
8353
florian55085f82012-11-21 00:36:55 +00008354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008355s390_irgen_SLGR(UChar r1, UChar r2)
8356{
8357 IRTemp op1 = newTemp(Ity_I64);
8358 IRTemp op2 = newTemp(Ity_I64);
8359 IRTemp result = newTemp(Ity_I64);
8360
8361 assign(op1, get_gpr_dw0(r1));
8362 assign(op2, get_gpr_dw0(r2));
8363 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8364 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8365 put_gpr_dw0(r1, mkexpr(result));
8366
8367 return "slgr";
8368}
8369
florian55085f82012-11-21 00:36:55 +00008370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008371s390_irgen_SLGFR(UChar r1, UChar r2)
8372{
8373 IRTemp op1 = newTemp(Ity_I64);
8374 IRTemp op2 = newTemp(Ity_I64);
8375 IRTemp result = newTemp(Ity_I64);
8376
8377 assign(op1, get_gpr_dw0(r1));
8378 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8379 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8380 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8381 put_gpr_dw0(r1, mkexpr(result));
8382
8383 return "slgfr";
8384}
8385
florian55085f82012-11-21 00:36:55 +00008386static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008387s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8388{
8389 IRTemp op2 = newTemp(Ity_I32);
8390 IRTemp op3 = newTemp(Ity_I32);
8391 IRTemp result = newTemp(Ity_I32);
8392
8393 assign(op2, get_gpr_w1(r2));
8394 assign(op3, get_gpr_w1(r3));
8395 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8396 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8397 put_gpr_w1(r1, mkexpr(result));
8398
8399 return "slrk";
8400}
8401
florian55085f82012-11-21 00:36:55 +00008402static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008403s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8404{
8405 IRTemp op2 = newTemp(Ity_I64);
8406 IRTemp op3 = newTemp(Ity_I64);
8407 IRTemp result = newTemp(Ity_I64);
8408
8409 assign(op2, get_gpr_dw0(r2));
8410 assign(op3, get_gpr_dw0(r3));
8411 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8412 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8413 put_gpr_dw0(r1, mkexpr(result));
8414
8415 return "slgrk";
8416}
8417
florian55085f82012-11-21 00:36:55 +00008418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008419s390_irgen_SL(UChar r1, IRTemp op2addr)
8420{
8421 IRTemp op1 = newTemp(Ity_I32);
8422 IRTemp op2 = newTemp(Ity_I32);
8423 IRTemp result = newTemp(Ity_I32);
8424
8425 assign(op1, get_gpr_w1(r1));
8426 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8427 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8428 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8429 put_gpr_w1(r1, mkexpr(result));
8430
8431 return "sl";
8432}
8433
florian55085f82012-11-21 00:36:55 +00008434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008435s390_irgen_SLY(UChar r1, IRTemp op2addr)
8436{
8437 IRTemp op1 = newTemp(Ity_I32);
8438 IRTemp op2 = newTemp(Ity_I32);
8439 IRTemp result = newTemp(Ity_I32);
8440
8441 assign(op1, get_gpr_w1(r1));
8442 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8443 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8444 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8445 put_gpr_w1(r1, mkexpr(result));
8446
8447 return "sly";
8448}
8449
florian55085f82012-11-21 00:36:55 +00008450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008451s390_irgen_SLG(UChar r1, IRTemp op2addr)
8452{
8453 IRTemp op1 = newTemp(Ity_I64);
8454 IRTemp op2 = newTemp(Ity_I64);
8455 IRTemp result = newTemp(Ity_I64);
8456
8457 assign(op1, get_gpr_dw0(r1));
8458 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8459 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8460 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8461 put_gpr_dw0(r1, mkexpr(result));
8462
8463 return "slg";
8464}
8465
florian55085f82012-11-21 00:36:55 +00008466static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008467s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8468{
8469 IRTemp op1 = newTemp(Ity_I64);
8470 IRTemp op2 = newTemp(Ity_I64);
8471 IRTemp result = newTemp(Ity_I64);
8472
8473 assign(op1, get_gpr_dw0(r1));
8474 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8475 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8476 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8477 put_gpr_dw0(r1, mkexpr(result));
8478
8479 return "slgf";
8480}
8481
florian55085f82012-11-21 00:36:55 +00008482static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008483s390_irgen_SLFI(UChar r1, UInt i2)
8484{
8485 IRTemp op1 = newTemp(Ity_I32);
8486 UInt op2;
8487 IRTemp result = newTemp(Ity_I32);
8488
8489 assign(op1, get_gpr_w1(r1));
8490 op2 = i2;
8491 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8492 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8493 mkU32(op2)));
8494 put_gpr_w1(r1, mkexpr(result));
8495
8496 return "slfi";
8497}
8498
florian55085f82012-11-21 00:36:55 +00008499static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008500s390_irgen_SLGFI(UChar r1, UInt i2)
8501{
8502 IRTemp op1 = newTemp(Ity_I64);
8503 ULong op2;
8504 IRTemp result = newTemp(Ity_I64);
8505
8506 assign(op1, get_gpr_dw0(r1));
8507 op2 = (ULong)i2;
8508 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8509 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8510 mkU64(op2)));
8511 put_gpr_dw0(r1, mkexpr(result));
8512
8513 return "slgfi";
8514}
8515
florian55085f82012-11-21 00:36:55 +00008516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008517s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8518{
8519 IRTemp op2 = newTemp(Ity_I32);
8520 IRTemp op3 = newTemp(Ity_I32);
8521 IRTemp result = newTemp(Ity_I32);
8522
8523 assign(op2, get_gpr_w0(r1));
8524 assign(op3, get_gpr_w0(r2));
8525 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8526 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8527 put_gpr_w0(r1, mkexpr(result));
8528
8529 return "slhhhr";
8530}
8531
florian55085f82012-11-21 00:36:55 +00008532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008533s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8534{
8535 IRTemp op2 = newTemp(Ity_I32);
8536 IRTemp op3 = newTemp(Ity_I32);
8537 IRTemp result = newTemp(Ity_I32);
8538
8539 assign(op2, get_gpr_w0(r1));
8540 assign(op3, get_gpr_w1(r2));
8541 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8542 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8543 put_gpr_w0(r1, mkexpr(result));
8544
8545 return "slhhlr";
8546}
8547
florian55085f82012-11-21 00:36:55 +00008548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008549s390_irgen_SLBR(UChar r1, UChar r2)
8550{
8551 IRTemp op1 = newTemp(Ity_I32);
8552 IRTemp op2 = newTemp(Ity_I32);
8553 IRTemp result = newTemp(Ity_I32);
8554 IRTemp borrow_in = newTemp(Ity_I32);
8555
8556 assign(op1, get_gpr_w1(r1));
8557 assign(op2, get_gpr_w1(r2));
8558 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8559 s390_call_calculate_cc(), mkU8(1))));
8560 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8561 mkexpr(borrow_in)));
8562 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8563 put_gpr_w1(r1, mkexpr(result));
8564
8565 return "slbr";
8566}
8567
florian55085f82012-11-21 00:36:55 +00008568static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008569s390_irgen_SLBGR(UChar r1, UChar r2)
8570{
8571 IRTemp op1 = newTemp(Ity_I64);
8572 IRTemp op2 = newTemp(Ity_I64);
8573 IRTemp result = newTemp(Ity_I64);
8574 IRTemp borrow_in = newTemp(Ity_I64);
8575
8576 assign(op1, get_gpr_dw0(r1));
8577 assign(op2, get_gpr_dw0(r2));
8578 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8579 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8580 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8581 mkexpr(borrow_in)));
8582 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8583 put_gpr_dw0(r1, mkexpr(result));
8584
8585 return "slbgr";
8586}
8587
florian55085f82012-11-21 00:36:55 +00008588static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008589s390_irgen_SLB(UChar r1, IRTemp op2addr)
8590{
8591 IRTemp op1 = newTemp(Ity_I32);
8592 IRTemp op2 = newTemp(Ity_I32);
8593 IRTemp result = newTemp(Ity_I32);
8594 IRTemp borrow_in = newTemp(Ity_I32);
8595
8596 assign(op1, get_gpr_w1(r1));
8597 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8598 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8599 s390_call_calculate_cc(), mkU8(1))));
8600 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8601 mkexpr(borrow_in)));
8602 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8603 put_gpr_w1(r1, mkexpr(result));
8604
8605 return "slb";
8606}
8607
florian55085f82012-11-21 00:36:55 +00008608static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008609s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8610{
8611 IRTemp op1 = newTemp(Ity_I64);
8612 IRTemp op2 = newTemp(Ity_I64);
8613 IRTemp result = newTemp(Ity_I64);
8614 IRTemp borrow_in = newTemp(Ity_I64);
8615
8616 assign(op1, get_gpr_dw0(r1));
8617 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8618 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8619 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8620 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8621 mkexpr(borrow_in)));
8622 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8623 put_gpr_dw0(r1, mkexpr(result));
8624
8625 return "slbg";
8626}
8627
florian55085f82012-11-21 00:36:55 +00008628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008629s390_irgen_SVC(UChar i)
8630{
8631 IRTemp sysno = newTemp(Ity_I64);
8632
8633 if (i != 0) {
8634 assign(sysno, mkU64(i));
8635 } else {
8636 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8637 }
8638 system_call(mkexpr(sysno));
8639
8640 return "svc";
8641}
8642
florian55085f82012-11-21 00:36:55 +00008643static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008644s390_irgen_TM(UChar i2, IRTemp op1addr)
8645{
8646 UChar mask;
8647 IRTemp value = newTemp(Ity_I8);
8648
8649 mask = i2;
8650 assign(value, load(Ity_I8, mkexpr(op1addr)));
8651 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8652 mkU8(mask)));
8653
8654 return "tm";
8655}
8656
florian55085f82012-11-21 00:36:55 +00008657static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008658s390_irgen_TMY(UChar i2, IRTemp op1addr)
8659{
8660 UChar mask;
8661 IRTemp value = newTemp(Ity_I8);
8662
8663 mask = i2;
8664 assign(value, load(Ity_I8, mkexpr(op1addr)));
8665 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8666 mkU8(mask)));
8667
8668 return "tmy";
8669}
8670
florian55085f82012-11-21 00:36:55 +00008671static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008672s390_irgen_TMHH(UChar r1, UShort i2)
8673{
8674 UShort mask;
8675 IRTemp value = newTemp(Ity_I16);
8676
8677 mask = i2;
8678 assign(value, get_gpr_hw0(r1));
8679 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8680 mkU16(mask)));
8681
8682 return "tmhh";
8683}
8684
florian55085f82012-11-21 00:36:55 +00008685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008686s390_irgen_TMHL(UChar r1, UShort i2)
8687{
8688 UShort mask;
8689 IRTemp value = newTemp(Ity_I16);
8690
8691 mask = i2;
8692 assign(value, get_gpr_hw1(r1));
8693 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8694 mkU16(mask)));
8695
8696 return "tmhl";
8697}
8698
florian55085f82012-11-21 00:36:55 +00008699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008700s390_irgen_TMLH(UChar r1, UShort i2)
8701{
8702 UShort mask;
8703 IRTemp value = newTemp(Ity_I16);
8704
8705 mask = i2;
8706 assign(value, get_gpr_hw2(r1));
8707 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8708 mkU16(mask)));
8709
8710 return "tmlh";
8711}
8712
florian55085f82012-11-21 00:36:55 +00008713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008714s390_irgen_TMLL(UChar r1, UShort i2)
8715{
8716 UShort mask;
8717 IRTemp value = newTemp(Ity_I16);
8718
8719 mask = i2;
8720 assign(value, get_gpr_hw3(r1));
8721 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8722 mkU16(mask)));
8723
8724 return "tmll";
8725}
8726
florian55085f82012-11-21 00:36:55 +00008727static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008728s390_irgen_EFPC(UChar r1)
8729{
8730 put_gpr_w1(r1, get_fpc_w0());
8731
8732 return "efpc";
8733}
8734
florian55085f82012-11-21 00:36:55 +00008735static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008736s390_irgen_LER(UChar r1, UChar r2)
8737{
8738 put_fpr_w0(r1, get_fpr_w0(r2));
8739
8740 return "ler";
8741}
8742
florian55085f82012-11-21 00:36:55 +00008743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008744s390_irgen_LDR(UChar r1, UChar r2)
8745{
8746 put_fpr_dw0(r1, get_fpr_dw0(r2));
8747
8748 return "ldr";
8749}
8750
florian55085f82012-11-21 00:36:55 +00008751static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008752s390_irgen_LXR(UChar r1, UChar r2)
8753{
8754 put_fpr_dw0(r1, get_fpr_dw0(r2));
8755 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8756
8757 return "lxr";
8758}
8759
florian55085f82012-11-21 00:36:55 +00008760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008761s390_irgen_LE(UChar r1, IRTemp op2addr)
8762{
8763 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8764
8765 return "le";
8766}
8767
florian55085f82012-11-21 00:36:55 +00008768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008769s390_irgen_LD(UChar r1, IRTemp op2addr)
8770{
8771 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8772
8773 return "ld";
8774}
8775
florian55085f82012-11-21 00:36:55 +00008776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008777s390_irgen_LEY(UChar r1, IRTemp op2addr)
8778{
8779 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8780
8781 return "ley";
8782}
8783
florian55085f82012-11-21 00:36:55 +00008784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008785s390_irgen_LDY(UChar r1, IRTemp op2addr)
8786{
8787 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8788
8789 return "ldy";
8790}
8791
florian55085f82012-11-21 00:36:55 +00008792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008793s390_irgen_LFPC(IRTemp op2addr)
8794{
8795 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8796
8797 return "lfpc";
8798}
8799
florian55085f82012-11-21 00:36:55 +00008800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008801s390_irgen_LZER(UChar r1)
8802{
8803 put_fpr_w0(r1, mkF32i(0x0));
8804
8805 return "lzer";
8806}
8807
florian55085f82012-11-21 00:36:55 +00008808static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008809s390_irgen_LZDR(UChar r1)
8810{
8811 put_fpr_dw0(r1, mkF64i(0x0));
8812
8813 return "lzdr";
8814}
8815
florian55085f82012-11-21 00:36:55 +00008816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008817s390_irgen_LZXR(UChar r1)
8818{
8819 put_fpr_dw0(r1, mkF64i(0x0));
8820 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8821
8822 return "lzxr";
8823}
8824
florian55085f82012-11-21 00:36:55 +00008825static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008826s390_irgen_SRNM(IRTemp op2addr)
8827{
florianf0fa1be2012-09-18 20:24:38 +00008828 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008829
florianf0fa1be2012-09-18 20:24:38 +00008830 input_mask = 3;
8831 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008832
florianf0fa1be2012-09-18 20:24:38 +00008833 put_fpc_w0(binop(Iop_Or32,
8834 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8835 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8836 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008837 return "srnm";
8838}
8839
florian55085f82012-11-21 00:36:55 +00008840static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008841s390_irgen_SRNMB(IRTemp op2addr)
8842{
8843 UInt input_mask, fpc_mask;
8844
8845 input_mask = 7;
8846 fpc_mask = 7;
8847
8848 put_fpc_w0(binop(Iop_Or32,
8849 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8850 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8851 mkU32(input_mask))));
8852 return "srnmb";
8853}
8854
florian81a4bfe2012-09-20 01:25:28 +00008855static void
florianf0fa1be2012-09-18 20:24:38 +00008856s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8857{
8858 if (b2 == 0) { /* This is the typical case */
8859 if (d2 > 3) {
8860 if (s390_host_has_fpext && d2 == 7) {
8861 /* ok */
8862 } else {
8863 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008864 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008865 }
8866 }
8867 }
8868
8869 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8870}
8871
florian82cdba62013-03-12 01:31:24 +00008872/* Wrapper to validate the parameter as in SRNMB is not required, as all
8873 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8874static const HChar *
8875s390_irgen_SRNMT(IRTemp op2addr)
8876{
8877 UInt input_mask, fpc_mask;
8878
8879 input_mask = 7;
8880 fpc_mask = 0x70;
8881
8882 /* fpc[25:27] <- op2addr[61:63]
8883 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8884 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8885 binop(Iop_Shl32, binop(Iop_And32,
8886 unop(Iop_64to32, mkexpr(op2addr)),
8887 mkU32(input_mask)), mkU8(4))));
8888 return "srnmt";
8889}
8890
florianf0fa1be2012-09-18 20:24:38 +00008891
florian55085f82012-11-21 00:36:55 +00008892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008893s390_irgen_SFPC(UChar r1)
8894{
8895 put_fpc_w0(get_gpr_w1(r1));
8896
8897 return "sfpc";
8898}
8899
florian55085f82012-11-21 00:36:55 +00008900static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008901s390_irgen_STE(UChar r1, IRTemp op2addr)
8902{
8903 store(mkexpr(op2addr), get_fpr_w0(r1));
8904
8905 return "ste";
8906}
8907
florian55085f82012-11-21 00:36:55 +00008908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008909s390_irgen_STD(UChar r1, IRTemp op2addr)
8910{
8911 store(mkexpr(op2addr), get_fpr_dw0(r1));
8912
8913 return "std";
8914}
8915
florian55085f82012-11-21 00:36:55 +00008916static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008917s390_irgen_STEY(UChar r1, IRTemp op2addr)
8918{
8919 store(mkexpr(op2addr), get_fpr_w0(r1));
8920
8921 return "stey";
8922}
8923
florian55085f82012-11-21 00:36:55 +00008924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008925s390_irgen_STDY(UChar r1, IRTemp op2addr)
8926{
8927 store(mkexpr(op2addr), get_fpr_dw0(r1));
8928
8929 return "stdy";
8930}
8931
florian55085f82012-11-21 00:36:55 +00008932static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008933s390_irgen_STFPC(IRTemp op2addr)
8934{
8935 store(mkexpr(op2addr), get_fpc_w0());
8936
8937 return "stfpc";
8938}
8939
florian55085f82012-11-21 00:36:55 +00008940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008941s390_irgen_AEBR(UChar r1, UChar r2)
8942{
8943 IRTemp op1 = newTemp(Ity_F32);
8944 IRTemp op2 = newTemp(Ity_F32);
8945 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008946 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008947
8948 assign(op1, get_fpr_w0(r1));
8949 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008950 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008951 mkexpr(op2)));
8952 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8953 put_fpr_w0(r1, mkexpr(result));
8954
8955 return "aebr";
8956}
8957
florian55085f82012-11-21 00:36:55 +00008958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008959s390_irgen_ADBR(UChar r1, UChar r2)
8960{
8961 IRTemp op1 = newTemp(Ity_F64);
8962 IRTemp op2 = newTemp(Ity_F64);
8963 IRTemp result = newTemp(Ity_F64);
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_dw0(r1));
8967 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008968 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008969 mkexpr(op2)));
8970 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8971 put_fpr_dw0(r1, mkexpr(result));
8972
8973 return "adbr";
8974}
8975
florian55085f82012-11-21 00:36:55 +00008976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008977s390_irgen_AEB(UChar r1, IRTemp op2addr)
8978{
8979 IRTemp op1 = newTemp(Ity_F32);
8980 IRTemp op2 = newTemp(Ity_F32);
8981 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008982 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008983
8984 assign(op1, get_fpr_w0(r1));
8985 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008986 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008987 mkexpr(op2)));
8988 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8989 put_fpr_w0(r1, mkexpr(result));
8990
8991 return "aeb";
8992}
8993
florian55085f82012-11-21 00:36:55 +00008994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008995s390_irgen_ADB(UChar r1, IRTemp op2addr)
8996{
8997 IRTemp op1 = newTemp(Ity_F64);
8998 IRTemp op2 = newTemp(Ity_F64);
8999 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009000 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009001
9002 assign(op1, get_fpr_dw0(r1));
9003 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009004 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009005 mkexpr(op2)));
9006 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9007 put_fpr_dw0(r1, mkexpr(result));
9008
9009 return "adb";
9010}
9011
florian55085f82012-11-21 00:36:55 +00009012static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009013s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
9014 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009015{
florian125e20d2012-10-07 15:42:37 +00009016 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009017 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009018 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009019 }
sewardj2019a972011-03-07 16:04:07 +00009020 IRTemp op2 = newTemp(Ity_I32);
9021
9022 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009023 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009024 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009025
9026 return "cefbr";
9027}
9028
florian55085f82012-11-21 00:36:55 +00009029static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009030s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
9031 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009032{
9033 IRTemp op2 = newTemp(Ity_I32);
9034
9035 assign(op2, get_gpr_w1(r2));
9036 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
9037
9038 return "cdfbr";
9039}
9040
florian55085f82012-11-21 00:36:55 +00009041static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009042s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
9043 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009044{
florian125e20d2012-10-07 15:42:37 +00009045 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009046 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009047 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009048 }
sewardj2019a972011-03-07 16:04:07 +00009049 IRTemp op2 = newTemp(Ity_I64);
9050
9051 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009052 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009053 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009054
9055 return "cegbr";
9056}
9057
florian55085f82012-11-21 00:36:55 +00009058static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009059s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
9060 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009061{
florian125e20d2012-10-07 15:42:37 +00009062 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00009063 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009064 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00009065 }
sewardj2019a972011-03-07 16:04:07 +00009066 IRTemp op2 = newTemp(Ity_I64);
9067
9068 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009069 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009070 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00009071
9072 return "cdgbr";
9073}
9074
florian55085f82012-11-21 00:36:55 +00009075static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009076s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
9077 UChar r1, UChar r2)
9078{
floriane75dafa2012-09-01 17:54:09 +00009079 if (! s390_host_has_fpext) {
9080 emulation_failure(EmFail_S390X_fpext);
9081 } else {
9082 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009083
floriane75dafa2012-09-01 17:54:09 +00009084 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009085 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009086 mkexpr(op2)));
9087 }
florian1c8f7ff2012-09-01 00:12:11 +00009088 return "celfbr";
9089}
9090
florian55085f82012-11-21 00:36:55 +00009091static const HChar *
floriand2129202012-09-01 20:01:39 +00009092s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
9093 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00009094{
floriane75dafa2012-09-01 17:54:09 +00009095 if (! s390_host_has_fpext) {
9096 emulation_failure(EmFail_S390X_fpext);
9097 } else {
9098 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00009099
floriane75dafa2012-09-01 17:54:09 +00009100 assign(op2, get_gpr_w1(r2));
9101 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
9102 }
florian1c8f7ff2012-09-01 00:12:11 +00009103 return "cdlfbr";
9104}
9105
florian55085f82012-11-21 00:36:55 +00009106static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009107s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
9108 UChar r1, UChar r2)
9109{
floriane75dafa2012-09-01 17:54:09 +00009110 if (! s390_host_has_fpext) {
9111 emulation_failure(EmFail_S390X_fpext);
9112 } else {
9113 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009114
floriane75dafa2012-09-01 17:54:09 +00009115 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009116 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009117 mkexpr(op2)));
9118 }
florian1c8f7ff2012-09-01 00:12:11 +00009119 return "celgbr";
9120}
9121
florian55085f82012-11-21 00:36:55 +00009122static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009123s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
9124 UChar r1, UChar r2)
9125{
floriane75dafa2012-09-01 17:54:09 +00009126 if (! s390_host_has_fpext) {
9127 emulation_failure(EmFail_S390X_fpext);
9128 } else {
9129 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00009130
floriane75dafa2012-09-01 17:54:09 +00009131 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009132 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
9133 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00009134 mkexpr(op2)));
9135 }
florian1c8f7ff2012-09-01 00:12:11 +00009136 return "cdlgbr";
9137}
9138
florian55085f82012-11-21 00:36:55 +00009139static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009140s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
9141 UChar r1, UChar r2)
9142{
floriane75dafa2012-09-01 17:54:09 +00009143 if (! s390_host_has_fpext) {
9144 emulation_failure(EmFail_S390X_fpext);
9145 } else {
9146 IRTemp op = newTemp(Ity_F32);
9147 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009148 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009149
floriane75dafa2012-09-01 17:54:09 +00009150 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009151 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009152 mkexpr(op)));
9153 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009154 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009155 }
florian1c8f7ff2012-09-01 00:12:11 +00009156 return "clfebr";
9157}
9158
florian55085f82012-11-21 00:36:55 +00009159static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009160s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
9161 UChar r1, UChar r2)
9162{
floriane75dafa2012-09-01 17:54:09 +00009163 if (! s390_host_has_fpext) {
9164 emulation_failure(EmFail_S390X_fpext);
9165 } else {
9166 IRTemp op = newTemp(Ity_F64);
9167 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009168 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009169
floriane75dafa2012-09-01 17:54:09 +00009170 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009171 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009172 mkexpr(op)));
9173 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009174 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009175 }
florian1c8f7ff2012-09-01 00:12:11 +00009176 return "clfdbr";
9177}
9178
florian55085f82012-11-21 00:36:55 +00009179static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009180s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
9181 UChar r1, UChar r2)
9182{
floriane75dafa2012-09-01 17:54:09 +00009183 if (! s390_host_has_fpext) {
9184 emulation_failure(EmFail_S390X_fpext);
9185 } else {
9186 IRTemp op = newTemp(Ity_F32);
9187 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009188 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009189
floriane75dafa2012-09-01 17:54:09 +00009190 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009191 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009192 mkexpr(op)));
9193 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009194 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009195 }
florian1c8f7ff2012-09-01 00:12:11 +00009196 return "clgebr";
9197}
9198
florian55085f82012-11-21 00:36:55 +00009199static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00009200s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
9201 UChar r1, UChar r2)
9202{
floriane75dafa2012-09-01 17:54:09 +00009203 if (! s390_host_has_fpext) {
9204 emulation_failure(EmFail_S390X_fpext);
9205 } else {
9206 IRTemp op = newTemp(Ity_F64);
9207 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009208 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00009209
floriane75dafa2012-09-01 17:54:09 +00009210 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009211 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00009212 mkexpr(op)));
9213 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009214 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00009215 }
florian1c8f7ff2012-09-01 00:12:11 +00009216 return "clgdbr";
9217}
9218
florian55085f82012-11-21 00:36:55 +00009219static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009220s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
9221 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009222{
9223 IRTemp op = newTemp(Ity_F32);
9224 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009225 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009226
9227 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009228 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009229 mkexpr(op)));
9230 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009231 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009232
9233 return "cfebr";
9234}
9235
florian55085f82012-11-21 00:36:55 +00009236static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009237s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
9238 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009239{
9240 IRTemp op = newTemp(Ity_F64);
9241 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00009242 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009243
9244 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009245 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009246 mkexpr(op)));
9247 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009248 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009249
9250 return "cfdbr";
9251}
9252
florian55085f82012-11-21 00:36:55 +00009253static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009254s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
9255 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009256{
9257 IRTemp op = newTemp(Ity_F32);
9258 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009259 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009260
9261 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00009262 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009263 mkexpr(op)));
9264 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009265 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009266
9267 return "cgebr";
9268}
9269
florian55085f82012-11-21 00:36:55 +00009270static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009271s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
9272 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009273{
9274 IRTemp op = newTemp(Ity_F64);
9275 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00009276 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00009277
9278 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00009279 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00009280 mkexpr(op)));
9281 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00009282 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00009283
9284 return "cgdbr";
9285}
9286
florian55085f82012-11-21 00:36:55 +00009287static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009288s390_irgen_DEBR(UChar r1, UChar r2)
9289{
9290 IRTemp op1 = newTemp(Ity_F32);
9291 IRTemp op2 = newTemp(Ity_F32);
9292 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009293 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009294
9295 assign(op1, get_fpr_w0(r1));
9296 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009297 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009298 mkexpr(op2)));
9299 put_fpr_w0(r1, mkexpr(result));
9300
9301 return "debr";
9302}
9303
florian55085f82012-11-21 00:36:55 +00009304static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009305s390_irgen_DDBR(UChar r1, UChar r2)
9306{
9307 IRTemp op1 = newTemp(Ity_F64);
9308 IRTemp op2 = newTemp(Ity_F64);
9309 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009310 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009311
9312 assign(op1, get_fpr_dw0(r1));
9313 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009314 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009315 mkexpr(op2)));
9316 put_fpr_dw0(r1, mkexpr(result));
9317
9318 return "ddbr";
9319}
9320
florian55085f82012-11-21 00:36:55 +00009321static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009322s390_irgen_DEB(UChar r1, IRTemp op2addr)
9323{
9324 IRTemp op1 = newTemp(Ity_F32);
9325 IRTemp op2 = newTemp(Ity_F32);
9326 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009327 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009328
9329 assign(op1, get_fpr_w0(r1));
9330 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009331 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009332 mkexpr(op2)));
9333 put_fpr_w0(r1, mkexpr(result));
9334
9335 return "deb";
9336}
9337
florian55085f82012-11-21 00:36:55 +00009338static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009339s390_irgen_DDB(UChar r1, IRTemp op2addr)
9340{
9341 IRTemp op1 = newTemp(Ity_F64);
9342 IRTemp op2 = newTemp(Ity_F64);
9343 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009344 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009345
9346 assign(op1, get_fpr_dw0(r1));
9347 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009348 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009349 mkexpr(op2)));
9350 put_fpr_dw0(r1, mkexpr(result));
9351
9352 return "ddb";
9353}
9354
florian55085f82012-11-21 00:36:55 +00009355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009356s390_irgen_LTEBR(UChar r1, UChar r2)
9357{
9358 IRTemp result = newTemp(Ity_F32);
9359
9360 assign(result, get_fpr_w0(r2));
9361 put_fpr_w0(r1, mkexpr(result));
9362 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9363
9364 return "ltebr";
9365}
9366
florian55085f82012-11-21 00:36:55 +00009367static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009368s390_irgen_LTDBR(UChar r1, UChar r2)
9369{
9370 IRTemp result = newTemp(Ity_F64);
9371
9372 assign(result, get_fpr_dw0(r2));
9373 put_fpr_dw0(r1, mkexpr(result));
9374 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9375
9376 return "ltdbr";
9377}
9378
florian55085f82012-11-21 00:36:55 +00009379static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009380s390_irgen_LCEBR(UChar r1, UChar r2)
9381{
9382 IRTemp result = newTemp(Ity_F32);
9383
9384 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9385 put_fpr_w0(r1, mkexpr(result));
9386 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9387
9388 return "lcebr";
9389}
9390
florian55085f82012-11-21 00:36:55 +00009391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009392s390_irgen_LCDBR(UChar r1, UChar r2)
9393{
9394 IRTemp result = newTemp(Ity_F64);
9395
9396 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9397 put_fpr_dw0(r1, mkexpr(result));
9398 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9399
9400 return "lcdbr";
9401}
9402
florian55085f82012-11-21 00:36:55 +00009403static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009404s390_irgen_LDEBR(UChar r1, UChar r2)
9405{
9406 IRTemp op = newTemp(Ity_F32);
9407
9408 assign(op, get_fpr_w0(r2));
9409 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9410
9411 return "ldebr";
9412}
9413
florian55085f82012-11-21 00:36:55 +00009414static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009415s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9416{
9417 IRTemp op = newTemp(Ity_F32);
9418
9419 assign(op, load(Ity_F32, mkexpr(op2addr)));
9420 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9421
9422 return "ldeb";
9423}
9424
florian55085f82012-11-21 00:36:55 +00009425static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009426s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9427 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009428{
florian125e20d2012-10-07 15:42:37 +00009429 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009430 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009431 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009432 }
sewardj2019a972011-03-07 16:04:07 +00009433 IRTemp op = newTemp(Ity_F64);
9434
9435 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009436 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009437 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009438
9439 return "ledbr";
9440}
9441
florian55085f82012-11-21 00:36:55 +00009442static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009443s390_irgen_MEEBR(UChar r1, UChar r2)
9444{
9445 IRTemp op1 = newTemp(Ity_F32);
9446 IRTemp op2 = newTemp(Ity_F32);
9447 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009448 IRRoundingMode rounding_mode =
9449 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009450
9451 assign(op1, get_fpr_w0(r1));
9452 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009453 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009454 mkexpr(op2)));
9455 put_fpr_w0(r1, mkexpr(result));
9456
9457 return "meebr";
9458}
9459
florian55085f82012-11-21 00:36:55 +00009460static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009461s390_irgen_MDBR(UChar r1, UChar r2)
9462{
9463 IRTemp op1 = newTemp(Ity_F64);
9464 IRTemp op2 = newTemp(Ity_F64);
9465 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009466 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009467
9468 assign(op1, get_fpr_dw0(r1));
9469 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009470 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009471 mkexpr(op2)));
9472 put_fpr_dw0(r1, mkexpr(result));
9473
9474 return "mdbr";
9475}
9476
florian55085f82012-11-21 00:36:55 +00009477static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009478s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9479{
9480 IRTemp op1 = newTemp(Ity_F32);
9481 IRTemp op2 = newTemp(Ity_F32);
9482 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009483 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009484
9485 assign(op1, get_fpr_w0(r1));
9486 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009487 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009488 mkexpr(op2)));
9489 put_fpr_w0(r1, mkexpr(result));
9490
9491 return "meeb";
9492}
9493
florian55085f82012-11-21 00:36:55 +00009494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009495s390_irgen_MDB(UChar r1, IRTemp op2addr)
9496{
9497 IRTemp op1 = newTemp(Ity_F64);
9498 IRTemp op2 = newTemp(Ity_F64);
9499 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009500 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009501
9502 assign(op1, get_fpr_dw0(r1));
9503 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009504 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009505 mkexpr(op2)));
9506 put_fpr_dw0(r1, mkexpr(result));
9507
9508 return "mdb";
9509}
9510
florian55085f82012-11-21 00:36:55 +00009511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009512s390_irgen_SEBR(UChar r1, UChar r2)
9513{
9514 IRTemp op1 = newTemp(Ity_F32);
9515 IRTemp op2 = newTemp(Ity_F32);
9516 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009517 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009518
9519 assign(op1, get_fpr_w0(r1));
9520 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009521 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009522 mkexpr(op2)));
9523 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9524 put_fpr_w0(r1, mkexpr(result));
9525
9526 return "sebr";
9527}
9528
florian55085f82012-11-21 00:36:55 +00009529static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009530s390_irgen_SDBR(UChar r1, UChar r2)
9531{
9532 IRTemp op1 = newTemp(Ity_F64);
9533 IRTemp op2 = newTemp(Ity_F64);
9534 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009535 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009536
9537 assign(op1, get_fpr_dw0(r1));
9538 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009539 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009540 mkexpr(op2)));
9541 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9542 put_fpr_dw0(r1, mkexpr(result));
9543
9544 return "sdbr";
9545}
9546
florian55085f82012-11-21 00:36:55 +00009547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009548s390_irgen_SEB(UChar r1, IRTemp op2addr)
9549{
9550 IRTemp op1 = newTemp(Ity_F32);
9551 IRTemp op2 = newTemp(Ity_F32);
9552 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009553 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009554
9555 assign(op1, get_fpr_w0(r1));
9556 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009557 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009558 mkexpr(op2)));
9559 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9560 put_fpr_w0(r1, mkexpr(result));
9561
9562 return "seb";
9563}
9564
florian55085f82012-11-21 00:36:55 +00009565static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009566s390_irgen_SDB(UChar r1, IRTemp op2addr)
9567{
9568 IRTemp op1 = newTemp(Ity_F64);
9569 IRTemp op2 = newTemp(Ity_F64);
9570 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009571 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009572
9573 assign(op1, get_fpr_dw0(r1));
9574 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009575 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009576 mkexpr(op2)));
9577 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9578 put_fpr_dw0(r1, mkexpr(result));
9579
9580 return "sdb";
9581}
9582
florian55085f82012-11-21 00:36:55 +00009583static const HChar *
florian12390202012-11-10 22:34:14 +00009584s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9585{
9586 IRTemp op1 = newTemp(Ity_D64);
9587 IRTemp op2 = newTemp(Ity_D64);
9588 IRTemp result = newTemp(Ity_D64);
9589 IRTemp rounding_mode;
9590
9591 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009592
9593 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9594 emulation_warning(EmWarn_S390X_fpext_rounding);
9595 m4 = S390_DFP_ROUND_PER_FPC_0;
9596 }
9597
florian12390202012-11-10 22:34:14 +00009598 rounding_mode = encode_dfp_rounding_mode(m4);
9599 assign(op1, get_dpr_dw0(r2));
9600 assign(op2, get_dpr_dw0(r3));
9601 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9602 mkexpr(op2)));
9603 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9604 put_dpr_dw0(r1, mkexpr(result));
9605
9606 return (m4 == 0) ? "adtr" : "adtra";
9607}
9608
florian55085f82012-11-21 00:36:55 +00009609static const HChar *
floriane38f6412012-12-21 17:32:12 +00009610s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9611{
9612 IRTemp op1 = newTemp(Ity_D128);
9613 IRTemp op2 = newTemp(Ity_D128);
9614 IRTemp result = newTemp(Ity_D128);
9615 IRTemp rounding_mode;
9616
9617 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009618
9619 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9620 emulation_warning(EmWarn_S390X_fpext_rounding);
9621 m4 = S390_DFP_ROUND_PER_FPC_0;
9622 }
9623
floriane38f6412012-12-21 17:32:12 +00009624 rounding_mode = encode_dfp_rounding_mode(m4);
9625 assign(op1, get_dpr_pair(r2));
9626 assign(op2, get_dpr_pair(r3));
9627 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9628 mkexpr(op2)));
9629 put_dpr_pair(r1, mkexpr(result));
9630
9631 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9632
9633 return (m4 == 0) ? "axtr" : "axtra";
9634}
9635
9636static const HChar *
9637s390_irgen_CDTR(UChar r1, UChar r2)
9638{
9639 IRTemp op1 = newTemp(Ity_D64);
9640 IRTemp op2 = newTemp(Ity_D64);
9641 IRTemp cc_vex = newTemp(Ity_I32);
9642 IRTemp cc_s390 = newTemp(Ity_I32);
9643
9644 assign(op1, get_dpr_dw0(r1));
9645 assign(op2, get_dpr_dw0(r2));
9646 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9647
florian2d3d87f2012-12-21 21:05:17 +00009648 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009649 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9650
9651 return "cdtr";
9652}
9653
9654static const HChar *
9655s390_irgen_CXTR(UChar r1, UChar r2)
9656{
9657 IRTemp op1 = newTemp(Ity_D128);
9658 IRTemp op2 = newTemp(Ity_D128);
9659 IRTemp cc_vex = newTemp(Ity_I32);
9660 IRTemp cc_s390 = newTemp(Ity_I32);
9661
9662 assign(op1, get_dpr_pair(r1));
9663 assign(op2, get_dpr_pair(r2));
9664 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9665
florian2d3d87f2012-12-21 21:05:17 +00009666 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009667 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9668
9669 return "cxtr";
9670}
9671
9672static const HChar *
florian5f034622013-01-13 02:29:05 +00009673s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9674 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9675{
9676 vassert(s390_host_has_dfp);
9677
9678 if (! s390_host_has_fpext) {
9679 emulation_failure(EmFail_S390X_fpext);
9680 } else {
9681 IRTemp op2 = newTemp(Ity_I32);
9682
9683 assign(op2, get_gpr_w1(r2));
9684 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9685 }
9686 return "cdftr";
9687}
9688
9689static const HChar *
9690s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9691 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9692{
9693 vassert(s390_host_has_dfp);
9694
9695 if (! s390_host_has_fpext) {
9696 emulation_failure(EmFail_S390X_fpext);
9697 } else {
9698 IRTemp op2 = newTemp(Ity_I32);
9699
9700 assign(op2, get_gpr_w1(r2));
9701 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9702 }
9703 return "cxftr";
9704}
9705
9706static const HChar *
floriana887acd2013-02-08 23:32:54 +00009707s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9708 UChar r1, UChar r2)
9709{
9710 IRTemp op2 = newTemp(Ity_I64);
9711
9712 vassert(s390_host_has_dfp);
9713 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9714 emulation_warning(EmWarn_S390X_fpext_rounding);
9715 m3 = S390_DFP_ROUND_PER_FPC_0;
9716 }
9717
9718 assign(op2, get_gpr_dw0(r2));
9719 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9720 mkexpr(op2)));
9721
9722 return (m3 == 0) ? "cdgtr" : "cdgtra";
9723}
9724
9725static const HChar *
9726s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9727 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9728{
9729 IRTemp op2 = newTemp(Ity_I64);
9730
9731 vassert(s390_host_has_dfp);
9732
florian1bb7f6f2013-02-11 00:03:27 +00009733 /* No emulation warning here about an non-zero m3 on hosts without
9734 floating point extension facility. No rounding is performed */
9735
floriana887acd2013-02-08 23:32:54 +00009736 assign(op2, get_gpr_dw0(r2));
9737 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9738
9739 return "cxgtr";
9740}
9741
9742static const HChar *
florian5f034622013-01-13 02:29:05 +00009743s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9744 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9745{
9746 vassert(s390_host_has_dfp);
9747
9748 if (! s390_host_has_fpext) {
9749 emulation_failure(EmFail_S390X_fpext);
9750 } else {
9751 IRTemp op2 = newTemp(Ity_I32);
9752
9753 assign(op2, get_gpr_w1(r2));
9754 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9755 }
9756 return "cdlftr";
9757}
9758
9759static const HChar *
9760s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9761 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9762{
9763 vassert(s390_host_has_dfp);
9764
9765 if (! s390_host_has_fpext) {
9766 emulation_failure(EmFail_S390X_fpext);
9767 } else {
9768 IRTemp op2 = newTemp(Ity_I32);
9769
9770 assign(op2, get_gpr_w1(r2));
9771 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9772 }
9773 return "cxlftr";
9774}
9775
9776static const HChar *
9777s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9778 UChar r1, UChar r2)
9779{
9780 vassert(s390_host_has_dfp);
9781
9782 if (! s390_host_has_fpext) {
9783 emulation_failure(EmFail_S390X_fpext);
9784 } else {
9785 IRTemp op2 = newTemp(Ity_I64);
9786
9787 assign(op2, get_gpr_dw0(r2));
9788 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9789 mkexpr(encode_dfp_rounding_mode(m3)),
9790 mkexpr(op2)));
9791 }
9792 return "cdlgtr";
9793}
9794
9795static const HChar *
9796s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9797 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9798{
9799 vassert(s390_host_has_dfp);
9800
9801 if (! s390_host_has_fpext) {
9802 emulation_failure(EmFail_S390X_fpext);
9803 } else {
9804 IRTemp op2 = newTemp(Ity_I64);
9805
9806 assign(op2, get_gpr_dw0(r2));
9807 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9808 }
9809 return "cxlgtr";
9810}
9811
9812static const HChar *
9813s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9814 UChar r1, UChar r2)
9815{
9816 vassert(s390_host_has_dfp);
9817
9818 if (! s390_host_has_fpext) {
9819 emulation_failure(EmFail_S390X_fpext);
9820 } else {
9821 IRTemp op = newTemp(Ity_D64);
9822 IRTemp result = newTemp(Ity_I32);
9823 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9824
9825 assign(op, get_dpr_dw0(r2));
9826 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9827 mkexpr(op)));
9828 put_gpr_w1(r1, mkexpr(result));
9829 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9830 }
9831 return "cfdtr";
9832}
9833
9834static const HChar *
9835s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9836 UChar r1, UChar r2)
9837{
9838 vassert(s390_host_has_dfp);
9839
9840 if (! s390_host_has_fpext) {
9841 emulation_failure(EmFail_S390X_fpext);
9842 } else {
9843 IRTemp op = newTemp(Ity_D128);
9844 IRTemp result = newTemp(Ity_I32);
9845 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9846
9847 assign(op, get_dpr_pair(r2));
9848 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9849 mkexpr(op)));
9850 put_gpr_w1(r1, mkexpr(result));
9851 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9852 }
9853 return "cfxtr";
9854}
9855
9856static const HChar *
floriana887acd2013-02-08 23:32:54 +00009857s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9858 UChar r1, UChar r2)
9859{
9860 IRTemp op = newTemp(Ity_D64);
9861 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9862
9863 vassert(s390_host_has_dfp);
9864
9865 /* If fpext is not installed and m3 is in 1:7,
9866 rounding mode performed is unpredictable */
9867 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9868 emulation_warning(EmWarn_S390X_fpext_rounding);
9869 m3 = S390_DFP_ROUND_PER_FPC_0;
9870 }
9871
9872 assign(op, get_dpr_dw0(r2));
9873 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9874 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9875
9876 return "cgdtr";
9877}
9878
9879static const HChar *
9880s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9881 UChar r1, UChar r2)
9882{
9883 IRTemp op = newTemp(Ity_D128);
9884 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9885
9886 vassert(s390_host_has_dfp);
9887
9888 /* If fpext is not installed and m3 is in 1:7,
9889 rounding mode performed is unpredictable */
9890 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9891 emulation_warning(EmWarn_S390X_fpext_rounding);
9892 m3 = S390_DFP_ROUND_PER_FPC_0;
9893 }
9894 assign(op, get_dpr_pair(r2));
9895 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9896 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9897
9898 return "cgxtr";
9899}
9900
9901static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009902s390_irgen_CEDTR(UChar r1, UChar r2)
9903{
9904 IRTemp op1 = newTemp(Ity_D64);
9905 IRTemp op2 = newTemp(Ity_D64);
9906 IRTemp cc_vex = newTemp(Ity_I32);
9907 IRTemp cc_s390 = newTemp(Ity_I32);
9908
9909 vassert(s390_host_has_dfp);
9910 assign(op1, get_dpr_dw0(r1));
9911 assign(op2, get_dpr_dw0(r2));
9912 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9913
9914 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9915 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9916
9917 return "cedtr";
9918}
9919
9920static const HChar *
9921s390_irgen_CEXTR(UChar r1, UChar r2)
9922{
9923 IRTemp op1 = newTemp(Ity_D128);
9924 IRTemp op2 = newTemp(Ity_D128);
9925 IRTemp cc_vex = newTemp(Ity_I32);
9926 IRTemp cc_s390 = newTemp(Ity_I32);
9927
9928 vassert(s390_host_has_dfp);
9929 assign(op1, get_dpr_pair(r1));
9930 assign(op2, get_dpr_pair(r2));
9931 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9932
9933 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9934 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9935
9936 return "cextr";
9937}
9938
9939static const HChar *
florian5f034622013-01-13 02:29:05 +00009940s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9941 UChar r1, UChar r2)
9942{
9943 vassert(s390_host_has_dfp);
9944
9945 if (! s390_host_has_fpext) {
9946 emulation_failure(EmFail_S390X_fpext);
9947 } else {
9948 IRTemp op = newTemp(Ity_D64);
9949 IRTemp result = newTemp(Ity_I32);
9950 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9951
9952 assign(op, get_dpr_dw0(r2));
9953 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9954 mkexpr(op)));
9955 put_gpr_w1(r1, mkexpr(result));
9956 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9957 }
9958 return "clfdtr";
9959}
9960
9961static const HChar *
9962s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9963 UChar r1, UChar r2)
9964{
9965 vassert(s390_host_has_dfp);
9966
9967 if (! s390_host_has_fpext) {
9968 emulation_failure(EmFail_S390X_fpext);
9969 } else {
9970 IRTemp op = newTemp(Ity_D128);
9971 IRTemp result = newTemp(Ity_I32);
9972 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9973
9974 assign(op, get_dpr_pair(r2));
9975 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9976 mkexpr(op)));
9977 put_gpr_w1(r1, mkexpr(result));
9978 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9979 }
9980 return "clfxtr";
9981}
9982
9983static const HChar *
9984s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9985 UChar r1, UChar r2)
9986{
9987 vassert(s390_host_has_dfp);
9988
9989 if (! s390_host_has_fpext) {
9990 emulation_failure(EmFail_S390X_fpext);
9991 } else {
9992 IRTemp op = newTemp(Ity_D64);
9993 IRTemp result = newTemp(Ity_I64);
9994 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9995
9996 assign(op, get_dpr_dw0(r2));
9997 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
9998 mkexpr(op)));
9999 put_gpr_dw0(r1, mkexpr(result));
10000 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
10001 }
10002 return "clgdtr";
10003}
10004
10005static const HChar *
10006s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
10007 UChar r1, UChar r2)
10008{
10009 vassert(s390_host_has_dfp);
10010
10011 if (! s390_host_has_fpext) {
10012 emulation_failure(EmFail_S390X_fpext);
10013 } else {
10014 IRTemp op = newTemp(Ity_D128);
10015 IRTemp result = newTemp(Ity_I64);
10016 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
10017
10018 assign(op, get_dpr_pair(r2));
10019 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
10020 mkexpr(op)));
10021 put_gpr_dw0(r1, mkexpr(result));
10022 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
10023 rounding_mode);
10024 }
10025 return "clgxtr";
10026}
10027
10028static const HChar *
florian12390202012-11-10 22:34:14 +000010029s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10030{
10031 IRTemp op1 = newTemp(Ity_D64);
10032 IRTemp op2 = newTemp(Ity_D64);
10033 IRTemp result = newTemp(Ity_D64);
10034 IRTemp rounding_mode;
10035
10036 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010037
10038 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10039 emulation_warning(EmWarn_S390X_fpext_rounding);
10040 m4 = S390_DFP_ROUND_PER_FPC_0;
10041 }
10042
florian12390202012-11-10 22:34:14 +000010043 rounding_mode = encode_dfp_rounding_mode(m4);
10044 assign(op1, get_dpr_dw0(r2));
10045 assign(op2, get_dpr_dw0(r3));
10046 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
10047 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010048 put_dpr_dw0(r1, mkexpr(result));
10049
10050 return (m4 == 0) ? "ddtr" : "ddtra";
10051}
10052
florian55085f82012-11-21 00:36:55 +000010053static const HChar *
floriane38f6412012-12-21 17:32:12 +000010054s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10055{
10056 IRTemp op1 = newTemp(Ity_D128);
10057 IRTemp op2 = newTemp(Ity_D128);
10058 IRTemp result = newTemp(Ity_D128);
10059 IRTemp rounding_mode;
10060
10061 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010062
10063 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10064 emulation_warning(EmWarn_S390X_fpext_rounding);
10065 m4 = S390_DFP_ROUND_PER_FPC_0;
10066 }
10067
floriane38f6412012-12-21 17:32:12 +000010068 rounding_mode = encode_dfp_rounding_mode(m4);
10069 assign(op1, get_dpr_pair(r2));
10070 assign(op2, get_dpr_pair(r3));
10071 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
10072 mkexpr(op2)));
10073 put_dpr_pair(r1, mkexpr(result));
10074
10075 return (m4 == 0) ? "dxtr" : "dxtra";
10076}
10077
10078static const HChar *
florian5c539732013-02-14 14:27:12 +000010079s390_irgen_EEDTR(UChar r1, UChar r2)
10080{
10081 vassert(s390_host_has_dfp);
10082
10083 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
10084 return "eedtr";
10085}
10086
10087static const HChar *
10088s390_irgen_EEXTR(UChar r1, UChar r2)
10089{
10090 vassert(s390_host_has_dfp);
10091
10092 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
10093 return "eextr";
10094}
10095
10096static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010097s390_irgen_ESDTR(UChar r1, UChar r2)
10098{
10099 vassert(s390_host_has_dfp);
10100 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
10101 return "esdtr";
10102}
10103
10104static const HChar *
10105s390_irgen_ESXTR(UChar r1, UChar r2)
10106{
10107 vassert(s390_host_has_dfp);
10108 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
10109 return "esxtr";
10110}
10111
10112static const HChar *
florian5c539732013-02-14 14:27:12 +000010113s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
10114{
10115 IRTemp op1 = newTemp(Ity_I64);
10116 IRTemp op2 = newTemp(Ity_D64);
10117 IRTemp result = newTemp(Ity_D64);
10118
10119 vassert(s390_host_has_dfp);
10120
10121 assign(op1, get_gpr_dw0(r2));
10122 assign(op2, get_dpr_dw0(r3));
10123 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
10124 put_dpr_dw0(r1, mkexpr(result));
10125
10126 return "iedtr";
10127}
10128
10129static const HChar *
10130s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
10131{
10132 IRTemp op1 = newTemp(Ity_I64);
10133 IRTemp op2 = newTemp(Ity_D128);
10134 IRTemp result = newTemp(Ity_D128);
10135
10136 vassert(s390_host_has_dfp);
10137
10138 assign(op1, get_gpr_dw0(r2));
10139 assign(op2, get_dpr_pair(r3));
10140 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
10141 put_dpr_pair(r1, mkexpr(result));
10142
10143 return "iextr";
10144}
10145
10146static const HChar *
floriane38f6412012-12-21 17:32:12 +000010147s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10148{
10149 IRTemp op = newTemp(Ity_D32);
10150
10151 vassert(s390_host_has_dfp);
10152
10153 assign(op, get_dpr_w0(r2));
10154 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
10155
10156 return "ldetr";
10157}
10158
10159static const HChar *
10160s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
10161{
10162 IRTemp op = newTemp(Ity_D64);
10163
10164 assign(op, get_dpr_dw0(r2));
10165 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
10166
10167 return "lxdtr";
10168}
10169
10170static const HChar *
10171s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
10172 UChar r1, UChar r2)
10173{
10174 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010175
10176 /* If fpext is not installed and m3 is in 1:7,
10177 rounding mode performed is unpredictable */
10178 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010179 emulation_warning(EmWarn_S390X_fpext_rounding);
10180 m3 = S390_DFP_ROUND_PER_FPC_0;
10181 }
10182 IRTemp result = newTemp(Ity_D64);
10183
10184 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
10185 get_dpr_pair(r2)));
10186 put_dpr_dw0(r1, mkexpr(result));
10187
10188 return "ldxtr";
10189}
10190
10191static const HChar *
10192s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
10193 UChar r1, UChar r2)
10194{
10195 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010196
10197 /* If fpext is not installed and m3 is in 1:7,
10198 rounding mode performed is unpredictable */
10199 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +000010200 emulation_warning(EmWarn_S390X_fpext_rounding);
10201 m3 = S390_DFP_ROUND_PER_FPC_0;
10202 }
10203 IRTemp op = newTemp(Ity_D64);
10204
10205 assign(op, get_dpr_dw0(r2));
10206 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
10207 mkexpr(op)));
10208
10209 return "ledtr";
10210}
10211
10212static const HChar *
10213s390_irgen_LTDTR(UChar r1, UChar r2)
10214{
10215 IRTemp result = newTemp(Ity_D64);
10216
10217 assign(result, get_dpr_dw0(r2));
10218 put_dpr_dw0(r1, mkexpr(result));
10219 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10220
10221 return "ltdtr";
10222}
10223
10224static const HChar *
10225s390_irgen_LTXTR(UChar r1, UChar r2)
10226{
10227 IRTemp result = newTemp(Ity_D128);
10228
10229 assign(result, get_dpr_pair(r2));
10230 put_dpr_pair(r1, mkexpr(result));
10231 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10232
10233 return "ltxtr";
10234}
10235
10236static const HChar *
florian12390202012-11-10 22:34:14 +000010237s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10238{
10239 IRTemp op1 = newTemp(Ity_D64);
10240 IRTemp op2 = newTemp(Ity_D64);
10241 IRTemp result = newTemp(Ity_D64);
10242 IRTemp rounding_mode;
10243
10244 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010245
10246 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10247 emulation_warning(EmWarn_S390X_fpext_rounding);
10248 m4 = S390_DFP_ROUND_PER_FPC_0;
10249 }
10250
florian12390202012-11-10 22:34:14 +000010251 rounding_mode = encode_dfp_rounding_mode(m4);
10252 assign(op1, get_dpr_dw0(r2));
10253 assign(op2, get_dpr_dw0(r3));
10254 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
10255 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +000010256 put_dpr_dw0(r1, mkexpr(result));
10257
10258 return (m4 == 0) ? "mdtr" : "mdtra";
10259}
10260
florian55085f82012-11-21 00:36:55 +000010261static const HChar *
floriane38f6412012-12-21 17:32:12 +000010262s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10263{
10264 IRTemp op1 = newTemp(Ity_D128);
10265 IRTemp op2 = newTemp(Ity_D128);
10266 IRTemp result = newTemp(Ity_D128);
10267 IRTemp rounding_mode;
10268
10269 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010270
10271 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10272 emulation_warning(EmWarn_S390X_fpext_rounding);
10273 m4 = S390_DFP_ROUND_PER_FPC_0;
10274 }
10275
floriane38f6412012-12-21 17:32:12 +000010276 rounding_mode = encode_dfp_rounding_mode(m4);
10277 assign(op1, get_dpr_pair(r2));
10278 assign(op2, get_dpr_pair(r3));
10279 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
10280 mkexpr(op2)));
10281 put_dpr_pair(r1, mkexpr(result));
10282
10283 return (m4 == 0) ? "mxtr" : "mxtra";
10284}
10285
10286static const HChar *
florian5c539732013-02-14 14:27:12 +000010287s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
10288{
10289 IRTemp op1 = newTemp(Ity_D64);
10290 IRTemp op2 = newTemp(Ity_D64);
10291 IRTemp result = newTemp(Ity_D64);
10292 IRTemp rounding_mode;
10293
10294 vassert(s390_host_has_dfp);
10295 /* If fpext is not installed and m4 is in 1:7,
10296 rounding mode performed is unpredictable */
10297 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10298 emulation_warning(EmWarn_S390X_fpext_rounding);
10299 m4 = S390_DFP_ROUND_PER_FPC_0;
10300 }
10301
10302 rounding_mode = encode_dfp_rounding_mode(m4);
10303 assign(op1, get_dpr_dw0(r2));
10304 assign(op2, get_dpr_dw0(r3));
10305 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
10306 mkexpr(op2)));
10307 put_dpr_dw0(r1, mkexpr(result));
10308
10309 return "qadtr";
10310}
10311
10312static const HChar *
10313s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10314{
10315 IRTemp op1 = newTemp(Ity_D128);
10316 IRTemp op2 = newTemp(Ity_D128);
10317 IRTemp result = newTemp(Ity_D128);
10318 IRTemp rounding_mode;
10319
10320 vassert(s390_host_has_dfp);
10321 /* If fpext is not installed and m4 is in 1:7,
10322 rounding mode performed is unpredictable */
10323 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10324 emulation_warning(EmWarn_S390X_fpext_rounding);
10325 m4 = S390_DFP_ROUND_PER_FPC_0;
10326 }
10327
10328 rounding_mode = encode_dfp_rounding_mode(m4);
10329 assign(op1, get_dpr_pair(r2));
10330 assign(op2, get_dpr_pair(r3));
10331 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10332 mkexpr(op2)));
10333 put_dpr_pair(r1, mkexpr(result));
10334
10335 return "qaxtr";
10336}
10337
10338static const HChar *
10339s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10340{
10341 IRTemp op1 = newTemp(Ity_I8);
10342 IRTemp op2 = newTemp(Ity_D64);
10343 IRTemp result = newTemp(Ity_D64);
10344 IRTemp rounding_mode;
10345
10346 vassert(s390_host_has_dfp);
10347 /* If fpext is not installed and m4 is in 1:7,
10348 rounding mode performed is unpredictable */
10349 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10350 emulation_warning(EmWarn_S390X_fpext_rounding);
10351 m4 = S390_DFP_ROUND_PER_FPC_0;
10352 }
10353
10354 rounding_mode = encode_dfp_rounding_mode(m4);
10355 assign(op1, get_gpr_b7(r2));
10356 assign(op2, get_dpr_dw0(r3));
10357 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10358 mkexpr(op1), mkexpr(op2)));
10359 put_dpr_dw0(r1, mkexpr(result));
10360
10361 return "rrdtr";
10362}
10363
10364static const HChar *
10365s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10366{
10367 IRTemp op1 = newTemp(Ity_I8);
10368 IRTemp op2 = newTemp(Ity_D128);
10369 IRTemp result = newTemp(Ity_D128);
10370 IRTemp rounding_mode;
10371
10372 vassert(s390_host_has_dfp);
10373 /* If fpext is not installed and m4 is in 1:7,
10374 rounding mode performed is unpredictable */
10375 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10376 emulation_warning(EmWarn_S390X_fpext_rounding);
10377 m4 = S390_DFP_ROUND_PER_FPC_0;
10378 }
10379
10380 rounding_mode = encode_dfp_rounding_mode(m4);
10381 assign(op1, get_gpr_b7(r2));
10382 assign(op2, get_dpr_pair(r3));
10383 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10384 mkexpr(op1), mkexpr(op2)));
10385 put_dpr_pair(r1, mkexpr(result));
10386
10387 return "rrxtr";
10388}
10389
10390static const HChar *
florian12390202012-11-10 22:34:14 +000010391s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10392{
10393 IRTemp op1 = newTemp(Ity_D64);
10394 IRTemp op2 = newTemp(Ity_D64);
10395 IRTemp result = newTemp(Ity_D64);
10396 IRTemp rounding_mode;
10397
10398 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010399
10400 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10401 emulation_warning(EmWarn_S390X_fpext_rounding);
10402 m4 = S390_DFP_ROUND_PER_FPC_0;
10403 }
10404
florian12390202012-11-10 22:34:14 +000010405 rounding_mode = encode_dfp_rounding_mode(m4);
10406 assign(op1, get_dpr_dw0(r2));
10407 assign(op2, get_dpr_dw0(r3));
10408 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10409 mkexpr(op2)));
10410 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10411 put_dpr_dw0(r1, mkexpr(result));
10412
10413 return (m4 == 0) ? "sdtr" : "sdtra";
10414}
10415
floriane38f6412012-12-21 17:32:12 +000010416static const HChar *
10417s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10418{
10419 IRTemp op1 = newTemp(Ity_D128);
10420 IRTemp op2 = newTemp(Ity_D128);
10421 IRTemp result = newTemp(Ity_D128);
10422 IRTemp rounding_mode;
10423
10424 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010425
10426 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10427 emulation_warning(EmWarn_S390X_fpext_rounding);
10428 m4 = S390_DFP_ROUND_PER_FPC_0;
10429 }
10430
floriane38f6412012-12-21 17:32:12 +000010431 rounding_mode = encode_dfp_rounding_mode(m4);
10432 assign(op1, get_dpr_pair(r2));
10433 assign(op2, get_dpr_pair(r3));
10434 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10435 mkexpr(op2)));
10436 put_dpr_pair(r1, mkexpr(result));
10437
10438 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10439
10440 return (m4 == 0) ? "sxtr" : "sxtra";
10441}
sewardj2019a972011-03-07 16:04:07 +000010442
florian55085f82012-11-21 00:36:55 +000010443static const HChar *
florian1b901d42013-01-01 22:19:24 +000010444s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10445{
10446 IRTemp op = newTemp(Ity_D64);
10447
10448 vassert(s390_host_has_dfp);
10449
10450 assign(op, get_dpr_dw0(r3));
10451 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
10452 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10453
10454 return "sldt";
10455}
10456
10457static const HChar *
10458s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10459{
10460 IRTemp op = newTemp(Ity_D128);
10461
10462 vassert(s390_host_has_dfp);
10463
10464 assign(op, get_dpr_pair(r3));
10465 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
10466 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10467
10468 return "slxt";
10469}
10470
10471static const HChar *
10472s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10473{
10474 IRTemp op = newTemp(Ity_D64);
10475
10476 vassert(s390_host_has_dfp);
10477
10478 assign(op, get_dpr_dw0(r3));
10479 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
10480 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10481
10482 return "srdt";
10483}
10484
10485static const HChar *
10486s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10487{
10488 IRTemp op = newTemp(Ity_D128);
10489
10490 vassert(s390_host_has_dfp);
10491
10492 assign(op, get_dpr_pair(r3));
10493 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
10494 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10495
10496 return "srxt";
10497}
10498
10499static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010500s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10501{
10502 IRTemp value = newTemp(Ity_D32);
10503
10504 vassert(s390_host_has_dfp);
10505 assign(value, get_dpr_w0(r1));
10506
10507 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10508
10509 return "tdcet";
10510}
10511
10512static const HChar *
10513s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10514{
10515 IRTemp value = newTemp(Ity_D64);
10516
10517 vassert(s390_host_has_dfp);
10518 assign(value, get_dpr_dw0(r1));
10519
10520 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10521
10522 return "tdcdt";
10523}
10524
10525static const HChar *
10526s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10527{
10528 IRTemp value = newTemp(Ity_D128);
10529
10530 vassert(s390_host_has_dfp);
10531 assign(value, get_dpr_pair(r1));
10532
10533 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10534
10535 return "tdcxt";
10536}
10537
10538static const HChar *
10539s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10540{
10541 IRTemp value = newTemp(Ity_D32);
10542
10543 vassert(s390_host_has_dfp);
10544 assign(value, get_dpr_w0(r1));
10545
10546 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10547
10548 return "tdget";
10549}
10550
10551static const HChar *
10552s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10553{
10554 IRTemp value = newTemp(Ity_D64);
10555
10556 vassert(s390_host_has_dfp);
10557 assign(value, get_dpr_dw0(r1));
10558
10559 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10560
10561 return "tdgdt";
10562}
10563
10564static const HChar *
10565s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10566{
10567 IRTemp value = newTemp(Ity_D128);
10568
10569 vassert(s390_host_has_dfp);
10570 assign(value, get_dpr_pair(r1));
10571
10572 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10573
10574 return "tdgxt";
10575}
10576
10577static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010578s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10579{
florian79e839e2012-05-05 02:20:30 +000010580 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010581
florian79e839e2012-05-05 02:20:30 +000010582 assign(len, mkU64(length));
10583 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010584
10585 return "clc";
10586}
10587
florian55085f82012-11-21 00:36:55 +000010588static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010589s390_irgen_CLCL(UChar r1, UChar r2)
10590{
10591 IRTemp addr1 = newTemp(Ity_I64);
10592 IRTemp addr2 = newTemp(Ity_I64);
10593 IRTemp addr1_load = newTemp(Ity_I64);
10594 IRTemp addr2_load = newTemp(Ity_I64);
10595 IRTemp len1 = newTemp(Ity_I32);
10596 IRTemp len2 = newTemp(Ity_I32);
10597 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10598 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10599 IRTemp single1 = newTemp(Ity_I8);
10600 IRTemp single2 = newTemp(Ity_I8);
10601 IRTemp pad = newTemp(Ity_I8);
10602
10603 assign(addr1, get_gpr_dw0(r1));
10604 assign(r1p1, get_gpr_w1(r1 + 1));
10605 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10606 assign(addr2, get_gpr_dw0(r2));
10607 assign(r2p1, get_gpr_w1(r2 + 1));
10608 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10609 assign(pad, get_gpr_b4(r2 + 1));
10610
10611 /* len1 == 0 and len2 == 0? Exit */
10612 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010613 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10614 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010615
10616 /* Because mkite evaluates both the then-clause and the else-clause
10617 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10618 may be NULL and loading from there would segfault. So we provide a
10619 valid dummy address in that case. Loading from there does no harm and
10620 the value will be discarded at runtime. */
10621 assign(addr1_load,
10622 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10623 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10624 assign(single1,
10625 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10626 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10627
10628 assign(addr2_load,
10629 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10630 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10631 assign(single2,
10632 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10633 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10634
10635 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10636 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010637 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010638
10639 /* Update len1 and addr1, unless len1 == 0. */
10640 put_gpr_dw0(r1,
10641 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10642 mkexpr(addr1),
10643 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10644
10645 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10646 put_gpr_w1(r1 + 1,
10647 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10648 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10649 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10650
10651 /* Update len2 and addr2, unless len2 == 0. */
10652 put_gpr_dw0(r2,
10653 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10654 mkexpr(addr2),
10655 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10656
10657 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10658 put_gpr_w1(r2 + 1,
10659 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10660 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10661 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10662
florian6820ba52012-07-26 02:01:50 +000010663 iterate();
florianb0c9a132011-09-08 15:37:39 +000010664
10665 return "clcl";
10666}
10667
florian55085f82012-11-21 00:36:55 +000010668static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010669s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10670{
10671 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10672
10673 addr1 = newTemp(Ity_I64);
10674 addr3 = newTemp(Ity_I64);
10675 addr1_load = newTemp(Ity_I64);
10676 addr3_load = newTemp(Ity_I64);
10677 len1 = newTemp(Ity_I64);
10678 len3 = newTemp(Ity_I64);
10679 single1 = newTemp(Ity_I8);
10680 single3 = newTemp(Ity_I8);
10681
10682 assign(addr1, get_gpr_dw0(r1));
10683 assign(len1, get_gpr_dw0(r1 + 1));
10684 assign(addr3, get_gpr_dw0(r3));
10685 assign(len3, get_gpr_dw0(r3 + 1));
10686
10687 /* len1 == 0 and len3 == 0? Exit */
10688 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010689 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10690 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010691
10692 /* A mux requires both ways to be possible. This is a way to prevent clcle
10693 from reading from addr1 if it should read from the pad. Since the pad
10694 has no address, just read from the instruction, we discard that anyway */
10695 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010696 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10697 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010698
10699 /* same for addr3 */
10700 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010701 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10702 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010703
10704 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010705 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10706 unop(Iop_64to8, mkexpr(pad2)),
10707 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010708
10709 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010710 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10711 unop(Iop_64to8, mkexpr(pad2)),
10712 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010713
10714 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10715 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010716 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010717
10718 /* If a length in 0 we must not change this length and the address */
10719 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010720 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10721 mkexpr(addr1),
10722 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010723
10724 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010725 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10726 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010727
10728 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010729 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10730 mkexpr(addr3),
10731 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010732
10733 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010734 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10735 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010736
florian6820ba52012-07-26 02:01:50 +000010737 iterate();
sewardj2019a972011-03-07 16:04:07 +000010738
10739 return "clcle";
10740}
floriana64c2432011-07-16 02:11:50 +000010741
florianb0bf6602012-05-05 00:01:16 +000010742
sewardj2019a972011-03-07 16:04:07 +000010743static void
10744s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10745{
florianb0bf6602012-05-05 00:01:16 +000010746 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10747}
sewardj2019a972011-03-07 16:04:07 +000010748
sewardj2019a972011-03-07 16:04:07 +000010749
florianb0bf6602012-05-05 00:01:16 +000010750static void
10751s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10752{
10753 s390_irgen_xonc(Iop_And8, length, start1, start2);
10754}
sewardj2019a972011-03-07 16:04:07 +000010755
sewardj2019a972011-03-07 16:04:07 +000010756
florianb0bf6602012-05-05 00:01:16 +000010757static void
10758s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10759{
10760 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010761}
10762
10763
10764static void
10765s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10766{
10767 IRTemp current1 = newTemp(Ity_I8);
10768 IRTemp current2 = newTemp(Ity_I8);
10769 IRTemp counter = newTemp(Ity_I64);
10770
10771 assign(counter, get_counter_dw0());
10772 put_counter_dw0(mkU64(0));
10773
10774 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10775 mkexpr(counter))));
10776 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10777 mkexpr(counter))));
10778 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10779 False);
10780
10781 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010782 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010783
10784 /* Check for end of field */
10785 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010786 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010787 put_counter_dw0(mkU64(0));
10788}
10789
10790static void
10791s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10792{
10793 IRTemp counter = newTemp(Ity_I64);
10794
10795 assign(counter, get_counter_dw0());
10796
10797 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10798 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10799
10800 /* Check for end of field */
10801 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010802 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010803 put_counter_dw0(mkU64(0));
10804}
10805
florianf87d4fb2012-05-05 02:55:24 +000010806static void
10807s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10808{
10809 IRTemp op = newTemp(Ity_I8);
10810 IRTemp op1 = newTemp(Ity_I8);
10811 IRTemp result = newTemp(Ity_I64);
10812 IRTemp counter = newTemp(Ity_I64);
10813
10814 assign(counter, get_counter_dw0());
10815
10816 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10817
10818 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10819
10820 assign(op1, load(Ity_I8, mkexpr(result)));
10821 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10822
10823 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010824 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010825 put_counter_dw0(mkU64(0));
10826}
sewardj2019a972011-03-07 16:04:07 +000010827
10828
10829static void
10830s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010831 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010832 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010833{
10834 struct SS {
10835 unsigned int op : 8;
10836 unsigned int l : 8;
10837 unsigned int b1 : 4;
10838 unsigned int d1 : 12;
10839 unsigned int b2 : 4;
10840 unsigned int d2 : 12;
10841 };
10842 union {
10843 struct SS dec;
10844 unsigned long bytes;
10845 } ss;
10846 IRTemp cond;
10847 IRDirty *d;
10848 IRTemp torun;
10849
10850 IRTemp start1 = newTemp(Ity_I64);
10851 IRTemp start2 = newTemp(Ity_I64);
10852 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10853 cond = newTemp(Ity_I1);
10854 torun = newTemp(Ity_I64);
10855
10856 assign(torun, load(Ity_I64, mkexpr(addr2)));
10857 /* Start with a check that the saved code is still correct */
10858 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10859 /* If not, save the new value */
10860 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10861 mkIRExprVec_1(mkexpr(torun)));
10862 d->guard = mkexpr(cond);
10863 stmt(IRStmt_Dirty(d));
10864
10865 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010866 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian428dfdd2012-03-27 03:09:49 +000010867 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000010868 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010869 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010870
10871 ss.bytes = last_execute_target;
10872 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10873 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10874 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10875 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10876 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10877 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10878 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010879
sewardj2019a972011-03-07 16:04:07 +000010880 last_execute_target = 0;
10881}
10882
florian55085f82012-11-21 00:36:55 +000010883static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010884s390_irgen_EX(UChar r1, IRTemp addr2)
10885{
10886 switch(last_execute_target & 0xff00000000000000ULL) {
10887 case 0:
10888 {
10889 /* no code information yet */
10890 IRDirty *d;
10891
10892 /* so safe the code... */
10893 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10894 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10895 stmt(IRStmt_Dirty(d));
10896 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010897 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian428dfdd2012-03-27 03:09:49 +000010898 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000010899 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010900 restart_if(IRExpr_Const(IRConst_U1(True)));
10901
sewardj2019a972011-03-07 16:04:07 +000010902 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010903 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010904 dis_res->whatNext = Dis_StopHere;
sewardj05f5e012014-05-04 10:52:11 +000010905 dis_res->jk_StopHere = Ijk_InvalICache;
sewardj2019a972011-03-07 16:04:07 +000010906 break;
10907 }
10908
10909 case 0xd200000000000000ULL:
10910 /* special case MVC */
10911 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010912 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010913
10914 case 0xd500000000000000ULL:
10915 /* special case CLC */
10916 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010917 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010918
10919 case 0xd700000000000000ULL:
10920 /* special case XC */
10921 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010922 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010923
florianb0bf6602012-05-05 00:01:16 +000010924 case 0xd600000000000000ULL:
10925 /* special case OC */
10926 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010927 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010928
10929 case 0xd400000000000000ULL:
10930 /* special case NC */
10931 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010932 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010933
florianf87d4fb2012-05-05 02:55:24 +000010934 case 0xdc00000000000000ULL:
10935 /* special case TR */
10936 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010937 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010938
sewardj2019a972011-03-07 16:04:07 +000010939 default:
10940 {
10941 /* everything else will get a self checking prefix that also checks the
10942 register content */
10943 IRDirty *d;
10944 UChar *bytes;
10945 IRTemp cond;
10946 IRTemp orperand;
10947 IRTemp torun;
10948
10949 cond = newTemp(Ity_I1);
10950 orperand = newTemp(Ity_I64);
10951 torun = newTemp(Ity_I64);
10952
10953 if (r1 == 0)
10954 assign(orperand, mkU64(0));
10955 else
10956 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10957 /* This code is going to be translated */
10958 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10959 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10960
10961 /* Start with a check that saved code is still correct */
10962 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10963 mkU64(last_execute_target)));
10964 /* If not, save the new value */
10965 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10966 mkIRExprVec_1(mkexpr(torun)));
10967 d->guard = mkexpr(cond);
10968 stmt(IRStmt_Dirty(d));
10969
10970 /* and restart */
sewardj05f5e012014-05-04 10:52:11 +000010971 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART), mkU64(guest_IA_curr_instr)));
10972 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010973 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010974
10975 /* Now comes the actual translation */
10976 bytes = (UChar *) &last_execute_target;
10977 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10978 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010979 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010980 vex_printf(" which was executed by\n");
10981 /* dont make useless translations in the next execute */
10982 last_execute_target = 0;
10983 }
10984 }
10985 return "ex";
10986}
10987
florian55085f82012-11-21 00:36:55 +000010988static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010989s390_irgen_EXRL(UChar r1, UInt offset)
10990{
10991 IRTemp addr = newTemp(Ity_I64);
10992 /* we might save one round trip because we know the target */
10993 if (!last_execute_target)
10994 last_execute_target = *(ULong *)(HWord)
10995 (guest_IA_curr_instr + offset * 2UL);
10996 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10997 s390_irgen_EX(r1, addr);
10998 return "exrl";
10999}
11000
florian55085f82012-11-21 00:36:55 +000011001static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011002s390_irgen_IPM(UChar r1)
11003{
11004 // As long as we dont support SPM, lets just assume 0 as program mask
11005 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
11006 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
11007
11008 return "ipm";
11009}
11010
11011
florian55085f82012-11-21 00:36:55 +000011012static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011013s390_irgen_SRST(UChar r1, UChar r2)
11014{
11015 IRTemp address = newTemp(Ity_I64);
11016 IRTemp next = newTemp(Ity_I64);
11017 IRTemp delim = newTemp(Ity_I8);
11018 IRTemp counter = newTemp(Ity_I64);
11019 IRTemp byte = newTemp(Ity_I8);
11020
11021 assign(address, get_gpr_dw0(r2));
11022 assign(next, get_gpr_dw0(r1));
11023
11024 assign(counter, get_counter_dw0());
11025 put_counter_dw0(mkU64(0));
11026
11027 // start = next? CC=2 and out r1 and r2 unchanged
11028 s390_cc_set(2);
11029 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011030 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000011031
11032 assign(byte, load(Ity_I8, mkexpr(address)));
11033 assign(delim, get_gpr_b7(0));
11034
11035 // byte = delim? CC=1, R1=address
11036 s390_cc_set(1);
11037 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000011038 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011039
11040 // else: all equal, no end yet, loop
11041 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11042 put_gpr_dw0(r1, mkexpr(next));
11043 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011044
florian6820ba52012-07-26 02:01:50 +000011045 iterate();
sewardj2019a972011-03-07 16:04:07 +000011046
11047 return "srst";
11048}
11049
florian55085f82012-11-21 00:36:55 +000011050static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011051s390_irgen_CLST(UChar r1, UChar r2)
11052{
11053 IRTemp address1 = newTemp(Ity_I64);
11054 IRTemp address2 = newTemp(Ity_I64);
11055 IRTemp end = newTemp(Ity_I8);
11056 IRTemp counter = newTemp(Ity_I64);
11057 IRTemp byte1 = newTemp(Ity_I8);
11058 IRTemp byte2 = newTemp(Ity_I8);
11059
11060 assign(address1, get_gpr_dw0(r1));
11061 assign(address2, get_gpr_dw0(r2));
11062 assign(end, get_gpr_b7(0));
11063 assign(counter, get_counter_dw0());
11064 put_counter_dw0(mkU64(0));
11065 assign(byte1, load(Ity_I8, mkexpr(address1)));
11066 assign(byte2, load(Ity_I8, mkexpr(address2)));
11067
11068 // end in both? all equal, reset r1 and r2 to start values
11069 s390_cc_set(0);
11070 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
11071 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000011072 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
11073 binop(Iop_Or8,
11074 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
11075 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000011076
11077 put_gpr_dw0(r1, mkexpr(address1));
11078 put_gpr_dw0(r2, mkexpr(address2));
11079
11080 // End found in string1
11081 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011082 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000011083
11084 // End found in string2
11085 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011086 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000011087
11088 // string1 < string2
11089 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000011090 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
11091 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000011092
11093 // string2 < string1
11094 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000011095 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
11096 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000011097
11098 // else: all equal, no end yet, loop
11099 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
11100 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
11101 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000011102
florian6820ba52012-07-26 02:01:50 +000011103 iterate();
sewardj2019a972011-03-07 16:04:07 +000011104
11105 return "clst";
11106}
11107
11108static void
11109s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11110{
11111 UChar reg;
11112 IRTemp addr = newTemp(Ity_I64);
11113
11114 assign(addr, mkexpr(op2addr));
11115 reg = r1;
11116 do {
11117 IRTemp old = addr;
11118
11119 reg %= 16;
11120 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
11121 addr = newTemp(Ity_I64);
11122 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11123 reg++;
11124 } while (reg != (r3 + 1));
11125}
11126
florian55085f82012-11-21 00:36:55 +000011127static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011128s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
11129{
11130 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11131
11132 return "lm";
11133}
11134
florian55085f82012-11-21 00:36:55 +000011135static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011136s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
11137{
11138 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
11139
11140 return "lmy";
11141}
11142
florian55085f82012-11-21 00:36:55 +000011143static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011144s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
11145{
11146 UChar reg;
11147 IRTemp addr = newTemp(Ity_I64);
11148
11149 assign(addr, mkexpr(op2addr));
11150 reg = r1;
11151 do {
11152 IRTemp old = addr;
11153
11154 reg %= 16;
11155 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
11156 addr = newTemp(Ity_I64);
11157 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11158 reg++;
11159 } while (reg != (r3 + 1));
11160
11161 return "lmh";
11162}
11163
florian55085f82012-11-21 00:36:55 +000011164static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011165s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
11166{
11167 UChar reg;
11168 IRTemp addr = newTemp(Ity_I64);
11169
11170 assign(addr, mkexpr(op2addr));
11171 reg = r1;
11172 do {
11173 IRTemp old = addr;
11174
11175 reg %= 16;
11176 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
11177 addr = newTemp(Ity_I64);
11178 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11179 reg++;
11180 } while (reg != (r3 + 1));
11181
11182 return "lmg";
11183}
11184
11185static void
11186s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
11187{
11188 UChar reg;
11189 IRTemp addr = newTemp(Ity_I64);
11190
11191 assign(addr, mkexpr(op2addr));
11192 reg = r1;
11193 do {
11194 IRTemp old = addr;
11195
11196 reg %= 16;
11197 store(mkexpr(addr), get_gpr_w1(reg));
11198 addr = newTemp(Ity_I64);
11199 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11200 reg++;
11201 } while( reg != (r3 + 1));
11202}
11203
florian55085f82012-11-21 00:36:55 +000011204static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011205s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
11206{
11207 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11208
11209 return "stm";
11210}
11211
florian55085f82012-11-21 00:36:55 +000011212static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011213s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
11214{
11215 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
11216
11217 return "stmy";
11218}
11219
florian55085f82012-11-21 00:36:55 +000011220static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011221s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
11222{
11223 UChar reg;
11224 IRTemp addr = newTemp(Ity_I64);
11225
11226 assign(addr, mkexpr(op2addr));
11227 reg = r1;
11228 do {
11229 IRTemp old = addr;
11230
11231 reg %= 16;
11232 store(mkexpr(addr), get_gpr_w0(reg));
11233 addr = newTemp(Ity_I64);
11234 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11235 reg++;
11236 } while( reg != (r3 + 1));
11237
11238 return "stmh";
11239}
11240
florian55085f82012-11-21 00:36:55 +000011241static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011242s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
11243{
11244 UChar reg;
11245 IRTemp addr = newTemp(Ity_I64);
11246
11247 assign(addr, mkexpr(op2addr));
11248 reg = r1;
11249 do {
11250 IRTemp old = addr;
11251
11252 reg %= 16;
11253 store(mkexpr(addr), get_gpr_dw0(reg));
11254 addr = newTemp(Ity_I64);
11255 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
11256 reg++;
11257 } while( reg != (r3 + 1));
11258
11259 return "stmg";
11260}
11261
11262static void
florianb0bf6602012-05-05 00:01:16 +000011263s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000011264{
11265 IRTemp old1 = newTemp(Ity_I8);
11266 IRTemp old2 = newTemp(Ity_I8);
11267 IRTemp new1 = newTemp(Ity_I8);
11268 IRTemp counter = newTemp(Ity_I32);
11269 IRTemp addr1 = newTemp(Ity_I64);
11270
11271 assign(counter, get_counter_w0());
11272
11273 assign(addr1, binop(Iop_Add64, mkexpr(start1),
11274 unop(Iop_32Uto64, mkexpr(counter))));
11275
11276 assign(old1, load(Ity_I8, mkexpr(addr1)));
11277 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
11278 unop(Iop_32Uto64,mkexpr(counter)))));
11279 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
11280
11281 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000011282 if (op == Iop_Xor8) {
11283 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000011284 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
11285 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000011286 } else
11287 store(mkexpr(addr1), mkexpr(new1));
11288 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
11289 get_counter_w1()));
11290
11291 /* Check for end of field */
11292 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011293 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000011294 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
11295 False);
11296 put_counter_dw0(mkU64(0));
11297}
11298
florian55085f82012-11-21 00:36:55 +000011299static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011300s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
11301{
florianb0bf6602012-05-05 00:01:16 +000011302 IRTemp len = newTemp(Ity_I32);
11303
11304 assign(len, mkU32(length));
11305 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011306
11307 return "xc";
11308}
11309
sewardjb63967e2011-03-24 08:50:04 +000011310static void
11311s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
11312{
11313 IRTemp counter = newTemp(Ity_I32);
11314 IRTemp start = newTemp(Ity_I64);
11315 IRTemp addr = newTemp(Ity_I64);
11316
11317 assign(start,
11318 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11319
11320 if (length < 8) {
11321 UInt i;
11322
11323 for (i = 0; i <= length; ++i) {
11324 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11325 }
11326 } else {
11327 assign(counter, get_counter_w0());
11328
11329 assign(addr, binop(Iop_Add64, mkexpr(start),
11330 unop(Iop_32Uto64, mkexpr(counter))));
11331
11332 store(mkexpr(addr), mkU8(0));
11333
11334 /* Check for end of field */
11335 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011336 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011337
11338 /* Reset counter */
11339 put_counter_dw0(mkU64(0));
11340 }
11341
11342 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11343
sewardj7ee97522011-05-09 21:45:04 +000011344 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011345 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11346}
11347
florian55085f82012-11-21 00:36:55 +000011348static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011349s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11350{
florianb0bf6602012-05-05 00:01:16 +000011351 IRTemp len = newTemp(Ity_I32);
11352
11353 assign(len, mkU32(length));
11354 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011355
11356 return "nc";
11357}
11358
florian55085f82012-11-21 00:36:55 +000011359static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011360s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11361{
florianb0bf6602012-05-05 00:01:16 +000011362 IRTemp len = newTemp(Ity_I32);
11363
11364 assign(len, mkU32(length));
11365 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011366
11367 return "oc";
11368}
11369
11370
florian55085f82012-11-21 00:36:55 +000011371static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011372s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11373{
florian79e839e2012-05-05 02:20:30 +000011374 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011375
florian79e839e2012-05-05 02:20:30 +000011376 assign(len, mkU64(length));
11377 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011378
11379 return "mvc";
11380}
11381
florian55085f82012-11-21 00:36:55 +000011382static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011383s390_irgen_MVCL(UChar r1, UChar r2)
11384{
11385 IRTemp addr1 = newTemp(Ity_I64);
11386 IRTemp addr2 = newTemp(Ity_I64);
11387 IRTemp addr2_load = newTemp(Ity_I64);
11388 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11389 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11390 IRTemp len1 = newTemp(Ity_I32);
11391 IRTemp len2 = newTemp(Ity_I32);
11392 IRTemp pad = newTemp(Ity_I8);
11393 IRTemp single = newTemp(Ity_I8);
11394
11395 assign(addr1, get_gpr_dw0(r1));
11396 assign(r1p1, get_gpr_w1(r1 + 1));
11397 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11398 assign(addr2, get_gpr_dw0(r2));
11399 assign(r2p1, get_gpr_w1(r2 + 1));
11400 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11401 assign(pad, get_gpr_b4(r2 + 1));
11402
11403 /* len1 == 0 ? */
11404 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011405 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011406
11407 /* Check for destructive overlap:
11408 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11409 s390_cc_set(3);
11410 IRTemp cond1 = newTemp(Ity_I32);
11411 assign(cond1, unop(Iop_1Uto32,
11412 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11413 IRTemp cond2 = newTemp(Ity_I32);
11414 assign(cond2, unop(Iop_1Uto32,
11415 binop(Iop_CmpLT64U, mkexpr(addr1),
11416 binop(Iop_Add64, mkexpr(addr2),
11417 unop(Iop_32Uto64, mkexpr(len1))))));
11418 IRTemp cond3 = newTemp(Ity_I32);
11419 assign(cond3, unop(Iop_1Uto32,
11420 binop(Iop_CmpLT64U,
11421 mkexpr(addr1),
11422 binop(Iop_Add64, mkexpr(addr2),
11423 unop(Iop_32Uto64, mkexpr(len2))))));
11424
florian6820ba52012-07-26 02:01:50 +000011425 next_insn_if(binop(Iop_CmpEQ32,
11426 binop(Iop_And32,
11427 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11428 mkexpr(cond3)),
11429 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011430
11431 /* See s390_irgen_CLCL for explanation why we cannot load directly
11432 and need two steps. */
11433 assign(addr2_load,
11434 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11435 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11436 assign(single,
11437 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11438 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11439
11440 store(mkexpr(addr1), mkexpr(single));
11441
11442 /* Update addr1 and len1 */
11443 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11444 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11445
11446 /* Update addr2 and len2 */
11447 put_gpr_dw0(r2,
11448 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11449 mkexpr(addr2),
11450 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11451
11452 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11453 put_gpr_w1(r2 + 1,
11454 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11455 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11456 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11457
11458 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011459 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011460
11461 return "mvcl";
11462}
11463
11464
florian55085f82012-11-21 00:36:55 +000011465static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011466s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11467{
11468 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11469
11470 addr1 = newTemp(Ity_I64);
11471 addr3 = newTemp(Ity_I64);
11472 addr3_load = newTemp(Ity_I64);
11473 len1 = newTemp(Ity_I64);
11474 len3 = newTemp(Ity_I64);
11475 single = newTemp(Ity_I8);
11476
11477 assign(addr1, get_gpr_dw0(r1));
11478 assign(len1, get_gpr_dw0(r1 + 1));
11479 assign(addr3, get_gpr_dw0(r3));
11480 assign(len3, get_gpr_dw0(r3 + 1));
11481
11482 // len1 == 0 ?
11483 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011484 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011485
11486 /* This is a hack to prevent mvcle from reading from addr3 if it
11487 should read from the pad. Since the pad has no address, just
11488 read from the instruction, we discard that anyway */
11489 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011490 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11491 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011492
11493 assign(single,
florian6ad49522011-09-09 02:38:55 +000011494 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11495 unop(Iop_64to8, mkexpr(pad2)),
11496 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011497 store(mkexpr(addr1), mkexpr(single));
11498
11499 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11500
11501 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11502
11503 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011504 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11505 mkexpr(addr3),
11506 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011507
11508 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011509 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11510 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011511
sewardj2019a972011-03-07 16:04:07 +000011512 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011513 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011514
11515 return "mvcle";
11516}
11517
florian55085f82012-11-21 00:36:55 +000011518static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011519s390_irgen_MVST(UChar r1, UChar r2)
11520{
11521 IRTemp addr1 = newTemp(Ity_I64);
11522 IRTemp addr2 = newTemp(Ity_I64);
11523 IRTemp end = newTemp(Ity_I8);
11524 IRTemp byte = newTemp(Ity_I8);
11525 IRTemp counter = newTemp(Ity_I64);
11526
11527 assign(addr1, get_gpr_dw0(r1));
11528 assign(addr2, get_gpr_dw0(r2));
11529 assign(counter, get_counter_dw0());
11530 assign(end, get_gpr_b7(0));
11531 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11532 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11533
11534 // We use unlimited as cpu-determined number
11535 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011536 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011537
11538 // and always set cc=1 at the end + update r1
11539 s390_cc_set(1);
11540 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11541 put_counter_dw0(mkU64(0));
11542
11543 return "mvst";
11544}
11545
11546static void
11547s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11548{
11549 IRTemp op1 = newTemp(Ity_I64);
11550 IRTemp result = newTemp(Ity_I64);
11551
11552 assign(op1, binop(Iop_32HLto64,
11553 get_gpr_w1(r1), // high 32 bits
11554 get_gpr_w1(r1 + 1))); // low 32 bits
11555 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11556 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11557 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11558}
11559
11560static void
11561s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11562{
11563 IRTemp op1 = newTemp(Ity_I128);
11564 IRTemp result = newTemp(Ity_I128);
11565
11566 assign(op1, binop(Iop_64HLto128,
11567 get_gpr_dw0(r1), // high 64 bits
11568 get_gpr_dw0(r1 + 1))); // low 64 bits
11569 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11570 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11571 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11572}
11573
11574static void
11575s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11576{
11577 IRTemp op1 = newTemp(Ity_I64);
11578 IRTemp result = newTemp(Ity_I128);
11579
11580 assign(op1, get_gpr_dw0(r1 + 1));
11581 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11582 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11583 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11584}
11585
florian55085f82012-11-21 00:36:55 +000011586static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011587s390_irgen_DR(UChar r1, UChar r2)
11588{
11589 IRTemp op2 = newTemp(Ity_I32);
11590
11591 assign(op2, get_gpr_w1(r2));
11592
11593 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11594
11595 return "dr";
11596}
11597
florian55085f82012-11-21 00:36:55 +000011598static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011599s390_irgen_D(UChar r1, IRTemp op2addr)
11600{
11601 IRTemp op2 = newTemp(Ity_I32);
11602
11603 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11604
11605 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11606
11607 return "d";
11608}
11609
florian55085f82012-11-21 00:36:55 +000011610static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011611s390_irgen_DLR(UChar r1, UChar r2)
11612{
11613 IRTemp op2 = newTemp(Ity_I32);
11614
11615 assign(op2, get_gpr_w1(r2));
11616
11617 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11618
florian7cd1cde2012-08-16 23:57:43 +000011619 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011620}
11621
florian55085f82012-11-21 00:36:55 +000011622static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011623s390_irgen_DL(UChar r1, IRTemp op2addr)
11624{
11625 IRTemp op2 = newTemp(Ity_I32);
11626
11627 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11628
11629 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11630
11631 return "dl";
11632}
11633
florian55085f82012-11-21 00:36:55 +000011634static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011635s390_irgen_DLG(UChar r1, IRTemp op2addr)
11636{
11637 IRTemp op2 = newTemp(Ity_I64);
11638
11639 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11640
11641 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11642
11643 return "dlg";
11644}
11645
florian55085f82012-11-21 00:36:55 +000011646static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011647s390_irgen_DLGR(UChar r1, UChar r2)
11648{
11649 IRTemp op2 = newTemp(Ity_I64);
11650
11651 assign(op2, get_gpr_dw0(r2));
11652
11653 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11654
11655 return "dlgr";
11656}
11657
florian55085f82012-11-21 00:36:55 +000011658static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011659s390_irgen_DSGR(UChar r1, UChar r2)
11660{
11661 IRTemp op2 = newTemp(Ity_I64);
11662
11663 assign(op2, get_gpr_dw0(r2));
11664
11665 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11666
11667 return "dsgr";
11668}
11669
florian55085f82012-11-21 00:36:55 +000011670static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011671s390_irgen_DSG(UChar r1, IRTemp op2addr)
11672{
11673 IRTemp op2 = newTemp(Ity_I64);
11674
11675 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11676
11677 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11678
11679 return "dsg";
11680}
11681
florian55085f82012-11-21 00:36:55 +000011682static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011683s390_irgen_DSGFR(UChar r1, UChar r2)
11684{
11685 IRTemp op2 = newTemp(Ity_I64);
11686
11687 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11688
11689 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11690
11691 return "dsgfr";
11692}
11693
florian55085f82012-11-21 00:36:55 +000011694static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011695s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11696{
11697 IRTemp op2 = newTemp(Ity_I64);
11698
11699 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11700
11701 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11702
11703 return "dsgf";
11704}
11705
11706static void
11707s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11708{
11709 UChar reg;
11710 IRTemp addr = newTemp(Ity_I64);
11711
11712 assign(addr, mkexpr(op2addr));
11713 reg = r1;
11714 do {
11715 IRTemp old = addr;
11716
11717 reg %= 16;
11718 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11719 addr = newTemp(Ity_I64);
11720 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11721 reg++;
11722 } while (reg != (r3 + 1));
11723}
11724
florian55085f82012-11-21 00:36:55 +000011725static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011726s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11727{
11728 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11729
11730 return "lam";
11731}
11732
florian55085f82012-11-21 00:36:55 +000011733static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011734s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11735{
11736 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11737
11738 return "lamy";
11739}
11740
11741static void
11742s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11743{
11744 UChar reg;
11745 IRTemp addr = newTemp(Ity_I64);
11746
11747 assign(addr, mkexpr(op2addr));
11748 reg = r1;
11749 do {
11750 IRTemp old = addr;
11751
11752 reg %= 16;
11753 store(mkexpr(addr), get_ar_w0(reg));
11754 addr = newTemp(Ity_I64);
11755 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11756 reg++;
11757 } while (reg != (r3 + 1));
11758}
11759
florian55085f82012-11-21 00:36:55 +000011760static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011761s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11762{
11763 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11764
11765 return "stam";
11766}
11767
florian55085f82012-11-21 00:36:55 +000011768static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011769s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11770{
11771 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11772
11773 return "stamy";
11774}
11775
11776
11777/* Implementation for 32-bit compare-and-swap */
11778static void
11779s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11780{
11781 IRCAS *cas;
11782 IRTemp op1 = newTemp(Ity_I32);
11783 IRTemp old_mem = newTemp(Ity_I32);
11784 IRTemp op3 = newTemp(Ity_I32);
11785 IRTemp result = newTemp(Ity_I32);
11786 IRTemp nequal = newTemp(Ity_I1);
11787
11788 assign(op1, get_gpr_w1(r1));
11789 assign(op3, get_gpr_w1(r3));
11790
11791 /* The first and second operands are compared. If they are equal,
11792 the third operand is stored at the second- operand location. */
11793 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11794 Iend_BE, mkexpr(op2addr),
11795 NULL, mkexpr(op1), /* expected value */
11796 NULL, mkexpr(op3) /* new value */);
11797 stmt(IRStmt_CAS(cas));
11798
11799 /* Set CC. Operands compared equal -> 0, else 1. */
11800 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11801 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11802
11803 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11804 Otherwise, store the old_value from memory in r1 and yield. */
11805 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11806 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011807 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011808}
11809
florian55085f82012-11-21 00:36:55 +000011810static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011811s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11812{
11813 s390_irgen_cas_32(r1, r3, op2addr);
11814
11815 return "cs";
11816}
11817
florian55085f82012-11-21 00:36:55 +000011818static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011819s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11820{
11821 s390_irgen_cas_32(r1, r3, op2addr);
11822
11823 return "csy";
11824}
11825
florian55085f82012-11-21 00:36:55 +000011826static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011827s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11828{
11829 IRCAS *cas;
11830 IRTemp op1 = newTemp(Ity_I64);
11831 IRTemp old_mem = newTemp(Ity_I64);
11832 IRTemp op3 = newTemp(Ity_I64);
11833 IRTemp result = newTemp(Ity_I64);
11834 IRTemp nequal = newTemp(Ity_I1);
11835
11836 assign(op1, get_gpr_dw0(r1));
11837 assign(op3, get_gpr_dw0(r3));
11838
11839 /* The first and second operands are compared. If they are equal,
11840 the third operand is stored at the second- operand location. */
11841 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11842 Iend_BE, mkexpr(op2addr),
11843 NULL, mkexpr(op1), /* expected value */
11844 NULL, mkexpr(op3) /* new value */);
11845 stmt(IRStmt_CAS(cas));
11846
11847 /* Set CC. Operands compared equal -> 0, else 1. */
11848 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11849 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11850
11851 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11852 Otherwise, store the old_value from memory in r1 and yield. */
11853 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11854 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011855 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011856
11857 return "csg";
11858}
11859
florian448cbba2012-06-06 02:26:01 +000011860/* Implementation for 32-bit compare-double-and-swap */
11861static void
11862s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11863{
11864 IRCAS *cas;
11865 IRTemp op1_high = newTemp(Ity_I32);
11866 IRTemp op1_low = newTemp(Ity_I32);
11867 IRTemp old_mem_high = newTemp(Ity_I32);
11868 IRTemp old_mem_low = newTemp(Ity_I32);
11869 IRTemp op3_high = newTemp(Ity_I32);
11870 IRTemp op3_low = newTemp(Ity_I32);
11871 IRTemp result = newTemp(Ity_I32);
11872 IRTemp nequal = newTemp(Ity_I1);
11873
11874 assign(op1_high, get_gpr_w1(r1));
11875 assign(op1_low, get_gpr_w1(r1+1));
11876 assign(op3_high, get_gpr_w1(r3));
11877 assign(op3_low, get_gpr_w1(r3+1));
11878
11879 /* The first and second operands are compared. If they are equal,
11880 the third operand is stored at the second-operand location. */
11881 cas = mkIRCAS(old_mem_high, old_mem_low,
11882 Iend_BE, mkexpr(op2addr),
11883 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11884 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11885 stmt(IRStmt_CAS(cas));
11886
11887 /* Set CC. Operands compared equal -> 0, else 1. */
11888 assign(result, unop(Iop_1Uto32,
11889 binop(Iop_CmpNE32,
11890 binop(Iop_Or32,
11891 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11892 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11893 mkU32(0))));
11894
11895 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11896
11897 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11898 Otherwise, store the old_value from memory in r1 and yield. */
11899 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11900 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11901 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011902 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011903}
11904
florian55085f82012-11-21 00:36:55 +000011905static const HChar *
florian448cbba2012-06-06 02:26:01 +000011906s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11907{
11908 s390_irgen_cdas_32(r1, r3, op2addr);
11909
11910 return "cds";
11911}
11912
florian55085f82012-11-21 00:36:55 +000011913static const HChar *
florian448cbba2012-06-06 02:26:01 +000011914s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11915{
11916 s390_irgen_cdas_32(r1, r3, op2addr);
11917
11918 return "cdsy";
11919}
11920
florian55085f82012-11-21 00:36:55 +000011921static const HChar *
florian448cbba2012-06-06 02:26:01 +000011922s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11923{
11924 IRCAS *cas;
11925 IRTemp op1_high = newTemp(Ity_I64);
11926 IRTemp op1_low = newTemp(Ity_I64);
11927 IRTemp old_mem_high = newTemp(Ity_I64);
11928 IRTemp old_mem_low = newTemp(Ity_I64);
11929 IRTemp op3_high = newTemp(Ity_I64);
11930 IRTemp op3_low = newTemp(Ity_I64);
11931 IRTemp result = newTemp(Ity_I64);
11932 IRTemp nequal = newTemp(Ity_I1);
11933
11934 assign(op1_high, get_gpr_dw0(r1));
11935 assign(op1_low, get_gpr_dw0(r1+1));
11936 assign(op3_high, get_gpr_dw0(r3));
11937 assign(op3_low, get_gpr_dw0(r3+1));
11938
11939 /* The first and second operands are compared. If they are equal,
11940 the third operand is stored at the second-operand location. */
11941 cas = mkIRCAS(old_mem_high, old_mem_low,
11942 Iend_BE, mkexpr(op2addr),
11943 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11944 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11945 stmt(IRStmt_CAS(cas));
11946
11947 /* Set CC. Operands compared equal -> 0, else 1. */
11948 assign(result, unop(Iop_1Uto64,
11949 binop(Iop_CmpNE64,
11950 binop(Iop_Or64,
11951 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11952 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11953 mkU64(0))));
11954
11955 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11956
11957 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11958 Otherwise, store the old_value from memory in r1 and yield. */
11959 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11960 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11961 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011962 yield_if(mkexpr(nequal));
11963
florian448cbba2012-06-06 02:26:01 +000011964 return "cdsg";
11965}
11966
sewardj2019a972011-03-07 16:04:07 +000011967
11968/* Binary floating point */
11969
florian55085f82012-11-21 00:36:55 +000011970static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011971s390_irgen_AXBR(UChar r1, UChar r2)
11972{
11973 IRTemp op1 = newTemp(Ity_F128);
11974 IRTemp op2 = newTemp(Ity_F128);
11975 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011976 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011977
11978 assign(op1, get_fpr_pair(r1));
11979 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011980 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011981 mkexpr(op2)));
11982 put_fpr_pair(r1, mkexpr(result));
11983
11984 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11985
11986 return "axbr";
11987}
11988
florian55085f82012-11-21 00:36:55 +000011989static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011990s390_irgen_CEBR(UChar r1, UChar r2)
11991{
11992 IRTemp op1 = newTemp(Ity_F32);
11993 IRTemp op2 = newTemp(Ity_F32);
11994 IRTemp cc_vex = newTemp(Ity_I32);
11995 IRTemp cc_s390 = newTemp(Ity_I32);
11996
11997 assign(op1, get_fpr_w0(r1));
11998 assign(op2, get_fpr_w0(r2));
11999 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12000
florian2d3d87f2012-12-21 21:05:17 +000012001 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012002 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12003
12004 return "cebr";
12005}
12006
florian55085f82012-11-21 00:36:55 +000012007static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012008s390_irgen_CDBR(UChar r1, UChar r2)
12009{
12010 IRTemp op1 = newTemp(Ity_F64);
12011 IRTemp op2 = newTemp(Ity_F64);
12012 IRTemp cc_vex = newTemp(Ity_I32);
12013 IRTemp cc_s390 = newTemp(Ity_I32);
12014
12015 assign(op1, get_fpr_dw0(r1));
12016 assign(op2, get_fpr_dw0(r2));
12017 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12018
florian2d3d87f2012-12-21 21:05:17 +000012019 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012020 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12021
12022 return "cdbr";
12023}
12024
florian55085f82012-11-21 00:36:55 +000012025static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012026s390_irgen_CXBR(UChar r1, UChar r2)
12027{
12028 IRTemp op1 = newTemp(Ity_F128);
12029 IRTemp op2 = newTemp(Ity_F128);
12030 IRTemp cc_vex = newTemp(Ity_I32);
12031 IRTemp cc_s390 = newTemp(Ity_I32);
12032
12033 assign(op1, get_fpr_pair(r1));
12034 assign(op2, get_fpr_pair(r2));
12035 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
12036
florian2d3d87f2012-12-21 21:05:17 +000012037 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012038 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12039
12040 return "cxbr";
12041}
12042
florian55085f82012-11-21 00:36:55 +000012043static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012044s390_irgen_CEB(UChar r1, IRTemp op2addr)
12045{
12046 IRTemp op1 = newTemp(Ity_F32);
12047 IRTemp op2 = newTemp(Ity_F32);
12048 IRTemp cc_vex = newTemp(Ity_I32);
12049 IRTemp cc_s390 = newTemp(Ity_I32);
12050
12051 assign(op1, get_fpr_w0(r1));
12052 assign(op2, load(Ity_F32, mkexpr(op2addr)));
12053 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
12054
florian2d3d87f2012-12-21 21:05:17 +000012055 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012056 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12057
12058 return "ceb";
12059}
12060
florian55085f82012-11-21 00:36:55 +000012061static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012062s390_irgen_CDB(UChar r1, IRTemp op2addr)
12063{
12064 IRTemp op1 = newTemp(Ity_F64);
12065 IRTemp op2 = newTemp(Ity_F64);
12066 IRTemp cc_vex = newTemp(Ity_I32);
12067 IRTemp cc_s390 = newTemp(Ity_I32);
12068
12069 assign(op1, get_fpr_dw0(r1));
12070 assign(op2, load(Ity_F64, mkexpr(op2addr)));
12071 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
12072
florian2d3d87f2012-12-21 21:05:17 +000012073 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000012074 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
12075
12076 return "cdb";
12077}
12078
florian55085f82012-11-21 00:36:55 +000012079static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012080s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
12081 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012082{
12083 IRTemp op2 = newTemp(Ity_I32);
12084
12085 assign(op2, get_gpr_w1(r2));
12086 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
12087
12088 return "cxfbr";
12089}
12090
florian55085f82012-11-21 00:36:55 +000012091static const HChar *
floriand2129202012-09-01 20:01:39 +000012092s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
12093 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012094{
floriane75dafa2012-09-01 17:54:09 +000012095 if (! s390_host_has_fpext) {
12096 emulation_failure(EmFail_S390X_fpext);
12097 } else {
12098 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000012099
floriane75dafa2012-09-01 17:54:09 +000012100 assign(op2, get_gpr_w1(r2));
12101 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
12102 }
florian1c8f7ff2012-09-01 00:12:11 +000012103 return "cxlfbr";
12104}
12105
12106
florian55085f82012-11-21 00:36:55 +000012107static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012108s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
12109 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012110{
12111 IRTemp op2 = newTemp(Ity_I64);
12112
12113 assign(op2, get_gpr_dw0(r2));
12114 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
12115
12116 return "cxgbr";
12117}
12118
florian55085f82012-11-21 00:36:55 +000012119static const HChar *
floriand2129202012-09-01 20:01:39 +000012120s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
12121 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000012122{
floriane75dafa2012-09-01 17:54:09 +000012123 if (! s390_host_has_fpext) {
12124 emulation_failure(EmFail_S390X_fpext);
12125 } else {
12126 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000012127
floriane75dafa2012-09-01 17:54:09 +000012128 assign(op2, get_gpr_dw0(r2));
12129 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
12130 }
florian1c8f7ff2012-09-01 00:12:11 +000012131 return "cxlgbr";
12132}
12133
florian55085f82012-11-21 00:36:55 +000012134static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012135s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
12136 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012137{
12138 IRTemp op = newTemp(Ity_F128);
12139 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012140 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012141
12142 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012143 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012144 mkexpr(op)));
12145 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012146 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012147
12148 return "cfxbr";
12149}
12150
florian55085f82012-11-21 00:36:55 +000012151static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012152s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
12153 UChar r1, UChar r2)
12154{
floriane75dafa2012-09-01 17:54:09 +000012155 if (! s390_host_has_fpext) {
12156 emulation_failure(EmFail_S390X_fpext);
12157 } else {
12158 IRTemp op = newTemp(Ity_F128);
12159 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000012160 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012161
floriane75dafa2012-09-01 17:54:09 +000012162 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012163 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012164 mkexpr(op)));
12165 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012166 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012167 }
florian1c8f7ff2012-09-01 00:12:11 +000012168 return "clfxbr";
12169}
12170
12171
florian55085f82012-11-21 00:36:55 +000012172static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012173s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
12174 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012175{
12176 IRTemp op = newTemp(Ity_F128);
12177 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012178 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000012179
12180 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012181 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000012182 mkexpr(op)));
12183 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012184 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000012185
12186 return "cgxbr";
12187}
12188
florian55085f82012-11-21 00:36:55 +000012189static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000012190s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
12191 UChar r1, UChar r2)
12192{
floriane75dafa2012-09-01 17:54:09 +000012193 if (! s390_host_has_fpext) {
12194 emulation_failure(EmFail_S390X_fpext);
12195 } else {
12196 IRTemp op = newTemp(Ity_F128);
12197 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000012198 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000012199
floriane75dafa2012-09-01 17:54:09 +000012200 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000012201 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000012202 mkexpr(op)));
12203 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000012204 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
12205 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000012206 }
florian1c8f7ff2012-09-01 00:12:11 +000012207 return "clgxbr";
12208}
12209
florian55085f82012-11-21 00:36:55 +000012210static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012211s390_irgen_DXBR(UChar r1, UChar r2)
12212{
12213 IRTemp op1 = newTemp(Ity_F128);
12214 IRTemp op2 = newTemp(Ity_F128);
12215 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012216 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012217
12218 assign(op1, get_fpr_pair(r1));
12219 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012220 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012221 mkexpr(op2)));
12222 put_fpr_pair(r1, mkexpr(result));
12223
12224 return "dxbr";
12225}
12226
florian55085f82012-11-21 00:36:55 +000012227static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012228s390_irgen_LTXBR(UChar r1, UChar r2)
12229{
12230 IRTemp result = newTemp(Ity_F128);
12231
12232 assign(result, get_fpr_pair(r2));
12233 put_fpr_pair(r1, mkexpr(result));
12234 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12235
12236 return "ltxbr";
12237}
12238
florian55085f82012-11-21 00:36:55 +000012239static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012240s390_irgen_LCXBR(UChar r1, UChar r2)
12241{
12242 IRTemp result = newTemp(Ity_F128);
12243
12244 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
12245 put_fpr_pair(r1, mkexpr(result));
12246 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12247
12248 return "lcxbr";
12249}
12250
florian55085f82012-11-21 00:36:55 +000012251static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012252s390_irgen_LXDBR(UChar r1, UChar r2)
12253{
12254 IRTemp op = newTemp(Ity_F64);
12255
12256 assign(op, get_fpr_dw0(r2));
12257 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12258
12259 return "lxdbr";
12260}
12261
florian55085f82012-11-21 00:36:55 +000012262static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012263s390_irgen_LXEBR(UChar r1, UChar r2)
12264{
12265 IRTemp op = newTemp(Ity_F32);
12266
12267 assign(op, get_fpr_w0(r2));
12268 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12269
12270 return "lxebr";
12271}
12272
florian55085f82012-11-21 00:36:55 +000012273static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012274s390_irgen_LXDB(UChar r1, IRTemp op2addr)
12275{
12276 IRTemp op = newTemp(Ity_F64);
12277
12278 assign(op, load(Ity_F64, mkexpr(op2addr)));
12279 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
12280
12281 return "lxdb";
12282}
12283
florian55085f82012-11-21 00:36:55 +000012284static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012285s390_irgen_LXEB(UChar r1, IRTemp op2addr)
12286{
12287 IRTemp op = newTemp(Ity_F32);
12288
12289 assign(op, load(Ity_F32, mkexpr(op2addr)));
12290 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
12291
12292 return "lxeb";
12293}
12294
florian55085f82012-11-21 00:36:55 +000012295static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012296s390_irgen_LNEBR(UChar r1, UChar r2)
12297{
12298 IRTemp result = newTemp(Ity_F32);
12299
12300 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
12301 put_fpr_w0(r1, mkexpr(result));
12302 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12303
12304 return "lnebr";
12305}
12306
florian55085f82012-11-21 00:36:55 +000012307static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012308s390_irgen_LNDBR(UChar r1, UChar r2)
12309{
12310 IRTemp result = newTemp(Ity_F64);
12311
12312 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12313 put_fpr_dw0(r1, mkexpr(result));
12314 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12315
12316 return "lndbr";
12317}
12318
florian55085f82012-11-21 00:36:55 +000012319static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012320s390_irgen_LNXBR(UChar r1, UChar r2)
12321{
12322 IRTemp result = newTemp(Ity_F128);
12323
12324 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12325 put_fpr_pair(r1, mkexpr(result));
12326 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12327
12328 return "lnxbr";
12329}
12330
florian55085f82012-11-21 00:36:55 +000012331static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012332s390_irgen_LPEBR(UChar r1, UChar r2)
12333{
12334 IRTemp result = newTemp(Ity_F32);
12335
12336 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12337 put_fpr_w0(r1, mkexpr(result));
12338 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12339
12340 return "lpebr";
12341}
12342
florian55085f82012-11-21 00:36:55 +000012343static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012344s390_irgen_LPDBR(UChar r1, UChar r2)
12345{
12346 IRTemp result = newTemp(Ity_F64);
12347
12348 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12349 put_fpr_dw0(r1, mkexpr(result));
12350 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12351
12352 return "lpdbr";
12353}
12354
florian55085f82012-11-21 00:36:55 +000012355static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012356s390_irgen_LPXBR(UChar r1, UChar r2)
12357{
12358 IRTemp result = newTemp(Ity_F128);
12359
12360 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12361 put_fpr_pair(r1, mkexpr(result));
12362 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12363
12364 return "lpxbr";
12365}
12366
florian55085f82012-11-21 00:36:55 +000012367static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012368s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12369 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012370{
florian125e20d2012-10-07 15:42:37 +000012371 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012372 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012373 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012374 }
sewardj2019a972011-03-07 16:04:07 +000012375 IRTemp result = newTemp(Ity_F64);
12376
floriandb4fcaa2012-09-05 19:54:08 +000012377 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012378 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012379 put_fpr_dw0(r1, mkexpr(result));
12380
12381 return "ldxbr";
12382}
12383
florian55085f82012-11-21 00:36:55 +000012384static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012385s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12386 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012387{
florian125e20d2012-10-07 15:42:37 +000012388 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012389 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012390 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012391 }
sewardj2019a972011-03-07 16:04:07 +000012392 IRTemp result = newTemp(Ity_F32);
12393
floriandb4fcaa2012-09-05 19:54:08 +000012394 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012395 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012396 put_fpr_w0(r1, mkexpr(result));
12397
12398 return "lexbr";
12399}
12400
florian55085f82012-11-21 00:36:55 +000012401static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012402s390_irgen_MXBR(UChar r1, UChar r2)
12403{
12404 IRTemp op1 = newTemp(Ity_F128);
12405 IRTemp op2 = newTemp(Ity_F128);
12406 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012407 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012408
12409 assign(op1, get_fpr_pair(r1));
12410 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012411 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012412 mkexpr(op2)));
12413 put_fpr_pair(r1, mkexpr(result));
12414
12415 return "mxbr";
12416}
12417
florian55085f82012-11-21 00:36:55 +000012418static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012419s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12420{
florian125e20d2012-10-07 15:42:37 +000012421 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012422
floriandb4fcaa2012-09-05 19:54:08 +000012423 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012424 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012425
12426 return "maebr";
12427}
12428
florian55085f82012-11-21 00:36:55 +000012429static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012430s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12431{
florian125e20d2012-10-07 15:42:37 +000012432 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012433
floriandb4fcaa2012-09-05 19:54:08 +000012434 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012435 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012436
12437 return "madbr";
12438}
12439
florian55085f82012-11-21 00:36:55 +000012440static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012441s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12442{
12443 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012444 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012445
floriandb4fcaa2012-09-05 19:54:08 +000012446 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012447 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012448
12449 return "maeb";
12450}
12451
florian55085f82012-11-21 00:36:55 +000012452static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012453s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12454{
12455 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012456 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012457
floriandb4fcaa2012-09-05 19:54:08 +000012458 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012459 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012460
12461 return "madb";
12462}
12463
florian55085f82012-11-21 00:36:55 +000012464static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012465s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12466{
florian125e20d2012-10-07 15:42:37 +000012467 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012468
floriandb4fcaa2012-09-05 19:54:08 +000012469 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012470 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012471
12472 return "msebr";
12473}
12474
florian55085f82012-11-21 00:36:55 +000012475static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012476s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12477{
florian125e20d2012-10-07 15:42:37 +000012478 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012479
floriandb4fcaa2012-09-05 19:54:08 +000012480 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012481 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012482
12483 return "msdbr";
12484}
12485
florian55085f82012-11-21 00:36:55 +000012486static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012487s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12488{
12489 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012490 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012491
floriandb4fcaa2012-09-05 19:54:08 +000012492 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012493 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012494
12495 return "mseb";
12496}
12497
florian55085f82012-11-21 00:36:55 +000012498static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012499s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12500{
12501 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012502 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012503
floriandb4fcaa2012-09-05 19:54:08 +000012504 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012505 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012506
12507 return "msdb";
12508}
12509
florian55085f82012-11-21 00:36:55 +000012510static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012511s390_irgen_SQEBR(UChar r1, UChar r2)
12512{
12513 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012514 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012515
floriandb4fcaa2012-09-05 19:54:08 +000012516 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012517 put_fpr_w0(r1, mkexpr(result));
12518
12519 return "sqebr";
12520}
12521
florian55085f82012-11-21 00:36:55 +000012522static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012523s390_irgen_SQDBR(UChar r1, UChar r2)
12524{
12525 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012526 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012527
floriandb4fcaa2012-09-05 19:54:08 +000012528 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012529 put_fpr_dw0(r1, mkexpr(result));
12530
12531 return "sqdbr";
12532}
12533
florian55085f82012-11-21 00:36:55 +000012534static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012535s390_irgen_SQXBR(UChar r1, UChar r2)
12536{
12537 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012538 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012539
floriandb4fcaa2012-09-05 19:54:08 +000012540 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12541 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012542 put_fpr_pair(r1, mkexpr(result));
12543
12544 return "sqxbr";
12545}
12546
florian55085f82012-11-21 00:36:55 +000012547static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012548s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12549{
12550 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012551 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012552
12553 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012554 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012555
12556 return "sqeb";
12557}
12558
florian55085f82012-11-21 00:36:55 +000012559static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012560s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12561{
12562 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012563 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012564
12565 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012566 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012567
12568 return "sqdb";
12569}
12570
florian55085f82012-11-21 00:36:55 +000012571static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012572s390_irgen_SXBR(UChar r1, UChar r2)
12573{
12574 IRTemp op1 = newTemp(Ity_F128);
12575 IRTemp op2 = newTemp(Ity_F128);
12576 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012577 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012578
12579 assign(op1, get_fpr_pair(r1));
12580 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012581 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012582 mkexpr(op2)));
12583 put_fpr_pair(r1, mkexpr(result));
12584 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12585
12586 return "sxbr";
12587}
12588
florian55085f82012-11-21 00:36:55 +000012589static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012590s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12591{
12592 IRTemp value = newTemp(Ity_F32);
12593
12594 assign(value, get_fpr_w0(r1));
12595
12596 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12597
12598 return "tceb";
12599}
12600
florian55085f82012-11-21 00:36:55 +000012601static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012602s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12603{
12604 IRTemp value = newTemp(Ity_F64);
12605
12606 assign(value, get_fpr_dw0(r1));
12607
12608 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12609
12610 return "tcdb";
12611}
12612
florian55085f82012-11-21 00:36:55 +000012613static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012614s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12615{
12616 IRTemp value = newTemp(Ity_F128);
12617
12618 assign(value, get_fpr_pair(r1));
12619
12620 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12621
12622 return "tcxb";
12623}
12624
florian55085f82012-11-21 00:36:55 +000012625static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012626s390_irgen_LCDFR(UChar r1, UChar r2)
12627{
12628 IRTemp result = newTemp(Ity_F64);
12629
12630 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12631 put_fpr_dw0(r1, mkexpr(result));
12632
12633 return "lcdfr";
12634}
12635
florian55085f82012-11-21 00:36:55 +000012636static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012637s390_irgen_LNDFR(UChar r1, UChar r2)
12638{
12639 IRTemp result = newTemp(Ity_F64);
12640
12641 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12642 put_fpr_dw0(r1, mkexpr(result));
12643
12644 return "lndfr";
12645}
12646
florian55085f82012-11-21 00:36:55 +000012647static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012648s390_irgen_LPDFR(UChar r1, UChar r2)
12649{
12650 IRTemp result = newTemp(Ity_F64);
12651
12652 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12653 put_fpr_dw0(r1, mkexpr(result));
12654
12655 return "lpdfr";
12656}
12657
florian55085f82012-11-21 00:36:55 +000012658static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012659s390_irgen_LDGR(UChar r1, UChar r2)
12660{
12661 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12662
12663 return "ldgr";
12664}
12665
florian55085f82012-11-21 00:36:55 +000012666static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012667s390_irgen_LGDR(UChar r1, UChar r2)
12668{
12669 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12670
12671 return "lgdr";
12672}
12673
12674
florian55085f82012-11-21 00:36:55 +000012675static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012676s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12677{
12678 IRTemp sign = newTemp(Ity_I64);
12679 IRTemp value = newTemp(Ity_I64);
12680
12681 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12682 mkU64(1ULL << 63)));
12683 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12684 mkU64((1ULL << 63) - 1)));
12685 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12686 mkexpr(sign))));
12687
12688 return "cpsdr";
12689}
12690
12691
sewardj2019a972011-03-07 16:04:07 +000012692static IRExpr *
12693s390_call_cvb(IRExpr *in)
12694{
12695 IRExpr **args, *call;
12696
12697 args = mkIRExprVec_1(in);
12698 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12699 "s390_do_cvb", &s390_do_cvb, args);
12700
12701 /* Nothing is excluded from definedness checking. */
12702 call->Iex.CCall.cee->mcx_mask = 0;
12703
12704 return call;
12705}
12706
florian55085f82012-11-21 00:36:55 +000012707static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012708s390_irgen_CVB(UChar r1, IRTemp op2addr)
12709{
12710 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12711
12712 return "cvb";
12713}
12714
florian55085f82012-11-21 00:36:55 +000012715static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012716s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12717{
12718 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12719
12720 return "cvby";
12721}
12722
12723
sewardj2019a972011-03-07 16:04:07 +000012724static IRExpr *
12725s390_call_cvd(IRExpr *in)
12726{
12727 IRExpr **args, *call;
12728
12729 args = mkIRExprVec_1(in);
12730 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12731 "s390_do_cvd", &s390_do_cvd, args);
12732
12733 /* Nothing is excluded from definedness checking. */
12734 call->Iex.CCall.cee->mcx_mask = 0;
12735
12736 return call;
12737}
12738
florian55085f82012-11-21 00:36:55 +000012739static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012740s390_irgen_CVD(UChar r1, IRTemp op2addr)
12741{
florian11b8ee82012-08-06 13:35:33 +000012742 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012743
12744 return "cvd";
12745}
12746
florian55085f82012-11-21 00:36:55 +000012747static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012748s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12749{
12750 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12751
12752 return "cvdy";
12753}
12754
florian55085f82012-11-21 00:36:55 +000012755static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012756s390_irgen_FLOGR(UChar r1, UChar r2)
12757{
12758 IRTemp input = newTemp(Ity_I64);
12759 IRTemp not_zero = newTemp(Ity_I64);
12760 IRTemp tmpnum = newTemp(Ity_I64);
12761 IRTemp num = newTemp(Ity_I64);
12762 IRTemp shift_amount = newTemp(Ity_I8);
12763
12764 /* We use the "count leading zeroes" operator because the number of
12765 leading zeroes is identical with the bit position of the first '1' bit.
12766 However, that operator does not work when the input value is zero.
12767 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12768 the modified value. If input == 0, then the result is 64. Otherwise,
12769 the result of Clz64 is what we want. */
12770
12771 assign(input, get_gpr_dw0(r2));
12772 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12773 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12774
12775 /* num = (input == 0) ? 64 : tmpnum */
12776 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12777 /* == 0 */ mkU64(64),
12778 /* != 0 */ mkexpr(tmpnum)));
12779
12780 put_gpr_dw0(r1, mkexpr(num));
12781
12782 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12783 is to first shift the input value by NUM + 1 bits to the left which
12784 causes the leftmost '1' bit to disappear. Then we shift logically to
12785 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12786 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12787 the width of the value-to-be-shifted, we need to special case
12788 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12789 For both such INPUT values the result will be 0. */
12790
12791 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12792 mkU64(1))));
12793
12794 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012795 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12796 /* == 0 || == 1*/ mkU64(0),
12797 /* otherwise */
12798 binop(Iop_Shr64,
12799 binop(Iop_Shl64, mkexpr(input),
12800 mkexpr(shift_amount)),
12801 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012802
12803 /* Compare the original value as an unsigned integer with 0. */
12804 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12805 mktemp(Ity_I64, mkU64(0)), False);
12806
12807 return "flogr";
12808}
12809
florian55085f82012-11-21 00:36:55 +000012810static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012811s390_irgen_STCK(IRTemp op2addr)
12812{
12813 IRDirty *d;
12814 IRTemp cc = newTemp(Ity_I64);
12815
12816 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12817 &s390x_dirtyhelper_STCK,
12818 mkIRExprVec_1(mkexpr(op2addr)));
12819 d->mFx = Ifx_Write;
12820 d->mAddr = mkexpr(op2addr);
12821 d->mSize = 8;
12822 stmt(IRStmt_Dirty(d));
12823 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12824 mkexpr(cc), mkU64(0), mkU64(0));
12825 return "stck";
12826}
12827
florian55085f82012-11-21 00:36:55 +000012828static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012829s390_irgen_STCKF(IRTemp op2addr)
12830{
florianc5c669b2012-08-26 14:32:28 +000012831 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012832 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012833 } else {
12834 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012835
florianc5c669b2012-08-26 14:32:28 +000012836 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12837 &s390x_dirtyhelper_STCKF,
12838 mkIRExprVec_1(mkexpr(op2addr)));
12839 d->mFx = Ifx_Write;
12840 d->mAddr = mkexpr(op2addr);
12841 d->mSize = 8;
12842 stmt(IRStmt_Dirty(d));
12843 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12844 mkexpr(cc), mkU64(0), mkU64(0));
12845 }
sewardj1e5fea62011-05-17 16:18:36 +000012846 return "stckf";
12847}
12848
florian55085f82012-11-21 00:36:55 +000012849static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012850s390_irgen_STCKE(IRTemp op2addr)
12851{
12852 IRDirty *d;
12853 IRTemp cc = newTemp(Ity_I64);
12854
12855 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12856 &s390x_dirtyhelper_STCKE,
12857 mkIRExprVec_1(mkexpr(op2addr)));
12858 d->mFx = Ifx_Write;
12859 d->mAddr = mkexpr(op2addr);
12860 d->mSize = 16;
12861 stmt(IRStmt_Dirty(d));
12862 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12863 mkexpr(cc), mkU64(0), mkU64(0));
12864 return "stcke";
12865}
12866
florian55085f82012-11-21 00:36:55 +000012867static const HChar *
florian933065d2011-07-11 01:48:02 +000012868s390_irgen_STFLE(IRTemp op2addr)
12869{
florian4e0083e2012-08-26 03:41:56 +000012870 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012871 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012872 return "stfle";
12873 }
12874
florian933065d2011-07-11 01:48:02 +000012875 IRDirty *d;
12876 IRTemp cc = newTemp(Ity_I64);
12877
florian90419562013-08-15 20:54:52 +000012878 /* IRExpr_BBPTR() => Need to pass pointer to guest state to helper */
florian933065d2011-07-11 01:48:02 +000012879 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12880 &s390x_dirtyhelper_STFLE,
florian90419562013-08-15 20:54:52 +000012881 mkIRExprVec_2(IRExpr_BBPTR(), mkexpr(op2addr)));
florian933065d2011-07-11 01:48:02 +000012882
sewardjc9069f22012-06-01 16:09:50 +000012883 d->nFxState = 1;
12884 vex_bzero(&d->fxState, sizeof(d->fxState));
12885
florian933065d2011-07-11 01:48:02 +000012886 d->fxState[0].fx = Ifx_Modify; /* read then write */
12887 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12888 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012889
12890 d->mAddr = mkexpr(op2addr);
12891 /* Pretend all double words are written */
12892 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12893 d->mFx = Ifx_Write;
12894
12895 stmt(IRStmt_Dirty(d));
12896
12897 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12898
12899 return "stfle";
12900}
12901
florian55085f82012-11-21 00:36:55 +000012902static const HChar *
floriana4384a32011-08-11 16:58:45 +000012903s390_irgen_CKSM(UChar r1,UChar r2)
12904{
12905 IRTemp addr = newTemp(Ity_I64);
12906 IRTemp op = newTemp(Ity_I32);
12907 IRTemp len = newTemp(Ity_I64);
12908 IRTemp oldval = newTemp(Ity_I32);
12909 IRTemp mask = newTemp(Ity_I32);
12910 IRTemp newop = newTemp(Ity_I32);
12911 IRTemp result = newTemp(Ity_I32);
12912 IRTemp result1 = newTemp(Ity_I32);
12913 IRTemp inc = newTemp(Ity_I64);
12914
12915 assign(oldval, get_gpr_w1(r1));
12916 assign(addr, get_gpr_dw0(r2));
12917 assign(len, get_gpr_dw0(r2+1));
12918
12919 /* Condition code is always zero. */
12920 s390_cc_set(0);
12921
12922 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012923 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012924
12925 /* Assiging the increment variable to adjust address and length
12926 later on. */
12927 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12928 mkexpr(len), mkU64(4)));
12929
12930 /* If length < 4 the final 4-byte 2nd operand value is computed by
12931 appending the remaining bytes to the right with 0. This is done
12932 by AND'ing the 4 bytes loaded from memory with an appropriate
12933 mask. If length >= 4, that mask is simply 0xffffffff. */
12934
12935 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12936 /* Mask computation when len < 4:
12937 0xffffffff << (32 - (len % 4)*8) */
12938 binop(Iop_Shl32, mkU32(0xffffffff),
12939 unop(Iop_32to8,
12940 binop(Iop_Sub32, mkU32(32),
12941 binop(Iop_Shl32,
12942 unop(Iop_64to32,
12943 binop(Iop_And64,
12944 mkexpr(len), mkU64(3))),
12945 mkU8(3))))),
12946 mkU32(0xffffffff)));
12947
12948 assign(op, load(Ity_I32, mkexpr(addr)));
12949 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12950 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12951
12952 /* Checking for carry */
12953 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12954 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12955 mkexpr(result)));
12956
12957 put_gpr_w1(r1, mkexpr(result1));
12958 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12959 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12960
florian6820ba52012-07-26 02:01:50 +000012961 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012962
12963 return "cksm";
12964}
12965
florian55085f82012-11-21 00:36:55 +000012966static const HChar *
florian9af37692012-01-15 21:01:16 +000012967s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12968{
12969 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12970 src_addr = newTemp(Ity_I64);
12971 des_addr = newTemp(Ity_I64);
12972 tab_addr = newTemp(Ity_I64);
12973 test_byte = newTemp(Ity_I8);
12974 src_len = newTemp(Ity_I64);
12975
12976 assign(src_addr, get_gpr_dw0(r2));
12977 assign(des_addr, get_gpr_dw0(r1));
12978 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012979 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012980 assign(test_byte, get_gpr_b7(0));
12981
12982 IRTemp op = newTemp(Ity_I8);
12983 IRTemp op1 = newTemp(Ity_I8);
12984 IRTemp result = newTemp(Ity_I64);
12985
12986 /* End of source string? We're done; proceed to next insn */
12987 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012988 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012989
12990 /* Load character from source string, index translation table and
12991 store translated character in op1. */
12992 assign(op, load(Ity_I8, mkexpr(src_addr)));
12993
12994 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12995 mkexpr(tab_addr)));
12996 assign(op1, load(Ity_I8, mkexpr(result)));
12997
12998 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12999 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013000 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000013001 }
13002 store(get_gpr_dw0(r1), mkexpr(op1));
13003
13004 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13005 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13006 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13007
florian6820ba52012-07-26 02:01:50 +000013008 iterate();
florian9af37692012-01-15 21:01:16 +000013009
13010 return "troo";
13011}
13012
florian55085f82012-11-21 00:36:55 +000013013static const HChar *
florian730448f2012-02-04 17:07:07 +000013014s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
13015{
13016 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13017 src_addr = newTemp(Ity_I64);
13018 des_addr = newTemp(Ity_I64);
13019 tab_addr = newTemp(Ity_I64);
13020 test_byte = newTemp(Ity_I8);
13021 src_len = newTemp(Ity_I64);
13022
13023 assign(src_addr, get_gpr_dw0(r2));
13024 assign(des_addr, get_gpr_dw0(r1));
13025 assign(tab_addr, get_gpr_dw0(1));
13026 assign(src_len, get_gpr_dw0(r1+1));
13027 assign(test_byte, get_gpr_b7(0));
13028
13029 IRTemp op = newTemp(Ity_I16);
13030 IRTemp op1 = newTemp(Ity_I8);
13031 IRTemp result = newTemp(Ity_I64);
13032
13033 /* End of source string? We're done; proceed to next insn */
13034 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013035 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013036
13037 /* Load character from source string, index translation table and
13038 store translated character in op1. */
13039 assign(op, load(Ity_I16, mkexpr(src_addr)));
13040
13041 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13042 mkexpr(tab_addr)));
13043
13044 assign(op1, load(Ity_I8, mkexpr(result)));
13045
13046 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13047 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013048 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013049 }
13050 store(get_gpr_dw0(r1), mkexpr(op1));
13051
13052 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13053 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
13054 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13055
florian6820ba52012-07-26 02:01:50 +000013056 iterate();
florian730448f2012-02-04 17:07:07 +000013057
13058 return "trto";
13059}
13060
florian55085f82012-11-21 00:36:55 +000013061static const HChar *
florian730448f2012-02-04 17:07:07 +000013062s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
13063{
13064 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13065 src_addr = newTemp(Ity_I64);
13066 des_addr = newTemp(Ity_I64);
13067 tab_addr = newTemp(Ity_I64);
13068 test_byte = newTemp(Ity_I16);
13069 src_len = newTemp(Ity_I64);
13070
13071 assign(src_addr, get_gpr_dw0(r2));
13072 assign(des_addr, get_gpr_dw0(r1));
13073 assign(tab_addr, get_gpr_dw0(1));
13074 assign(src_len, get_gpr_dw0(r1+1));
13075 assign(test_byte, get_gpr_hw3(0));
13076
13077 IRTemp op = newTemp(Ity_I8);
13078 IRTemp op1 = newTemp(Ity_I16);
13079 IRTemp result = newTemp(Ity_I64);
13080
13081 /* End of source string? We're done; proceed to next insn */
13082 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013083 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013084
13085 /* Load character from source string, index translation table and
13086 store translated character in op1. */
13087 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
13088
13089 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13090 mkexpr(tab_addr)));
13091 assign(op1, load(Ity_I16, mkexpr(result)));
13092
13093 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13094 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013095 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013096 }
13097 store(get_gpr_dw0(r1), mkexpr(op1));
13098
13099 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13100 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13101 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13102
florian6820ba52012-07-26 02:01:50 +000013103 iterate();
florian730448f2012-02-04 17:07:07 +000013104
13105 return "trot";
13106}
13107
florian55085f82012-11-21 00:36:55 +000013108static const HChar *
florian730448f2012-02-04 17:07:07 +000013109s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
13110{
13111 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
13112 src_addr = newTemp(Ity_I64);
13113 des_addr = newTemp(Ity_I64);
13114 tab_addr = newTemp(Ity_I64);
13115 test_byte = newTemp(Ity_I16);
13116 src_len = newTemp(Ity_I64);
13117
13118 assign(src_addr, get_gpr_dw0(r2));
13119 assign(des_addr, get_gpr_dw0(r1));
13120 assign(tab_addr, get_gpr_dw0(1));
13121 assign(src_len, get_gpr_dw0(r1+1));
13122 assign(test_byte, get_gpr_hw3(0));
13123
13124 IRTemp op = newTemp(Ity_I16);
13125 IRTemp op1 = newTemp(Ity_I16);
13126 IRTemp result = newTemp(Ity_I64);
13127
13128 /* End of source string? We're done; proceed to next insn */
13129 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013130 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013131
13132 /* Load character from source string, index translation table and
13133 store translated character in op1. */
13134 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
13135
13136 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
13137 mkexpr(tab_addr)));
13138 assign(op1, load(Ity_I16, mkexpr(result)));
13139
13140 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
13141 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013142 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013143 }
13144
13145 store(get_gpr_dw0(r1), mkexpr(op1));
13146
13147 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
13148 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
13149 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
13150
florian6820ba52012-07-26 02:01:50 +000013151 iterate();
florian730448f2012-02-04 17:07:07 +000013152
13153 return "trtt";
13154}
13155
florian55085f82012-11-21 00:36:55 +000013156static const HChar *
florian730448f2012-02-04 17:07:07 +000013157s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
13158{
florianf87d4fb2012-05-05 02:55:24 +000013159 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000013160
florianf87d4fb2012-05-05 02:55:24 +000013161 assign(len, mkU64(length));
13162 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000013163
13164 return "tr";
13165}
13166
florian55085f82012-11-21 00:36:55 +000013167static const HChar *
florian730448f2012-02-04 17:07:07 +000013168s390_irgen_TRE(UChar r1,UChar r2)
13169{
13170 IRTemp src_addr, tab_addr, src_len, test_byte;
13171 src_addr = newTemp(Ity_I64);
13172 tab_addr = newTemp(Ity_I64);
13173 src_len = newTemp(Ity_I64);
13174 test_byte = newTemp(Ity_I8);
13175
13176 assign(src_addr, get_gpr_dw0(r1));
13177 assign(src_len, get_gpr_dw0(r1+1));
13178 assign(tab_addr, get_gpr_dw0(r2));
13179 assign(test_byte, get_gpr_b7(0));
13180
13181 IRTemp op = newTemp(Ity_I8);
13182 IRTemp op1 = newTemp(Ity_I8);
13183 IRTemp result = newTemp(Ity_I64);
13184
13185 /* End of source string? We're done; proceed to next insn */
13186 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013187 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000013188
13189 /* Load character from source string and compare with test byte */
13190 assign(op, load(Ity_I8, mkexpr(src_addr)));
13191
13192 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013193 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000013194
13195 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
13196 mkexpr(tab_addr)));
13197
13198 assign(op1, load(Ity_I8, mkexpr(result)));
13199
13200 store(get_gpr_dw0(r1), mkexpr(op1));
13201 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
13202 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
13203
florian6820ba52012-07-26 02:01:50 +000013204 iterate();
florian730448f2012-02-04 17:07:07 +000013205
13206 return "tre";
13207}
13208
floriana0100c92012-07-20 00:06:35 +000013209static IRExpr *
13210s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
13211{
13212 IRExpr **args, *call;
13213 args = mkIRExprVec_2(srcval, low_surrogate);
13214 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13215 "s390_do_cu21", &s390_do_cu21, args);
13216
13217 /* Nothing is excluded from definedness checking. */
13218 call->Iex.CCall.cee->mcx_mask = 0;
13219
13220 return call;
13221}
13222
florian55085f82012-11-21 00:36:55 +000013223static const HChar *
floriana0100c92012-07-20 00:06:35 +000013224s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
13225{
13226 IRTemp addr1 = newTemp(Ity_I64);
13227 IRTemp addr2 = newTemp(Ity_I64);
13228 IRTemp len1 = newTemp(Ity_I64);
13229 IRTemp len2 = newTemp(Ity_I64);
13230
13231 assign(addr1, get_gpr_dw0(r1));
13232 assign(addr2, get_gpr_dw0(r2));
13233 assign(len1, get_gpr_dw0(r1 + 1));
13234 assign(len2, get_gpr_dw0(r2 + 1));
13235
13236 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13237 there are less than 2 bytes left, then the 2nd operand is exhausted
13238 and we're done here. cc = 0 */
13239 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013240 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000013241
13242 /* There are at least two bytes there. Read them. */
13243 IRTemp srcval = newTemp(Ity_I32);
13244 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13245
13246 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13247 inside the interval [0xd800 - 0xdbff] */
13248 IRTemp is_high_surrogate = newTemp(Ity_I32);
13249 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13250 mkU32(1), mkU32(0));
13251 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13252 mkU32(1), mkU32(0));
13253 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13254
13255 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13256 then the 2nd operand is exhausted and we're done here. cc = 0 */
13257 IRExpr *not_enough_bytes =
13258 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13259
florian6820ba52012-07-26 02:01:50 +000013260 next_insn_if(binop(Iop_CmpEQ32,
13261 binop(Iop_And32, mkexpr(is_high_surrogate),
13262 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000013263
13264 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13265 surrogate, read the next two bytes (low surrogate). */
13266 IRTemp low_surrogate = newTemp(Ity_I32);
13267 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13268
13269 assign(low_surrogate,
13270 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13271 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13272 mkU32(0))); // any value is fine; it will not be used
13273
13274 /* Call the helper */
13275 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013276 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
13277 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000013278
13279 /* Before we can test whether the 1st operand is exhausted we need to
13280 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13281 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13282 IRExpr *invalid_low_surrogate =
13283 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13284
13285 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013286 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000013287 }
13288
13289 /* Now test whether the 1st operand is exhausted */
13290 IRTemp num_bytes = newTemp(Ity_I64);
13291 assign(num_bytes, binop(Iop_And64,
13292 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13293 mkU64(0xff)));
13294 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013295 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000013296
13297 /* Extract the bytes to be stored at addr1 */
13298 IRTemp data = newTemp(Ity_I64);
13299 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13300
13301 /* To store the bytes construct 4 dirty helper calls. The helper calls
13302 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13303 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013304 UInt i;
floriana0100c92012-07-20 00:06:35 +000013305 for (i = 1; i <= 4; ++i) {
13306 IRDirty *d;
13307
13308 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13309 &s390x_dirtyhelper_CUxy,
13310 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13311 mkexpr(num_bytes)));
13312 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13313 d->mFx = Ifx_Write;
13314 d->mAddr = mkexpr(addr1);
13315 d->mSize = i;
13316 stmt(IRStmt_Dirty(d));
13317 }
13318
13319 /* Update source address and length */
13320 IRTemp num_src_bytes = newTemp(Ity_I64);
13321 assign(num_src_bytes,
13322 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13323 mkU64(4), mkU64(2)));
13324 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13325 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13326
13327 /* Update destination address and length */
13328 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13329 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13330
florian6820ba52012-07-26 02:01:50 +000013331 iterate();
floriana0100c92012-07-20 00:06:35 +000013332
13333 return "cu21";
13334}
13335
florian2a415a12012-07-21 17:41:36 +000013336static IRExpr *
13337s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13338{
13339 IRExpr **args, *call;
13340 args = mkIRExprVec_2(srcval, low_surrogate);
13341 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13342 "s390_do_cu24", &s390_do_cu24, args);
13343
13344 /* Nothing is excluded from definedness checking. */
13345 call->Iex.CCall.cee->mcx_mask = 0;
13346
13347 return call;
13348}
13349
florian55085f82012-11-21 00:36:55 +000013350static const HChar *
florian2a415a12012-07-21 17:41:36 +000013351s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13352{
13353 IRTemp addr1 = newTemp(Ity_I64);
13354 IRTemp addr2 = newTemp(Ity_I64);
13355 IRTemp len1 = newTemp(Ity_I64);
13356 IRTemp len2 = newTemp(Ity_I64);
13357
13358 assign(addr1, get_gpr_dw0(r1));
13359 assign(addr2, get_gpr_dw0(r2));
13360 assign(len1, get_gpr_dw0(r1 + 1));
13361 assign(len2, get_gpr_dw0(r2 + 1));
13362
13363 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13364 there are less than 2 bytes left, then the 2nd operand is exhausted
13365 and we're done here. cc = 0 */
13366 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013367 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013368
13369 /* There are at least two bytes there. Read them. */
13370 IRTemp srcval = newTemp(Ity_I32);
13371 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13372
13373 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13374 inside the interval [0xd800 - 0xdbff] */
13375 IRTemp is_high_surrogate = newTemp(Ity_I32);
13376 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13377 mkU32(1), mkU32(0));
13378 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13379 mkU32(1), mkU32(0));
13380 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13381
13382 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13383 then the 2nd operand is exhausted and we're done here. cc = 0 */
13384 IRExpr *not_enough_bytes =
13385 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13386
florian6820ba52012-07-26 02:01:50 +000013387 next_insn_if(binop(Iop_CmpEQ32,
13388 binop(Iop_And32, mkexpr(is_high_surrogate),
13389 not_enough_bytes),
13390 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013391
13392 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13393 surrogate, read the next two bytes (low surrogate). */
13394 IRTemp low_surrogate = newTemp(Ity_I32);
13395 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13396
13397 assign(low_surrogate,
13398 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13399 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13400 mkU32(0))); // any value is fine; it will not be used
13401
13402 /* Call the helper */
13403 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013404 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13405 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013406
13407 /* Before we can test whether the 1st operand is exhausted we need to
13408 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13409 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13410 IRExpr *invalid_low_surrogate =
13411 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13412
13413 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013414 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013415 }
13416
13417 /* Now test whether the 1st operand is exhausted */
13418 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013419 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013420
13421 /* Extract the bytes to be stored at addr1 */
13422 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13423
13424 store(mkexpr(addr1), data);
13425
13426 /* Update source address and length */
13427 IRTemp num_src_bytes = newTemp(Ity_I64);
13428 assign(num_src_bytes,
13429 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13430 mkU64(4), mkU64(2)));
13431 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13432 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13433
13434 /* Update destination address and length */
13435 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13436 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13437
florian6820ba52012-07-26 02:01:50 +000013438 iterate();
florian2a415a12012-07-21 17:41:36 +000013439
13440 return "cu24";
13441}
floriana4384a32011-08-11 16:58:45 +000013442
florian956194b2012-07-28 22:18:32 +000013443static IRExpr *
13444s390_call_cu42(IRExpr *srcval)
13445{
13446 IRExpr **args, *call;
13447 args = mkIRExprVec_1(srcval);
13448 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13449 "s390_do_cu42", &s390_do_cu42, args);
13450
13451 /* Nothing is excluded from definedness checking. */
13452 call->Iex.CCall.cee->mcx_mask = 0;
13453
13454 return call;
13455}
13456
florian55085f82012-11-21 00:36:55 +000013457static const HChar *
florian956194b2012-07-28 22:18:32 +000013458s390_irgen_CU42(UChar r1, UChar r2)
13459{
13460 IRTemp addr1 = newTemp(Ity_I64);
13461 IRTemp addr2 = newTemp(Ity_I64);
13462 IRTemp len1 = newTemp(Ity_I64);
13463 IRTemp len2 = newTemp(Ity_I64);
13464
13465 assign(addr1, get_gpr_dw0(r1));
13466 assign(addr2, get_gpr_dw0(r2));
13467 assign(len1, get_gpr_dw0(r1 + 1));
13468 assign(len2, get_gpr_dw0(r2 + 1));
13469
13470 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13471 there are less than 4 bytes left, then the 2nd operand is exhausted
13472 and we're done here. cc = 0 */
13473 s390_cc_set(0);
13474 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13475
13476 /* Read the 2nd operand. */
13477 IRTemp srcval = newTemp(Ity_I32);
13478 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13479
13480 /* Call the helper */
13481 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013482 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013483
13484 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13485 cc=2 outranks cc=1 (1st operand exhausted) */
13486 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13487
13488 s390_cc_set(2);
13489 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13490
13491 /* Now test whether the 1st operand is exhausted */
13492 IRTemp num_bytes = newTemp(Ity_I64);
13493 assign(num_bytes, binop(Iop_And64,
13494 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13495 mkU64(0xff)));
13496 s390_cc_set(1);
13497 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13498
13499 /* Extract the bytes to be stored at addr1 */
13500 IRTemp data = newTemp(Ity_I64);
13501 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13502
13503 /* To store the bytes construct 2 dirty helper calls. The helper calls
13504 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13505 that only one of them will be called at runtime. */
13506
13507 Int i;
13508 for (i = 2; i <= 4; ++i) {
13509 IRDirty *d;
13510
13511 if (i == 3) continue; // skip this one
13512
13513 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13514 &s390x_dirtyhelper_CUxy,
13515 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13516 mkexpr(num_bytes)));
13517 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13518 d->mFx = Ifx_Write;
13519 d->mAddr = mkexpr(addr1);
13520 d->mSize = i;
13521 stmt(IRStmt_Dirty(d));
13522 }
13523
13524 /* Update source address and length */
13525 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13526 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13527
13528 /* Update destination address and length */
13529 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13530 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13531
13532 iterate();
13533
13534 return "cu42";
13535}
13536
florian6d9b9b22012-08-03 18:35:39 +000013537static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013538s390_call_cu41(IRExpr *srcval)
13539{
13540 IRExpr **args, *call;
13541 args = mkIRExprVec_1(srcval);
13542 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13543 "s390_do_cu41", &s390_do_cu41, args);
13544
13545 /* Nothing is excluded from definedness checking. */
13546 call->Iex.CCall.cee->mcx_mask = 0;
13547
13548 return call;
13549}
13550
florian55085f82012-11-21 00:36:55 +000013551static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013552s390_irgen_CU41(UChar r1, UChar r2)
13553{
13554 IRTemp addr1 = newTemp(Ity_I64);
13555 IRTemp addr2 = newTemp(Ity_I64);
13556 IRTemp len1 = newTemp(Ity_I64);
13557 IRTemp len2 = newTemp(Ity_I64);
13558
13559 assign(addr1, get_gpr_dw0(r1));
13560 assign(addr2, get_gpr_dw0(r2));
13561 assign(len1, get_gpr_dw0(r1 + 1));
13562 assign(len2, get_gpr_dw0(r2 + 1));
13563
13564 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13565 there are less than 4 bytes left, then the 2nd operand is exhausted
13566 and we're done here. cc = 0 */
13567 s390_cc_set(0);
13568 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13569
13570 /* Read the 2nd operand. */
13571 IRTemp srcval = newTemp(Ity_I32);
13572 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13573
13574 /* Call the helper */
13575 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013576 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013577
13578 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13579 cc=2 outranks cc=1 (1st operand exhausted) */
13580 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13581
13582 s390_cc_set(2);
13583 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13584
13585 /* Now test whether the 1st operand is exhausted */
13586 IRTemp num_bytes = newTemp(Ity_I64);
13587 assign(num_bytes, binop(Iop_And64,
13588 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13589 mkU64(0xff)));
13590 s390_cc_set(1);
13591 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13592
13593 /* Extract the bytes to be stored at addr1 */
13594 IRTemp data = newTemp(Ity_I64);
13595 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13596
13597 /* To store the bytes construct 4 dirty helper calls. The helper calls
13598 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13599 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013600 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013601 for (i = 1; i <= 4; ++i) {
13602 IRDirty *d;
13603
13604 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13605 &s390x_dirtyhelper_CUxy,
13606 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13607 mkexpr(num_bytes)));
13608 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13609 d->mFx = Ifx_Write;
13610 d->mAddr = mkexpr(addr1);
13611 d->mSize = i;
13612 stmt(IRStmt_Dirty(d));
13613 }
13614
13615 /* Update source address and length */
13616 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13617 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13618
13619 /* Update destination address and length */
13620 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13621 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13622
13623 iterate();
13624
13625 return "cu41";
13626}
13627
13628static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013629s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013630{
13631 IRExpr **args, *call;
13632 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013633 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13634 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013635
13636 /* Nothing is excluded from definedness checking. */
13637 call->Iex.CCall.cee->mcx_mask = 0;
13638
13639 return call;
13640}
13641
13642static IRExpr *
13643s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13644 IRExpr *byte4, IRExpr *stuff)
13645{
13646 IRExpr **args, *call;
13647 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13648 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13649 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13650
13651 /* Nothing is excluded from definedness checking. */
13652 call->Iex.CCall.cee->mcx_mask = 0;
13653
13654 return call;
13655}
13656
florian3f8a96a2012-08-05 02:59:55 +000013657static IRExpr *
13658s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13659 IRExpr *byte4, IRExpr *stuff)
13660{
13661 IRExpr **args, *call;
13662 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13663 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13664 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13665
13666 /* Nothing is excluded from definedness checking. */
13667 call->Iex.CCall.cee->mcx_mask = 0;
13668
13669 return call;
13670}
13671
13672static void
13673s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013674{
13675 IRTemp addr1 = newTemp(Ity_I64);
13676 IRTemp addr2 = newTemp(Ity_I64);
13677 IRTemp len1 = newTemp(Ity_I64);
13678 IRTemp len2 = newTemp(Ity_I64);
13679
13680 assign(addr1, get_gpr_dw0(r1));
13681 assign(addr2, get_gpr_dw0(r2));
13682 assign(len1, get_gpr_dw0(r1 + 1));
13683 assign(len2, get_gpr_dw0(r2 + 1));
13684
13685 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13686
13687 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13688 there is less than 1 byte left, then the 2nd operand is exhausted
13689 and we're done here. cc = 0 */
13690 s390_cc_set(0);
13691 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13692
13693 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013694 IRTemp byte1 = newTemp(Ity_I64);
13695 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013696
13697 /* Call the helper to get number of bytes and invalid byte indicator */
13698 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013699 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013700 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013701
13702 /* Check for invalid 1st byte */
13703 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13704 s390_cc_set(2);
13705 next_insn_if(is_invalid);
13706
13707 /* How many bytes do we have to read? */
13708 IRTemp num_src_bytes = newTemp(Ity_I64);
13709 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13710
13711 /* Now test whether the 2nd operand is exhausted */
13712 s390_cc_set(0);
13713 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13714
13715 /* Read the remaining bytes */
13716 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13717
13718 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13719 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013720 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013721 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13722 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013723 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013724 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13725 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013726 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013727
13728 /* Call the helper to get the converted value and invalid byte indicator.
13729 We can pass at most 5 arguments; therefore some encoding is needed
13730 here */
13731 IRExpr *stuff = binop(Iop_Or64,
13732 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13733 mkU64(extended_checking));
13734 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013735
13736 if (is_cu12) {
13737 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13738 byte4, stuff));
13739 } else {
13740 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13741 byte4, stuff));
13742 }
florian6d9b9b22012-08-03 18:35:39 +000013743
13744 /* Check for invalid character */
13745 s390_cc_set(2);
13746 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13747 next_insn_if(is_invalid);
13748
13749 /* Now test whether the 1st operand is exhausted */
13750 IRTemp num_bytes = newTemp(Ity_I64);
13751 assign(num_bytes, binop(Iop_And64,
13752 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13753 mkU64(0xff)));
13754 s390_cc_set(1);
13755 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13756
13757 /* Extract the bytes to be stored at addr1 */
13758 IRTemp data = newTemp(Ity_I64);
13759 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13760
florian3f8a96a2012-08-05 02:59:55 +000013761 if (is_cu12) {
13762 /* To store the bytes construct 2 dirty helper calls. The helper calls
13763 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13764 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013765
florian3f8a96a2012-08-05 02:59:55 +000013766 Int i;
13767 for (i = 2; i <= 4; ++i) {
13768 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013769
florian3f8a96a2012-08-05 02:59:55 +000013770 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013771
florian3f8a96a2012-08-05 02:59:55 +000013772 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13773 &s390x_dirtyhelper_CUxy,
13774 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13775 mkexpr(num_bytes)));
13776 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13777 d->mFx = Ifx_Write;
13778 d->mAddr = mkexpr(addr1);
13779 d->mSize = i;
13780 stmt(IRStmt_Dirty(d));
13781 }
13782 } else {
13783 // cu14
13784 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013785 }
13786
13787 /* Update source address and length */
13788 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13789 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13790
13791 /* Update destination address and length */
13792 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13793 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13794
13795 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013796}
13797
florian55085f82012-11-21 00:36:55 +000013798static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013799s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13800{
13801 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013802
13803 return "cu12";
13804}
13805
florian55085f82012-11-21 00:36:55 +000013806static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013807s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13808{
13809 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13810
13811 return "cu14";
13812}
13813
florian8c88cb62012-08-26 18:58:13 +000013814static IRExpr *
13815s390_call_ecag(IRExpr *op2addr)
13816{
13817 IRExpr **args, *call;
13818
13819 args = mkIRExprVec_1(op2addr);
13820 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13821 "s390_do_ecag", &s390_do_ecag, args);
13822
13823 /* Nothing is excluded from definedness checking. */
13824 call->Iex.CCall.cee->mcx_mask = 0;
13825
13826 return call;
13827}
13828
florian55085f82012-11-21 00:36:55 +000013829static const HChar *
floriand2129202012-09-01 20:01:39 +000013830s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013831{
13832 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013833 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013834 } else {
13835 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13836 }
13837
13838 return "ecag";
13839}
13840
13841
florianb7def222012-12-04 04:45:32 +000013842/* New insns are added here.
13843 If an insn is contingent on a facility being installed also
13844 check whether the list of supported facilities in function
13845 s390x_dirtyhelper_STFLE needs updating */
13846
sewardj2019a972011-03-07 16:04:07 +000013847/*------------------------------------------------------------*/
13848/*--- Build IR for special instructions ---*/
13849/*------------------------------------------------------------*/
13850
florianb4df7682011-07-05 02:09:01 +000013851static void
sewardj2019a972011-03-07 16:04:07 +000013852s390_irgen_client_request(void)
13853{
13854 if (0)
13855 vex_printf("%%R3 = client_request ( %%R2 )\n");
13856
florianf9e1ed72012-04-17 02:41:56 +000013857 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13858 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013859
florianf9e1ed72012-04-17 02:41:56 +000013860 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013861 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013862
13863 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013864}
13865
florianb4df7682011-07-05 02:09:01 +000013866static void
sewardj2019a972011-03-07 16:04:07 +000013867s390_irgen_guest_NRADDR(void)
13868{
13869 if (0)
13870 vex_printf("%%R3 = guest_NRADDR\n");
13871
floriane88b3c92011-07-05 02:48:39 +000013872 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013873}
13874
florianb4df7682011-07-05 02:09:01 +000013875static void
sewardj2019a972011-03-07 16:04:07 +000013876s390_irgen_call_noredir(void)
13877{
florianf9e1ed72012-04-17 02:41:56 +000013878 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13879 + S390_SPECIAL_OP_SIZE;
13880
sewardj2019a972011-03-07 16:04:07 +000013881 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013882 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013883
13884 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013885 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013886
13887 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013888 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013889}
13890
13891/* Force proper alignment for the structures below. */
13892#pragma pack(1)
13893
13894
13895static s390_decode_t
13896s390_decode_2byte_and_irgen(UChar *bytes)
13897{
13898 typedef union {
13899 struct {
13900 unsigned int op : 16;
13901 } E;
13902 struct {
13903 unsigned int op : 8;
13904 unsigned int i : 8;
13905 } I;
13906 struct {
13907 unsigned int op : 8;
13908 unsigned int r1 : 4;
13909 unsigned int r2 : 4;
13910 } RR;
13911 } formats;
13912 union {
13913 formats fmt;
13914 UShort value;
13915 } ovl;
13916
13917 vassert(sizeof(formats) == 2);
13918
florianffbd84d2012-12-09 02:06:29 +000013919 ((UChar *)(&ovl.value))[0] = bytes[0];
13920 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013921
13922 switch (ovl.value & 0xffff) {
13923 case 0x0101: /* PR */ goto unimplemented;
13924 case 0x0102: /* UPT */ goto unimplemented;
13925 case 0x0104: /* PTFF */ goto unimplemented;
13926 case 0x0107: /* SCKPF */ goto unimplemented;
florian78d5ef72013-05-11 15:02:58 +000013927 case 0x010a: s390_format_E(s390_irgen_PFPO); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013928 case 0x010b: /* TAM */ goto unimplemented;
13929 case 0x010c: /* SAM24 */ goto unimplemented;
13930 case 0x010d: /* SAM31 */ goto unimplemented;
13931 case 0x010e: /* SAM64 */ goto unimplemented;
13932 case 0x01ff: /* TRAP2 */ goto unimplemented;
13933 }
13934
13935 switch ((ovl.value & 0xff00) >> 8) {
13936 case 0x04: /* SPM */ goto unimplemented;
13937 case 0x05: /* BALR */ goto unimplemented;
13938 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13939 goto ok;
13940 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13941 goto ok;
13942 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13943 case 0x0b: /* BSM */ goto unimplemented;
13944 case 0x0c: /* BASSM */ goto unimplemented;
13945 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13946 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013947 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13948 goto ok;
13949 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13950 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013951 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13952 goto ok;
13953 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13954 goto ok;
13955 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13956 goto ok;
13957 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13958 goto ok;
13959 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13960 goto ok;
13961 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13962 goto ok;
13963 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13964 goto ok;
13965 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13966 goto ok;
13967 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13968 goto ok;
13969 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13970 goto ok;
13971 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13972 goto ok;
13973 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13974 goto ok;
13975 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13976 goto ok;
13977 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13978 goto ok;
13979 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13980 goto ok;
13981 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13982 goto ok;
13983 case 0x20: /* LPDR */ goto unimplemented;
13984 case 0x21: /* LNDR */ goto unimplemented;
13985 case 0x22: /* LTDR */ goto unimplemented;
13986 case 0x23: /* LCDR */ goto unimplemented;
13987 case 0x24: /* HDR */ goto unimplemented;
13988 case 0x25: /* LDXR */ goto unimplemented;
13989 case 0x26: /* MXR */ goto unimplemented;
13990 case 0x27: /* MXDR */ goto unimplemented;
13991 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13992 goto ok;
13993 case 0x29: /* CDR */ goto unimplemented;
13994 case 0x2a: /* ADR */ goto unimplemented;
13995 case 0x2b: /* SDR */ goto unimplemented;
13996 case 0x2c: /* MDR */ goto unimplemented;
13997 case 0x2d: /* DDR */ goto unimplemented;
13998 case 0x2e: /* AWR */ goto unimplemented;
13999 case 0x2f: /* SWR */ goto unimplemented;
14000 case 0x30: /* LPER */ goto unimplemented;
14001 case 0x31: /* LNER */ goto unimplemented;
14002 case 0x32: /* LTER */ goto unimplemented;
14003 case 0x33: /* LCER */ goto unimplemented;
14004 case 0x34: /* HER */ goto unimplemented;
14005 case 0x35: /* LEDR */ goto unimplemented;
14006 case 0x36: /* AXR */ goto unimplemented;
14007 case 0x37: /* SXR */ goto unimplemented;
14008 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
14009 goto ok;
14010 case 0x39: /* CER */ goto unimplemented;
14011 case 0x3a: /* AER */ goto unimplemented;
14012 case 0x3b: /* SER */ goto unimplemented;
14013 case 0x3c: /* MDER */ goto unimplemented;
14014 case 0x3d: /* DER */ goto unimplemented;
14015 case 0x3e: /* AUR */ goto unimplemented;
14016 case 0x3f: /* SUR */ goto unimplemented;
14017 }
14018
14019 return S390_DECODE_UNKNOWN_INSN;
14020
14021ok:
14022 return S390_DECODE_OK;
14023
14024unimplemented:
14025 return S390_DECODE_UNIMPLEMENTED_INSN;
14026}
14027
14028static s390_decode_t
14029s390_decode_4byte_and_irgen(UChar *bytes)
14030{
14031 typedef union {
14032 struct {
14033 unsigned int op1 : 8;
14034 unsigned int r1 : 4;
14035 unsigned int op2 : 4;
14036 unsigned int i2 : 16;
14037 } RI;
14038 struct {
14039 unsigned int op : 16;
14040 unsigned int : 8;
14041 unsigned int r1 : 4;
14042 unsigned int r2 : 4;
14043 } RRE;
14044 struct {
14045 unsigned int op : 16;
14046 unsigned int r1 : 4;
14047 unsigned int : 4;
14048 unsigned int r3 : 4;
14049 unsigned int r2 : 4;
14050 } RRF;
14051 struct {
14052 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000014053 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000014054 unsigned int m4 : 4;
14055 unsigned int r1 : 4;
14056 unsigned int r2 : 4;
14057 } RRF2;
14058 struct {
14059 unsigned int op : 16;
14060 unsigned int r3 : 4;
14061 unsigned int : 4;
14062 unsigned int r1 : 4;
14063 unsigned int r2 : 4;
14064 } RRF3;
14065 struct {
14066 unsigned int op : 16;
14067 unsigned int r3 : 4;
14068 unsigned int : 4;
14069 unsigned int r1 : 4;
14070 unsigned int r2 : 4;
14071 } RRR;
14072 struct {
14073 unsigned int op : 16;
14074 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000014075 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000014076 unsigned int r1 : 4;
14077 unsigned int r2 : 4;
14078 } RRF4;
14079 struct {
floriane38f6412012-12-21 17:32:12 +000014080 unsigned int op : 16;
14081 unsigned int : 4;
14082 unsigned int m4 : 4;
14083 unsigned int r1 : 4;
14084 unsigned int r2 : 4;
14085 } RRF5;
14086 struct {
sewardj2019a972011-03-07 16:04:07 +000014087 unsigned int op : 8;
14088 unsigned int r1 : 4;
14089 unsigned int r3 : 4;
14090 unsigned int b2 : 4;
14091 unsigned int d2 : 12;
14092 } RS;
14093 struct {
14094 unsigned int op : 8;
14095 unsigned int r1 : 4;
14096 unsigned int r3 : 4;
14097 unsigned int i2 : 16;
14098 } RSI;
14099 struct {
14100 unsigned int op : 8;
14101 unsigned int r1 : 4;
14102 unsigned int x2 : 4;
14103 unsigned int b2 : 4;
14104 unsigned int d2 : 12;
14105 } RX;
14106 struct {
14107 unsigned int op : 16;
14108 unsigned int b2 : 4;
14109 unsigned int d2 : 12;
14110 } S;
14111 struct {
14112 unsigned int op : 8;
14113 unsigned int i2 : 8;
14114 unsigned int b1 : 4;
14115 unsigned int d1 : 12;
14116 } SI;
14117 } formats;
14118 union {
14119 formats fmt;
14120 UInt value;
14121 } ovl;
14122
14123 vassert(sizeof(formats) == 4);
14124
florianffbd84d2012-12-09 02:06:29 +000014125 ((UChar *)(&ovl.value))[0] = bytes[0];
14126 ((UChar *)(&ovl.value))[1] = bytes[1];
14127 ((UChar *)(&ovl.value))[2] = bytes[2];
14128 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000014129
14130 switch ((ovl.value & 0xff0f0000) >> 16) {
14131 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
14132 ovl.fmt.RI.i2); goto ok;
14133 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
14134 ovl.fmt.RI.i2); goto ok;
14135 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
14136 ovl.fmt.RI.i2); goto ok;
14137 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
14138 ovl.fmt.RI.i2); goto ok;
14139 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
14140 ovl.fmt.RI.i2); goto ok;
14141 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
14142 ovl.fmt.RI.i2); goto ok;
14143 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
14144 ovl.fmt.RI.i2); goto ok;
14145 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
14146 ovl.fmt.RI.i2); goto ok;
14147 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
14148 ovl.fmt.RI.i2); goto ok;
14149 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
14150 ovl.fmt.RI.i2); goto ok;
14151 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
14152 ovl.fmt.RI.i2); goto ok;
14153 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
14154 ovl.fmt.RI.i2); goto ok;
14155 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
14156 ovl.fmt.RI.i2); goto ok;
14157 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
14158 ovl.fmt.RI.i2); goto ok;
14159 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
14160 ovl.fmt.RI.i2); goto ok;
14161 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
14162 ovl.fmt.RI.i2); goto ok;
14163 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
14164 ovl.fmt.RI.i2); goto ok;
14165 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
14166 ovl.fmt.RI.i2); goto ok;
14167 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
14168 ovl.fmt.RI.i2); goto ok;
14169 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
14170 ovl.fmt.RI.i2); goto ok;
14171 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14172 goto ok;
14173 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
14174 ovl.fmt.RI.i2); goto ok;
14175 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
14176 ovl.fmt.RI.i2); goto ok;
14177 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
14178 ovl.fmt.RI.i2); goto ok;
14179 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14180 goto ok;
14181 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
14182 ovl.fmt.RI.i2); goto ok;
14183 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14184 goto ok;
14185 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
14186 ovl.fmt.RI.i2); goto ok;
14187 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14188 goto ok;
14189 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
14190 ovl.fmt.RI.i2); goto ok;
14191 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
14192 goto ok;
14193 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
14194 ovl.fmt.RI.i2); goto ok;
14195 }
14196
14197 switch ((ovl.value & 0xffff0000) >> 16) {
14198 case 0x8000: /* SSM */ goto unimplemented;
14199 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014200 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014201 case 0xb202: /* STIDP */ goto unimplemented;
14202 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000014203 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
14204 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014205 case 0xb206: /* SCKC */ goto unimplemented;
14206 case 0xb207: /* STCKC */ goto unimplemented;
14207 case 0xb208: /* SPT */ goto unimplemented;
14208 case 0xb209: /* STPT */ goto unimplemented;
14209 case 0xb20a: /* SPKA */ goto unimplemented;
14210 case 0xb20b: /* IPK */ goto unimplemented;
14211 case 0xb20d: /* PTLB */ goto unimplemented;
14212 case 0xb210: /* SPX */ goto unimplemented;
14213 case 0xb211: /* STPX */ goto unimplemented;
14214 case 0xb212: /* STAP */ goto unimplemented;
14215 case 0xb214: /* SIE */ goto unimplemented;
14216 case 0xb218: /* PC */ goto unimplemented;
14217 case 0xb219: /* SAC */ goto unimplemented;
14218 case 0xb21a: /* CFC */ goto unimplemented;
14219 case 0xb221: /* IPTE */ goto unimplemented;
14220 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
14221 case 0xb223: /* IVSK */ goto unimplemented;
14222 case 0xb224: /* IAC */ goto unimplemented;
14223 case 0xb225: /* SSAR */ goto unimplemented;
14224 case 0xb226: /* EPAR */ goto unimplemented;
14225 case 0xb227: /* ESAR */ goto unimplemented;
14226 case 0xb228: /* PT */ goto unimplemented;
14227 case 0xb229: /* ISKE */ goto unimplemented;
14228 case 0xb22a: /* RRBE */ goto unimplemented;
14229 case 0xb22b: /* SSKE */ goto unimplemented;
14230 case 0xb22c: /* TB */ goto unimplemented;
14231 case 0xb22d: /* DXR */ goto unimplemented;
14232 case 0xb22e: /* PGIN */ goto unimplemented;
14233 case 0xb22f: /* PGOUT */ goto unimplemented;
14234 case 0xb230: /* CSCH */ goto unimplemented;
14235 case 0xb231: /* HSCH */ goto unimplemented;
14236 case 0xb232: /* MSCH */ goto unimplemented;
14237 case 0xb233: /* SSCH */ goto unimplemented;
14238 case 0xb234: /* STSCH */ goto unimplemented;
14239 case 0xb235: /* TSCH */ goto unimplemented;
14240 case 0xb236: /* TPI */ goto unimplemented;
14241 case 0xb237: /* SAL */ goto unimplemented;
14242 case 0xb238: /* RSCH */ goto unimplemented;
14243 case 0xb239: /* STCRW */ goto unimplemented;
14244 case 0xb23a: /* STCPS */ goto unimplemented;
14245 case 0xb23b: /* RCHP */ goto unimplemented;
14246 case 0xb23c: /* SCHM */ goto unimplemented;
14247 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000014248 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
14249 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014250 case 0xb244: /* SQDR */ goto unimplemented;
14251 case 0xb245: /* SQER */ goto unimplemented;
14252 case 0xb246: /* STURA */ goto unimplemented;
14253 case 0xb247: /* MSTA */ goto unimplemented;
14254 case 0xb248: /* PALB */ goto unimplemented;
14255 case 0xb249: /* EREG */ goto unimplemented;
14256 case 0xb24a: /* ESTA */ goto unimplemented;
14257 case 0xb24b: /* LURA */ goto unimplemented;
14258 case 0xb24c: /* TAR */ goto unimplemented;
14259 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
14260 ovl.fmt.RRE.r2); goto ok;
14261 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14262 goto ok;
14263 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
14264 goto ok;
14265 case 0xb250: /* CSP */ goto unimplemented;
14266 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
14267 ovl.fmt.RRE.r2); goto ok;
14268 case 0xb254: /* MVPG */ goto unimplemented;
14269 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
14270 ovl.fmt.RRE.r2); goto ok;
14271 case 0xb257: /* CUSE */ goto unimplemented;
14272 case 0xb258: /* BSG */ goto unimplemented;
14273 case 0xb25a: /* BSA */ goto unimplemented;
14274 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
14275 ovl.fmt.RRE.r2); goto ok;
14276 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
14277 ovl.fmt.RRE.r2); goto ok;
14278 case 0xb263: /* CMPSC */ goto unimplemented;
14279 case 0xb274: /* SIGA */ goto unimplemented;
14280 case 0xb276: /* XSCH */ goto unimplemented;
14281 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014282 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 +000014283 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000014284 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 +000014285 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014286 case 0xb280: /* LPP */ goto unimplemented;
14287 case 0xb284: /* LCCTL */ goto unimplemented;
14288 case 0xb285: /* LPCTL */ goto unimplemented;
14289 case 0xb286: /* QSI */ goto unimplemented;
14290 case 0xb287: /* LSCTL */ goto unimplemented;
14291 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014292 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
14293 goto ok;
14294 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14295 goto ok;
14296 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
14297 goto ok;
florian730448f2012-02-04 17:07:07 +000014298 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 +000014299 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
14300 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14301 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000014302 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
14303 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14304 goto ok;
florian933065d2011-07-11 01:48:02 +000014305 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
14306 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014307 case 0xb2b1: /* STFL */ goto unimplemented;
14308 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000014309 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
14310 goto ok;
florian82cdba62013-03-12 01:31:24 +000014311 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
14312 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014313 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014314 case 0xb2e0: /* SCCTR */ goto unimplemented;
14315 case 0xb2e1: /* SPCTR */ goto unimplemented;
14316 case 0xb2e4: /* ECCTR */ goto unimplemented;
14317 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014318 case 0xb2e8: /* PPA */ goto unimplemented;
14319 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014320 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014321 case 0xb2f8: /* TEND */ goto unimplemented;
14322 case 0xb2fa: /* NIAI */ goto unimplemented;
14323 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014324 case 0xb2ff: /* TRAP4 */ goto unimplemented;
14325 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14326 ovl.fmt.RRE.r2); goto ok;
14327 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14328 ovl.fmt.RRE.r2); goto ok;
14329 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14330 ovl.fmt.RRE.r2); goto ok;
14331 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14332 ovl.fmt.RRE.r2); goto ok;
14333 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14334 ovl.fmt.RRE.r2); goto ok;
14335 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14336 ovl.fmt.RRE.r2); goto ok;
14337 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14338 ovl.fmt.RRE.r2); goto ok;
14339 case 0xb307: /* MXDBR */ goto unimplemented;
14340 case 0xb308: /* KEBR */ goto unimplemented;
14341 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14342 ovl.fmt.RRE.r2); goto ok;
14343 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14344 ovl.fmt.RRE.r2); goto ok;
14345 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14346 ovl.fmt.RRE.r2); goto ok;
14347 case 0xb30c: /* MDEBR */ goto unimplemented;
14348 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14349 ovl.fmt.RRE.r2); goto ok;
14350 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14351 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14352 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14353 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14354 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14355 ovl.fmt.RRE.r2); goto ok;
14356 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14357 ovl.fmt.RRE.r2); goto ok;
14358 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14359 ovl.fmt.RRE.r2); goto ok;
14360 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14361 ovl.fmt.RRE.r2); goto ok;
14362 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14363 ovl.fmt.RRE.r2); goto ok;
14364 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14365 ovl.fmt.RRE.r2); goto ok;
14366 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14367 ovl.fmt.RRE.r2); goto ok;
14368 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14369 ovl.fmt.RRE.r2); goto ok;
14370 case 0xb318: /* KDBR */ goto unimplemented;
14371 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14372 ovl.fmt.RRE.r2); goto ok;
14373 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14374 ovl.fmt.RRE.r2); goto ok;
14375 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14376 ovl.fmt.RRE.r2); goto ok;
14377 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14378 ovl.fmt.RRE.r2); goto ok;
14379 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14380 ovl.fmt.RRE.r2); goto ok;
14381 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14382 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14383 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14384 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14385 case 0xb324: /* LDER */ goto unimplemented;
14386 case 0xb325: /* LXDR */ goto unimplemented;
14387 case 0xb326: /* LXER */ goto unimplemented;
14388 case 0xb32e: /* MAER */ goto unimplemented;
14389 case 0xb32f: /* MSER */ goto unimplemented;
14390 case 0xb336: /* SQXR */ goto unimplemented;
14391 case 0xb337: /* MEER */ goto unimplemented;
14392 case 0xb338: /* MAYLR */ goto unimplemented;
14393 case 0xb339: /* MYLR */ goto unimplemented;
14394 case 0xb33a: /* MAYR */ goto unimplemented;
14395 case 0xb33b: /* MYR */ goto unimplemented;
14396 case 0xb33c: /* MAYHR */ goto unimplemented;
14397 case 0xb33d: /* MYHR */ goto unimplemented;
14398 case 0xb33e: /* MADR */ goto unimplemented;
14399 case 0xb33f: /* MSDR */ goto unimplemented;
14400 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14401 ovl.fmt.RRE.r2); goto ok;
14402 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14403 ovl.fmt.RRE.r2); goto ok;
14404 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14405 ovl.fmt.RRE.r2); goto ok;
14406 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14407 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014408 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14409 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14410 ovl.fmt.RRF2.r2); goto ok;
14411 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14412 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14413 ovl.fmt.RRF2.r2); goto ok;
14414 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14415 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14416 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014417 case 0xb347: /* FIXBR */ goto unimplemented;
14418 case 0xb348: /* KXBR */ goto unimplemented;
14419 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14420 ovl.fmt.RRE.r2); goto ok;
14421 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14422 ovl.fmt.RRE.r2); goto ok;
14423 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14424 ovl.fmt.RRE.r2); goto ok;
14425 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14426 ovl.fmt.RRE.r2); goto ok;
14427 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14428 ovl.fmt.RRE.r2); goto ok;
14429 case 0xb350: /* TBEDR */ goto unimplemented;
14430 case 0xb351: /* TBDR */ goto unimplemented;
14431 case 0xb353: /* DIEBR */ goto unimplemented;
14432 case 0xb357: /* FIEBR */ goto unimplemented;
14433 case 0xb358: /* THDER */ goto unimplemented;
14434 case 0xb359: /* THDR */ goto unimplemented;
14435 case 0xb35b: /* DIDBR */ goto unimplemented;
14436 case 0xb35f: /* FIDBR */ goto unimplemented;
14437 case 0xb360: /* LPXR */ goto unimplemented;
14438 case 0xb361: /* LNXR */ goto unimplemented;
14439 case 0xb362: /* LTXR */ goto unimplemented;
14440 case 0xb363: /* LCXR */ goto unimplemented;
14441 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14442 ovl.fmt.RRE.r2); goto ok;
14443 case 0xb366: /* LEXR */ goto unimplemented;
14444 case 0xb367: /* FIXR */ goto unimplemented;
14445 case 0xb369: /* CXR */ goto unimplemented;
14446 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14447 ovl.fmt.RRE.r2); goto ok;
14448 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14449 ovl.fmt.RRE.r2); goto ok;
14450 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14451 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14452 goto ok;
14453 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14454 ovl.fmt.RRE.r2); goto ok;
14455 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14456 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14457 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14458 case 0xb377: /* FIER */ goto unimplemented;
14459 case 0xb37f: /* FIDR */ goto unimplemented;
14460 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14461 case 0xb385: /* SFASR */ goto unimplemented;
14462 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014463 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14464 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14465 ovl.fmt.RRF2.r2); goto ok;
14466 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14467 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14468 ovl.fmt.RRF2.r2); goto ok;
14469 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14470 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14471 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014472 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14473 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14474 ovl.fmt.RRF2.r2); goto ok;
14475 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14476 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14477 ovl.fmt.RRF2.r2); goto ok;
14478 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14479 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14480 ovl.fmt.RRF2.r2); goto ok;
14481 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14482 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14483 ovl.fmt.RRF2.r2); goto ok;
14484 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14485 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14486 ovl.fmt.RRF2.r2); goto ok;
14487 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14488 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14489 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014490 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14491 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14492 ovl.fmt.RRF2.r2); goto ok;
14493 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14494 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14495 ovl.fmt.RRF2.r2); goto ok;
14496 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14497 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14498 ovl.fmt.RRF2.r2); goto ok;
14499 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14500 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14501 ovl.fmt.RRF2.r2); goto ok;
14502 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14503 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14504 ovl.fmt.RRF2.r2); goto ok;
14505 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14506 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14507 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014508 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14509 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14510 ovl.fmt.RRF2.r2); goto ok;
14511 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14512 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14513 ovl.fmt.RRF2.r2); goto ok;
14514 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14515 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14516 ovl.fmt.RRF2.r2); goto ok;
14517 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14518 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14519 ovl.fmt.RRF2.r2); goto ok;
14520 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14521 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14522 ovl.fmt.RRF2.r2); goto ok;
14523 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14524 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14525 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014526 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14527 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14528 ovl.fmt.RRF2.r2); goto ok;
14529 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14530 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14531 ovl.fmt.RRF2.r2); goto ok;
14532 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14533 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14534 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014535 case 0xb3b4: /* CEFR */ goto unimplemented;
14536 case 0xb3b5: /* CDFR */ goto unimplemented;
14537 case 0xb3b6: /* CXFR */ goto unimplemented;
14538 case 0xb3b8: /* CFER */ goto unimplemented;
14539 case 0xb3b9: /* CFDR */ goto unimplemented;
14540 case 0xb3ba: /* CFXR */ goto unimplemented;
14541 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14542 ovl.fmt.RRE.r2); goto ok;
14543 case 0xb3c4: /* CEGR */ goto unimplemented;
14544 case 0xb3c5: /* CDGR */ goto unimplemented;
14545 case 0xb3c6: /* CXGR */ goto unimplemented;
14546 case 0xb3c8: /* CGER */ goto unimplemented;
14547 case 0xb3c9: /* CGDR */ goto unimplemented;
14548 case 0xb3ca: /* CGXR */ goto unimplemented;
14549 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14550 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014551 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14552 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14553 ovl.fmt.RRF4.r2); goto ok;
14554 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14555 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14556 ovl.fmt.RRF4.r2); goto ok;
14557 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14558 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14559 ovl.fmt.RRF4.r2); goto ok;
14560 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14561 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14562 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014563 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14564 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14565 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14566 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14567 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014568 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14569 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014570 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014571 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14572 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14573 ovl.fmt.RRF4.r2); goto ok;
14574 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14575 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14576 ovl.fmt.RRF4.r2); goto ok;
14577 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14578 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14579 ovl.fmt.RRF4.r2); goto ok;
14580 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14581 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14582 ovl.fmt.RRF4.r2); goto ok;
14583 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14584 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14585 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14586 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14587 ovl.fmt.RRF2.r2); goto ok;
14588 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14589 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014590 case 0xb3df: /* FIXTR */ goto unimplemented;
14591 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014592 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14593 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14594 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014595 case 0xb3e2: /* CUDTR */ goto unimplemented;
14596 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014597 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14598 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014599 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14600 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014601 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14602 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014603 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014604 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14605 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14606 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014607 case 0xb3ea: /* CUXTR */ goto unimplemented;
14608 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014609 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14610 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014611 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14612 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014613 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14614 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014615 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14616 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14617 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014618 case 0xb3f2: /* CDUTR */ goto unimplemented;
14619 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014620 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14621 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014622 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14623 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14624 ovl.fmt.RRF4.r2); goto ok;
14625 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14626 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14627 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14628 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14629 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014630 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14631 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14632 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014633 case 0xb3fa: /* CXUTR */ goto unimplemented;
14634 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014635 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14636 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014637 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14638 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14639 ovl.fmt.RRF4.r2); goto ok;
14640 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14641 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14642 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14643 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14644 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014645 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14646 ovl.fmt.RRE.r2); goto ok;
14647 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14648 ovl.fmt.RRE.r2); goto ok;
14649 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14650 ovl.fmt.RRE.r2); goto ok;
14651 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14652 ovl.fmt.RRE.r2); goto ok;
14653 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14654 ovl.fmt.RRE.r2); goto ok;
14655 case 0xb905: /* LURAG */ goto unimplemented;
14656 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14657 ovl.fmt.RRE.r2); goto ok;
14658 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14659 ovl.fmt.RRE.r2); goto ok;
14660 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14661 ovl.fmt.RRE.r2); goto ok;
14662 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14663 ovl.fmt.RRE.r2); goto ok;
14664 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14665 ovl.fmt.RRE.r2); goto ok;
14666 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14667 ovl.fmt.RRE.r2); goto ok;
14668 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14669 ovl.fmt.RRE.r2); goto ok;
14670 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14671 ovl.fmt.RRE.r2); goto ok;
14672 case 0xb90e: /* EREGG */ goto unimplemented;
14673 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14674 ovl.fmt.RRE.r2); goto ok;
14675 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14676 ovl.fmt.RRE.r2); goto ok;
14677 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14678 ovl.fmt.RRE.r2); goto ok;
14679 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14680 ovl.fmt.RRE.r2); goto ok;
14681 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14682 ovl.fmt.RRE.r2); goto ok;
14683 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14684 ovl.fmt.RRE.r2); goto ok;
14685 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14686 ovl.fmt.RRE.r2); goto ok;
14687 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14688 ovl.fmt.RRE.r2); goto ok;
14689 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14690 ovl.fmt.RRE.r2); goto ok;
14691 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14692 ovl.fmt.RRE.r2); goto ok;
14693 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14694 ovl.fmt.RRE.r2); goto ok;
14695 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14696 ovl.fmt.RRE.r2); goto ok;
14697 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14698 ovl.fmt.RRE.r2); goto ok;
14699 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14700 ovl.fmt.RRE.r2); goto ok;
14701 case 0xb91e: /* KMAC */ goto unimplemented;
14702 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14703 ovl.fmt.RRE.r2); goto ok;
14704 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14705 ovl.fmt.RRE.r2); goto ok;
14706 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14707 ovl.fmt.RRE.r2); goto ok;
14708 case 0xb925: /* STURG */ goto unimplemented;
14709 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14710 ovl.fmt.RRE.r2); goto ok;
14711 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14712 ovl.fmt.RRE.r2); goto ok;
14713 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014714 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014715 case 0xb92b: /* KMO */ goto unimplemented;
14716 case 0xb92c: /* PCC */ goto unimplemented;
14717 case 0xb92d: /* KMCTR */ goto unimplemented;
14718 case 0xb92e: /* KM */ goto unimplemented;
14719 case 0xb92f: /* KMC */ goto unimplemented;
14720 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14721 ovl.fmt.RRE.r2); goto ok;
14722 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14723 ovl.fmt.RRE.r2); goto ok;
14724 case 0xb93e: /* KIMD */ goto unimplemented;
14725 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014726 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14727 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14728 ovl.fmt.RRF2.r2); goto ok;
14729 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14730 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14731 ovl.fmt.RRF2.r2); goto ok;
14732 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14733 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14734 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014735 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14736 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014737 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14738 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14739 ovl.fmt.RRF2.r2); goto ok;
14740 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14741 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14742 ovl.fmt.RRF2.r2); goto ok;
14743 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14744 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14745 ovl.fmt.RRF2.r2); goto ok;
14746 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14747 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14748 ovl.fmt.RRF2.r2); goto ok;
14749 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14750 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14751 ovl.fmt.RRF2.r2); goto ok;
14752 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14753 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14754 ovl.fmt.RRF2.r2); goto ok;
14755 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14756 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14757 ovl.fmt.RRF2.r2); goto ok;
14758 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14759 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14760 ovl.fmt.RRF2.r2); goto ok;
14761 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14762 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14763 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014764 case 0xb960: /* CGRT */ goto unimplemented;
14765 case 0xb961: /* CLGRT */ goto unimplemented;
14766 case 0xb972: /* CRT */ goto unimplemented;
14767 case 0xb973: /* CLRT */ goto unimplemented;
14768 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14769 ovl.fmt.RRE.r2); goto ok;
14770 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14771 ovl.fmt.RRE.r2); goto ok;
14772 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14773 ovl.fmt.RRE.r2); goto ok;
14774 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14775 ovl.fmt.RRE.r2); goto ok;
14776 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14777 ovl.fmt.RRE.r2); goto ok;
14778 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14779 ovl.fmt.RRE.r2); goto ok;
14780 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14781 ovl.fmt.RRE.r2); goto ok;
14782 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14783 ovl.fmt.RRE.r2); goto ok;
14784 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14785 ovl.fmt.RRE.r2); goto ok;
14786 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14787 ovl.fmt.RRE.r2); goto ok;
14788 case 0xb98a: /* CSPG */ goto unimplemented;
14789 case 0xb98d: /* EPSW */ goto unimplemented;
14790 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014791 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014792 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14793 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14794 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14795 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14796 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14797 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014798 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14799 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014800 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14801 ovl.fmt.RRE.r2); goto ok;
14802 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14803 ovl.fmt.RRE.r2); goto ok;
14804 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14805 ovl.fmt.RRE.r2); goto ok;
14806 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14807 ovl.fmt.RRE.r2); goto ok;
14808 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14809 ovl.fmt.RRE.r2); goto ok;
14810 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14811 ovl.fmt.RRE.r2); goto ok;
14812 case 0xb99a: /* EPAIR */ goto unimplemented;
14813 case 0xb99b: /* ESAIR */ goto unimplemented;
14814 case 0xb99d: /* ESEA */ goto unimplemented;
14815 case 0xb99e: /* PTI */ goto unimplemented;
14816 case 0xb99f: /* SSAIR */ goto unimplemented;
14817 case 0xb9a2: /* PTF */ goto unimplemented;
14818 case 0xb9aa: /* LPTEA */ goto unimplemented;
14819 case 0xb9ae: /* RRBM */ goto unimplemented;
14820 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014821 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14822 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14823 goto ok;
florian2a415a12012-07-21 17:41:36 +000014824 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14825 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14826 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014827 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14828 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014829 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14830 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014831 case 0xb9bd: /* TRTRE */ goto unimplemented;
14832 case 0xb9be: /* SRSTU */ goto unimplemented;
14833 case 0xb9bf: /* TRTE */ goto unimplemented;
14834 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14835 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14836 goto ok;
14837 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14838 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14839 goto ok;
14840 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14841 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14842 goto ok;
14843 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14844 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14845 goto ok;
14846 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14847 ovl.fmt.RRE.r2); goto ok;
14848 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14849 ovl.fmt.RRE.r2); goto ok;
14850 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14851 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14852 goto ok;
14853 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14854 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14855 goto ok;
14856 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14857 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14858 goto ok;
14859 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14860 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14861 goto ok;
14862 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14863 ovl.fmt.RRE.r2); goto ok;
14864 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14865 ovl.fmt.RRE.r2); goto ok;
14866 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014867 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14868 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14869 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014870 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14871 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14872 goto ok;
14873 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14874 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14875 goto ok;
14876 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14877 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14878 goto ok;
14879 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14880 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14881 goto ok;
14882 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14883 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14884 goto ok;
14885 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14886 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14887 goto ok;
14888 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14889 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14890 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014891 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14892 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14893 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014894 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14895 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14896 goto ok;
14897 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14898 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14899 goto ok;
14900 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14901 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14902 goto ok;
14903 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14904 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14905 goto ok;
14906 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14907 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14908 goto ok;
14909 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14910 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14911 goto ok;
14912 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14913 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14914 goto ok;
14915 }
14916
14917 switch ((ovl.value & 0xff000000) >> 24) {
14918 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14919 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14920 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14921 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14922 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14923 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14924 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14925 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14926 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14927 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14928 case 0x45: /* BAL */ goto unimplemented;
14929 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14930 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14931 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14932 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14933 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14934 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14935 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14936 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14937 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14938 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14939 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14940 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14941 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14942 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14943 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14944 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14945 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14946 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14947 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14948 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14949 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14950 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14951 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14952 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14953 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14954 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14955 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14956 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14957 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14958 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14959 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14960 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14961 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14962 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14963 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14964 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14965 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14966 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14967 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14968 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14969 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14970 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14971 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14972 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14973 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14974 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14975 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14976 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14977 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14978 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14979 case 0x67: /* MXD */ goto unimplemented;
14980 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14981 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14982 case 0x69: /* CD */ goto unimplemented;
14983 case 0x6a: /* AD */ goto unimplemented;
14984 case 0x6b: /* SD */ goto unimplemented;
14985 case 0x6c: /* MD */ goto unimplemented;
14986 case 0x6d: /* DD */ goto unimplemented;
14987 case 0x6e: /* AW */ goto unimplemented;
14988 case 0x6f: /* SW */ goto unimplemented;
14989 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14990 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14991 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14992 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14993 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14994 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14995 case 0x79: /* CE */ goto unimplemented;
14996 case 0x7a: /* AE */ goto unimplemented;
14997 case 0x7b: /* SE */ goto unimplemented;
14998 case 0x7c: /* MDE */ goto unimplemented;
14999 case 0x7d: /* DE */ goto unimplemented;
15000 case 0x7e: /* AU */ goto unimplemented;
15001 case 0x7f: /* SU */ goto unimplemented;
15002 case 0x83: /* DIAG */ goto unimplemented;
15003 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
15004 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15005 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
15006 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
15007 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15008 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15009 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15010 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15011 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15012 ovl.fmt.RS.d2); goto ok;
15013 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15014 ovl.fmt.RS.d2); goto ok;
15015 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15016 ovl.fmt.RS.d2); goto ok;
15017 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15018 ovl.fmt.RS.d2); goto ok;
15019 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15020 ovl.fmt.RS.d2); goto ok;
15021 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15022 ovl.fmt.RS.d2); goto ok;
15023 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15024 ovl.fmt.RS.d2); goto ok;
15025 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
15026 ovl.fmt.RS.d2); goto ok;
15027 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15028 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15029 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15030 ovl.fmt.SI.d1); goto ok;
15031 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15032 ovl.fmt.SI.d1); goto ok;
15033 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15034 ovl.fmt.SI.d1); goto ok;
15035 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15036 ovl.fmt.SI.d1); goto ok;
15037 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15038 ovl.fmt.SI.d1); goto ok;
15039 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
15040 ovl.fmt.SI.d1); goto ok;
15041 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15042 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15043 case 0x99: /* TRACE */ goto unimplemented;
15044 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15045 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15046 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15047 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15048 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
15049 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15050 goto ok;
15051 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
15052 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
15053 goto ok;
15054 case 0xac: /* STNSM */ goto unimplemented;
15055 case 0xad: /* STOSM */ goto unimplemented;
15056 case 0xae: /* SIGP */ goto unimplemented;
15057 case 0xaf: /* MC */ goto unimplemented;
15058 case 0xb1: /* LRA */ goto unimplemented;
15059 case 0xb6: /* STCTL */ goto unimplemented;
15060 case 0xb7: /* LCTL */ goto unimplemented;
15061 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15062 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015063 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15064 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015065 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15066 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15067 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15068 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15069 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
15070 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
15071 }
15072
15073 return S390_DECODE_UNKNOWN_INSN;
15074
15075ok:
15076 return S390_DECODE_OK;
15077
15078unimplemented:
15079 return S390_DECODE_UNIMPLEMENTED_INSN;
15080}
15081
15082static s390_decode_t
15083s390_decode_6byte_and_irgen(UChar *bytes)
15084{
15085 typedef union {
15086 struct {
15087 unsigned int op1 : 8;
15088 unsigned int r1 : 4;
15089 unsigned int r3 : 4;
15090 unsigned int i2 : 16;
15091 unsigned int : 8;
15092 unsigned int op2 : 8;
15093 } RIE;
15094 struct {
15095 unsigned int op1 : 8;
15096 unsigned int r1 : 4;
15097 unsigned int r2 : 4;
15098 unsigned int i3 : 8;
15099 unsigned int i4 : 8;
15100 unsigned int i5 : 8;
15101 unsigned int op2 : 8;
15102 } RIE_RRUUU;
15103 struct {
15104 unsigned int op1 : 8;
15105 unsigned int r1 : 4;
15106 unsigned int : 4;
15107 unsigned int i2 : 16;
15108 unsigned int m3 : 4;
15109 unsigned int : 4;
15110 unsigned int op2 : 8;
15111 } RIEv1;
15112 struct {
15113 unsigned int op1 : 8;
15114 unsigned int r1 : 4;
15115 unsigned int r2 : 4;
15116 unsigned int i4 : 16;
15117 unsigned int m3 : 4;
15118 unsigned int : 4;
15119 unsigned int op2 : 8;
15120 } RIE_RRPU;
15121 struct {
15122 unsigned int op1 : 8;
15123 unsigned int r1 : 4;
15124 unsigned int m3 : 4;
15125 unsigned int i4 : 16;
15126 unsigned int i2 : 8;
15127 unsigned int op2 : 8;
15128 } RIEv3;
15129 struct {
15130 unsigned int op1 : 8;
15131 unsigned int r1 : 4;
15132 unsigned int op2 : 4;
15133 unsigned int i2 : 32;
15134 } RIL;
15135 struct {
15136 unsigned int op1 : 8;
15137 unsigned int r1 : 4;
15138 unsigned int m3 : 4;
15139 unsigned int b4 : 4;
15140 unsigned int d4 : 12;
15141 unsigned int i2 : 8;
15142 unsigned int op2 : 8;
15143 } RIS;
15144 struct {
15145 unsigned int op1 : 8;
15146 unsigned int r1 : 4;
15147 unsigned int r2 : 4;
15148 unsigned int b4 : 4;
15149 unsigned int d4 : 12;
15150 unsigned int m3 : 4;
15151 unsigned int : 4;
15152 unsigned int op2 : 8;
15153 } RRS;
15154 struct {
15155 unsigned int op1 : 8;
15156 unsigned int l1 : 4;
15157 unsigned int : 4;
15158 unsigned int b1 : 4;
15159 unsigned int d1 : 12;
15160 unsigned int : 8;
15161 unsigned int op2 : 8;
15162 } RSL;
15163 struct {
15164 unsigned int op1 : 8;
15165 unsigned int r1 : 4;
15166 unsigned int r3 : 4;
15167 unsigned int b2 : 4;
15168 unsigned int dl2 : 12;
15169 unsigned int dh2 : 8;
15170 unsigned int op2 : 8;
15171 } RSY;
15172 struct {
15173 unsigned int op1 : 8;
15174 unsigned int r1 : 4;
15175 unsigned int x2 : 4;
15176 unsigned int b2 : 4;
15177 unsigned int d2 : 12;
15178 unsigned int : 8;
15179 unsigned int op2 : 8;
15180 } RXE;
15181 struct {
15182 unsigned int op1 : 8;
15183 unsigned int r3 : 4;
15184 unsigned int x2 : 4;
15185 unsigned int b2 : 4;
15186 unsigned int d2 : 12;
15187 unsigned int r1 : 4;
15188 unsigned int : 4;
15189 unsigned int op2 : 8;
15190 } RXF;
15191 struct {
15192 unsigned int op1 : 8;
15193 unsigned int r1 : 4;
15194 unsigned int x2 : 4;
15195 unsigned int b2 : 4;
15196 unsigned int dl2 : 12;
15197 unsigned int dh2 : 8;
15198 unsigned int op2 : 8;
15199 } RXY;
15200 struct {
15201 unsigned int op1 : 8;
15202 unsigned int i2 : 8;
15203 unsigned int b1 : 4;
15204 unsigned int dl1 : 12;
15205 unsigned int dh1 : 8;
15206 unsigned int op2 : 8;
15207 } SIY;
15208 struct {
15209 unsigned int op : 8;
15210 unsigned int l : 8;
15211 unsigned int b1 : 4;
15212 unsigned int d1 : 12;
15213 unsigned int b2 : 4;
15214 unsigned int d2 : 12;
15215 } SS;
15216 struct {
15217 unsigned int op : 8;
15218 unsigned int l1 : 4;
15219 unsigned int l2 : 4;
15220 unsigned int b1 : 4;
15221 unsigned int d1 : 12;
15222 unsigned int b2 : 4;
15223 unsigned int d2 : 12;
15224 } SS_LLRDRD;
15225 struct {
15226 unsigned int op : 8;
15227 unsigned int r1 : 4;
15228 unsigned int r3 : 4;
15229 unsigned int b2 : 4;
15230 unsigned int d2 : 12;
15231 unsigned int b4 : 4;
15232 unsigned int d4 : 12;
15233 } SS_RRRDRD2;
15234 struct {
15235 unsigned int op : 16;
15236 unsigned int b1 : 4;
15237 unsigned int d1 : 12;
15238 unsigned int b2 : 4;
15239 unsigned int d2 : 12;
15240 } SSE;
15241 struct {
15242 unsigned int op1 : 8;
15243 unsigned int r3 : 4;
15244 unsigned int op2 : 4;
15245 unsigned int b1 : 4;
15246 unsigned int d1 : 12;
15247 unsigned int b2 : 4;
15248 unsigned int d2 : 12;
15249 } SSF;
15250 struct {
15251 unsigned int op : 16;
15252 unsigned int b1 : 4;
15253 unsigned int d1 : 12;
15254 unsigned int i2 : 16;
15255 } SIL;
15256 } formats;
15257 union {
15258 formats fmt;
15259 ULong value;
15260 } ovl;
15261
15262 vassert(sizeof(formats) == 6);
15263
florianffbd84d2012-12-09 02:06:29 +000015264 ((UChar *)(&ovl.value))[0] = bytes[0];
15265 ((UChar *)(&ovl.value))[1] = bytes[1];
15266 ((UChar *)(&ovl.value))[2] = bytes[2];
15267 ((UChar *)(&ovl.value))[3] = bytes[3];
15268 ((UChar *)(&ovl.value))[4] = bytes[4];
15269 ((UChar *)(&ovl.value))[5] = bytes[5];
15270 ((UChar *)(&ovl.value))[6] = 0x0;
15271 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000015272
15273 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
15274 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
15275 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15276 ovl.fmt.RXY.dl2,
15277 ovl.fmt.RXY.dh2); goto ok;
15278 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
15279 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
15280 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15281 ovl.fmt.RXY.dl2,
15282 ovl.fmt.RXY.dh2); goto ok;
15283 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
15284 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15285 ovl.fmt.RXY.dl2,
15286 ovl.fmt.RXY.dh2); goto ok;
15287 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
15288 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15289 ovl.fmt.RXY.dl2,
15290 ovl.fmt.RXY.dh2); goto ok;
15291 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
15292 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15293 ovl.fmt.RXY.dl2,
15294 ovl.fmt.RXY.dh2); goto ok;
15295 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
15296 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15297 ovl.fmt.RXY.dl2,
15298 ovl.fmt.RXY.dh2); goto ok;
15299 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
15300 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15301 ovl.fmt.RXY.dl2,
15302 ovl.fmt.RXY.dh2); goto ok;
15303 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
15304 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15305 ovl.fmt.RXY.dl2,
15306 ovl.fmt.RXY.dh2); goto ok;
15307 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
15308 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15309 ovl.fmt.RXY.dl2,
15310 ovl.fmt.RXY.dh2); goto ok;
15311 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
15312 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15313 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15314 ovl.fmt.RXY.dl2,
15315 ovl.fmt.RXY.dh2); goto ok;
15316 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15317 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15318 ovl.fmt.RXY.dl2,
15319 ovl.fmt.RXY.dh2); goto ok;
15320 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15321 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15322 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15323 ovl.fmt.RXY.dl2,
15324 ovl.fmt.RXY.dh2); goto ok;
15325 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15326 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15327 ovl.fmt.RXY.dl2,
15328 ovl.fmt.RXY.dh2); goto ok;
15329 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15330 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15331 ovl.fmt.RXY.dl2,
15332 ovl.fmt.RXY.dh2); goto ok;
15333 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15334 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15335 ovl.fmt.RXY.dl2,
15336 ovl.fmt.RXY.dh2); goto ok;
15337 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15338 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15339 ovl.fmt.RXY.dl2,
15340 ovl.fmt.RXY.dh2); goto ok;
15341 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15342 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15343 ovl.fmt.RXY.dl2,
15344 ovl.fmt.RXY.dh2); goto ok;
15345 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15346 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15347 ovl.fmt.RXY.dl2,
15348 ovl.fmt.RXY.dh2); goto ok;
15349 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15350 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15351 ovl.fmt.RXY.dl2,
15352 ovl.fmt.RXY.dh2); goto ok;
15353 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15354 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15355 ovl.fmt.RXY.dl2,
15356 ovl.fmt.RXY.dh2); goto ok;
15357 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15358 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15359 ovl.fmt.RXY.dl2,
15360 ovl.fmt.RXY.dh2); goto ok;
15361 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15362 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15363 ovl.fmt.RXY.dl2,
15364 ovl.fmt.RXY.dh2); goto ok;
15365 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15366 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15367 ovl.fmt.RXY.dl2,
15368 ovl.fmt.RXY.dh2); goto ok;
15369 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15370 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15371 ovl.fmt.RXY.dl2,
15372 ovl.fmt.RXY.dh2); goto ok;
15373 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15374 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15375 ovl.fmt.RXY.dl2,
15376 ovl.fmt.RXY.dh2); goto ok;
15377 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15378 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15379 ovl.fmt.RXY.dl2,
15380 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015381 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015382 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15383 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15384 ovl.fmt.RXY.dl2,
15385 ovl.fmt.RXY.dh2); goto ok;
15386 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15387 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15388 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15389 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15390 ovl.fmt.RXY.dh2); goto ok;
15391 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15392 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15393 ovl.fmt.RXY.dl2,
15394 ovl.fmt.RXY.dh2); goto ok;
15395 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15396 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15397 ovl.fmt.RXY.dl2,
15398 ovl.fmt.RXY.dh2); goto ok;
15399 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15400 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15401 ovl.fmt.RXY.dl2,
15402 ovl.fmt.RXY.dh2); goto ok;
15403 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15404 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15405 ovl.fmt.RXY.dl2,
15406 ovl.fmt.RXY.dh2); goto ok;
15407 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15408 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15409 ovl.fmt.RXY.dl2,
15410 ovl.fmt.RXY.dh2); goto ok;
15411 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15412 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15413 ovl.fmt.RXY.dl2,
15414 ovl.fmt.RXY.dh2); goto ok;
15415 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15416 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15417 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15418 ovl.fmt.RXY.dh2); goto ok;
15419 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15420 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15421 ovl.fmt.RXY.dl2,
15422 ovl.fmt.RXY.dh2); goto ok;
15423 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15424 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15425 ovl.fmt.RXY.dl2,
15426 ovl.fmt.RXY.dh2); goto ok;
15427 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15428 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15429 ovl.fmt.RXY.dl2,
15430 ovl.fmt.RXY.dh2); goto ok;
15431 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15432 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15433 ovl.fmt.RXY.dl2,
15434 ovl.fmt.RXY.dh2); goto ok;
15435 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15436 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15437 ovl.fmt.RXY.dl2,
15438 ovl.fmt.RXY.dh2); goto ok;
15439 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15440 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15441 ovl.fmt.RXY.dl2,
15442 ovl.fmt.RXY.dh2); goto ok;
15443 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15444 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15445 ovl.fmt.RXY.dl2,
15446 ovl.fmt.RXY.dh2); goto ok;
15447 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15448 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15449 ovl.fmt.RXY.dl2,
15450 ovl.fmt.RXY.dh2); goto ok;
15451 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15452 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15453 ovl.fmt.RXY.dl2,
15454 ovl.fmt.RXY.dh2); goto ok;
15455 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15456 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15457 ovl.fmt.RXY.dl2,
15458 ovl.fmt.RXY.dh2); goto ok;
15459 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15460 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15461 ovl.fmt.RXY.dl2,
15462 ovl.fmt.RXY.dh2); goto ok;
15463 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15464 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15465 ovl.fmt.RXY.dl2,
15466 ovl.fmt.RXY.dh2); goto ok;
15467 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15468 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15469 ovl.fmt.RXY.dl2,
15470 ovl.fmt.RXY.dh2); goto ok;
15471 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15472 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15473 ovl.fmt.RXY.dl2,
15474 ovl.fmt.RXY.dh2); goto ok;
15475 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15476 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15477 ovl.fmt.RXY.dl2,
15478 ovl.fmt.RXY.dh2); goto ok;
15479 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15480 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15481 ovl.fmt.RXY.dl2,
15482 ovl.fmt.RXY.dh2); goto ok;
15483 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15484 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15485 ovl.fmt.RXY.dl2,
15486 ovl.fmt.RXY.dh2); goto ok;
15487 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15488 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15489 ovl.fmt.RXY.dl2,
15490 ovl.fmt.RXY.dh2); goto ok;
15491 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15492 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15493 ovl.fmt.RXY.dl2,
15494 ovl.fmt.RXY.dh2); goto ok;
15495 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15496 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15497 ovl.fmt.RXY.dl2,
15498 ovl.fmt.RXY.dh2); goto ok;
15499 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15500 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15501 ovl.fmt.RXY.dl2,
15502 ovl.fmt.RXY.dh2); goto ok;
15503 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15504 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15505 ovl.fmt.RXY.dl2,
15506 ovl.fmt.RXY.dh2); goto ok;
15507 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15508 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15509 ovl.fmt.RXY.dl2,
15510 ovl.fmt.RXY.dh2); goto ok;
15511 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15512 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15513 ovl.fmt.RXY.dl2,
15514 ovl.fmt.RXY.dh2); goto ok;
15515 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15516 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15517 ovl.fmt.RXY.dl2,
15518 ovl.fmt.RXY.dh2); goto ok;
15519 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15520 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15521 ovl.fmt.RXY.dl2,
15522 ovl.fmt.RXY.dh2); goto ok;
15523 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15524 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15525 ovl.fmt.RXY.dl2,
15526 ovl.fmt.RXY.dh2); goto ok;
15527 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15528 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15529 ovl.fmt.RXY.dl2,
15530 ovl.fmt.RXY.dh2); goto ok;
15531 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15532 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15533 ovl.fmt.RXY.dl2,
15534 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015535 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015536 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15537 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15538 ovl.fmt.RXY.dl2,
15539 ovl.fmt.RXY.dh2); goto ok;
15540 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15541 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15542 ovl.fmt.RXY.dl2,
15543 ovl.fmt.RXY.dh2); goto ok;
15544 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15545 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15546 ovl.fmt.RXY.dl2,
15547 ovl.fmt.RXY.dh2); goto ok;
15548 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15549 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15550 ovl.fmt.RXY.dl2,
15551 ovl.fmt.RXY.dh2); goto ok;
15552 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15553 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15554 ovl.fmt.RXY.dl2,
15555 ovl.fmt.RXY.dh2); goto ok;
15556 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15557 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15558 ovl.fmt.RXY.dl2,
15559 ovl.fmt.RXY.dh2); goto ok;
15560 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15561 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15562 ovl.fmt.RXY.dl2,
15563 ovl.fmt.RXY.dh2); goto ok;
15564 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15565 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15566 ovl.fmt.RXY.dl2,
15567 ovl.fmt.RXY.dh2); goto ok;
15568 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15569 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15570 ovl.fmt.RXY.dl2,
15571 ovl.fmt.RXY.dh2); goto ok;
15572 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15573 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15574 ovl.fmt.RXY.dl2,
15575 ovl.fmt.RXY.dh2); goto ok;
15576 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15577 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15578 ovl.fmt.RXY.dl2,
15579 ovl.fmt.RXY.dh2); goto ok;
15580 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15581 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15582 ovl.fmt.RXY.dl2,
15583 ovl.fmt.RXY.dh2); goto ok;
15584 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15585 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15586 ovl.fmt.RXY.dl2,
15587 ovl.fmt.RXY.dh2); goto ok;
15588 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15589 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15590 ovl.fmt.RXY.dl2,
15591 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015592 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15593 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15594 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015595 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15596 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15597 ovl.fmt.RXY.dl2,
15598 ovl.fmt.RXY.dh2); goto ok;
15599 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15600 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15601 ovl.fmt.RXY.dl2,
15602 ovl.fmt.RXY.dh2); goto ok;
15603 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15604 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15605 ovl.fmt.RXY.dl2,
15606 ovl.fmt.RXY.dh2); goto ok;
15607 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15608 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15609 ovl.fmt.RXY.dl2,
15610 ovl.fmt.RXY.dh2); goto ok;
15611 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15612 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15613 ovl.fmt.RXY.dl2,
15614 ovl.fmt.RXY.dh2); goto ok;
15615 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15616 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15617 ovl.fmt.RXY.dl2,
15618 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015619 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015620 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15621 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15622 ovl.fmt.RXY.dl2,
15623 ovl.fmt.RXY.dh2); goto ok;
15624 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15625 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15626 ovl.fmt.RXY.dl2,
15627 ovl.fmt.RXY.dh2); goto ok;
15628 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15629 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15630 ovl.fmt.RXY.dl2,
15631 ovl.fmt.RXY.dh2); goto ok;
15632 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15633 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15634 ovl.fmt.RXY.dl2,
15635 ovl.fmt.RXY.dh2); goto ok;
15636 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15637 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15638 ovl.fmt.RSY.dl2,
15639 ovl.fmt.RSY.dh2); goto ok;
15640 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15641 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15642 ovl.fmt.RSY.dl2,
15643 ovl.fmt.RSY.dh2); goto ok;
15644 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15645 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15646 ovl.fmt.RSY.dl2,
15647 ovl.fmt.RSY.dh2); goto ok;
15648 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15649 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15650 ovl.fmt.RSY.dl2,
15651 ovl.fmt.RSY.dh2); goto ok;
15652 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15653 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15654 ovl.fmt.RSY.dl2,
15655 ovl.fmt.RSY.dh2); goto ok;
15656 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15657 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15658 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15659 ovl.fmt.RSY.dl2,
15660 ovl.fmt.RSY.dh2); goto ok;
15661 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15662 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15663 ovl.fmt.RSY.dl2,
15664 ovl.fmt.RSY.dh2); goto ok;
15665 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15666 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15667 ovl.fmt.RSY.dl2,
15668 ovl.fmt.RSY.dh2); goto ok;
15669 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15670 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15671 ovl.fmt.RSY.dl2,
15672 ovl.fmt.RSY.dh2); goto ok;
15673 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15674 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15675 ovl.fmt.RSY.dl2,
15676 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015677 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015678 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15679 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15680 ovl.fmt.RSY.dl2,
15681 ovl.fmt.RSY.dh2); goto ok;
15682 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15683 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15684 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15685 ovl.fmt.RSY.dl2,
15686 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015687 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015688 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15689 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15690 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15691 ovl.fmt.RSY.dh2); goto ok;
15692 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15693 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15694 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15695 ovl.fmt.RSY.dh2); goto ok;
15696 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15697 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15698 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15699 ovl.fmt.RSY.dl2,
15700 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015701 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15702 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15703 ovl.fmt.RSY.dl2,
15704 ovl.fmt.RSY.dh2); goto ok;
15705 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15706 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15707 ovl.fmt.RSY.dl2,
15708 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015709 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15710 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15711 ovl.fmt.RSY.dl2,
15712 ovl.fmt.RSY.dh2); goto ok;
15713 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15714 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15715 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15716 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015717 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15718 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15719 ovl.fmt.RSY.dl2,
15720 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015721 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15722 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15723 ovl.fmt.SIY.dh1); goto ok;
15724 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15725 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15726 ovl.fmt.SIY.dh1); goto ok;
15727 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15728 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15729 ovl.fmt.SIY.dh1); goto ok;
15730 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15731 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15732 ovl.fmt.SIY.dh1); goto ok;
15733 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15734 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15735 ovl.fmt.SIY.dh1); goto ok;
15736 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15737 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15738 ovl.fmt.SIY.dh1); goto ok;
15739 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15740 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15741 ovl.fmt.SIY.dh1); goto ok;
15742 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15743 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15744 ovl.fmt.SIY.dh1); goto ok;
15745 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15746 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15747 ovl.fmt.SIY.dh1); goto ok;
15748 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15749 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15750 ovl.fmt.SIY.dh1); goto ok;
15751 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15752 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15753 ovl.fmt.RSY.dl2,
15754 ovl.fmt.RSY.dh2); goto ok;
15755 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15756 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15757 ovl.fmt.RSY.dl2,
15758 ovl.fmt.RSY.dh2); goto ok;
15759 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15760 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15761 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15762 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15763 ovl.fmt.RSY.dl2,
15764 ovl.fmt.RSY.dh2); goto ok;
15765 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15766 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15767 ovl.fmt.RSY.dl2,
15768 ovl.fmt.RSY.dh2); goto ok;
15769 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15770 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15771 ovl.fmt.RSY.dl2,
15772 ovl.fmt.RSY.dh2); goto ok;
15773 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15774 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15775 ovl.fmt.RSY.dl2,
15776 ovl.fmt.RSY.dh2); goto ok;
15777 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15778 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15779 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15780 ovl.fmt.RSY.dh2); goto ok;
15781 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15782 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15783 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15784 ovl.fmt.RSY.dl2,
15785 ovl.fmt.RSY.dh2); goto ok;
15786 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15787 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15788 ovl.fmt.RSY.dl2,
15789 ovl.fmt.RSY.dh2); goto ok;
15790 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15791 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15792 ovl.fmt.RSY.dl2,
15793 ovl.fmt.RSY.dh2); goto ok;
15794 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15795 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15796 ovl.fmt.RSY.dl2,
15797 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015798 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15799 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15800 ovl.fmt.RSY.dl2,
15801 ovl.fmt.RSY.dh2,
15802 S390_XMNM_LOCG); goto ok;
15803 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15804 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15805 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15806 ovl.fmt.RSY.dh2,
15807 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015808 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15809 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15810 ovl.fmt.RSY.dl2,
15811 ovl.fmt.RSY.dh2); goto ok;
15812 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15813 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15814 ovl.fmt.RSY.dl2,
15815 ovl.fmt.RSY.dh2); goto ok;
15816 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15817 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15818 ovl.fmt.RSY.dl2,
15819 ovl.fmt.RSY.dh2); goto ok;
15820 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15821 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15822 ovl.fmt.RSY.dl2,
15823 ovl.fmt.RSY.dh2); goto ok;
15824 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15825 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15826 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15827 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015828 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15829 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15830 ovl.fmt.RSY.dl2,
15831 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15832 goto ok;
15833 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15834 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15835 ovl.fmt.RSY.dl2,
15836 ovl.fmt.RSY.dh2,
15837 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015838 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15839 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15840 ovl.fmt.RSY.dl2,
15841 ovl.fmt.RSY.dh2); goto ok;
15842 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15843 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15844 ovl.fmt.RSY.dl2,
15845 ovl.fmt.RSY.dh2); goto ok;
15846 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15847 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15848 ovl.fmt.RSY.dl2,
15849 ovl.fmt.RSY.dh2); goto ok;
15850 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15851 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15852 ovl.fmt.RSY.dl2,
15853 ovl.fmt.RSY.dh2); goto ok;
15854 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15855 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15856 ovl.fmt.RSY.dl2,
15857 ovl.fmt.RSY.dh2); goto ok;
15858 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15859 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15860 goto ok;
15861 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15862 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15863 goto ok;
15864 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15865 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15866 ovl.fmt.RIE_RRUUU.r1,
15867 ovl.fmt.RIE_RRUUU.r2,
15868 ovl.fmt.RIE_RRUUU.i3,
15869 ovl.fmt.RIE_RRUUU.i4,
15870 ovl.fmt.RIE_RRUUU.i5);
15871 goto ok;
15872 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15873 ovl.fmt.RIE_RRUUU.r1,
15874 ovl.fmt.RIE_RRUUU.r2,
15875 ovl.fmt.RIE_RRUUU.i3,
15876 ovl.fmt.RIE_RRUUU.i4,
15877 ovl.fmt.RIE_RRUUU.i5);
15878 goto ok;
15879 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15880 ovl.fmt.RIE_RRUUU.r1,
15881 ovl.fmt.RIE_RRUUU.r2,
15882 ovl.fmt.RIE_RRUUU.i3,
15883 ovl.fmt.RIE_RRUUU.i4,
15884 ovl.fmt.RIE_RRUUU.i5);
15885 goto ok;
15886 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15887 ovl.fmt.RIE_RRUUU.r1,
15888 ovl.fmt.RIE_RRUUU.r2,
15889 ovl.fmt.RIE_RRUUU.i3,
15890 ovl.fmt.RIE_RRUUU.i4,
15891 ovl.fmt.RIE_RRUUU.i5);
15892 goto ok;
florian2289cd42012-12-05 04:23:42 +000015893 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015894 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15895 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15896 ovl.fmt.RIE_RRPU.r1,
15897 ovl.fmt.RIE_RRPU.r2,
15898 ovl.fmt.RIE_RRPU.i4,
15899 ovl.fmt.RIE_RRPU.m3); goto ok;
15900 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15901 ovl.fmt.RIE_RRPU.r1,
15902 ovl.fmt.RIE_RRPU.r2,
15903 ovl.fmt.RIE_RRPU.i4,
15904 ovl.fmt.RIE_RRPU.m3); goto ok;
15905 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15906 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15907 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15908 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15909 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15910 ovl.fmt.RIE_RRPU.r1,
15911 ovl.fmt.RIE_RRPU.r2,
15912 ovl.fmt.RIE_RRPU.i4,
15913 ovl.fmt.RIE_RRPU.m3); goto ok;
15914 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15915 ovl.fmt.RIE_RRPU.r1,
15916 ovl.fmt.RIE_RRPU.r2,
15917 ovl.fmt.RIE_RRPU.i4,
15918 ovl.fmt.RIE_RRPU.m3); goto ok;
15919 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15920 ovl.fmt.RIEv3.r1,
15921 ovl.fmt.RIEv3.m3,
15922 ovl.fmt.RIEv3.i4,
15923 ovl.fmt.RIEv3.i2); goto ok;
15924 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15925 ovl.fmt.RIEv3.r1,
15926 ovl.fmt.RIEv3.m3,
15927 ovl.fmt.RIEv3.i4,
15928 ovl.fmt.RIEv3.i2); goto ok;
15929 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15930 ovl.fmt.RIEv3.r1,
15931 ovl.fmt.RIEv3.m3,
15932 ovl.fmt.RIEv3.i4,
15933 ovl.fmt.RIEv3.i2); goto ok;
15934 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15935 ovl.fmt.RIEv3.r1,
15936 ovl.fmt.RIEv3.m3,
15937 ovl.fmt.RIEv3.i4,
15938 ovl.fmt.RIEv3.i2); goto ok;
15939 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15940 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15941 goto ok;
15942 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15943 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15944 ovl.fmt.RIE.i2); goto ok;
15945 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15946 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15947 ovl.fmt.RIE.i2); goto ok;
15948 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15949 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15950 ovl.fmt.RIE.i2); goto ok;
15951 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15952 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15953 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15954 goto ok;
15955 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15956 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15957 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15958 goto ok;
15959 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15960 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15961 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15962 goto ok;
15963 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15964 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15965 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15966 goto ok;
15967 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15968 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15969 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15970 ovl.fmt.RIS.i2); goto ok;
15971 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15972 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15973 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15974 ovl.fmt.RIS.i2); goto ok;
15975 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15976 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15977 ovl.fmt.RIS.d4,
15978 ovl.fmt.RIS.i2); goto ok;
15979 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15980 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15981 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15982 ovl.fmt.RIS.i2); goto ok;
15983 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15984 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15985 ovl.fmt.RXE.d2); goto ok;
15986 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15987 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15988 ovl.fmt.RXE.d2); goto ok;
15989 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15990 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15991 ovl.fmt.RXE.d2); goto ok;
15992 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15993 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15994 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15995 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15996 ovl.fmt.RXE.d2); goto ok;
15997 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15998 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15999 ovl.fmt.RXE.d2); goto ok;
16000 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
16001 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16002 ovl.fmt.RXE.d2); goto ok;
16003 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
16004 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
16005 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16006 ovl.fmt.RXE.d2); goto ok;
16007 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
16008 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16009 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16010 ovl.fmt.RXF.r1); goto ok;
16011 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
16012 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16013 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16014 ovl.fmt.RXF.r1); goto ok;
16015 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
16016 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16017 ovl.fmt.RXE.d2); goto ok;
16018 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
16019 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16020 ovl.fmt.RXE.d2); goto ok;
16021 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
16022 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16023 ovl.fmt.RXE.d2); goto ok;
16024 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
16025 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16026 ovl.fmt.RXE.d2); goto ok;
16027 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
16028 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16029 ovl.fmt.RXE.d2); goto ok;
16030 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
16031 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16032 ovl.fmt.RXE.d2); goto ok;
16033 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
16034 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
16035 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16036 ovl.fmt.RXE.d2); goto ok;
16037 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
16038 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16039 ovl.fmt.RXE.d2); goto ok;
16040 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
16041 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16042 ovl.fmt.RXE.d2); goto ok;
16043 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
16044 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16045 ovl.fmt.RXE.d2); goto ok;
16046 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
16047 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16048 ovl.fmt.RXE.d2); goto ok;
16049 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
16050 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16051 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16052 ovl.fmt.RXF.r1); goto ok;
16053 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
16054 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16055 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16056 ovl.fmt.RXF.r1); goto ok;
16057 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
16058 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
16059 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
16060 case 0xed000000002eULL: /* MAE */ goto unimplemented;
16061 case 0xed000000002fULL: /* MSE */ goto unimplemented;
16062 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
16063 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
16064 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
16065 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
16066 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
16067 case 0xed000000003aULL: /* MAY */ goto unimplemented;
16068 case 0xed000000003bULL: /* MY */ goto unimplemented;
16069 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
16070 case 0xed000000003dULL: /* MYH */ goto unimplemented;
16071 case 0xed000000003eULL: /* MAD */ goto unimplemented;
16072 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000016073 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
16074 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16075 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16076 ovl.fmt.RXF.r1); goto ok;
16077 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
16078 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16079 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16080 ovl.fmt.RXF.r1); goto ok;
16081 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
16082 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16083 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16084 ovl.fmt.RXF.r1); goto ok;
16085 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
16086 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
16087 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
16088 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000016089 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
16090 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16091 ovl.fmt.RXE.d2); goto ok;
16092 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
16093 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16094 ovl.fmt.RXE.d2); goto ok;
16095 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
16096 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16097 ovl.fmt.RXE.d2); goto ok;
16098 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
16099 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16100 ovl.fmt.RXE.d2); goto ok;
16101 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
16102 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16103 ovl.fmt.RXE.d2); goto ok;
16104 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
16105 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
16106 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016107 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
16108 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16109 ovl.fmt.RXY.dl2,
16110 ovl.fmt.RXY.dh2); goto ok;
16111 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
16112 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16113 ovl.fmt.RXY.dl2,
16114 ovl.fmt.RXY.dh2); goto ok;
16115 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
16116 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16117 ovl.fmt.RXY.dl2,
16118 ovl.fmt.RXY.dh2); goto ok;
16119 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
16120 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
16121 ovl.fmt.RXY.dl2,
16122 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000016123 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
16124 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
16125 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
16126 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016127 }
16128
16129 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
16130 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
16131 ovl.fmt.RIL.i2); goto ok;
16132 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
16133 ovl.fmt.RIL.i2); goto ok;
16134 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
16135 ovl.fmt.RIL.i2); goto ok;
16136 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
16137 ovl.fmt.RIL.i2); goto ok;
16138 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
16139 ovl.fmt.RIL.i2); goto ok;
16140 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
16141 ovl.fmt.RIL.i2); goto ok;
16142 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
16143 ovl.fmt.RIL.i2); goto ok;
16144 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
16145 ovl.fmt.RIL.i2); goto ok;
16146 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
16147 ovl.fmt.RIL.i2); goto ok;
16148 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
16149 ovl.fmt.RIL.i2); goto ok;
16150 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
16151 ovl.fmt.RIL.i2); goto ok;
16152 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
16153 ovl.fmt.RIL.i2); goto ok;
16154 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
16155 ovl.fmt.RIL.i2); goto ok;
16156 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
16157 ovl.fmt.RIL.i2); goto ok;
16158 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
16159 ovl.fmt.RIL.i2); goto ok;
16160 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
16161 ovl.fmt.RIL.i2); goto ok;
16162 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
16163 ovl.fmt.RIL.i2); goto ok;
16164 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
16165 ovl.fmt.RIL.i2); goto ok;
16166 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
16167 ovl.fmt.RIL.i2); goto ok;
16168 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
16169 ovl.fmt.RIL.i2); goto ok;
16170 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
16171 ovl.fmt.RIL.i2); goto ok;
16172 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
16173 ovl.fmt.RIL.i2); goto ok;
16174 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
16175 ovl.fmt.RIL.i2); goto ok;
16176 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
16177 ovl.fmt.RIL.i2); goto ok;
16178 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
16179 ovl.fmt.RIL.i2); goto ok;
16180 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
16181 ovl.fmt.RIL.i2); goto ok;
16182 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
16183 ovl.fmt.RIL.i2); goto ok;
16184 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
16185 ovl.fmt.RIL.i2); goto ok;
16186 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
16187 ovl.fmt.RIL.i2); goto ok;
16188 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
16189 ovl.fmt.RIL.i2); goto ok;
16190 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
16191 ovl.fmt.RIL.i2); goto ok;
16192 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
16193 ovl.fmt.RIL.i2); goto ok;
16194 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
16195 ovl.fmt.RIL.i2); goto ok;
16196 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
16197 ovl.fmt.RIL.i2); goto ok;
16198 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
16199 ovl.fmt.RIL.i2); goto ok;
16200 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
16201 ovl.fmt.RIL.i2); goto ok;
16202 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
16203 ovl.fmt.RIL.i2); goto ok;
16204 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
16205 ovl.fmt.RIL.i2); goto ok;
16206 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
16207 ovl.fmt.RIL.i2); goto ok;
16208 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
16209 ovl.fmt.RIL.i2); goto ok;
16210 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
16211 ovl.fmt.RIL.i2); goto ok;
16212 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
16213 ovl.fmt.RIL.i2); goto ok;
16214 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
16215 ovl.fmt.RIL.i2); goto ok;
16216 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
16217 ovl.fmt.RIL.i2); goto ok;
16218 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
16219 ovl.fmt.RIL.i2); goto ok;
16220 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
16221 ovl.fmt.RIL.i2); goto ok;
16222 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
16223 ovl.fmt.RIL.i2); goto ok;
16224 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
16225 ovl.fmt.RIL.i2); goto ok;
16226 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
16227 ovl.fmt.RIL.i2); goto ok;
16228 case 0xc800ULL: /* MVCOS */ goto unimplemented;
16229 case 0xc801ULL: /* ECTG */ goto unimplemented;
16230 case 0xc802ULL: /* CSST */ goto unimplemented;
16231 case 0xc804ULL: /* LPD */ goto unimplemented;
16232 case 0xc805ULL: /* LPDG */ goto unimplemented;
16233 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
16234 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
16235 ovl.fmt.RIL.i2); goto ok;
16236 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
16237 ovl.fmt.RIL.i2); goto ok;
16238 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
16239 ovl.fmt.RIL.i2); goto ok;
16240 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
16241 ovl.fmt.RIL.i2); goto ok;
16242 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
16243 ovl.fmt.RIL.i2); goto ok;
16244 }
16245
16246 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000016247 case 0xc5ULL: /* BPRP */ goto unimplemented;
16248 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016249 case 0xd0ULL: /* TRTR */ goto unimplemented;
16250 case 0xd1ULL: /* MVN */ goto unimplemented;
16251 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
16252 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16253 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16254 case 0xd3ULL: /* MVZ */ goto unimplemented;
16255 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
16256 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16257 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16258 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
16259 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16260 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
16261 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
16262 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16263 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000016264 case 0xd7ULL:
16265 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
16266 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
16267 else
16268 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
16269 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16270 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
16271 goto ok;
sewardj2019a972011-03-07 16:04:07 +000016272 case 0xd9ULL: /* MVCK */ goto unimplemented;
16273 case 0xdaULL: /* MVCP */ goto unimplemented;
16274 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000016275 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
16276 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
16277 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000016278 case 0xddULL: /* TRT */ goto unimplemented;
16279 case 0xdeULL: /* ED */ goto unimplemented;
16280 case 0xdfULL: /* EDMK */ goto unimplemented;
16281 case 0xe1ULL: /* PKU */ goto unimplemented;
16282 case 0xe2ULL: /* UNPKU */ goto unimplemented;
16283 case 0xe8ULL: /* MVCIN */ goto unimplemented;
16284 case 0xe9ULL: /* PKA */ goto unimplemented;
16285 case 0xeaULL: /* UNPKA */ goto unimplemented;
16286 case 0xeeULL: /* PLO */ goto unimplemented;
16287 case 0xefULL: /* LMD */ goto unimplemented;
16288 case 0xf0ULL: /* SRP */ goto unimplemented;
16289 case 0xf1ULL: /* MVO */ goto unimplemented;
16290 case 0xf2ULL: /* PACK */ goto unimplemented;
16291 case 0xf3ULL: /* UNPK */ goto unimplemented;
16292 case 0xf8ULL: /* ZAP */ goto unimplemented;
16293 case 0xf9ULL: /* CP */ goto unimplemented;
16294 case 0xfaULL: /* AP */ goto unimplemented;
16295 case 0xfbULL: /* SP */ goto unimplemented;
16296 case 0xfcULL: /* MP */ goto unimplemented;
16297 case 0xfdULL: /* DP */ goto unimplemented;
16298 }
16299
16300 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
16301 case 0xe500ULL: /* LASP */ goto unimplemented;
16302 case 0xe501ULL: /* TPROT */ goto unimplemented;
16303 case 0xe502ULL: /* STRAG */ goto unimplemented;
16304 case 0xe50eULL: /* MVCSK */ goto unimplemented;
16305 case 0xe50fULL: /* MVCDK */ goto unimplemented;
16306 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
16307 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16308 goto ok;
16309 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
16310 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16311 goto ok;
16312 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16313 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16314 goto ok;
16315 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16316 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16317 goto ok;
16318 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16319 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16320 goto ok;
16321 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16322 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16323 goto ok;
16324 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16325 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16326 goto ok;
16327 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16328 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16329 goto ok;
16330 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16331 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16332 goto ok;
florian2289cd42012-12-05 04:23:42 +000016333 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16334 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016335 }
16336
16337 return S390_DECODE_UNKNOWN_INSN;
16338
16339ok:
16340 return S390_DECODE_OK;
16341
16342unimplemented:
16343 return S390_DECODE_UNIMPLEMENTED_INSN;
16344}
16345
16346/* Handle "special" instructions. */
16347static s390_decode_t
16348s390_decode_special_and_irgen(UChar *bytes)
16349{
16350 s390_decode_t status = S390_DECODE_OK;
16351
16352 /* Got a "Special" instruction preamble. Which one is it? */
16353 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16354 s390_irgen_client_request();
16355 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16356 s390_irgen_guest_NRADDR();
16357 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16358 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016359 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16360 vex_inject_ir(irsb, Iend_BE);
16361
16362 /* Invalidate the current insn. The reason is that the IRop we're
16363 injecting here can change. In which case the translation has to
16364 be redone. For ease of handling, we simply invalidate all the
16365 time. */
sewardj05f5e012014-05-04 10:52:11 +000016366 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMSTART),
florian2245ce92012-08-28 16:49:30 +000016367 mkU64(guest_IA_curr_instr)));
sewardj05f5e012014-05-04 10:52:11 +000016368 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_CMLEN),
florian2245ce92012-08-28 16:49:30 +000016369 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16370 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16371 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16372
16373 put_IA(mkaddr_expr(guest_IA_next_instr));
16374 dis_res->whatNext = Dis_StopHere;
sewardj05f5e012014-05-04 10:52:11 +000016375 dis_res->jk_StopHere = Ijk_InvalICache;
sewardj2019a972011-03-07 16:04:07 +000016376 } else {
16377 /* We don't know what it is. */
16378 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16379 }
16380
16381 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16382
16383 return status;
16384}
16385
16386
16387/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016388static UInt
sewardj2019a972011-03-07 16:04:07 +000016389s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
16390{
16391 s390_decode_t status;
16392
16393 dis_res = dres;
16394
16395 /* Spot the 8-byte preamble: 18ff lr r15,r15
16396 1811 lr r1,r1
16397 1822 lr r2,r2
16398 1833 lr r3,r3 */
16399 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16400 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16401 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16402
16403 /* Handle special instruction that follows that preamble. */
16404 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016405
16406 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16407 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16408
16409 status =
16410 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016411 } else {
16412 /* Handle normal instructions. */
16413 switch (insn_length) {
16414 case 2:
16415 status = s390_decode_2byte_and_irgen(bytes);
16416 break;
16417
16418 case 4:
16419 status = s390_decode_4byte_and_irgen(bytes);
16420 break;
16421
16422 case 6:
16423 status = s390_decode_6byte_and_irgen(bytes);
16424 break;
16425
16426 default:
16427 status = S390_DECODE_ERROR;
16428 break;
16429 }
16430 }
florian5fcbba22011-07-27 20:40:22 +000016431 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016432 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16433 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016434 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016435 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016436 }
16437
16438 if (status == S390_DECODE_OK) return insn_length; /* OK */
16439
16440 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016441 if (sigill_diag) {
16442 vex_printf("vex s390->IR: ");
16443 switch (status) {
16444 case S390_DECODE_UNKNOWN_INSN:
16445 vex_printf("unknown insn: ");
16446 break;
sewardj2019a972011-03-07 16:04:07 +000016447
sewardj442e51a2012-12-06 18:08:04 +000016448 case S390_DECODE_UNIMPLEMENTED_INSN:
16449 vex_printf("unimplemented insn: ");
16450 break;
sewardj2019a972011-03-07 16:04:07 +000016451
sewardj442e51a2012-12-06 18:08:04 +000016452 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16453 vex_printf("unimplemented special insn: ");
16454 break;
sewardj2019a972011-03-07 16:04:07 +000016455
sewardj442e51a2012-12-06 18:08:04 +000016456 default:
16457 case S390_DECODE_ERROR:
16458 vex_printf("decoding error: ");
16459 break;
16460 }
16461
16462 vex_printf("%02x%02x", bytes[0], bytes[1]);
16463 if (insn_length > 2) {
16464 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16465 }
16466 if (insn_length > 4) {
16467 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16468 }
16469 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016470 }
16471
sewardj2019a972011-03-07 16:04:07 +000016472 return 0; /* Failed */
16473}
16474
16475
sewardj2019a972011-03-07 16:04:07 +000016476/* Disassemble a single instruction INSN into IR. */
16477static DisResult
florian420c5012011-07-22 02:12:28 +000016478disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016479{
16480 UChar byte;
16481 UInt insn_length;
16482 DisResult dres;
16483
16484 /* ---------------------------------------------------- */
16485 /* --- Compute instruction length -- */
16486 /* ---------------------------------------------------- */
16487
16488 /* Get the first byte of the insn. */
16489 byte = insn[0];
16490
16491 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16492 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16493 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16494
16495 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16496
16497 /* ---------------------------------------------------- */
16498 /* --- Initialise the DisResult data -- */
16499 /* ---------------------------------------------------- */
16500 dres.whatNext = Dis_Continue;
16501 dres.len = insn_length;
16502 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016503 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000016504
floriana99f20e2011-07-17 14:16:41 +000016505 /* fixs390: consider chasing of conditional jumps */
16506
sewardj2019a972011-03-07 16:04:07 +000016507 /* Normal and special instruction handling starts here. */
16508 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16509 /* All decode failures end up here. The decoder has already issued an
16510 error message.
16511 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016512 not been executed, and (is currently) the next to be executed.
16513 The insn address in the guest state needs to be set to
16514 guest_IA_curr_instr, otherwise the complaint will report an
16515 incorrect address. */
16516 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016517
florian8844a632012-04-13 04:04:06 +000016518 dres.whatNext = Dis_StopHere;
16519 dres.jk_StopHere = Ijk_NoDecode;
16520 dres.continueAt = 0;
16521 dres.len = 0;
16522 } else {
16523 /* Decode success */
16524 switch (dres.whatNext) {
16525 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016526 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016527 break;
16528 case Dis_ResteerU:
16529 case Dis_ResteerC:
16530 put_IA(mkaddr_expr(dres.continueAt));
16531 break;
16532 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016533 if (dres.jk_StopHere == Ijk_EmWarn ||
16534 dres.jk_StopHere == Ijk_EmFail) {
16535 /* We assume here, that emulation warnings are not given for
16536 insns that transfer control. There is no good way to
16537 do that. */
16538 put_IA(mkaddr_expr(guest_IA_next_instr));
16539 }
florian8844a632012-04-13 04:04:06 +000016540 break;
16541 default:
16542 vassert(0);
16543 }
sewardj2019a972011-03-07 16:04:07 +000016544 }
16545
16546 return dres;
16547}
16548
16549
16550/*------------------------------------------------------------*/
16551/*--- Top-level fn ---*/
16552/*------------------------------------------------------------*/
16553
16554/* Disassemble a single instruction into IR. The instruction
16555 is located in host memory at &guest_code[delta]. */
16556
16557DisResult
16558disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000016559 Bool (*resteerOkFn)(void *, Addr64),
16560 Bool resteerCisOk,
16561 void *callback_opaque,
16562 UChar *guest_code,
16563 Long delta,
16564 Addr64 guest_IP,
16565 VexArch guest_arch,
16566 VexArchInfo *archinfo,
16567 VexAbiInfo *abiinfo,
sewardj9b769162014-07-24 12:42:03 +000016568 VexEndness host_endness,
sewardj442e51a2012-12-06 18:08:04 +000016569 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016570{
16571 vassert(guest_arch == VexArchS390X);
16572
16573 /* The instruction decoder requires a big-endian machine. */
sewardj9b769162014-07-24 12:42:03 +000016574 vassert(host_endness == VexEndnessBE);
sewardj2019a972011-03-07 16:04:07 +000016575
16576 /* Set globals (see top of this file) */
16577 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016578 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016579 resteer_fn = resteerOkFn;
16580 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016581 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016582
florian420c5012011-07-22 02:12:28 +000016583 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016584}
16585
16586/*---------------------------------------------------------------*/
16587/*--- end guest_s390_toIR.c ---*/
16588/*---------------------------------------------------------------*/