blob: 377b5b68ac2b1c1252751f27bc75efb95e499a8b [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
florian99dd03e2013-01-29 03:56:06 +0000243 return IRExpr_ITE(condition, iftrue, iffalse);
sewardj2019a972011-03-07 16:04:07 +0000244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
635 op = mkU64(opc);
636 dep1 = mkexpr(d1);
637 dep2 = mkU64(0);
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, dep1, dep2, ndep);
641}
642
643
644/* Write a floating point value and an integer into the flags thunk. The
645 integer value is zero-extended first. */
646static void
647s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
648{
649 IRExpr *op, *dep1, *dep2, *ndep;
650
651 op = mkU64(opc);
652 dep1 = mkexpr(d1);
653 dep2 = s390_cc_widen(d2, False);
654 ndep = mkU64(0);
655
656 s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a 128-bit floating point value into the flags thunk. This is
661 done by splitting the value into two 64-bits values. */
662static void
663s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
664{
665 IRExpr *op, *hi, *lo, *ndep;
666
667 op = mkU64(opc);
668 hi = unop(Iop_F128HItoF64, mkexpr(d1));
669 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, hi, lo, ndep);
673}
674
675
676/* Write a 128-bit floating point value and an integer into the flags thunk.
677 The integer value is zero-extended first. */
678static void
679s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
680{
681 IRExpr *op, *hi, *lo, *lox, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
686 ndep = s390_cc_widen(nd, False);
687
688 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
689
690 s390_cc_thunk_fill(op, hi, lox, ndep);
691}
692
693
floriane38f6412012-12-21 17:32:12 +0000694/* Write a 128-bit decimal floating point value into the flags thunk.
695 This is done by splitting the value into two 64-bits values. */
696static void
697s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
698{
699 IRExpr *op, *hi, *lo, *ndep;
700
701 op = mkU64(opc);
702 hi = unop(Iop_D128HItoD64, mkexpr(d1));
703 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
704 ndep = mkU64(0);
705
706 s390_cc_thunk_fill(op, hi, lo, ndep);
707}
708
709
floriance9e3db2012-12-27 20:14:03 +0000710/* Write a 128-bit decimal floating point value and an integer into the flags
711 thunk. The integer value is zero-extended first. */
712static void
713s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
714{
715 IRExpr *op, *hi, *lo, *lox, *ndep;
716
717 op = mkU64(opc);
718 hi = unop(Iop_D128HItoD64, mkexpr(d1));
719 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
720 ndep = s390_cc_widen(nd, False);
721
722 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
723
724 s390_cc_thunk_fill(op, hi, lox, ndep);
725}
726
727
sewardj2019a972011-03-07 16:04:07 +0000728static void
729s390_cc_set(UInt val)
730{
731 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
732 mkU64(val), mkU64(0), mkU64(0));
733}
734
735/* Build IR to calculate the condition code from flags thunk.
736 Returns an expression of type Ity_I32 */
737static IRExpr *
738s390_call_calculate_cc(void)
739{
740 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
741
florian428dfdd2012-03-27 03:09:49 +0000742 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
743 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
744 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
745 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000746
747 args = mkIRExprVec_4(op, dep1, dep2, ndep);
748 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
749 "s390_calculate_cc", &s390_calculate_cc, args);
750
751 /* Exclude OP and NDEP from definedness checking. We're only
752 interested in DEP1 and DEP2. */
753 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
754
755 return call;
756}
757
758/* Build IR to calculate the internal condition code for a "compare and branch"
759 insn. Returns an expression of type Ity_I32 */
760static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000761s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000762{
florianff9613f2012-05-12 15:26:44 +0000763 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000764
florianff9613f2012-05-12 15:26:44 +0000765 switch (opc) {
766 case S390_CC_OP_SIGNED_COMPARE:
767 dep1 = s390_cc_widen(op1, True);
768 dep2 = s390_cc_widen(op2, True);
769 break;
770
771 case S390_CC_OP_UNSIGNED_COMPARE:
772 dep1 = s390_cc_widen(op1, False);
773 dep2 = s390_cc_widen(op2, False);
774 break;
775
776 default:
777 vpanic("s390_call_calculate_icc");
778 }
779
780 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000781 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000782
florianff9613f2012-05-12 15:26:44 +0000783 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000784 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000785 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000786
florianff9613f2012-05-12 15:26:44 +0000787 /* Exclude the requested condition, OP and NDEP from definedness
788 checking. We're only interested in DEP1 and DEP2. */
789 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000790
791 return call;
792}
793
794/* Build IR to calculate the condition code from flags thunk.
795 Returns an expression of type Ity_I32 */
796static IRExpr *
797s390_call_calculate_cond(UInt m)
798{
799 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
800
801 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000802 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
803 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
804 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
805 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000806
807 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
808 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
809 "s390_calculate_cond", &s390_calculate_cond, args);
810
811 /* Exclude the requested condition, OP and NDEP from definedness
812 checking. We're only interested in DEP1 and DEP2. */
813 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
814
815 return call;
816}
817
818#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
819#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
820#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
821#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
822#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
823#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
824#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
825 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
826#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
827 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000828
829
sewardj2019a972011-03-07 16:04:07 +0000830
831
832/*------------------------------------------------------------*/
833/*--- Guest register access ---*/
834/*------------------------------------------------------------*/
835
836
837/*------------------------------------------------------------*/
838/*--- ar registers ---*/
839/*------------------------------------------------------------*/
840
841/* Return the guest state offset of a ar register. */
842static UInt
843ar_offset(UInt archreg)
844{
845 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000846 S390X_GUEST_OFFSET(guest_a0),
847 S390X_GUEST_OFFSET(guest_a1),
848 S390X_GUEST_OFFSET(guest_a2),
849 S390X_GUEST_OFFSET(guest_a3),
850 S390X_GUEST_OFFSET(guest_a4),
851 S390X_GUEST_OFFSET(guest_a5),
852 S390X_GUEST_OFFSET(guest_a6),
853 S390X_GUEST_OFFSET(guest_a7),
854 S390X_GUEST_OFFSET(guest_a8),
855 S390X_GUEST_OFFSET(guest_a9),
856 S390X_GUEST_OFFSET(guest_a10),
857 S390X_GUEST_OFFSET(guest_a11),
858 S390X_GUEST_OFFSET(guest_a12),
859 S390X_GUEST_OFFSET(guest_a13),
860 S390X_GUEST_OFFSET(guest_a14),
861 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000862 };
863
864 vassert(archreg < 16);
865
866 return offset[archreg];
867}
868
869
870/* Return the guest state offset of word #0 of a ar register. */
871static __inline__ UInt
872ar_w0_offset(UInt archreg)
873{
874 return ar_offset(archreg) + 0;
875}
876
877/* Write word #0 of a ar to the guest state. */
878static __inline__ void
879put_ar_w0(UInt archreg, IRExpr *expr)
880{
881 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
882
883 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
884}
885
886/* Read word #0 of a ar register. */
887static __inline__ IRExpr *
888get_ar_w0(UInt archreg)
889{
890 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
891}
892
893
894/*------------------------------------------------------------*/
895/*--- fpr registers ---*/
896/*------------------------------------------------------------*/
897
898/* Return the guest state offset of a fpr register. */
899static UInt
900fpr_offset(UInt archreg)
901{
902 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000903 S390X_GUEST_OFFSET(guest_f0),
904 S390X_GUEST_OFFSET(guest_f1),
905 S390X_GUEST_OFFSET(guest_f2),
906 S390X_GUEST_OFFSET(guest_f3),
907 S390X_GUEST_OFFSET(guest_f4),
908 S390X_GUEST_OFFSET(guest_f5),
909 S390X_GUEST_OFFSET(guest_f6),
910 S390X_GUEST_OFFSET(guest_f7),
911 S390X_GUEST_OFFSET(guest_f8),
912 S390X_GUEST_OFFSET(guest_f9),
913 S390X_GUEST_OFFSET(guest_f10),
914 S390X_GUEST_OFFSET(guest_f11),
915 S390X_GUEST_OFFSET(guest_f12),
916 S390X_GUEST_OFFSET(guest_f13),
917 S390X_GUEST_OFFSET(guest_f14),
918 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000919 };
920
921 vassert(archreg < 16);
922
923 return offset[archreg];
924}
925
926
927/* Return the guest state offset of word #0 of a fpr register. */
928static __inline__ UInt
929fpr_w0_offset(UInt archreg)
930{
931 return fpr_offset(archreg) + 0;
932}
933
934/* Write word #0 of a fpr to the guest state. */
935static __inline__ void
936put_fpr_w0(UInt archreg, IRExpr *expr)
937{
938 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
939
940 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
941}
942
943/* Read word #0 of a fpr register. */
944static __inline__ IRExpr *
945get_fpr_w0(UInt archreg)
946{
947 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
948}
949
950/* Return the guest state offset of double word #0 of a fpr register. */
951static __inline__ UInt
952fpr_dw0_offset(UInt archreg)
953{
954 return fpr_offset(archreg) + 0;
955}
956
957/* Write double word #0 of a fpr to the guest state. */
958static __inline__ void
959put_fpr_dw0(UInt archreg, IRExpr *expr)
960{
961 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
962
963 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
964}
965
966/* Read double word #0 of a fpr register. */
967static __inline__ IRExpr *
968get_fpr_dw0(UInt archreg)
969{
970 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
971}
972
floriane38f6412012-12-21 17:32:12 +0000973/* Write word #0 of a dpr to the guest state. */
974static __inline__ void
975put_dpr_w0(UInt archreg, IRExpr *expr)
976{
977 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
978
979 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
980}
981
982/* Read word #0 of a dpr register. */
983static __inline__ IRExpr *
984get_dpr_w0(UInt archreg)
985{
986 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
987}
988
florian12390202012-11-10 22:34:14 +0000989/* Write double word #0 of a fpr containg DFP value to the guest state. */
990static __inline__ void
991put_dpr_dw0(UInt archreg, IRExpr *expr)
992{
993 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
994
995 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
996}
997
998/* Read double word #0 of a fpr register containing DFP value. */
999static __inline__ IRExpr *
1000get_dpr_dw0(UInt archreg)
1001{
1002 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1003}
sewardj2019a972011-03-07 16:04:07 +00001004
1005/*------------------------------------------------------------*/
1006/*--- gpr registers ---*/
1007/*------------------------------------------------------------*/
1008
1009/* Return the guest state offset of a gpr register. */
1010static UInt
1011gpr_offset(UInt archreg)
1012{
1013 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001014 S390X_GUEST_OFFSET(guest_r0),
1015 S390X_GUEST_OFFSET(guest_r1),
1016 S390X_GUEST_OFFSET(guest_r2),
1017 S390X_GUEST_OFFSET(guest_r3),
1018 S390X_GUEST_OFFSET(guest_r4),
1019 S390X_GUEST_OFFSET(guest_r5),
1020 S390X_GUEST_OFFSET(guest_r6),
1021 S390X_GUEST_OFFSET(guest_r7),
1022 S390X_GUEST_OFFSET(guest_r8),
1023 S390X_GUEST_OFFSET(guest_r9),
1024 S390X_GUEST_OFFSET(guest_r10),
1025 S390X_GUEST_OFFSET(guest_r11),
1026 S390X_GUEST_OFFSET(guest_r12),
1027 S390X_GUEST_OFFSET(guest_r13),
1028 S390X_GUEST_OFFSET(guest_r14),
1029 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001030 };
1031
1032 vassert(archreg < 16);
1033
1034 return offset[archreg];
1035}
1036
1037
1038/* Return the guest state offset of word #0 of a gpr register. */
1039static __inline__ UInt
1040gpr_w0_offset(UInt archreg)
1041{
1042 return gpr_offset(archreg) + 0;
1043}
1044
1045/* Write word #0 of a gpr to the guest state. */
1046static __inline__ void
1047put_gpr_w0(UInt archreg, IRExpr *expr)
1048{
1049 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1050
1051 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1052}
1053
1054/* Read word #0 of a gpr register. */
1055static __inline__ IRExpr *
1056get_gpr_w0(UInt archreg)
1057{
1058 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1059}
1060
1061/* Return the guest state offset of double word #0 of a gpr register. */
1062static __inline__ UInt
1063gpr_dw0_offset(UInt archreg)
1064{
1065 return gpr_offset(archreg) + 0;
1066}
1067
1068/* Write double word #0 of a gpr to the guest state. */
1069static __inline__ void
1070put_gpr_dw0(UInt archreg, IRExpr *expr)
1071{
1072 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1073
1074 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1075}
1076
1077/* Read double word #0 of a gpr register. */
1078static __inline__ IRExpr *
1079get_gpr_dw0(UInt archreg)
1080{
1081 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1082}
1083
1084/* Return the guest state offset of half word #1 of a gpr register. */
1085static __inline__ UInt
1086gpr_hw1_offset(UInt archreg)
1087{
1088 return gpr_offset(archreg) + 2;
1089}
1090
1091/* Write half word #1 of a gpr to the guest state. */
1092static __inline__ void
1093put_gpr_hw1(UInt archreg, IRExpr *expr)
1094{
1095 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1096
1097 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1098}
1099
1100/* Read half word #1 of a gpr register. */
1101static __inline__ IRExpr *
1102get_gpr_hw1(UInt archreg)
1103{
1104 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1105}
1106
1107/* Return the guest state offset of byte #6 of a gpr register. */
1108static __inline__ UInt
1109gpr_b6_offset(UInt archreg)
1110{
1111 return gpr_offset(archreg) + 6;
1112}
1113
1114/* Write byte #6 of a gpr to the guest state. */
1115static __inline__ void
1116put_gpr_b6(UInt archreg, IRExpr *expr)
1117{
1118 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1119
1120 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1121}
1122
1123/* Read byte #6 of a gpr register. */
1124static __inline__ IRExpr *
1125get_gpr_b6(UInt archreg)
1126{
1127 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1128}
1129
1130/* Return the guest state offset of byte #3 of a gpr register. */
1131static __inline__ UInt
1132gpr_b3_offset(UInt archreg)
1133{
1134 return gpr_offset(archreg) + 3;
1135}
1136
1137/* Write byte #3 of a gpr to the guest state. */
1138static __inline__ void
1139put_gpr_b3(UInt archreg, IRExpr *expr)
1140{
1141 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1142
1143 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1144}
1145
1146/* Read byte #3 of a gpr register. */
1147static __inline__ IRExpr *
1148get_gpr_b3(UInt archreg)
1149{
1150 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1151}
1152
1153/* Return the guest state offset of byte #0 of a gpr register. */
1154static __inline__ UInt
1155gpr_b0_offset(UInt archreg)
1156{
1157 return gpr_offset(archreg) + 0;
1158}
1159
1160/* Write byte #0 of a gpr to the guest state. */
1161static __inline__ void
1162put_gpr_b0(UInt archreg, IRExpr *expr)
1163{
1164 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1165
1166 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1167}
1168
1169/* Read byte #0 of a gpr register. */
1170static __inline__ IRExpr *
1171get_gpr_b0(UInt archreg)
1172{
1173 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1174}
1175
1176/* Return the guest state offset of word #1 of a gpr register. */
1177static __inline__ UInt
1178gpr_w1_offset(UInt archreg)
1179{
1180 return gpr_offset(archreg) + 4;
1181}
1182
1183/* Write word #1 of a gpr to the guest state. */
1184static __inline__ void
1185put_gpr_w1(UInt archreg, IRExpr *expr)
1186{
1187 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1188
1189 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1190}
1191
1192/* Read word #1 of a gpr register. */
1193static __inline__ IRExpr *
1194get_gpr_w1(UInt archreg)
1195{
1196 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1197}
1198
1199/* Return the guest state offset of half word #3 of a gpr register. */
1200static __inline__ UInt
1201gpr_hw3_offset(UInt archreg)
1202{
1203 return gpr_offset(archreg) + 6;
1204}
1205
1206/* Write half word #3 of a gpr to the guest state. */
1207static __inline__ void
1208put_gpr_hw3(UInt archreg, IRExpr *expr)
1209{
1210 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1211
1212 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1213}
1214
1215/* Read half word #3 of a gpr register. */
1216static __inline__ IRExpr *
1217get_gpr_hw3(UInt archreg)
1218{
1219 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1220}
1221
1222/* Return the guest state offset of byte #7 of a gpr register. */
1223static __inline__ UInt
1224gpr_b7_offset(UInt archreg)
1225{
1226 return gpr_offset(archreg) + 7;
1227}
1228
1229/* Write byte #7 of a gpr to the guest state. */
1230static __inline__ void
1231put_gpr_b7(UInt archreg, IRExpr *expr)
1232{
1233 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1234
1235 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1236}
1237
1238/* Read byte #7 of a gpr register. */
1239static __inline__ IRExpr *
1240get_gpr_b7(UInt archreg)
1241{
1242 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1243}
1244
1245/* Return the guest state offset of half word #0 of a gpr register. */
1246static __inline__ UInt
1247gpr_hw0_offset(UInt archreg)
1248{
1249 return gpr_offset(archreg) + 0;
1250}
1251
1252/* Write half word #0 of a gpr to the guest state. */
1253static __inline__ void
1254put_gpr_hw0(UInt archreg, IRExpr *expr)
1255{
1256 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1257
1258 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1259}
1260
1261/* Read half word #0 of a gpr register. */
1262static __inline__ IRExpr *
1263get_gpr_hw0(UInt archreg)
1264{
1265 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1266}
1267
1268/* Return the guest state offset of byte #4 of a gpr register. */
1269static __inline__ UInt
1270gpr_b4_offset(UInt archreg)
1271{
1272 return gpr_offset(archreg) + 4;
1273}
1274
1275/* Write byte #4 of a gpr to the guest state. */
1276static __inline__ void
1277put_gpr_b4(UInt archreg, IRExpr *expr)
1278{
1279 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1280
1281 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1282}
1283
1284/* Read byte #4 of a gpr register. */
1285static __inline__ IRExpr *
1286get_gpr_b4(UInt archreg)
1287{
1288 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1289}
1290
1291/* Return the guest state offset of byte #1 of a gpr register. */
1292static __inline__ UInt
1293gpr_b1_offset(UInt archreg)
1294{
1295 return gpr_offset(archreg) + 1;
1296}
1297
1298/* Write byte #1 of a gpr to the guest state. */
1299static __inline__ void
1300put_gpr_b1(UInt archreg, IRExpr *expr)
1301{
1302 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1303
1304 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1305}
1306
1307/* Read byte #1 of a gpr register. */
1308static __inline__ IRExpr *
1309get_gpr_b1(UInt archreg)
1310{
1311 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1312}
1313
1314/* Return the guest state offset of half word #2 of a gpr register. */
1315static __inline__ UInt
1316gpr_hw2_offset(UInt archreg)
1317{
1318 return gpr_offset(archreg) + 4;
1319}
1320
1321/* Write half word #2 of a gpr to the guest state. */
1322static __inline__ void
1323put_gpr_hw2(UInt archreg, IRExpr *expr)
1324{
1325 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1326
1327 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1328}
1329
1330/* Read half word #2 of a gpr register. */
1331static __inline__ IRExpr *
1332get_gpr_hw2(UInt archreg)
1333{
1334 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1335}
1336
1337/* Return the guest state offset of byte #5 of a gpr register. */
1338static __inline__ UInt
1339gpr_b5_offset(UInt archreg)
1340{
1341 return gpr_offset(archreg) + 5;
1342}
1343
1344/* Write byte #5 of a gpr to the guest state. */
1345static __inline__ void
1346put_gpr_b5(UInt archreg, IRExpr *expr)
1347{
1348 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1349
1350 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1351}
1352
1353/* Read byte #5 of a gpr register. */
1354static __inline__ IRExpr *
1355get_gpr_b5(UInt archreg)
1356{
1357 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1358}
1359
1360/* Return the guest state offset of byte #2 of a gpr register. */
1361static __inline__ UInt
1362gpr_b2_offset(UInt archreg)
1363{
1364 return gpr_offset(archreg) + 2;
1365}
1366
1367/* Write byte #2 of a gpr to the guest state. */
1368static __inline__ void
1369put_gpr_b2(UInt archreg, IRExpr *expr)
1370{
1371 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1372
1373 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1374}
1375
1376/* Read byte #2 of a gpr register. */
1377static __inline__ IRExpr *
1378get_gpr_b2(UInt archreg)
1379{
1380 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1381}
1382
1383/* Return the guest state offset of the counter register. */
1384static UInt
1385counter_offset(void)
1386{
floriane88b3c92011-07-05 02:48:39 +00001387 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001388}
1389
1390/* Return the guest state offset of double word #0 of the counter register. */
1391static __inline__ UInt
1392counter_dw0_offset(void)
1393{
1394 return counter_offset() + 0;
1395}
1396
1397/* Write double word #0 of the counter to the guest state. */
1398static __inline__ void
1399put_counter_dw0(IRExpr *expr)
1400{
1401 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1402
1403 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1404}
1405
1406/* Read double word #0 of the counter register. */
1407static __inline__ IRExpr *
1408get_counter_dw0(void)
1409{
1410 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1411}
1412
1413/* Return the guest state offset of word #0 of the counter register. */
1414static __inline__ UInt
1415counter_w0_offset(void)
1416{
1417 return counter_offset() + 0;
1418}
1419
1420/* Return the guest state offset of word #1 of the counter register. */
1421static __inline__ UInt
1422counter_w1_offset(void)
1423{
1424 return counter_offset() + 4;
1425}
1426
1427/* Write word #0 of the counter to the guest state. */
1428static __inline__ void
1429put_counter_w0(IRExpr *expr)
1430{
1431 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1432
1433 stmt(IRStmt_Put(counter_w0_offset(), expr));
1434}
1435
1436/* Read word #0 of the counter register. */
1437static __inline__ IRExpr *
1438get_counter_w0(void)
1439{
1440 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1441}
1442
1443/* Write word #1 of the counter to the guest state. */
1444static __inline__ void
1445put_counter_w1(IRExpr *expr)
1446{
1447 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1448
1449 stmt(IRStmt_Put(counter_w1_offset(), expr));
1450}
1451
1452/* Read word #1 of the counter register. */
1453static __inline__ IRExpr *
1454get_counter_w1(void)
1455{
1456 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1457}
1458
1459/* Return the guest state offset of the fpc register. */
1460static UInt
1461fpc_offset(void)
1462{
floriane88b3c92011-07-05 02:48:39 +00001463 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001464}
1465
1466/* Return the guest state offset of word #0 of the fpc register. */
1467static __inline__ UInt
1468fpc_w0_offset(void)
1469{
1470 return fpc_offset() + 0;
1471}
1472
1473/* Write word #0 of the fpc to the guest state. */
1474static __inline__ void
1475put_fpc_w0(IRExpr *expr)
1476{
1477 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1478
1479 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1480}
1481
1482/* Read word #0 of the fpc register. */
1483static __inline__ IRExpr *
1484get_fpc_w0(void)
1485{
1486 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1487}
1488
1489
1490/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001491/*--- Rounding modes ---*/
1492/*------------------------------------------------------------*/
1493
florian125e20d2012-10-07 15:42:37 +00001494/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001495 IRRoundingMode:
1496
1497 rounding mode | s390 | IR
1498 -------------------------
1499 to nearest | 00 | 00
1500 to zero | 01 | 11
1501 to +infinity | 10 | 10
1502 to -infinity | 11 | 01
1503
1504 So: IR = (4 - s390) & 3
1505*/
1506static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001507get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001508{
1509 IRTemp fpc_bits = newTemp(Ity_I32);
1510
1511 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1512 Prior to that bits [30:31] contained the bfp rounding mode with
1513 bit 29 being unused and having a value of 0. So we can always
1514 extract the least significant 3 bits. */
1515 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1516
1517 /* fixs390:
1518
1519
1520 if (! s390_host_has_fpext && rounding_mode > 3) {
1521 emulation warning @ runtime and
1522 set fpc to round nearest
1523 }
1524 */
1525
1526 /* For now silently adjust an unsupported rounding mode to "nearest" */
1527 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1528 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001529 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001530
1531 // rm_IR = (4 - rm_s390) & 3;
1532 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1533}
1534
1535/* Encode the s390 rounding mode as it appears in the m3 field of certain
1536 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1537 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1538 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1539 considers the default rounding mode (4.3.3). */
1540static IRTemp
1541encode_bfp_rounding_mode(UChar mode)
1542{
1543 IRExpr *rm;
1544
1545 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001546 case S390_BFP_ROUND_PER_FPC:
1547 rm = get_bfp_rounding_mode_from_fpc();
1548 break;
1549 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1550 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1551 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1552 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1553 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1554 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001555 default:
1556 vpanic("encode_bfp_rounding_mode");
1557 }
1558
1559 return mktemp(Ity_I32, rm);
1560}
1561
florianc8e4f562012-10-27 16:19:31 +00001562/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1563 IRRoundingMode:
1564
1565 rounding mode | s390 | IR
1566 ------------------------------------------------
1567 to nearest, ties to even | 000 | 000
1568 to zero | 001 | 011
1569 to +infinity | 010 | 010
1570 to -infinity | 011 | 001
1571 to nearest, ties away from 0 | 100 | 100
1572 to nearest, ties toward 0 | 101 | 111
1573 to away from 0 | 110 | 110
1574 to prepare for shorter precision | 111 | 101
1575
1576 So: IR = (s390 ^ ((s390 << 1) & 2))
1577*/
florianc8e4f562012-10-27 16:19:31 +00001578static IRExpr *
1579get_dfp_rounding_mode_from_fpc(void)
1580{
1581 IRTemp fpc_bits = newTemp(Ity_I32);
1582
1583 /* The dfp rounding mode is stored in bits [25:27].
1584 extract the bits at 25:27 and right shift 4 times. */
1585 assign(fpc_bits, binop(Iop_Shr32,
1586 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1587 mkU8(4)));
1588
1589 IRExpr *rm_s390 = mkexpr(fpc_bits);
1590 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1591
1592 return binop(Iop_Xor32, rm_s390,
1593 binop( Iop_And32,
1594 binop(Iop_Shl32, rm_s390, mkU8(1)),
1595 mkU32(2)));
1596}
1597
1598/* Encode the s390 rounding mode as it appears in the m3 field of certain
1599 instructions to VEX's IRRoundingMode. */
1600static IRTemp
1601encode_dfp_rounding_mode(UChar mode)
1602{
1603 IRExpr *rm;
1604
1605 switch (mode) {
1606 case S390_DFP_ROUND_PER_FPC_0:
1607 case S390_DFP_ROUND_PER_FPC_2:
1608 rm = get_dfp_rounding_mode_from_fpc(); break;
1609 case S390_DFP_ROUND_NEAREST_EVEN_4:
1610 case S390_DFP_ROUND_NEAREST_EVEN_8:
1611 rm = mkU32(Irrm_DFP_NEAREST); break;
1612 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1613 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1614 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1615 case S390_DFP_ROUND_PREPARE_SHORT_3:
1616 case S390_DFP_ROUND_PREPARE_SHORT_15:
1617 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1618 case S390_DFP_ROUND_ZERO_5:
1619 case S390_DFP_ROUND_ZERO_9:
1620 rm = mkU32(Irrm_DFP_ZERO ); break;
1621 case S390_DFP_ROUND_POSINF_6:
1622 case S390_DFP_ROUND_POSINF_10:
1623 rm = mkU32(Irrm_DFP_PosINF); break;
1624 case S390_DFP_ROUND_NEGINF_7:
1625 case S390_DFP_ROUND_NEGINF_11:
1626 rm = mkU32(Irrm_DFP_NegINF); break;
1627 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1628 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1629 case S390_DFP_ROUND_AWAY_0:
1630 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1631 default:
1632 vpanic("encode_dfp_rounding_mode");
1633 }
1634
1635 return mktemp(Ity_I32, rm);
1636}
florian12390202012-11-10 22:34:14 +00001637
florianc8e4f562012-10-27 16:19:31 +00001638
florian2c74d242012-09-12 19:38:42 +00001639/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001640/*--- Condition code helpers ---*/
1641/*------------------------------------------------------------*/
1642
1643/* The result of a Iop_CmpFxx operation is a condition code. It is
1644 encoded using the values defined in type IRCmpFxxResult.
1645 Before we can store the condition code into the guest state (or do
1646 anything else with it for that matter) we need to convert it to
1647 the encoding that s390 uses. This is what this function does.
1648
1649 s390 VEX b6 b2 b0 cc.1 cc.0
1650 0 0x40 EQ 1 0 0 0 0
1651 1 0x01 LT 0 0 1 0 1
1652 2 0x00 GT 0 0 0 1 0
1653 3 0x45 Unordered 1 1 1 1 1
1654
1655 The following bits from the VEX encoding are interesting:
1656 b0, b2, b6 with b0 being the LSB. We observe:
1657
1658 cc.0 = b0;
1659 cc.1 = b2 | (~b0 & ~b6)
1660
1661 with cc being the s390 condition code.
1662*/
1663static IRExpr *
1664convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1665{
1666 IRTemp cc0 = newTemp(Ity_I32);
1667 IRTemp cc1 = newTemp(Ity_I32);
1668 IRTemp b0 = newTemp(Ity_I32);
1669 IRTemp b2 = newTemp(Ity_I32);
1670 IRTemp b6 = newTemp(Ity_I32);
1671
1672 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1673 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1674 mkU32(1)));
1675 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1676 mkU32(1)));
1677
1678 assign(cc0, mkexpr(b0));
1679 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1680 binop(Iop_And32,
1681 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1682 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1683 )));
1684
1685 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1686}
1687
1688
1689/* The result of a Iop_CmpDxx operation is a condition code. It is
1690 encoded using the values defined in type IRCmpDxxResult.
1691 Before we can store the condition code into the guest state (or do
1692 anything else with it for that matter) we need to convert it to
1693 the encoding that s390 uses. This is what this function does. */
1694static IRExpr *
1695convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1696{
1697 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1698 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001699 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001700}
1701
1702
1703/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001704/*--- Build IR for formats ---*/
1705/*------------------------------------------------------------*/
1706static void
florian55085f82012-11-21 00:36:55 +00001707s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001708 UChar i)
1709{
florian55085f82012-11-21 00:36:55 +00001710 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001711
sewardj7ee97522011-05-09 21:45:04 +00001712 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001713 s390_disasm(ENC2(MNM, UINT), mnm, i);
1714}
1715
1716static void
florian55085f82012-11-21 00:36:55 +00001717s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001718 UChar r1, UShort i2)
1719{
1720 irgen(r1, i2);
1721}
1722
1723static void
florian55085f82012-11-21 00:36:55 +00001724s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001725 UChar r1, UShort i2)
1726{
florian55085f82012-11-21 00:36:55 +00001727 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001728
sewardj7ee97522011-05-09 21:45:04 +00001729 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001730 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1731}
1732
1733static void
florian55085f82012-11-21 00:36:55 +00001734s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001735 UChar r1, UShort i2)
1736{
florian55085f82012-11-21 00:36:55 +00001737 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001738
sewardj7ee97522011-05-09 21:45:04 +00001739 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001740 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1741}
1742
1743static void
florian55085f82012-11-21 00:36:55 +00001744s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001745 UChar r1, UShort i2)
1746{
florian55085f82012-11-21 00:36:55 +00001747 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001748
sewardj7ee97522011-05-09 21:45:04 +00001749 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001750 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1751}
1752
1753static void
florian55085f82012-11-21 00:36:55 +00001754s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001755 UChar r1, UChar r3, UShort i2)
1756{
florian55085f82012-11-21 00:36:55 +00001757 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001758
sewardj7ee97522011-05-09 21:45:04 +00001759 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001760 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1761}
1762
1763static void
florian55085f82012-11-21 00:36:55 +00001764s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001765 UChar r1, UChar r3, UShort i2)
1766{
florian55085f82012-11-21 00:36:55 +00001767 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001768
sewardj7ee97522011-05-09 21:45:04 +00001769 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001770 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1771}
1772
1773static void
florian55085f82012-11-21 00:36:55 +00001774s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1775 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001776 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1777{
florian55085f82012-11-21 00:36:55 +00001778 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001779
sewardj7ee97522011-05-09 21:45:04 +00001780 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001781 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1782 i5);
1783}
1784
1785static void
florian55085f82012-11-21 00:36:55 +00001786s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1787 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001788 UChar r1, UChar r2, UShort i4, UChar m3)
1789{
florian55085f82012-11-21 00:36:55 +00001790 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001791
sewardj7ee97522011-05-09 21:45:04 +00001792 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001793 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1794 r2, m3, (Int)(Short)i4);
1795}
1796
1797static void
florian55085f82012-11-21 00:36:55 +00001798s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1799 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001800 UChar r1, UChar m3, UShort i4, UChar i2)
1801{
florian55085f82012-11-21 00:36:55 +00001802 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001803
sewardj7ee97522011-05-09 21:45:04 +00001804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001805 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1806 r1, i2, m3, (Int)(Short)i4);
1807}
1808
1809static void
florian55085f82012-11-21 00:36:55 +00001810s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1811 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001812 UChar r1, UChar m3, UShort i4, UChar i2)
1813{
florian55085f82012-11-21 00:36:55 +00001814 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001815
sewardj7ee97522011-05-09 21:45:04 +00001816 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001817 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1818 (Int)(Char)i2, m3, (Int)(Short)i4);
1819}
1820
1821static void
florian55085f82012-11-21 00:36:55 +00001822s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001823 UChar r1, UInt i2)
1824{
1825 irgen(r1, i2);
1826}
1827
1828static void
florian55085f82012-11-21 00:36:55 +00001829s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001830 UChar r1, UInt i2)
1831{
florian55085f82012-11-21 00:36:55 +00001832 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001833
sewardj7ee97522011-05-09 21:45:04 +00001834 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001835 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1836}
1837
1838static void
florian55085f82012-11-21 00:36:55 +00001839s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001840 UChar r1, UInt i2)
1841{
florian55085f82012-11-21 00:36:55 +00001842 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001843
sewardj7ee97522011-05-09 21:45:04 +00001844 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001845 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1846}
1847
1848static void
florian55085f82012-11-21 00:36:55 +00001849s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001850 UChar r1, UInt i2)
1851{
florian55085f82012-11-21 00:36:55 +00001852 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001853
sewardj7ee97522011-05-09 21:45:04 +00001854 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001855 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1856}
1857
1858static void
florian55085f82012-11-21 00:36:55 +00001859s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001860 UChar r1, UInt i2)
1861{
florian55085f82012-11-21 00:36:55 +00001862 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001863
sewardj7ee97522011-05-09 21:45:04 +00001864 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001865 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1866}
1867
1868static void
florian55085f82012-11-21 00:36:55 +00001869s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001870 IRTemp op4addr),
1871 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1872{
florian55085f82012-11-21 00:36:55 +00001873 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001874 IRTemp op4addr = newTemp(Ity_I64);
1875
1876 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1877 mkU64(0)));
1878
1879 mnm = irgen(r1, m3, i2, op4addr);
1880
sewardj7ee97522011-05-09 21:45:04 +00001881 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001882 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1883 (Int)(Char)i2, m3, d4, 0, b4);
1884}
1885
1886static void
florian55085f82012-11-21 00:36:55 +00001887s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001888 IRTemp op4addr),
1889 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1890{
florian55085f82012-11-21 00:36:55 +00001891 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001892 IRTemp op4addr = newTemp(Ity_I64);
1893
1894 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1895 mkU64(0)));
1896
1897 mnm = irgen(r1, m3, i2, op4addr);
1898
sewardj7ee97522011-05-09 21:45:04 +00001899 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001900 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1901 i2, m3, d4, 0, b4);
1902}
1903
1904static void
florian55085f82012-11-21 00:36:55 +00001905s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001906 UChar r1, UChar r2)
1907{
1908 irgen(r1, r2);
1909}
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001913 UChar r1, UChar r2)
1914{
florian55085f82012-11-21 00:36:55 +00001915 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001916
sewardj7ee97522011-05-09 21:45:04 +00001917 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001918 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1919}
1920
1921static void
florian55085f82012-11-21 00:36:55 +00001922s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001923 UChar r1, UChar r2)
1924{
florian55085f82012-11-21 00:36:55 +00001925 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001926
sewardj7ee97522011-05-09 21:45:04 +00001927 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001928 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1929}
1930
1931static void
florian55085f82012-11-21 00:36:55 +00001932s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001933 UChar r1, UChar r2)
1934{
1935 irgen(r1, r2);
1936}
1937
1938static void
florian55085f82012-11-21 00:36:55 +00001939s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001940 UChar r1, UChar r2)
1941{
florian55085f82012-11-21 00:36:55 +00001942 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001943
sewardj7ee97522011-05-09 21:45:04 +00001944 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001945 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1946}
1947
1948static void
florian55085f82012-11-21 00:36:55 +00001949s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001950 UChar r1, UChar r2)
1951{
florian55085f82012-11-21 00:36:55 +00001952 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001953
sewardj7ee97522011-05-09 21:45:04 +00001954 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001955 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1956}
1957
1958static void
florian55085f82012-11-21 00:36:55 +00001959s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001960 UChar r1, UChar r2)
1961{
florian55085f82012-11-21 00:36:55 +00001962 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001963
sewardj7ee97522011-05-09 21:45:04 +00001964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001965 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1966}
1967
1968static void
florian55085f82012-11-21 00:36:55 +00001969s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001970 UChar r1, UChar r2)
1971{
florian55085f82012-11-21 00:36:55 +00001972 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001973
sewardj7ee97522011-05-09 21:45:04 +00001974 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001975 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1976}
1977
1978static void
florian55085f82012-11-21 00:36:55 +00001979s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001980 UChar r1)
1981{
florian55085f82012-11-21 00:36:55 +00001982 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001983
sewardj7ee97522011-05-09 21:45:04 +00001984 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001985 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1986}
1987
1988static void
florian55085f82012-11-21 00:36:55 +00001989s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001990 UChar r1)
1991{
florian55085f82012-11-21 00:36:55 +00001992 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001993
sewardj7ee97522011-05-09 21:45:04 +00001994 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001995 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1996}
1997
1998static void
florian55085f82012-11-21 00:36:55 +00001999s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002000 UChar m3, UChar r1, UChar r2)
2001{
florian55085f82012-11-21 00:36:55 +00002002 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002003
2004 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002005 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002006}
2007
2008static void
florian55085f82012-11-21 00:36:55 +00002009s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002010 UChar r1, UChar r3, UChar r2)
2011{
florian55085f82012-11-21 00:36:55 +00002012 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002013
sewardj7ee97522011-05-09 21:45:04 +00002014 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002015 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2016}
2017
2018static void
florian55085f82012-11-21 00:36:55 +00002019s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2020 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002021 UChar m3, UChar m4, UChar r1, UChar r2)
2022{
florian55085f82012-11-21 00:36:55 +00002023 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002024
2025 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2026 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2027}
2028
2029static void
floriane38f6412012-12-21 17:32:12 +00002030s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2031 UChar m4, UChar r1, UChar r2)
2032{
2033 const HChar *mnm = irgen(m4, r1, r2);
2034
2035 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2036 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2037}
2038
2039static void
florian55085f82012-11-21 00:36:55 +00002040s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2041 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002042 UChar m3, UChar m4, UChar r1, UChar r2)
2043{
florian55085f82012-11-21 00:36:55 +00002044 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002045
2046 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2047 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2048}
2049
2050static void
florian55085f82012-11-21 00:36:55 +00002051s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2052 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002053 UChar m3, UChar m4, UChar r1, UChar r2)
2054{
florian55085f82012-11-21 00:36:55 +00002055 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002056
2057 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2058 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2059}
2060
2061
2062static void
florian55085f82012-11-21 00:36:55 +00002063s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002064 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2065{
2066 irgen(m3, r1, r2);
2067
sewardj7ee97522011-05-09 21:45:04 +00002068 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002069 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2070}
2071
2072static void
florian55085f82012-11-21 00:36:55 +00002073s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002074 UChar r3, UChar r1, UChar r2)
2075{
florian55085f82012-11-21 00:36:55 +00002076 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002077
sewardj7ee97522011-05-09 21:45:04 +00002078 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002079 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2080}
2081
2082static void
florian55085f82012-11-21 00:36:55 +00002083s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002084 UChar r3, UChar m4, UChar r1, UChar r2)
2085{
florian55085f82012-11-21 00:36:55 +00002086 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002087
2088 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2089 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2090}
2091
2092static void
florian55085f82012-11-21 00:36:55 +00002093s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002094 UChar r3, UChar r1, UChar r2)
2095{
florian55085f82012-11-21 00:36:55 +00002096 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002097
sewardj7ee97522011-05-09 21:45:04 +00002098 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002099 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2100}
2101
2102static void
florian55085f82012-11-21 00:36:55 +00002103s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2104 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002105 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2106{
florian55085f82012-11-21 00:36:55 +00002107 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002108 IRTemp op4addr = newTemp(Ity_I64);
2109
2110 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2111 mkU64(0)));
2112
2113 mnm = irgen(r1, r2, m3, op4addr);
2114
sewardj7ee97522011-05-09 21:45:04 +00002115 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002116 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2117 r2, m3, d4, 0, b4);
2118}
2119
2120static void
florian55085f82012-11-21 00:36:55 +00002121s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002122 UChar r1, UChar b2, UShort d2)
2123{
florian55085f82012-11-21 00:36:55 +00002124 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002125 IRTemp op2addr = newTemp(Ity_I64);
2126
2127 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2128 mkU64(0)));
2129
2130 mnm = irgen(r1, op2addr);
2131
sewardj7ee97522011-05-09 21:45:04 +00002132 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002133 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2134}
2135
2136static void
florian55085f82012-11-21 00:36:55 +00002137s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002138 UChar r1, UChar r3, UChar b2, UShort d2)
2139{
florian55085f82012-11-21 00:36:55 +00002140 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002141 IRTemp op2addr = newTemp(Ity_I64);
2142
2143 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2144 mkU64(0)));
2145
2146 mnm = irgen(r1, r3, op2addr);
2147
sewardj7ee97522011-05-09 21:45:04 +00002148 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002149 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2150}
2151
2152static void
florian55085f82012-11-21 00:36:55 +00002153s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002154 UChar r1, UChar r3, UChar b2, UShort d2)
2155{
florian55085f82012-11-21 00:36:55 +00002156 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002157 IRTemp op2addr = newTemp(Ity_I64);
2158
2159 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2160 mkU64(0)));
2161
2162 mnm = irgen(r1, r3, op2addr);
2163
sewardj7ee97522011-05-09 21:45:04 +00002164 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002165 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2166}
2167
2168static void
florian55085f82012-11-21 00:36:55 +00002169s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002170 UChar r1, UChar r3, UChar b2, UShort d2)
2171{
florian55085f82012-11-21 00:36:55 +00002172 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002173 IRTemp op2addr = newTemp(Ity_I64);
2174
2175 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2176 mkU64(0)));
2177
2178 mnm = irgen(r1, r3, op2addr);
2179
sewardj7ee97522011-05-09 21:45:04 +00002180 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002181 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2182}
2183
2184static void
florian55085f82012-11-21 00:36:55 +00002185s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002186 UChar r1, UChar r3, UShort i2)
2187{
florian55085f82012-11-21 00:36:55 +00002188 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002189
sewardj7ee97522011-05-09 21:45:04 +00002190 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002191 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2192}
2193
2194static void
florian55085f82012-11-21 00:36:55 +00002195s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002196 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2197{
florian55085f82012-11-21 00:36:55 +00002198 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002199 IRTemp op2addr = newTemp(Ity_I64);
2200 IRTemp d2 = newTemp(Ity_I64);
2201
2202 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2203 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2204 mkU64(0)));
2205
2206 mnm = irgen(r1, r3, op2addr);
2207
sewardj7ee97522011-05-09 21:45:04 +00002208 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002209 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2210}
2211
2212static void
florian55085f82012-11-21 00:36:55 +00002213s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002214 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2215{
florian55085f82012-11-21 00:36:55 +00002216 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002217 IRTemp op2addr = newTemp(Ity_I64);
2218 IRTemp d2 = newTemp(Ity_I64);
2219
2220 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2221 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2222 mkU64(0)));
2223
2224 mnm = irgen(r1, r3, op2addr);
2225
sewardj7ee97522011-05-09 21:45:04 +00002226 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002227 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2228}
2229
2230static void
florian55085f82012-11-21 00:36:55 +00002231s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002232 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2233{
florian55085f82012-11-21 00:36:55 +00002234 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002235 IRTemp op2addr = newTemp(Ity_I64);
2236 IRTemp d2 = newTemp(Ity_I64);
2237
2238 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2239 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2240 mkU64(0)));
2241
2242 mnm = irgen(r1, r3, op2addr);
2243
sewardj7ee97522011-05-09 21:45:04 +00002244 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002245 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2246}
2247
2248static void
florian55085f82012-11-21 00:36:55 +00002249s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002250 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2251 Int xmnm_kind)
2252{
2253 IRTemp op2addr = newTemp(Ity_I64);
2254 IRTemp d2 = newTemp(Ity_I64);
2255
florian6820ba52012-07-26 02:01:50 +00002256 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2257
sewardjd7bde722011-04-05 13:19:33 +00002258 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2259 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2260 mkU64(0)));
2261
2262 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002263
2264 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002265
sewardj7ee97522011-05-09 21:45:04 +00002266 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002267 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2268}
2269
2270static void
florian55085f82012-11-21 00:36:55 +00002271s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002272 IRTemp op2addr),
2273 UChar r1, UChar x2, UChar b2, UShort d2)
2274{
2275 IRTemp op2addr = newTemp(Ity_I64);
2276
2277 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2278 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2279 mkU64(0)));
2280
2281 irgen(r1, x2, b2, d2, op2addr);
2282}
2283
2284static void
florian55085f82012-11-21 00:36:55 +00002285s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002286 UChar r1, UChar x2, UChar b2, UShort d2)
2287{
florian55085f82012-11-21 00:36:55 +00002288 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002289 IRTemp op2addr = newTemp(Ity_I64);
2290
2291 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2292 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2293 mkU64(0)));
2294
2295 mnm = irgen(r1, op2addr);
2296
sewardj7ee97522011-05-09 21:45:04 +00002297 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002298 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2299}
2300
2301static void
florian55085f82012-11-21 00:36:55 +00002302s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002303 UChar r1, UChar x2, UChar b2, UShort d2)
2304{
florian55085f82012-11-21 00:36:55 +00002305 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002306 IRTemp op2addr = newTemp(Ity_I64);
2307
2308 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2309 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2310 mkU64(0)));
2311
2312 mnm = irgen(r1, op2addr);
2313
sewardj7ee97522011-05-09 21:45:04 +00002314 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002315 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2316}
2317
2318static void
florian55085f82012-11-21 00:36:55 +00002319s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002320 UChar r1, UChar x2, UChar b2, UShort d2)
2321{
florian55085f82012-11-21 00:36:55 +00002322 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002323 IRTemp op2addr = newTemp(Ity_I64);
2324
2325 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2326 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2327 mkU64(0)));
2328
2329 mnm = irgen(r1, op2addr);
2330
sewardj7ee97522011-05-09 21:45:04 +00002331 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002332 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2333}
2334
2335static void
florian55085f82012-11-21 00:36:55 +00002336s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002337 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2338{
florian55085f82012-11-21 00:36:55 +00002339 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002340 IRTemp op2addr = newTemp(Ity_I64);
2341
2342 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2343 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2344 mkU64(0)));
2345
2346 mnm = irgen(r3, op2addr, r1);
2347
sewardj7ee97522011-05-09 21:45:04 +00002348 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002349 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2350}
2351
2352static void
florian55085f82012-11-21 00:36:55 +00002353s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002354 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2355{
florian55085f82012-11-21 00:36:55 +00002356 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002357 IRTemp op2addr = newTemp(Ity_I64);
2358 IRTemp d2 = newTemp(Ity_I64);
2359
2360 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2361 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2362 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2363 mkU64(0)));
2364
2365 mnm = irgen(r1, op2addr);
2366
sewardj7ee97522011-05-09 21:45:04 +00002367 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002368 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2369}
2370
2371static void
florian55085f82012-11-21 00:36:55 +00002372s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002373 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2374{
florian55085f82012-11-21 00:36:55 +00002375 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002376 IRTemp op2addr = newTemp(Ity_I64);
2377 IRTemp d2 = newTemp(Ity_I64);
2378
2379 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2380 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2381 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2382 mkU64(0)));
2383
2384 mnm = irgen(r1, op2addr);
2385
sewardj7ee97522011-05-09 21:45:04 +00002386 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002387 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2388}
2389
2390static void
florian55085f82012-11-21 00:36:55 +00002391s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002392 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2393{
florian55085f82012-11-21 00:36:55 +00002394 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002395 IRTemp op2addr = newTemp(Ity_I64);
2396 IRTemp d2 = newTemp(Ity_I64);
2397
2398 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2399 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2400 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2401 mkU64(0)));
2402
2403 mnm = irgen();
2404
sewardj7ee97522011-05-09 21:45:04 +00002405 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002406 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2407}
2408
2409static void
florian55085f82012-11-21 00:36:55 +00002410s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002411 UChar b2, UShort d2)
2412{
florian55085f82012-11-21 00:36:55 +00002413 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002414 IRTemp op2addr = newTemp(Ity_I64);
2415
2416 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2417 mkU64(0)));
2418
2419 mnm = irgen(op2addr);
2420
sewardj7ee97522011-05-09 21:45:04 +00002421 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002422 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2423}
2424
2425static void
florian55085f82012-11-21 00:36:55 +00002426s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002427 UChar i2, UChar b1, UShort d1)
2428{
florian55085f82012-11-21 00:36:55 +00002429 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002430 IRTemp op1addr = newTemp(Ity_I64);
2431
2432 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2433 mkU64(0)));
2434
2435 mnm = irgen(i2, op1addr);
2436
sewardj7ee97522011-05-09 21:45:04 +00002437 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002438 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2439}
2440
2441static void
florian55085f82012-11-21 00:36:55 +00002442s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002443 UChar i2, UChar b1, UShort dl1, UChar dh1)
2444{
florian55085f82012-11-21 00:36:55 +00002445 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002446 IRTemp op1addr = newTemp(Ity_I64);
2447 IRTemp d1 = newTemp(Ity_I64);
2448
2449 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2450 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2451 mkU64(0)));
2452
2453 mnm = irgen(i2, op1addr);
2454
sewardj7ee97522011-05-09 21:45:04 +00002455 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002456 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2457}
2458
2459static void
florian55085f82012-11-21 00:36:55 +00002460s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002461 UChar i2, UChar b1, UShort dl1, UChar dh1)
2462{
florian55085f82012-11-21 00:36:55 +00002463 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002464 IRTemp op1addr = newTemp(Ity_I64);
2465 IRTemp d1 = newTemp(Ity_I64);
2466
2467 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2468 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2469 mkU64(0)));
2470
2471 mnm = irgen(i2, op1addr);
2472
sewardj7ee97522011-05-09 21:45:04 +00002473 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002474 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2475}
2476
2477static void
florian55085f82012-11-21 00:36:55 +00002478s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002479 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2480{
florian55085f82012-11-21 00:36:55 +00002481 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002482 IRTemp op1addr = newTemp(Ity_I64);
2483 IRTemp op2addr = newTemp(Ity_I64);
2484
2485 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2486 mkU64(0)));
2487 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2488 mkU64(0)));
2489
2490 mnm = irgen(l, op1addr, op2addr);
2491
sewardj7ee97522011-05-09 21:45:04 +00002492 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002493 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2494}
2495
2496static void
florian55085f82012-11-21 00:36:55 +00002497s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002498 UChar b1, UShort d1, UShort i2)
2499{
florian55085f82012-11-21 00:36:55 +00002500 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002501 IRTemp op1addr = newTemp(Ity_I64);
2502
2503 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2504 mkU64(0)));
2505
2506 mnm = irgen(i2, op1addr);
2507
sewardj7ee97522011-05-09 21:45:04 +00002508 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002509 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2510}
2511
2512static void
florian55085f82012-11-21 00:36:55 +00002513s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002514 UChar b1, UShort d1, UShort i2)
2515{
florian55085f82012-11-21 00:36:55 +00002516 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002517 IRTemp op1addr = newTemp(Ity_I64);
2518
2519 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2520 mkU64(0)));
2521
2522 mnm = irgen(i2, op1addr);
2523
sewardj7ee97522011-05-09 21:45:04 +00002524 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002525 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2526}
2527
2528
2529
2530/*------------------------------------------------------------*/
2531/*--- Build IR for opcodes ---*/
2532/*------------------------------------------------------------*/
2533
florian55085f82012-11-21 00:36:55 +00002534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002535s390_irgen_AR(UChar r1, UChar r2)
2536{
2537 IRTemp op1 = newTemp(Ity_I32);
2538 IRTemp op2 = newTemp(Ity_I32);
2539 IRTemp result = newTemp(Ity_I32);
2540
2541 assign(op1, get_gpr_w1(r1));
2542 assign(op2, get_gpr_w1(r2));
2543 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2544 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2545 put_gpr_w1(r1, mkexpr(result));
2546
2547 return "ar";
2548}
2549
florian55085f82012-11-21 00:36:55 +00002550static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002551s390_irgen_AGR(UChar r1, UChar r2)
2552{
2553 IRTemp op1 = newTemp(Ity_I64);
2554 IRTemp op2 = newTemp(Ity_I64);
2555 IRTemp result = newTemp(Ity_I64);
2556
2557 assign(op1, get_gpr_dw0(r1));
2558 assign(op2, get_gpr_dw0(r2));
2559 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2560 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2561 put_gpr_dw0(r1, mkexpr(result));
2562
2563 return "agr";
2564}
2565
florian55085f82012-11-21 00:36:55 +00002566static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002567s390_irgen_AGFR(UChar r1, UChar r2)
2568{
2569 IRTemp op1 = newTemp(Ity_I64);
2570 IRTemp op2 = newTemp(Ity_I64);
2571 IRTemp result = newTemp(Ity_I64);
2572
2573 assign(op1, get_gpr_dw0(r1));
2574 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2575 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2576 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2577 put_gpr_dw0(r1, mkexpr(result));
2578
2579 return "agfr";
2580}
2581
florian55085f82012-11-21 00:36:55 +00002582static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002583s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2584{
2585 IRTemp op2 = newTemp(Ity_I32);
2586 IRTemp op3 = newTemp(Ity_I32);
2587 IRTemp result = newTemp(Ity_I32);
2588
2589 assign(op2, get_gpr_w1(r2));
2590 assign(op3, get_gpr_w1(r3));
2591 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2592 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2593 put_gpr_w1(r1, mkexpr(result));
2594
2595 return "ark";
2596}
2597
florian55085f82012-11-21 00:36:55 +00002598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002599s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2600{
2601 IRTemp op2 = newTemp(Ity_I64);
2602 IRTemp op3 = newTemp(Ity_I64);
2603 IRTemp result = newTemp(Ity_I64);
2604
2605 assign(op2, get_gpr_dw0(r2));
2606 assign(op3, get_gpr_dw0(r3));
2607 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2608 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2609 put_gpr_dw0(r1, mkexpr(result));
2610
2611 return "agrk";
2612}
2613
florian55085f82012-11-21 00:36:55 +00002614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002615s390_irgen_A(UChar r1, IRTemp op2addr)
2616{
2617 IRTemp op1 = newTemp(Ity_I32);
2618 IRTemp op2 = newTemp(Ity_I32);
2619 IRTemp result = newTemp(Ity_I32);
2620
2621 assign(op1, get_gpr_w1(r1));
2622 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2623 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2624 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2625 put_gpr_w1(r1, mkexpr(result));
2626
2627 return "a";
2628}
2629
florian55085f82012-11-21 00:36:55 +00002630static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002631s390_irgen_AY(UChar r1, IRTemp op2addr)
2632{
2633 IRTemp op1 = newTemp(Ity_I32);
2634 IRTemp op2 = newTemp(Ity_I32);
2635 IRTemp result = newTemp(Ity_I32);
2636
2637 assign(op1, get_gpr_w1(r1));
2638 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2639 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2640 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2641 put_gpr_w1(r1, mkexpr(result));
2642
2643 return "ay";
2644}
2645
florian55085f82012-11-21 00:36:55 +00002646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002647s390_irgen_AG(UChar r1, IRTemp op2addr)
2648{
2649 IRTemp op1 = newTemp(Ity_I64);
2650 IRTemp op2 = newTemp(Ity_I64);
2651 IRTemp result = newTemp(Ity_I64);
2652
2653 assign(op1, get_gpr_dw0(r1));
2654 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2655 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2656 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2657 put_gpr_dw0(r1, mkexpr(result));
2658
2659 return "ag";
2660}
2661
florian55085f82012-11-21 00:36:55 +00002662static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002663s390_irgen_AGF(UChar r1, IRTemp op2addr)
2664{
2665 IRTemp op1 = newTemp(Ity_I64);
2666 IRTemp op2 = newTemp(Ity_I64);
2667 IRTemp result = newTemp(Ity_I64);
2668
2669 assign(op1, get_gpr_dw0(r1));
2670 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2671 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2672 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2673 put_gpr_dw0(r1, mkexpr(result));
2674
2675 return "agf";
2676}
2677
florian55085f82012-11-21 00:36:55 +00002678static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002679s390_irgen_AFI(UChar r1, UInt i2)
2680{
2681 IRTemp op1 = newTemp(Ity_I32);
2682 Int op2;
2683 IRTemp result = newTemp(Ity_I32);
2684
2685 assign(op1, get_gpr_w1(r1));
2686 op2 = (Int)i2;
2687 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2688 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2689 mkU32((UInt)op2)));
2690 put_gpr_w1(r1, mkexpr(result));
2691
2692 return "afi";
2693}
2694
florian55085f82012-11-21 00:36:55 +00002695static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002696s390_irgen_AGFI(UChar r1, UInt i2)
2697{
2698 IRTemp op1 = newTemp(Ity_I64);
2699 Long op2;
2700 IRTemp result = newTemp(Ity_I64);
2701
2702 assign(op1, get_gpr_dw0(r1));
2703 op2 = (Long)(Int)i2;
2704 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2705 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2706 mkU64((ULong)op2)));
2707 put_gpr_dw0(r1, mkexpr(result));
2708
2709 return "agfi";
2710}
2711
florian55085f82012-11-21 00:36:55 +00002712static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002713s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2714{
2715 Int op2;
2716 IRTemp op3 = newTemp(Ity_I32);
2717 IRTemp result = newTemp(Ity_I32);
2718
2719 op2 = (Int)(Short)i2;
2720 assign(op3, get_gpr_w1(r3));
2721 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2722 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2723 op2)), op3);
2724 put_gpr_w1(r1, mkexpr(result));
2725
2726 return "ahik";
2727}
2728
florian55085f82012-11-21 00:36:55 +00002729static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002730s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2731{
2732 Long op2;
2733 IRTemp op3 = newTemp(Ity_I64);
2734 IRTemp result = newTemp(Ity_I64);
2735
2736 op2 = (Long)(Short)i2;
2737 assign(op3, get_gpr_dw0(r3));
2738 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2739 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2740 op2)), op3);
2741 put_gpr_dw0(r1, mkexpr(result));
2742
2743 return "aghik";
2744}
2745
florian55085f82012-11-21 00:36:55 +00002746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002747s390_irgen_ASI(UChar i2, IRTemp op1addr)
2748{
2749 IRTemp op1 = newTemp(Ity_I32);
2750 Int op2;
2751 IRTemp result = newTemp(Ity_I32);
2752
2753 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2754 op2 = (Int)(Char)i2;
2755 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2756 store(mkexpr(op1addr), mkexpr(result));
2757 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2758 mkU32((UInt)op2)));
2759
2760 return "asi";
2761}
2762
florian55085f82012-11-21 00:36:55 +00002763static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002764s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2765{
2766 IRTemp op1 = newTemp(Ity_I64);
2767 Long op2;
2768 IRTemp result = newTemp(Ity_I64);
2769
2770 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2771 op2 = (Long)(Char)i2;
2772 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2773 store(mkexpr(op1addr), mkexpr(result));
2774 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2775 mkU64((ULong)op2)));
2776
2777 return "agsi";
2778}
2779
florian55085f82012-11-21 00:36:55 +00002780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002781s390_irgen_AH(UChar r1, IRTemp op2addr)
2782{
2783 IRTemp op1 = newTemp(Ity_I32);
2784 IRTemp op2 = newTemp(Ity_I32);
2785 IRTemp result = newTemp(Ity_I32);
2786
2787 assign(op1, get_gpr_w1(r1));
2788 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2789 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2790 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2791 put_gpr_w1(r1, mkexpr(result));
2792
2793 return "ah";
2794}
2795
florian55085f82012-11-21 00:36:55 +00002796static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002797s390_irgen_AHY(UChar r1, IRTemp op2addr)
2798{
2799 IRTemp op1 = newTemp(Ity_I32);
2800 IRTemp op2 = newTemp(Ity_I32);
2801 IRTemp result = newTemp(Ity_I32);
2802
2803 assign(op1, get_gpr_w1(r1));
2804 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2805 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2806 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2807 put_gpr_w1(r1, mkexpr(result));
2808
2809 return "ahy";
2810}
2811
florian55085f82012-11-21 00:36:55 +00002812static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002813s390_irgen_AHI(UChar r1, UShort i2)
2814{
2815 IRTemp op1 = newTemp(Ity_I32);
2816 Int op2;
2817 IRTemp result = newTemp(Ity_I32);
2818
2819 assign(op1, get_gpr_w1(r1));
2820 op2 = (Int)(Short)i2;
2821 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2822 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2823 mkU32((UInt)op2)));
2824 put_gpr_w1(r1, mkexpr(result));
2825
2826 return "ahi";
2827}
2828
florian55085f82012-11-21 00:36:55 +00002829static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002830s390_irgen_AGHI(UChar r1, UShort i2)
2831{
2832 IRTemp op1 = newTemp(Ity_I64);
2833 Long op2;
2834 IRTemp result = newTemp(Ity_I64);
2835
2836 assign(op1, get_gpr_dw0(r1));
2837 op2 = (Long)(Short)i2;
2838 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2839 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2840 mkU64((ULong)op2)));
2841 put_gpr_dw0(r1, mkexpr(result));
2842
2843 return "aghi";
2844}
2845
florian55085f82012-11-21 00:36:55 +00002846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002847s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2848{
2849 IRTemp op2 = newTemp(Ity_I32);
2850 IRTemp op3 = newTemp(Ity_I32);
2851 IRTemp result = newTemp(Ity_I32);
2852
2853 assign(op2, get_gpr_w0(r2));
2854 assign(op3, get_gpr_w0(r3));
2855 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2856 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2857 put_gpr_w0(r1, mkexpr(result));
2858
2859 return "ahhhr";
2860}
2861
florian55085f82012-11-21 00:36:55 +00002862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002863s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2864{
2865 IRTemp op2 = newTemp(Ity_I32);
2866 IRTemp op3 = newTemp(Ity_I32);
2867 IRTemp result = newTemp(Ity_I32);
2868
2869 assign(op2, get_gpr_w0(r2));
2870 assign(op3, get_gpr_w1(r3));
2871 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2872 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2873 put_gpr_w0(r1, mkexpr(result));
2874
2875 return "ahhlr";
2876}
2877
florian55085f82012-11-21 00:36:55 +00002878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002879s390_irgen_AIH(UChar r1, UInt i2)
2880{
2881 IRTemp op1 = newTemp(Ity_I32);
2882 Int op2;
2883 IRTemp result = newTemp(Ity_I32);
2884
2885 assign(op1, get_gpr_w0(r1));
2886 op2 = (Int)i2;
2887 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2888 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2889 mkU32((UInt)op2)));
2890 put_gpr_w0(r1, mkexpr(result));
2891
2892 return "aih";
2893}
2894
florian55085f82012-11-21 00:36:55 +00002895static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002896s390_irgen_ALR(UChar r1, UChar r2)
2897{
2898 IRTemp op1 = newTemp(Ity_I32);
2899 IRTemp op2 = newTemp(Ity_I32);
2900 IRTemp result = newTemp(Ity_I32);
2901
2902 assign(op1, get_gpr_w1(r1));
2903 assign(op2, get_gpr_w1(r2));
2904 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2905 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2906 put_gpr_w1(r1, mkexpr(result));
2907
2908 return "alr";
2909}
2910
florian55085f82012-11-21 00:36:55 +00002911static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002912s390_irgen_ALGR(UChar r1, UChar r2)
2913{
2914 IRTemp op1 = newTemp(Ity_I64);
2915 IRTemp op2 = newTemp(Ity_I64);
2916 IRTemp result = newTemp(Ity_I64);
2917
2918 assign(op1, get_gpr_dw0(r1));
2919 assign(op2, get_gpr_dw0(r2));
2920 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2921 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2922 put_gpr_dw0(r1, mkexpr(result));
2923
2924 return "algr";
2925}
2926
florian55085f82012-11-21 00:36:55 +00002927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002928s390_irgen_ALGFR(UChar r1, UChar r2)
2929{
2930 IRTemp op1 = newTemp(Ity_I64);
2931 IRTemp op2 = newTemp(Ity_I64);
2932 IRTemp result = newTemp(Ity_I64);
2933
2934 assign(op1, get_gpr_dw0(r1));
2935 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2936 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2937 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2938 put_gpr_dw0(r1, mkexpr(result));
2939
2940 return "algfr";
2941}
2942
florian55085f82012-11-21 00:36:55 +00002943static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002944s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2945{
2946 IRTemp op2 = newTemp(Ity_I32);
2947 IRTemp op3 = newTemp(Ity_I32);
2948 IRTemp result = newTemp(Ity_I32);
2949
2950 assign(op2, get_gpr_w1(r2));
2951 assign(op3, get_gpr_w1(r3));
2952 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2953 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2954 put_gpr_w1(r1, mkexpr(result));
2955
2956 return "alrk";
2957}
2958
florian55085f82012-11-21 00:36:55 +00002959static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002960s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2961{
2962 IRTemp op2 = newTemp(Ity_I64);
2963 IRTemp op3 = newTemp(Ity_I64);
2964 IRTemp result = newTemp(Ity_I64);
2965
2966 assign(op2, get_gpr_dw0(r2));
2967 assign(op3, get_gpr_dw0(r3));
2968 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2969 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
2970 put_gpr_dw0(r1, mkexpr(result));
2971
2972 return "algrk";
2973}
2974
florian55085f82012-11-21 00:36:55 +00002975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002976s390_irgen_AL(UChar r1, IRTemp op2addr)
2977{
2978 IRTemp op1 = newTemp(Ity_I32);
2979 IRTemp op2 = newTemp(Ity_I32);
2980 IRTemp result = newTemp(Ity_I32);
2981
2982 assign(op1, get_gpr_w1(r1));
2983 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2984 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2985 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2986 put_gpr_w1(r1, mkexpr(result));
2987
2988 return "al";
2989}
2990
florian55085f82012-11-21 00:36:55 +00002991static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002992s390_irgen_ALY(UChar r1, IRTemp op2addr)
2993{
2994 IRTemp op1 = newTemp(Ity_I32);
2995 IRTemp op2 = newTemp(Ity_I32);
2996 IRTemp result = newTemp(Ity_I32);
2997
2998 assign(op1, get_gpr_w1(r1));
2999 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3000 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3001 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3002 put_gpr_w1(r1, mkexpr(result));
3003
3004 return "aly";
3005}
3006
florian55085f82012-11-21 00:36:55 +00003007static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003008s390_irgen_ALG(UChar r1, IRTemp op2addr)
3009{
3010 IRTemp op1 = newTemp(Ity_I64);
3011 IRTemp op2 = newTemp(Ity_I64);
3012 IRTemp result = newTemp(Ity_I64);
3013
3014 assign(op1, get_gpr_dw0(r1));
3015 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3016 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3017 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3018 put_gpr_dw0(r1, mkexpr(result));
3019
3020 return "alg";
3021}
3022
florian55085f82012-11-21 00:36:55 +00003023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003024s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3025{
3026 IRTemp op1 = newTemp(Ity_I64);
3027 IRTemp op2 = newTemp(Ity_I64);
3028 IRTemp result = newTemp(Ity_I64);
3029
3030 assign(op1, get_gpr_dw0(r1));
3031 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3032 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3033 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3034 put_gpr_dw0(r1, mkexpr(result));
3035
3036 return "algf";
3037}
3038
florian55085f82012-11-21 00:36:55 +00003039static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003040s390_irgen_ALFI(UChar r1, UInt i2)
3041{
3042 IRTemp op1 = newTemp(Ity_I32);
3043 UInt op2;
3044 IRTemp result = newTemp(Ity_I32);
3045
3046 assign(op1, get_gpr_w1(r1));
3047 op2 = i2;
3048 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3049 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3050 mkU32(op2)));
3051 put_gpr_w1(r1, mkexpr(result));
3052
3053 return "alfi";
3054}
3055
florian55085f82012-11-21 00:36:55 +00003056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003057s390_irgen_ALGFI(UChar r1, UInt i2)
3058{
3059 IRTemp op1 = newTemp(Ity_I64);
3060 ULong op2;
3061 IRTemp result = newTemp(Ity_I64);
3062
3063 assign(op1, get_gpr_dw0(r1));
3064 op2 = (ULong)i2;
3065 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3066 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3067 mkU64(op2)));
3068 put_gpr_dw0(r1, mkexpr(result));
3069
3070 return "algfi";
3071}
3072
florian55085f82012-11-21 00:36:55 +00003073static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003074s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3075{
3076 IRTemp op2 = newTemp(Ity_I32);
3077 IRTemp op3 = newTemp(Ity_I32);
3078 IRTemp result = newTemp(Ity_I32);
3079
3080 assign(op2, get_gpr_w0(r2));
3081 assign(op3, get_gpr_w0(r3));
3082 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3083 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3084 put_gpr_w0(r1, mkexpr(result));
3085
3086 return "alhhhr";
3087}
3088
florian55085f82012-11-21 00:36:55 +00003089static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003090s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3091{
3092 IRTemp op2 = newTemp(Ity_I32);
3093 IRTemp op3 = newTemp(Ity_I32);
3094 IRTemp result = newTemp(Ity_I32);
3095
3096 assign(op2, get_gpr_w0(r2));
3097 assign(op3, get_gpr_w1(r3));
3098 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3099 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3100 put_gpr_w0(r1, mkexpr(result));
3101
3102 return "alhhlr";
3103}
3104
florian55085f82012-11-21 00:36:55 +00003105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003106s390_irgen_ALCR(UChar r1, UChar r2)
3107{
3108 IRTemp op1 = newTemp(Ity_I32);
3109 IRTemp op2 = newTemp(Ity_I32);
3110 IRTemp result = newTemp(Ity_I32);
3111 IRTemp carry_in = newTemp(Ity_I32);
3112
3113 assign(op1, get_gpr_w1(r1));
3114 assign(op2, get_gpr_w1(r2));
3115 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3116 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3117 mkexpr(carry_in)));
3118 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3119 put_gpr_w1(r1, mkexpr(result));
3120
3121 return "alcr";
3122}
3123
florian55085f82012-11-21 00:36:55 +00003124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003125s390_irgen_ALCGR(UChar r1, UChar r2)
3126{
3127 IRTemp op1 = newTemp(Ity_I64);
3128 IRTemp op2 = newTemp(Ity_I64);
3129 IRTemp result = newTemp(Ity_I64);
3130 IRTemp carry_in = newTemp(Ity_I64);
3131
3132 assign(op1, get_gpr_dw0(r1));
3133 assign(op2, get_gpr_dw0(r2));
3134 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3135 mkU8(1))));
3136 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3137 mkexpr(carry_in)));
3138 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3139 put_gpr_dw0(r1, mkexpr(result));
3140
3141 return "alcgr";
3142}
3143
florian55085f82012-11-21 00:36:55 +00003144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003145s390_irgen_ALC(UChar r1, IRTemp op2addr)
3146{
3147 IRTemp op1 = newTemp(Ity_I32);
3148 IRTemp op2 = newTemp(Ity_I32);
3149 IRTemp result = newTemp(Ity_I32);
3150 IRTemp carry_in = newTemp(Ity_I32);
3151
3152 assign(op1, get_gpr_w1(r1));
3153 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3154 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3155 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3156 mkexpr(carry_in)));
3157 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3158 put_gpr_w1(r1, mkexpr(result));
3159
3160 return "alc";
3161}
3162
florian55085f82012-11-21 00:36:55 +00003163static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003164s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3165{
3166 IRTemp op1 = newTemp(Ity_I64);
3167 IRTemp op2 = newTemp(Ity_I64);
3168 IRTemp result = newTemp(Ity_I64);
3169 IRTemp carry_in = newTemp(Ity_I64);
3170
3171 assign(op1, get_gpr_dw0(r1));
3172 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3173 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3174 mkU8(1))));
3175 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3176 mkexpr(carry_in)));
3177 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3178 put_gpr_dw0(r1, mkexpr(result));
3179
3180 return "alcg";
3181}
3182
florian55085f82012-11-21 00:36:55 +00003183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003184s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3185{
3186 IRTemp op1 = newTemp(Ity_I32);
3187 UInt op2;
3188 IRTemp result = newTemp(Ity_I32);
3189
3190 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3191 op2 = (UInt)(Int)(Char)i2;
3192 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3193 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3194 mkU32(op2)));
3195 store(mkexpr(op1addr), mkexpr(result));
3196
3197 return "alsi";
3198}
3199
florian55085f82012-11-21 00:36:55 +00003200static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003201s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3202{
3203 IRTemp op1 = newTemp(Ity_I64);
3204 ULong op2;
3205 IRTemp result = newTemp(Ity_I64);
3206
3207 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3208 op2 = (ULong)(Long)(Char)i2;
3209 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3210 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3211 mkU64(op2)));
3212 store(mkexpr(op1addr), mkexpr(result));
3213
3214 return "algsi";
3215}
3216
florian55085f82012-11-21 00:36:55 +00003217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003218s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3219{
3220 UInt op2;
3221 IRTemp op3 = newTemp(Ity_I32);
3222 IRTemp result = newTemp(Ity_I32);
3223
3224 op2 = (UInt)(Int)(Short)i2;
3225 assign(op3, get_gpr_w1(r3));
3226 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3227 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3228 op3);
3229 put_gpr_w1(r1, mkexpr(result));
3230
3231 return "alhsik";
3232}
3233
florian55085f82012-11-21 00:36:55 +00003234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003235s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3236{
3237 ULong op2;
3238 IRTemp op3 = newTemp(Ity_I64);
3239 IRTemp result = newTemp(Ity_I64);
3240
3241 op2 = (ULong)(Long)(Short)i2;
3242 assign(op3, get_gpr_dw0(r3));
3243 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3244 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3245 op3);
3246 put_gpr_dw0(r1, mkexpr(result));
3247
3248 return "alghsik";
3249}
3250
florian55085f82012-11-21 00:36:55 +00003251static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003252s390_irgen_ALSIH(UChar r1, UInt i2)
3253{
3254 IRTemp op1 = newTemp(Ity_I32);
3255 UInt op2;
3256 IRTemp result = newTemp(Ity_I32);
3257
3258 assign(op1, get_gpr_w0(r1));
3259 op2 = i2;
3260 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3261 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3262 mkU32(op2)));
3263 put_gpr_w0(r1, mkexpr(result));
3264
3265 return "alsih";
3266}
3267
florian55085f82012-11-21 00:36:55 +00003268static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003269s390_irgen_ALSIHN(UChar r1, UInt i2)
3270{
3271 IRTemp op1 = newTemp(Ity_I32);
3272 UInt op2;
3273 IRTemp result = newTemp(Ity_I32);
3274
3275 assign(op1, get_gpr_w0(r1));
3276 op2 = i2;
3277 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3278 put_gpr_w0(r1, mkexpr(result));
3279
3280 return "alsihn";
3281}
3282
florian55085f82012-11-21 00:36:55 +00003283static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003284s390_irgen_NR(UChar r1, UChar r2)
3285{
3286 IRTemp op1 = newTemp(Ity_I32);
3287 IRTemp op2 = newTemp(Ity_I32);
3288 IRTemp result = newTemp(Ity_I32);
3289
3290 assign(op1, get_gpr_w1(r1));
3291 assign(op2, get_gpr_w1(r2));
3292 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3293 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3294 put_gpr_w1(r1, mkexpr(result));
3295
3296 return "nr";
3297}
3298
florian55085f82012-11-21 00:36:55 +00003299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003300s390_irgen_NGR(UChar r1, UChar r2)
3301{
3302 IRTemp op1 = newTemp(Ity_I64);
3303 IRTemp op2 = newTemp(Ity_I64);
3304 IRTemp result = newTemp(Ity_I64);
3305
3306 assign(op1, get_gpr_dw0(r1));
3307 assign(op2, get_gpr_dw0(r2));
3308 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3309 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3310 put_gpr_dw0(r1, mkexpr(result));
3311
3312 return "ngr";
3313}
3314
florian55085f82012-11-21 00:36:55 +00003315static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003316s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3317{
3318 IRTemp op2 = newTemp(Ity_I32);
3319 IRTemp op3 = newTemp(Ity_I32);
3320 IRTemp result = newTemp(Ity_I32);
3321
3322 assign(op2, get_gpr_w1(r2));
3323 assign(op3, get_gpr_w1(r3));
3324 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3325 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3326 put_gpr_w1(r1, mkexpr(result));
3327
3328 return "nrk";
3329}
3330
florian55085f82012-11-21 00:36:55 +00003331static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003332s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3333{
3334 IRTemp op2 = newTemp(Ity_I64);
3335 IRTemp op3 = newTemp(Ity_I64);
3336 IRTemp result = newTemp(Ity_I64);
3337
3338 assign(op2, get_gpr_dw0(r2));
3339 assign(op3, get_gpr_dw0(r3));
3340 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3341 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3342 put_gpr_dw0(r1, mkexpr(result));
3343
3344 return "ngrk";
3345}
3346
florian55085f82012-11-21 00:36:55 +00003347static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003348s390_irgen_N(UChar r1, IRTemp op2addr)
3349{
3350 IRTemp op1 = newTemp(Ity_I32);
3351 IRTemp op2 = newTemp(Ity_I32);
3352 IRTemp result = newTemp(Ity_I32);
3353
3354 assign(op1, get_gpr_w1(r1));
3355 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3356 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3357 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3358 put_gpr_w1(r1, mkexpr(result));
3359
3360 return "n";
3361}
3362
florian55085f82012-11-21 00:36:55 +00003363static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003364s390_irgen_NY(UChar r1, IRTemp op2addr)
3365{
3366 IRTemp op1 = newTemp(Ity_I32);
3367 IRTemp op2 = newTemp(Ity_I32);
3368 IRTemp result = newTemp(Ity_I32);
3369
3370 assign(op1, get_gpr_w1(r1));
3371 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3372 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3373 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3374 put_gpr_w1(r1, mkexpr(result));
3375
3376 return "ny";
3377}
3378
florian55085f82012-11-21 00:36:55 +00003379static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003380s390_irgen_NG(UChar r1, IRTemp op2addr)
3381{
3382 IRTemp op1 = newTemp(Ity_I64);
3383 IRTemp op2 = newTemp(Ity_I64);
3384 IRTemp result = newTemp(Ity_I64);
3385
3386 assign(op1, get_gpr_dw0(r1));
3387 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3388 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3389 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3390 put_gpr_dw0(r1, mkexpr(result));
3391
3392 return "ng";
3393}
3394
florian55085f82012-11-21 00:36:55 +00003395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003396s390_irgen_NI(UChar i2, IRTemp op1addr)
3397{
3398 IRTemp op1 = newTemp(Ity_I8);
3399 UChar op2;
3400 IRTemp result = newTemp(Ity_I8);
3401
3402 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3403 op2 = i2;
3404 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3405 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3406 store(mkexpr(op1addr), mkexpr(result));
3407
3408 return "ni";
3409}
3410
florian55085f82012-11-21 00:36:55 +00003411static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003412s390_irgen_NIY(UChar i2, IRTemp op1addr)
3413{
3414 IRTemp op1 = newTemp(Ity_I8);
3415 UChar op2;
3416 IRTemp result = newTemp(Ity_I8);
3417
3418 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3419 op2 = i2;
3420 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3421 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3422 store(mkexpr(op1addr), mkexpr(result));
3423
3424 return "niy";
3425}
3426
florian55085f82012-11-21 00:36:55 +00003427static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003428s390_irgen_NIHF(UChar r1, UInt i2)
3429{
3430 IRTemp op1 = newTemp(Ity_I32);
3431 UInt op2;
3432 IRTemp result = newTemp(Ity_I32);
3433
3434 assign(op1, get_gpr_w0(r1));
3435 op2 = i2;
3436 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3437 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3438 put_gpr_w0(r1, mkexpr(result));
3439
3440 return "nihf";
3441}
3442
florian55085f82012-11-21 00:36:55 +00003443static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003444s390_irgen_NIHH(UChar r1, UShort i2)
3445{
3446 IRTemp op1 = newTemp(Ity_I16);
3447 UShort op2;
3448 IRTemp result = newTemp(Ity_I16);
3449
3450 assign(op1, get_gpr_hw0(r1));
3451 op2 = i2;
3452 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3453 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3454 put_gpr_hw0(r1, mkexpr(result));
3455
3456 return "nihh";
3457}
3458
florian55085f82012-11-21 00:36:55 +00003459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003460s390_irgen_NIHL(UChar r1, UShort i2)
3461{
3462 IRTemp op1 = newTemp(Ity_I16);
3463 UShort op2;
3464 IRTemp result = newTemp(Ity_I16);
3465
3466 assign(op1, get_gpr_hw1(r1));
3467 op2 = i2;
3468 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3469 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3470 put_gpr_hw1(r1, mkexpr(result));
3471
3472 return "nihl";
3473}
3474
florian55085f82012-11-21 00:36:55 +00003475static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003476s390_irgen_NILF(UChar r1, UInt i2)
3477{
3478 IRTemp op1 = newTemp(Ity_I32);
3479 UInt op2;
3480 IRTemp result = newTemp(Ity_I32);
3481
3482 assign(op1, get_gpr_w1(r1));
3483 op2 = i2;
3484 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3485 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3486 put_gpr_w1(r1, mkexpr(result));
3487
3488 return "nilf";
3489}
3490
florian55085f82012-11-21 00:36:55 +00003491static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003492s390_irgen_NILH(UChar r1, UShort i2)
3493{
3494 IRTemp op1 = newTemp(Ity_I16);
3495 UShort op2;
3496 IRTemp result = newTemp(Ity_I16);
3497
3498 assign(op1, get_gpr_hw2(r1));
3499 op2 = i2;
3500 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3501 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3502 put_gpr_hw2(r1, mkexpr(result));
3503
3504 return "nilh";
3505}
3506
florian55085f82012-11-21 00:36:55 +00003507static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003508s390_irgen_NILL(UChar r1, UShort i2)
3509{
3510 IRTemp op1 = newTemp(Ity_I16);
3511 UShort op2;
3512 IRTemp result = newTemp(Ity_I16);
3513
3514 assign(op1, get_gpr_hw3(r1));
3515 op2 = i2;
3516 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3517 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3518 put_gpr_hw3(r1, mkexpr(result));
3519
3520 return "nill";
3521}
3522
florian55085f82012-11-21 00:36:55 +00003523static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003524s390_irgen_BASR(UChar r1, UChar r2)
3525{
3526 IRTemp target = newTemp(Ity_I64);
3527
3528 if (r2 == 0) {
3529 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3530 } else {
3531 if (r1 != r2) {
3532 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3533 call_function(get_gpr_dw0(r2));
3534 } else {
3535 assign(target, get_gpr_dw0(r2));
3536 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3537 call_function(mkexpr(target));
3538 }
3539 }
3540
3541 return "basr";
3542}
3543
florian55085f82012-11-21 00:36:55 +00003544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003545s390_irgen_BAS(UChar r1, IRTemp op2addr)
3546{
3547 IRTemp target = newTemp(Ity_I64);
3548
3549 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3550 assign(target, mkexpr(op2addr));
3551 call_function(mkexpr(target));
3552
3553 return "bas";
3554}
3555
florian55085f82012-11-21 00:36:55 +00003556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003557s390_irgen_BCR(UChar r1, UChar r2)
3558{
3559 IRTemp cond = newTemp(Ity_I32);
3560
sewardja52e37e2011-04-28 18:48:06 +00003561 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3562 stmt(IRStmt_MBE(Imbe_Fence));
3563 }
3564
sewardj2019a972011-03-07 16:04:07 +00003565 if ((r2 == 0) || (r1 == 0)) {
3566 } else {
3567 if (r1 == 15) {
3568 return_from_function(get_gpr_dw0(r2));
3569 } else {
3570 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003571 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3572 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003573 }
3574 }
sewardj7ee97522011-05-09 21:45:04 +00003575 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003576 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3577
3578 return "bcr";
3579}
3580
florian55085f82012-11-21 00:36:55 +00003581static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003582s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3583{
3584 IRTemp cond = newTemp(Ity_I32);
3585
3586 if (r1 == 0) {
3587 } else {
3588 if (r1 == 15) {
3589 always_goto(mkexpr(op2addr));
3590 } else {
3591 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003592 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3593 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003594 }
3595 }
sewardj7ee97522011-05-09 21:45:04 +00003596 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003597 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3598
3599 return "bc";
3600}
3601
florian55085f82012-11-21 00:36:55 +00003602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003603s390_irgen_BCTR(UChar r1, UChar r2)
3604{
3605 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3606 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003607 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3608 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003609 }
3610
3611 return "bctr";
3612}
3613
florian55085f82012-11-21 00:36:55 +00003614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003615s390_irgen_BCTGR(UChar r1, UChar r2)
3616{
3617 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3618 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003619 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3620 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003621 }
3622
3623 return "bctgr";
3624}
3625
florian55085f82012-11-21 00:36:55 +00003626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003627s390_irgen_BCT(UChar r1, IRTemp op2addr)
3628{
3629 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003630 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3631 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003632
3633 return "bct";
3634}
3635
florian55085f82012-11-21 00:36:55 +00003636static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003637s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3638{
3639 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003640 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3641 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003642
3643 return "bctg";
3644}
3645
florian55085f82012-11-21 00:36:55 +00003646static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003647s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3648{
3649 IRTemp value = newTemp(Ity_I32);
3650
3651 assign(value, get_gpr_w1(r3 | 1));
3652 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003653 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3654 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003655
3656 return "bxh";
3657}
3658
florian55085f82012-11-21 00:36:55 +00003659static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003660s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3661{
3662 IRTemp value = newTemp(Ity_I64);
3663
3664 assign(value, get_gpr_dw0(r3 | 1));
3665 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003666 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3667 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003668
3669 return "bxhg";
3670}
3671
florian55085f82012-11-21 00:36:55 +00003672static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003673s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3674{
3675 IRTemp value = newTemp(Ity_I32);
3676
3677 assign(value, get_gpr_w1(r3 | 1));
3678 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003679 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3680 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003681
3682 return "bxle";
3683}
3684
florian55085f82012-11-21 00:36:55 +00003685static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003686s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3687{
3688 IRTemp value = newTemp(Ity_I64);
3689
3690 assign(value, get_gpr_dw0(r3 | 1));
3691 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003692 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3693 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003694
3695 return "bxleg";
3696}
3697
florian55085f82012-11-21 00:36:55 +00003698static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003699s390_irgen_BRAS(UChar r1, UShort i2)
3700{
3701 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003702 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003703
3704 return "bras";
3705}
3706
florian55085f82012-11-21 00:36:55 +00003707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003708s390_irgen_BRASL(UChar r1, UInt i2)
3709{
3710 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003711 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003712
3713 return "brasl";
3714}
3715
florian55085f82012-11-21 00:36:55 +00003716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003717s390_irgen_BRC(UChar r1, UShort i2)
3718{
3719 IRTemp cond = newTemp(Ity_I32);
3720
3721 if (r1 == 0) {
3722 } else {
3723 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003724 always_goto_and_chase(
3725 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003726 } else {
3727 assign(cond, s390_call_calculate_cond(r1));
3728 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3729 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3730
3731 }
3732 }
sewardj7ee97522011-05-09 21:45:04 +00003733 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003734 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3735
3736 return "brc";
3737}
3738
florian55085f82012-11-21 00:36:55 +00003739static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003740s390_irgen_BRCL(UChar r1, UInt i2)
3741{
3742 IRTemp cond = newTemp(Ity_I32);
3743
3744 if (r1 == 0) {
3745 } else {
3746 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003747 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003748 } else {
3749 assign(cond, s390_call_calculate_cond(r1));
3750 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3751 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3752 }
3753 }
sewardj7ee97522011-05-09 21:45:04 +00003754 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003755 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3756
3757 return "brcl";
3758}
3759
florian55085f82012-11-21 00:36:55 +00003760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003761s390_irgen_BRCT(UChar r1, UShort i2)
3762{
3763 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3764 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3765 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3766
3767 return "brct";
3768}
3769
florian55085f82012-11-21 00:36:55 +00003770static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003771s390_irgen_BRCTG(UChar r1, UShort i2)
3772{
3773 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3774 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3775 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3776
3777 return "brctg";
3778}
3779
florian55085f82012-11-21 00:36:55 +00003780static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003781s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3782{
3783 IRTemp value = newTemp(Ity_I32);
3784
3785 assign(value, get_gpr_w1(r3 | 1));
3786 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3787 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3788 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3789
3790 return "brxh";
3791}
3792
florian55085f82012-11-21 00:36:55 +00003793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003794s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3795{
3796 IRTemp value = newTemp(Ity_I64);
3797
3798 assign(value, get_gpr_dw0(r3 | 1));
3799 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3800 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3801 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3802
3803 return "brxhg";
3804}
3805
florian55085f82012-11-21 00:36:55 +00003806static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003807s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3808{
3809 IRTemp value = newTemp(Ity_I32);
3810
3811 assign(value, get_gpr_w1(r3 | 1));
3812 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3813 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3814 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3815
3816 return "brxle";
3817}
3818
florian55085f82012-11-21 00:36:55 +00003819static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003820s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3821{
3822 IRTemp value = newTemp(Ity_I64);
3823
3824 assign(value, get_gpr_dw0(r3 | 1));
3825 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3826 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3827 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3828
3829 return "brxlg";
3830}
3831
florian55085f82012-11-21 00:36:55 +00003832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003833s390_irgen_CR(UChar r1, UChar r2)
3834{
3835 IRTemp op1 = newTemp(Ity_I32);
3836 IRTemp op2 = newTemp(Ity_I32);
3837
3838 assign(op1, get_gpr_w1(r1));
3839 assign(op2, get_gpr_w1(r2));
3840 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3841
3842 return "cr";
3843}
3844
florian55085f82012-11-21 00:36:55 +00003845static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003846s390_irgen_CGR(UChar r1, UChar r2)
3847{
3848 IRTemp op1 = newTemp(Ity_I64);
3849 IRTemp op2 = newTemp(Ity_I64);
3850
3851 assign(op1, get_gpr_dw0(r1));
3852 assign(op2, get_gpr_dw0(r2));
3853 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3854
3855 return "cgr";
3856}
3857
florian55085f82012-11-21 00:36:55 +00003858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003859s390_irgen_CGFR(UChar r1, UChar r2)
3860{
3861 IRTemp op1 = newTemp(Ity_I64);
3862 IRTemp op2 = newTemp(Ity_I64);
3863
3864 assign(op1, get_gpr_dw0(r1));
3865 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3866 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3867
3868 return "cgfr";
3869}
3870
florian55085f82012-11-21 00:36:55 +00003871static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003872s390_irgen_C(UChar r1, IRTemp op2addr)
3873{
3874 IRTemp op1 = newTemp(Ity_I32);
3875 IRTemp op2 = newTemp(Ity_I32);
3876
3877 assign(op1, get_gpr_w1(r1));
3878 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3879 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3880
3881 return "c";
3882}
3883
florian55085f82012-11-21 00:36:55 +00003884static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003885s390_irgen_CY(UChar r1, IRTemp op2addr)
3886{
3887 IRTemp op1 = newTemp(Ity_I32);
3888 IRTemp op2 = newTemp(Ity_I32);
3889
3890 assign(op1, get_gpr_w1(r1));
3891 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3892 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3893
3894 return "cy";
3895}
3896
florian55085f82012-11-21 00:36:55 +00003897static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003898s390_irgen_CG(UChar r1, IRTemp op2addr)
3899{
3900 IRTemp op1 = newTemp(Ity_I64);
3901 IRTemp op2 = newTemp(Ity_I64);
3902
3903 assign(op1, get_gpr_dw0(r1));
3904 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3905 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3906
3907 return "cg";
3908}
3909
florian55085f82012-11-21 00:36:55 +00003910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003911s390_irgen_CGF(UChar r1, IRTemp op2addr)
3912{
3913 IRTemp op1 = newTemp(Ity_I64);
3914 IRTemp op2 = newTemp(Ity_I64);
3915
3916 assign(op1, get_gpr_dw0(r1));
3917 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3918 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3919
3920 return "cgf";
3921}
3922
florian55085f82012-11-21 00:36:55 +00003923static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003924s390_irgen_CFI(UChar r1, UInt i2)
3925{
3926 IRTemp op1 = newTemp(Ity_I32);
3927 Int op2;
3928
3929 assign(op1, get_gpr_w1(r1));
3930 op2 = (Int)i2;
3931 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3932 mkU32((UInt)op2)));
3933
3934 return "cfi";
3935}
3936
florian55085f82012-11-21 00:36:55 +00003937static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003938s390_irgen_CGFI(UChar r1, UInt i2)
3939{
3940 IRTemp op1 = newTemp(Ity_I64);
3941 Long op2;
3942
3943 assign(op1, get_gpr_dw0(r1));
3944 op2 = (Long)(Int)i2;
3945 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3946 mkU64((ULong)op2)));
3947
3948 return "cgfi";
3949}
3950
florian55085f82012-11-21 00:36:55 +00003951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003952s390_irgen_CRL(UChar r1, UInt i2)
3953{
3954 IRTemp op1 = newTemp(Ity_I32);
3955 IRTemp op2 = newTemp(Ity_I32);
3956
3957 assign(op1, get_gpr_w1(r1));
3958 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3959 i2 << 1))));
3960 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3961
3962 return "crl";
3963}
3964
florian55085f82012-11-21 00:36:55 +00003965static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003966s390_irgen_CGRL(UChar r1, UInt i2)
3967{
3968 IRTemp op1 = newTemp(Ity_I64);
3969 IRTemp op2 = newTemp(Ity_I64);
3970
3971 assign(op1, get_gpr_dw0(r1));
3972 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3973 i2 << 1))));
3974 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3975
3976 return "cgrl";
3977}
3978
florian55085f82012-11-21 00:36:55 +00003979static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003980s390_irgen_CGFRL(UChar r1, UInt i2)
3981{
3982 IRTemp op1 = newTemp(Ity_I64);
3983 IRTemp op2 = newTemp(Ity_I64);
3984
3985 assign(op1, get_gpr_dw0(r1));
3986 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
3987 ((ULong)(Long)(Int)i2 << 1)))));
3988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3989
3990 return "cgfrl";
3991}
3992
florian55085f82012-11-21 00:36:55 +00003993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003994s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
3995{
3996 IRTemp op1 = newTemp(Ity_I32);
3997 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00003998 IRTemp cond = newTemp(Ity_I32);
3999
4000 if (m3 == 0) {
4001 } else {
4002 if (m3 == 14) {
4003 always_goto(mkexpr(op4addr));
4004 } else {
4005 assign(op1, get_gpr_w1(r1));
4006 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004007 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4008 op1, op2));
florianf321da72012-07-21 20:32:57 +00004009 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4010 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004011 }
4012 }
4013
4014 return "crb";
4015}
4016
florian55085f82012-11-21 00:36:55 +00004017static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004018s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4019{
4020 IRTemp op1 = newTemp(Ity_I64);
4021 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004022 IRTemp cond = newTemp(Ity_I32);
4023
4024 if (m3 == 0) {
4025 } else {
4026 if (m3 == 14) {
4027 always_goto(mkexpr(op4addr));
4028 } else {
4029 assign(op1, get_gpr_dw0(r1));
4030 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004031 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4032 op1, op2));
florianf321da72012-07-21 20:32:57 +00004033 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4034 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004035 }
4036 }
4037
4038 return "cgrb";
4039}
4040
florian55085f82012-11-21 00:36:55 +00004041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004042s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4043{
4044 IRTemp op1 = newTemp(Ity_I32);
4045 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004046 IRTemp cond = newTemp(Ity_I32);
4047
4048 if (m3 == 0) {
4049 } else {
4050 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004051 always_goto_and_chase(
4052 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004053 } else {
4054 assign(op1, get_gpr_w1(r1));
4055 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004056 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4057 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004058 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4059 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4060
4061 }
4062 }
4063
4064 return "crj";
4065}
4066
florian55085f82012-11-21 00:36:55 +00004067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004068s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4069{
4070 IRTemp op1 = newTemp(Ity_I64);
4071 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004072 IRTemp cond = newTemp(Ity_I32);
4073
4074 if (m3 == 0) {
4075 } else {
4076 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004077 always_goto_and_chase(
4078 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004079 } else {
4080 assign(op1, get_gpr_dw0(r1));
4081 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004082 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4083 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004084 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4085 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4086
4087 }
4088 }
4089
4090 return "cgrj";
4091}
4092
florian55085f82012-11-21 00:36:55 +00004093static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004094s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4095{
4096 IRTemp op1 = newTemp(Ity_I32);
4097 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004098 IRTemp cond = newTemp(Ity_I32);
4099
4100 if (m3 == 0) {
4101 } else {
4102 if (m3 == 14) {
4103 always_goto(mkexpr(op4addr));
4104 } else {
4105 assign(op1, get_gpr_w1(r1));
4106 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004107 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4108 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004109 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4110 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004111 }
4112 }
4113
4114 return "cib";
4115}
4116
florian55085f82012-11-21 00:36:55 +00004117static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004118s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4119{
4120 IRTemp op1 = newTemp(Ity_I64);
4121 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004122 IRTemp cond = newTemp(Ity_I32);
4123
4124 if (m3 == 0) {
4125 } else {
4126 if (m3 == 14) {
4127 always_goto(mkexpr(op4addr));
4128 } else {
4129 assign(op1, get_gpr_dw0(r1));
4130 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004131 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4132 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004133 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4134 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004135 }
4136 }
4137
4138 return "cgib";
4139}
4140
florian55085f82012-11-21 00:36:55 +00004141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004142s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4143{
4144 IRTemp op1 = newTemp(Ity_I32);
4145 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004146 IRTemp cond = newTemp(Ity_I32);
4147
4148 if (m3 == 0) {
4149 } else {
4150 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004151 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004152 } else {
4153 assign(op1, get_gpr_w1(r1));
4154 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004155 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4156 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004157 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4158 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4159
4160 }
4161 }
4162
4163 return "cij";
4164}
4165
florian55085f82012-11-21 00:36:55 +00004166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004167s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4168{
4169 IRTemp op1 = newTemp(Ity_I64);
4170 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004171 IRTemp cond = newTemp(Ity_I32);
4172
4173 if (m3 == 0) {
4174 } else {
4175 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004176 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004177 } else {
4178 assign(op1, get_gpr_dw0(r1));
4179 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004180 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4181 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004182 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4183 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4184
4185 }
4186 }
4187
4188 return "cgij";
4189}
4190
florian55085f82012-11-21 00:36:55 +00004191static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004192s390_irgen_CH(UChar r1, IRTemp op2addr)
4193{
4194 IRTemp op1 = newTemp(Ity_I32);
4195 IRTemp op2 = newTemp(Ity_I32);
4196
4197 assign(op1, get_gpr_w1(r1));
4198 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4199 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4200
4201 return "ch";
4202}
4203
florian55085f82012-11-21 00:36:55 +00004204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004205s390_irgen_CHY(UChar r1, IRTemp op2addr)
4206{
4207 IRTemp op1 = newTemp(Ity_I32);
4208 IRTemp op2 = newTemp(Ity_I32);
4209
4210 assign(op1, get_gpr_w1(r1));
4211 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4212 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4213
4214 return "chy";
4215}
4216
florian55085f82012-11-21 00:36:55 +00004217static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004218s390_irgen_CGH(UChar r1, IRTemp op2addr)
4219{
4220 IRTemp op1 = newTemp(Ity_I64);
4221 IRTemp op2 = newTemp(Ity_I64);
4222
4223 assign(op1, get_gpr_dw0(r1));
4224 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4225 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4226
4227 return "cgh";
4228}
4229
florian55085f82012-11-21 00:36:55 +00004230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004231s390_irgen_CHI(UChar r1, UShort i2)
4232{
4233 IRTemp op1 = newTemp(Ity_I32);
4234 Int op2;
4235
4236 assign(op1, get_gpr_w1(r1));
4237 op2 = (Int)(Short)i2;
4238 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4239 mkU32((UInt)op2)));
4240
4241 return "chi";
4242}
4243
florian55085f82012-11-21 00:36:55 +00004244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004245s390_irgen_CGHI(UChar r1, UShort i2)
4246{
4247 IRTemp op1 = newTemp(Ity_I64);
4248 Long op2;
4249
4250 assign(op1, get_gpr_dw0(r1));
4251 op2 = (Long)(Short)i2;
4252 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4253 mkU64((ULong)op2)));
4254
4255 return "cghi";
4256}
4257
florian55085f82012-11-21 00:36:55 +00004258static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004259s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4260{
4261 IRTemp op1 = newTemp(Ity_I16);
4262 Short op2;
4263
4264 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4265 op2 = (Short)i2;
4266 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4267 mkU16((UShort)op2)));
4268
4269 return "chhsi";
4270}
4271
florian55085f82012-11-21 00:36:55 +00004272static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004273s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4274{
4275 IRTemp op1 = newTemp(Ity_I32);
4276 Int op2;
4277
4278 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4279 op2 = (Int)(Short)i2;
4280 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4281 mkU32((UInt)op2)));
4282
4283 return "chsi";
4284}
4285
florian55085f82012-11-21 00:36:55 +00004286static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004287s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4288{
4289 IRTemp op1 = newTemp(Ity_I64);
4290 Long op2;
4291
4292 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4293 op2 = (Long)(Short)i2;
4294 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4295 mkU64((ULong)op2)));
4296
4297 return "cghsi";
4298}
4299
florian55085f82012-11-21 00:36:55 +00004300static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004301s390_irgen_CHRL(UChar r1, UInt i2)
4302{
4303 IRTemp op1 = newTemp(Ity_I32);
4304 IRTemp op2 = newTemp(Ity_I32);
4305
4306 assign(op1, get_gpr_w1(r1));
4307 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4308 ((ULong)(Long)(Int)i2 << 1)))));
4309 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4310
4311 return "chrl";
4312}
4313
florian55085f82012-11-21 00:36:55 +00004314static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004315s390_irgen_CGHRL(UChar r1, UInt i2)
4316{
4317 IRTemp op1 = newTemp(Ity_I64);
4318 IRTemp op2 = newTemp(Ity_I64);
4319
4320 assign(op1, get_gpr_dw0(r1));
4321 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4322 ((ULong)(Long)(Int)i2 << 1)))));
4323 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4324
4325 return "cghrl";
4326}
4327
florian55085f82012-11-21 00:36:55 +00004328static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004329s390_irgen_CHHR(UChar r1, UChar r2)
4330{
4331 IRTemp op1 = newTemp(Ity_I32);
4332 IRTemp op2 = newTemp(Ity_I32);
4333
4334 assign(op1, get_gpr_w0(r1));
4335 assign(op2, get_gpr_w0(r2));
4336 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4337
4338 return "chhr";
4339}
4340
florian55085f82012-11-21 00:36:55 +00004341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004342s390_irgen_CHLR(UChar r1, UChar r2)
4343{
4344 IRTemp op1 = newTemp(Ity_I32);
4345 IRTemp op2 = newTemp(Ity_I32);
4346
4347 assign(op1, get_gpr_w0(r1));
4348 assign(op2, get_gpr_w1(r2));
4349 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4350
4351 return "chlr";
4352}
4353
florian55085f82012-11-21 00:36:55 +00004354static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004355s390_irgen_CHF(UChar r1, IRTemp op2addr)
4356{
4357 IRTemp op1 = newTemp(Ity_I32);
4358 IRTemp op2 = newTemp(Ity_I32);
4359
4360 assign(op1, get_gpr_w0(r1));
4361 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4362 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4363
4364 return "chf";
4365}
4366
florian55085f82012-11-21 00:36:55 +00004367static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004368s390_irgen_CIH(UChar r1, UInt i2)
4369{
4370 IRTemp op1 = newTemp(Ity_I32);
4371 Int op2;
4372
4373 assign(op1, get_gpr_w0(r1));
4374 op2 = (Int)i2;
4375 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4376 mkU32((UInt)op2)));
4377
4378 return "cih";
4379}
4380
florian55085f82012-11-21 00:36:55 +00004381static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004382s390_irgen_CLR(UChar r1, UChar r2)
4383{
4384 IRTemp op1 = newTemp(Ity_I32);
4385 IRTemp op2 = newTemp(Ity_I32);
4386
4387 assign(op1, get_gpr_w1(r1));
4388 assign(op2, get_gpr_w1(r2));
4389 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4390
4391 return "clr";
4392}
4393
florian55085f82012-11-21 00:36:55 +00004394static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004395s390_irgen_CLGR(UChar r1, UChar r2)
4396{
4397 IRTemp op1 = newTemp(Ity_I64);
4398 IRTemp op2 = newTemp(Ity_I64);
4399
4400 assign(op1, get_gpr_dw0(r1));
4401 assign(op2, get_gpr_dw0(r2));
4402 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4403
4404 return "clgr";
4405}
4406
florian55085f82012-11-21 00:36:55 +00004407static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004408s390_irgen_CLGFR(UChar r1, UChar r2)
4409{
4410 IRTemp op1 = newTemp(Ity_I64);
4411 IRTemp op2 = newTemp(Ity_I64);
4412
4413 assign(op1, get_gpr_dw0(r1));
4414 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4415 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4416
4417 return "clgfr";
4418}
4419
florian55085f82012-11-21 00:36:55 +00004420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004421s390_irgen_CL(UChar r1, IRTemp op2addr)
4422{
4423 IRTemp op1 = newTemp(Ity_I32);
4424 IRTemp op2 = newTemp(Ity_I32);
4425
4426 assign(op1, get_gpr_w1(r1));
4427 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4428 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4429
4430 return "cl";
4431}
4432
florian55085f82012-11-21 00:36:55 +00004433static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004434s390_irgen_CLY(UChar r1, IRTemp op2addr)
4435{
4436 IRTemp op1 = newTemp(Ity_I32);
4437 IRTemp op2 = newTemp(Ity_I32);
4438
4439 assign(op1, get_gpr_w1(r1));
4440 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4441 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4442
4443 return "cly";
4444}
4445
florian55085f82012-11-21 00:36:55 +00004446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004447s390_irgen_CLG(UChar r1, IRTemp op2addr)
4448{
4449 IRTemp op1 = newTemp(Ity_I64);
4450 IRTemp op2 = newTemp(Ity_I64);
4451
4452 assign(op1, get_gpr_dw0(r1));
4453 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4454 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4455
4456 return "clg";
4457}
4458
florian55085f82012-11-21 00:36:55 +00004459static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004460s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4461{
4462 IRTemp op1 = newTemp(Ity_I64);
4463 IRTemp op2 = newTemp(Ity_I64);
4464
4465 assign(op1, get_gpr_dw0(r1));
4466 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4467 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4468
4469 return "clgf";
4470}
4471
florian55085f82012-11-21 00:36:55 +00004472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004473s390_irgen_CLFI(UChar r1, UInt i2)
4474{
4475 IRTemp op1 = newTemp(Ity_I32);
4476 UInt op2;
4477
4478 assign(op1, get_gpr_w1(r1));
4479 op2 = i2;
4480 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4481 mkU32(op2)));
4482
4483 return "clfi";
4484}
4485
florian55085f82012-11-21 00:36:55 +00004486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004487s390_irgen_CLGFI(UChar r1, UInt i2)
4488{
4489 IRTemp op1 = newTemp(Ity_I64);
4490 ULong op2;
4491
4492 assign(op1, get_gpr_dw0(r1));
4493 op2 = (ULong)i2;
4494 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4495 mkU64(op2)));
4496
4497 return "clgfi";
4498}
4499
florian55085f82012-11-21 00:36:55 +00004500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004501s390_irgen_CLI(UChar i2, IRTemp op1addr)
4502{
4503 IRTemp op1 = newTemp(Ity_I8);
4504 UChar op2;
4505
4506 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4507 op2 = i2;
4508 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4509 mkU8(op2)));
4510
4511 return "cli";
4512}
4513
florian55085f82012-11-21 00:36:55 +00004514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004515s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4516{
4517 IRTemp op1 = newTemp(Ity_I8);
4518 UChar op2;
4519
4520 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4521 op2 = i2;
4522 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4523 mkU8(op2)));
4524
4525 return "cliy";
4526}
4527
florian55085f82012-11-21 00:36:55 +00004528static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004529s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4530{
4531 IRTemp op1 = newTemp(Ity_I32);
4532 UInt op2;
4533
4534 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4535 op2 = (UInt)i2;
4536 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4537 mkU32(op2)));
4538
4539 return "clfhsi";
4540}
4541
florian55085f82012-11-21 00:36:55 +00004542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004543s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4544{
4545 IRTemp op1 = newTemp(Ity_I64);
4546 ULong op2;
4547
4548 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4549 op2 = (ULong)i2;
4550 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4551 mkU64(op2)));
4552
4553 return "clghsi";
4554}
4555
florian55085f82012-11-21 00:36:55 +00004556static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004557s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4558{
4559 IRTemp op1 = newTemp(Ity_I16);
4560 UShort op2;
4561
4562 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4563 op2 = i2;
4564 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4565 mkU16(op2)));
4566
4567 return "clhhsi";
4568}
4569
florian55085f82012-11-21 00:36:55 +00004570static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004571s390_irgen_CLRL(UChar r1, UInt i2)
4572{
4573 IRTemp op1 = newTemp(Ity_I32);
4574 IRTemp op2 = newTemp(Ity_I32);
4575
4576 assign(op1, get_gpr_w1(r1));
4577 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4578 i2 << 1))));
4579 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4580
4581 return "clrl";
4582}
4583
florian55085f82012-11-21 00:36:55 +00004584static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004585s390_irgen_CLGRL(UChar r1, UInt i2)
4586{
4587 IRTemp op1 = newTemp(Ity_I64);
4588 IRTemp op2 = newTemp(Ity_I64);
4589
4590 assign(op1, get_gpr_dw0(r1));
4591 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4592 i2 << 1))));
4593 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4594
4595 return "clgrl";
4596}
4597
florian55085f82012-11-21 00:36:55 +00004598static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004599s390_irgen_CLGFRL(UChar r1, UInt i2)
4600{
4601 IRTemp op1 = newTemp(Ity_I64);
4602 IRTemp op2 = newTemp(Ity_I64);
4603
4604 assign(op1, get_gpr_dw0(r1));
4605 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4606 ((ULong)(Long)(Int)i2 << 1)))));
4607 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4608
4609 return "clgfrl";
4610}
4611
florian55085f82012-11-21 00:36:55 +00004612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004613s390_irgen_CLHRL(UChar r1, UInt i2)
4614{
4615 IRTemp op1 = newTemp(Ity_I32);
4616 IRTemp op2 = newTemp(Ity_I32);
4617
4618 assign(op1, get_gpr_w1(r1));
4619 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4620 ((ULong)(Long)(Int)i2 << 1)))));
4621 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4622
4623 return "clhrl";
4624}
4625
florian55085f82012-11-21 00:36:55 +00004626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004627s390_irgen_CLGHRL(UChar r1, UInt i2)
4628{
4629 IRTemp op1 = newTemp(Ity_I64);
4630 IRTemp op2 = newTemp(Ity_I64);
4631
4632 assign(op1, get_gpr_dw0(r1));
4633 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4634 ((ULong)(Long)(Int)i2 << 1)))));
4635 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4636
4637 return "clghrl";
4638}
4639
florian55085f82012-11-21 00:36:55 +00004640static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004641s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4642{
4643 IRTemp op1 = newTemp(Ity_I32);
4644 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004645 IRTemp cond = newTemp(Ity_I32);
4646
4647 if (m3 == 0) {
4648 } else {
4649 if (m3 == 14) {
4650 always_goto(mkexpr(op4addr));
4651 } else {
4652 assign(op1, get_gpr_w1(r1));
4653 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004654 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4655 op1, op2));
florianf321da72012-07-21 20:32:57 +00004656 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4657 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004658 }
4659 }
4660
4661 return "clrb";
4662}
4663
florian55085f82012-11-21 00:36:55 +00004664static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004665s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4666{
4667 IRTemp op1 = newTemp(Ity_I64);
4668 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004669 IRTemp cond = newTemp(Ity_I32);
4670
4671 if (m3 == 0) {
4672 } else {
4673 if (m3 == 14) {
4674 always_goto(mkexpr(op4addr));
4675 } else {
4676 assign(op1, get_gpr_dw0(r1));
4677 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004678 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4679 op1, op2));
florianf321da72012-07-21 20:32:57 +00004680 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4681 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004682 }
4683 }
4684
4685 return "clgrb";
4686}
4687
florian55085f82012-11-21 00:36:55 +00004688static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004689s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4690{
4691 IRTemp op1 = newTemp(Ity_I32);
4692 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004693 IRTemp cond = newTemp(Ity_I32);
4694
4695 if (m3 == 0) {
4696 } else {
4697 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004698 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004699 } else {
4700 assign(op1, get_gpr_w1(r1));
4701 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004702 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4703 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004704 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4705 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4706
4707 }
4708 }
4709
4710 return "clrj";
4711}
4712
florian55085f82012-11-21 00:36:55 +00004713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004714s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4715{
4716 IRTemp op1 = newTemp(Ity_I64);
4717 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004718 IRTemp cond = newTemp(Ity_I32);
4719
4720 if (m3 == 0) {
4721 } else {
4722 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004723 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004724 } else {
4725 assign(op1, get_gpr_dw0(r1));
4726 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004727 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4728 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004729 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4730 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4731
4732 }
4733 }
4734
4735 return "clgrj";
4736}
4737
florian55085f82012-11-21 00:36:55 +00004738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004739s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4740{
4741 IRTemp op1 = newTemp(Ity_I32);
4742 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004743 IRTemp cond = newTemp(Ity_I32);
4744
4745 if (m3 == 0) {
4746 } else {
4747 if (m3 == 14) {
4748 always_goto(mkexpr(op4addr));
4749 } else {
4750 assign(op1, get_gpr_w1(r1));
4751 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004752 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4753 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004754 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4755 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004756 }
4757 }
4758
4759 return "clib";
4760}
4761
florian55085f82012-11-21 00:36:55 +00004762static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004763s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4764{
4765 IRTemp op1 = newTemp(Ity_I64);
4766 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004767 IRTemp cond = newTemp(Ity_I32);
4768
4769 if (m3 == 0) {
4770 } else {
4771 if (m3 == 14) {
4772 always_goto(mkexpr(op4addr));
4773 } else {
4774 assign(op1, get_gpr_dw0(r1));
4775 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004776 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4777 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004778 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4779 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004780 }
4781 }
4782
4783 return "clgib";
4784}
4785
florian55085f82012-11-21 00:36:55 +00004786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004787s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4788{
4789 IRTemp op1 = newTemp(Ity_I32);
4790 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004791 IRTemp cond = newTemp(Ity_I32);
4792
4793 if (m3 == 0) {
4794 } else {
4795 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004796 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004797 } else {
4798 assign(op1, get_gpr_w1(r1));
4799 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004800 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4801 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004802 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4803 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4804
4805 }
4806 }
4807
4808 return "clij";
4809}
4810
florian55085f82012-11-21 00:36:55 +00004811static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004812s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4813{
4814 IRTemp op1 = newTemp(Ity_I64);
4815 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004816 IRTemp cond = newTemp(Ity_I32);
4817
4818 if (m3 == 0) {
4819 } else {
4820 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004821 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004822 } else {
4823 assign(op1, get_gpr_dw0(r1));
4824 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004825 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4826 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004827 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4828 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4829
4830 }
4831 }
4832
4833 return "clgij";
4834}
4835
florian55085f82012-11-21 00:36:55 +00004836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004837s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4838{
4839 IRTemp op1 = newTemp(Ity_I32);
4840 IRTemp op2 = newTemp(Ity_I32);
4841 IRTemp b0 = newTemp(Ity_I32);
4842 IRTemp b1 = newTemp(Ity_I32);
4843 IRTemp b2 = newTemp(Ity_I32);
4844 IRTemp b3 = newTemp(Ity_I32);
4845 IRTemp c0 = newTemp(Ity_I32);
4846 IRTemp c1 = newTemp(Ity_I32);
4847 IRTemp c2 = newTemp(Ity_I32);
4848 IRTemp c3 = newTemp(Ity_I32);
4849 UChar n;
4850
4851 n = 0;
4852 if ((r3 & 8) != 0) {
4853 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4854 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4855 n = n + 1;
4856 } else {
4857 assign(b0, mkU32(0));
4858 assign(c0, mkU32(0));
4859 }
4860 if ((r3 & 4) != 0) {
4861 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4862 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4863 mkU64(n)))));
4864 n = n + 1;
4865 } else {
4866 assign(b1, mkU32(0));
4867 assign(c1, mkU32(0));
4868 }
4869 if ((r3 & 2) != 0) {
4870 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4871 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4872 mkU64(n)))));
4873 n = n + 1;
4874 } else {
4875 assign(b2, mkU32(0));
4876 assign(c2, mkU32(0));
4877 }
4878 if ((r3 & 1) != 0) {
4879 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4880 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4881 mkU64(n)))));
4882 n = n + 1;
4883 } else {
4884 assign(b3, mkU32(0));
4885 assign(c3, mkU32(0));
4886 }
4887 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4888 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4889 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4890 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4891 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4892 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4893 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4894
4895 return "clm";
4896}
4897
florian55085f82012-11-21 00:36:55 +00004898static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004899s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4900{
4901 IRTemp op1 = newTemp(Ity_I32);
4902 IRTemp op2 = newTemp(Ity_I32);
4903 IRTemp b0 = newTemp(Ity_I32);
4904 IRTemp b1 = newTemp(Ity_I32);
4905 IRTemp b2 = newTemp(Ity_I32);
4906 IRTemp b3 = newTemp(Ity_I32);
4907 IRTemp c0 = newTemp(Ity_I32);
4908 IRTemp c1 = newTemp(Ity_I32);
4909 IRTemp c2 = newTemp(Ity_I32);
4910 IRTemp c3 = newTemp(Ity_I32);
4911 UChar n;
4912
4913 n = 0;
4914 if ((r3 & 8) != 0) {
4915 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4916 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4917 n = n + 1;
4918 } else {
4919 assign(b0, mkU32(0));
4920 assign(c0, mkU32(0));
4921 }
4922 if ((r3 & 4) != 0) {
4923 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4924 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4925 mkU64(n)))));
4926 n = n + 1;
4927 } else {
4928 assign(b1, mkU32(0));
4929 assign(c1, mkU32(0));
4930 }
4931 if ((r3 & 2) != 0) {
4932 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4933 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4934 mkU64(n)))));
4935 n = n + 1;
4936 } else {
4937 assign(b2, mkU32(0));
4938 assign(c2, mkU32(0));
4939 }
4940 if ((r3 & 1) != 0) {
4941 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4942 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4943 mkU64(n)))));
4944 n = n + 1;
4945 } else {
4946 assign(b3, mkU32(0));
4947 assign(c3, mkU32(0));
4948 }
4949 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4950 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4951 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4952 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4953 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4954 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4955 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4956
4957 return "clmy";
4958}
4959
florian55085f82012-11-21 00:36:55 +00004960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004961s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4962{
4963 IRTemp op1 = newTemp(Ity_I32);
4964 IRTemp op2 = newTemp(Ity_I32);
4965 IRTemp b0 = newTemp(Ity_I32);
4966 IRTemp b1 = newTemp(Ity_I32);
4967 IRTemp b2 = newTemp(Ity_I32);
4968 IRTemp b3 = newTemp(Ity_I32);
4969 IRTemp c0 = newTemp(Ity_I32);
4970 IRTemp c1 = newTemp(Ity_I32);
4971 IRTemp c2 = newTemp(Ity_I32);
4972 IRTemp c3 = newTemp(Ity_I32);
4973 UChar n;
4974
4975 n = 0;
4976 if ((r3 & 8) != 0) {
4977 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
4978 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4979 n = n + 1;
4980 } else {
4981 assign(b0, mkU32(0));
4982 assign(c0, mkU32(0));
4983 }
4984 if ((r3 & 4) != 0) {
4985 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
4986 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4987 mkU64(n)))));
4988 n = n + 1;
4989 } else {
4990 assign(b1, mkU32(0));
4991 assign(c1, mkU32(0));
4992 }
4993 if ((r3 & 2) != 0) {
4994 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
4995 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4996 mkU64(n)))));
4997 n = n + 1;
4998 } else {
4999 assign(b2, mkU32(0));
5000 assign(c2, mkU32(0));
5001 }
5002 if ((r3 & 1) != 0) {
5003 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5004 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5005 mkU64(n)))));
5006 n = n + 1;
5007 } else {
5008 assign(b3, mkU32(0));
5009 assign(c3, mkU32(0));
5010 }
5011 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5012 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5013 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5014 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5015 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5016 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5017 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5018
5019 return "clmh";
5020}
5021
florian55085f82012-11-21 00:36:55 +00005022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005023s390_irgen_CLHHR(UChar r1, UChar r2)
5024{
5025 IRTemp op1 = newTemp(Ity_I32);
5026 IRTemp op2 = newTemp(Ity_I32);
5027
5028 assign(op1, get_gpr_w0(r1));
5029 assign(op2, get_gpr_w0(r2));
5030 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5031
5032 return "clhhr";
5033}
5034
florian55085f82012-11-21 00:36:55 +00005035static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005036s390_irgen_CLHLR(UChar r1, UChar r2)
5037{
5038 IRTemp op1 = newTemp(Ity_I32);
5039 IRTemp op2 = newTemp(Ity_I32);
5040
5041 assign(op1, get_gpr_w0(r1));
5042 assign(op2, get_gpr_w1(r2));
5043 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5044
5045 return "clhlr";
5046}
5047
florian55085f82012-11-21 00:36:55 +00005048static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005049s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5050{
5051 IRTemp op1 = newTemp(Ity_I32);
5052 IRTemp op2 = newTemp(Ity_I32);
5053
5054 assign(op1, get_gpr_w0(r1));
5055 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5056 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5057
5058 return "clhf";
5059}
5060
florian55085f82012-11-21 00:36:55 +00005061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005062s390_irgen_CLIH(UChar r1, UInt i2)
5063{
5064 IRTemp op1 = newTemp(Ity_I32);
5065 UInt op2;
5066
5067 assign(op1, get_gpr_w0(r1));
5068 op2 = i2;
5069 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5070 mkU32(op2)));
5071
5072 return "clih";
5073}
5074
florian55085f82012-11-21 00:36:55 +00005075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005076s390_irgen_CPYA(UChar r1, UChar r2)
5077{
5078 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005079 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005080 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5081
5082 return "cpya";
5083}
5084
florian55085f82012-11-21 00:36:55 +00005085static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005086s390_irgen_XR(UChar r1, UChar r2)
5087{
5088 IRTemp op1 = newTemp(Ity_I32);
5089 IRTemp op2 = newTemp(Ity_I32);
5090 IRTemp result = newTemp(Ity_I32);
5091
5092 if (r1 == r2) {
5093 assign(result, mkU32(0));
5094 } else {
5095 assign(op1, get_gpr_w1(r1));
5096 assign(op2, get_gpr_w1(r2));
5097 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5098 }
5099 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5100 put_gpr_w1(r1, mkexpr(result));
5101
5102 return "xr";
5103}
5104
florian55085f82012-11-21 00:36:55 +00005105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005106s390_irgen_XGR(UChar r1, UChar r2)
5107{
5108 IRTemp op1 = newTemp(Ity_I64);
5109 IRTemp op2 = newTemp(Ity_I64);
5110 IRTemp result = newTemp(Ity_I64);
5111
5112 if (r1 == r2) {
5113 assign(result, mkU64(0));
5114 } else {
5115 assign(op1, get_gpr_dw0(r1));
5116 assign(op2, get_gpr_dw0(r2));
5117 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5118 }
5119 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5120 put_gpr_dw0(r1, mkexpr(result));
5121
5122 return "xgr";
5123}
5124
florian55085f82012-11-21 00:36:55 +00005125static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005126s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5127{
5128 IRTemp op2 = newTemp(Ity_I32);
5129 IRTemp op3 = newTemp(Ity_I32);
5130 IRTemp result = newTemp(Ity_I32);
5131
5132 assign(op2, get_gpr_w1(r2));
5133 assign(op3, get_gpr_w1(r3));
5134 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5135 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5136 put_gpr_w1(r1, mkexpr(result));
5137
5138 return "xrk";
5139}
5140
florian55085f82012-11-21 00:36:55 +00005141static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005142s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5143{
5144 IRTemp op2 = newTemp(Ity_I64);
5145 IRTemp op3 = newTemp(Ity_I64);
5146 IRTemp result = newTemp(Ity_I64);
5147
5148 assign(op2, get_gpr_dw0(r2));
5149 assign(op3, get_gpr_dw0(r3));
5150 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5151 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5152 put_gpr_dw0(r1, mkexpr(result));
5153
5154 return "xgrk";
5155}
5156
florian55085f82012-11-21 00:36:55 +00005157static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005158s390_irgen_X(UChar r1, IRTemp op2addr)
5159{
5160 IRTemp op1 = newTemp(Ity_I32);
5161 IRTemp op2 = newTemp(Ity_I32);
5162 IRTemp result = newTemp(Ity_I32);
5163
5164 assign(op1, get_gpr_w1(r1));
5165 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5166 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5167 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5168 put_gpr_w1(r1, mkexpr(result));
5169
5170 return "x";
5171}
5172
florian55085f82012-11-21 00:36:55 +00005173static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005174s390_irgen_XY(UChar r1, IRTemp op2addr)
5175{
5176 IRTemp op1 = newTemp(Ity_I32);
5177 IRTemp op2 = newTemp(Ity_I32);
5178 IRTemp result = newTemp(Ity_I32);
5179
5180 assign(op1, get_gpr_w1(r1));
5181 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5182 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5183 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5184 put_gpr_w1(r1, mkexpr(result));
5185
5186 return "xy";
5187}
5188
florian55085f82012-11-21 00:36:55 +00005189static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005190s390_irgen_XG(UChar r1, IRTemp op2addr)
5191{
5192 IRTemp op1 = newTemp(Ity_I64);
5193 IRTemp op2 = newTemp(Ity_I64);
5194 IRTemp result = newTemp(Ity_I64);
5195
5196 assign(op1, get_gpr_dw0(r1));
5197 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5198 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5199 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5200 put_gpr_dw0(r1, mkexpr(result));
5201
5202 return "xg";
5203}
5204
florian55085f82012-11-21 00:36:55 +00005205static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005206s390_irgen_XI(UChar i2, IRTemp op1addr)
5207{
5208 IRTemp op1 = newTemp(Ity_I8);
5209 UChar op2;
5210 IRTemp result = newTemp(Ity_I8);
5211
5212 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5213 op2 = i2;
5214 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5215 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5216 store(mkexpr(op1addr), mkexpr(result));
5217
5218 return "xi";
5219}
5220
florian55085f82012-11-21 00:36:55 +00005221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005222s390_irgen_XIY(UChar i2, IRTemp op1addr)
5223{
5224 IRTemp op1 = newTemp(Ity_I8);
5225 UChar op2;
5226 IRTemp result = newTemp(Ity_I8);
5227
5228 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5229 op2 = i2;
5230 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5231 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5232 store(mkexpr(op1addr), mkexpr(result));
5233
5234 return "xiy";
5235}
5236
florian55085f82012-11-21 00:36:55 +00005237static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005238s390_irgen_XIHF(UChar r1, UInt i2)
5239{
5240 IRTemp op1 = newTemp(Ity_I32);
5241 UInt op2;
5242 IRTemp result = newTemp(Ity_I32);
5243
5244 assign(op1, get_gpr_w0(r1));
5245 op2 = i2;
5246 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5247 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5248 put_gpr_w0(r1, mkexpr(result));
5249
5250 return "xihf";
5251}
5252
florian55085f82012-11-21 00:36:55 +00005253static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005254s390_irgen_XILF(UChar r1, UInt i2)
5255{
5256 IRTemp op1 = newTemp(Ity_I32);
5257 UInt op2;
5258 IRTemp result = newTemp(Ity_I32);
5259
5260 assign(op1, get_gpr_w1(r1));
5261 op2 = i2;
5262 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5263 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5264 put_gpr_w1(r1, mkexpr(result));
5265
5266 return "xilf";
5267}
5268
florian55085f82012-11-21 00:36:55 +00005269static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005270s390_irgen_EAR(UChar r1, UChar r2)
5271{
5272 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005273 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005274 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5275
5276 return "ear";
5277}
5278
florian55085f82012-11-21 00:36:55 +00005279static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005280s390_irgen_IC(UChar r1, IRTemp op2addr)
5281{
5282 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5283
5284 return "ic";
5285}
5286
florian55085f82012-11-21 00:36:55 +00005287static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005288s390_irgen_ICY(UChar r1, IRTemp op2addr)
5289{
5290 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5291
5292 return "icy";
5293}
5294
florian55085f82012-11-21 00:36:55 +00005295static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005296s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5297{
5298 UChar n;
5299 IRTemp result = newTemp(Ity_I32);
5300 UInt mask;
5301
5302 n = 0;
5303 mask = (UInt)r3;
5304 if ((mask & 8) != 0) {
5305 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5306 n = n + 1;
5307 }
5308 if ((mask & 4) != 0) {
5309 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5310
5311 n = n + 1;
5312 }
5313 if ((mask & 2) != 0) {
5314 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5315
5316 n = n + 1;
5317 }
5318 if ((mask & 1) != 0) {
5319 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5320
5321 n = n + 1;
5322 }
5323 assign(result, get_gpr_w1(r1));
5324 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5325 mkU32(mask)));
5326
5327 return "icm";
5328}
5329
florian55085f82012-11-21 00:36:55 +00005330static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005331s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5332{
5333 UChar n;
5334 IRTemp result = newTemp(Ity_I32);
5335 UInt mask;
5336
5337 n = 0;
5338 mask = (UInt)r3;
5339 if ((mask & 8) != 0) {
5340 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5341 n = n + 1;
5342 }
5343 if ((mask & 4) != 0) {
5344 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5345
5346 n = n + 1;
5347 }
5348 if ((mask & 2) != 0) {
5349 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5350
5351 n = n + 1;
5352 }
5353 if ((mask & 1) != 0) {
5354 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5355
5356 n = n + 1;
5357 }
5358 assign(result, get_gpr_w1(r1));
5359 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5360 mkU32(mask)));
5361
5362 return "icmy";
5363}
5364
florian55085f82012-11-21 00:36:55 +00005365static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005366s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5367{
5368 UChar n;
5369 IRTemp result = newTemp(Ity_I32);
5370 UInt mask;
5371
5372 n = 0;
5373 mask = (UInt)r3;
5374 if ((mask & 8) != 0) {
5375 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5376 n = n + 1;
5377 }
5378 if ((mask & 4) != 0) {
5379 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5380
5381 n = n + 1;
5382 }
5383 if ((mask & 2) != 0) {
5384 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5385
5386 n = n + 1;
5387 }
5388 if ((mask & 1) != 0) {
5389 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5390
5391 n = n + 1;
5392 }
5393 assign(result, get_gpr_w0(r1));
5394 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5395 mkU32(mask)));
5396
5397 return "icmh";
5398}
5399
florian55085f82012-11-21 00:36:55 +00005400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005401s390_irgen_IIHF(UChar r1, UInt i2)
5402{
5403 put_gpr_w0(r1, mkU32(i2));
5404
5405 return "iihf";
5406}
5407
florian55085f82012-11-21 00:36:55 +00005408static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005409s390_irgen_IIHH(UChar r1, UShort i2)
5410{
5411 put_gpr_hw0(r1, mkU16(i2));
5412
5413 return "iihh";
5414}
5415
florian55085f82012-11-21 00:36:55 +00005416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005417s390_irgen_IIHL(UChar r1, UShort i2)
5418{
5419 put_gpr_hw1(r1, mkU16(i2));
5420
5421 return "iihl";
5422}
5423
florian55085f82012-11-21 00:36:55 +00005424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005425s390_irgen_IILF(UChar r1, UInt i2)
5426{
5427 put_gpr_w1(r1, mkU32(i2));
5428
5429 return "iilf";
5430}
5431
florian55085f82012-11-21 00:36:55 +00005432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005433s390_irgen_IILH(UChar r1, UShort i2)
5434{
5435 put_gpr_hw2(r1, mkU16(i2));
5436
5437 return "iilh";
5438}
5439
florian55085f82012-11-21 00:36:55 +00005440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005441s390_irgen_IILL(UChar r1, UShort i2)
5442{
5443 put_gpr_hw3(r1, mkU16(i2));
5444
5445 return "iill";
5446}
5447
florian55085f82012-11-21 00:36:55 +00005448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005449s390_irgen_LR(UChar r1, UChar r2)
5450{
5451 put_gpr_w1(r1, get_gpr_w1(r2));
5452
5453 return "lr";
5454}
5455
florian55085f82012-11-21 00:36:55 +00005456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005457s390_irgen_LGR(UChar r1, UChar r2)
5458{
5459 put_gpr_dw0(r1, get_gpr_dw0(r2));
5460
5461 return "lgr";
5462}
5463
florian55085f82012-11-21 00:36:55 +00005464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005465s390_irgen_LGFR(UChar r1, UChar r2)
5466{
5467 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5468
5469 return "lgfr";
5470}
5471
florian55085f82012-11-21 00:36:55 +00005472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005473s390_irgen_L(UChar r1, IRTemp op2addr)
5474{
5475 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5476
5477 return "l";
5478}
5479
florian55085f82012-11-21 00:36:55 +00005480static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005481s390_irgen_LY(UChar r1, IRTemp op2addr)
5482{
5483 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5484
5485 return "ly";
5486}
5487
florian55085f82012-11-21 00:36:55 +00005488static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005489s390_irgen_LG(UChar r1, IRTemp op2addr)
5490{
5491 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5492
5493 return "lg";
5494}
5495
florian55085f82012-11-21 00:36:55 +00005496static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005497s390_irgen_LGF(UChar r1, IRTemp op2addr)
5498{
5499 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5500
5501 return "lgf";
5502}
5503
florian55085f82012-11-21 00:36:55 +00005504static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005505s390_irgen_LGFI(UChar r1, UInt i2)
5506{
5507 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5508
5509 return "lgfi";
5510}
5511
florian55085f82012-11-21 00:36:55 +00005512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005513s390_irgen_LRL(UChar r1, UInt i2)
5514{
5515 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5516 i2 << 1))));
5517
5518 return "lrl";
5519}
5520
florian55085f82012-11-21 00:36:55 +00005521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005522s390_irgen_LGRL(UChar r1, UInt i2)
5523{
5524 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5525 i2 << 1))));
5526
5527 return "lgrl";
5528}
5529
florian55085f82012-11-21 00:36:55 +00005530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005531s390_irgen_LGFRL(UChar r1, UInt i2)
5532{
5533 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5534 ((ULong)(Long)(Int)i2 << 1)))));
5535
5536 return "lgfrl";
5537}
5538
florian55085f82012-11-21 00:36:55 +00005539static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005540s390_irgen_LA(UChar r1, IRTemp op2addr)
5541{
5542 put_gpr_dw0(r1, mkexpr(op2addr));
5543
5544 return "la";
5545}
5546
florian55085f82012-11-21 00:36:55 +00005547static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005548s390_irgen_LAY(UChar r1, IRTemp op2addr)
5549{
5550 put_gpr_dw0(r1, mkexpr(op2addr));
5551
5552 return "lay";
5553}
5554
florian55085f82012-11-21 00:36:55 +00005555static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005556s390_irgen_LAE(UChar r1, IRTemp op2addr)
5557{
5558 put_gpr_dw0(r1, mkexpr(op2addr));
5559
5560 return "lae";
5561}
5562
florian55085f82012-11-21 00:36:55 +00005563static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005564s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5565{
5566 put_gpr_dw0(r1, mkexpr(op2addr));
5567
5568 return "laey";
5569}
5570
florian55085f82012-11-21 00:36:55 +00005571static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005572s390_irgen_LARL(UChar r1, UInt i2)
5573{
5574 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5575
5576 return "larl";
5577}
5578
floriana265ee72012-12-02 20:58:17 +00005579/* The IR representation of LAA and friends is an approximation of what
5580 happens natively. Essentially a loop containing a compare-and-swap is
5581 constructed which will iterate until the CAS succeeds. As a consequence,
5582 instrumenters may see more memory accesses than happen natively. See also
5583 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005584static void
5585s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005586{
floriana265ee72012-12-02 20:58:17 +00005587 IRCAS *cas;
5588 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005589 IRTemp op2 = newTemp(Ity_I32);
5590 IRTemp op3 = newTemp(Ity_I32);
5591 IRTemp result = newTemp(Ity_I32);
5592
5593 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5594 assign(op3, get_gpr_w1(r3));
5595 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005596
5597 /* Place the addition of second operand and third operand at the
5598 second-operand location everytime */
5599 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5600 Iend_BE, mkexpr(op2addr),
5601 NULL, mkexpr(op2), /* expected value */
5602 NULL, mkexpr(result) /* new value */);
5603 stmt(IRStmt_CAS(cas));
5604
florianffc94012012-12-02 21:31:15 +00005605 /* Set CC according to 32-bit addition */
5606 if (is_signed) {
5607 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5608 } else {
5609 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5610 }
floriana265ee72012-12-02 20:58:17 +00005611
5612 /* If old_mem contains the expected value, then the CAS succeeded.
5613 Otherwise, it did not */
5614 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5615 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005616}
5617
5618static void
5619s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5620{
5621 IRCAS *cas;
5622 IRTemp old_mem = newTemp(Ity_I64);
5623 IRTemp op2 = newTemp(Ity_I64);
5624 IRTemp op3 = newTemp(Ity_I64);
5625 IRTemp result = newTemp(Ity_I64);
5626
5627 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5628 assign(op3, get_gpr_dw0(r3));
5629 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5630
5631 /* Place the addition of second operand and third operand at the
5632 second-operand location everytime */
5633 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5634 Iend_BE, mkexpr(op2addr),
5635 NULL, mkexpr(op2), /* expected value */
5636 NULL, mkexpr(result) /* new value */);
5637 stmt(IRStmt_CAS(cas));
5638
5639 /* Set CC according to 64-bit addition */
5640 if (is_signed) {
5641 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5642 } else {
5643 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5644 }
5645
5646 /* If old_mem contains the expected value, then the CAS succeeded.
5647 Otherwise, it did not */
5648 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5649 put_gpr_dw0(r1, mkexpr(old_mem));
5650}
5651
5652static void
5653s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5654{
5655 IRCAS *cas;
5656 IRTemp old_mem = newTemp(Ity_I32);
5657 IRTemp op2 = newTemp(Ity_I32);
5658 IRTemp op3 = newTemp(Ity_I32);
5659 IRTemp result = newTemp(Ity_I32);
5660
5661 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5662 assign(op3, get_gpr_w1(r3));
5663 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5664
5665 /* Place the addition of second operand and third operand at the
5666 second-operand location everytime */
5667 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5668 Iend_BE, mkexpr(op2addr),
5669 NULL, mkexpr(op2), /* expected value */
5670 NULL, mkexpr(result) /* new value */);
5671 stmt(IRStmt_CAS(cas));
5672
5673 /* Set CC according to bitwise operation */
5674 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5675
5676 /* If old_mem contains the expected value, then the CAS succeeded.
5677 Otherwise, it did not */
5678 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5679 put_gpr_w1(r1, mkexpr(old_mem));
5680}
5681
5682static void
5683s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5684{
5685 IRCAS *cas;
5686 IRTemp old_mem = newTemp(Ity_I64);
5687 IRTemp op2 = newTemp(Ity_I64);
5688 IRTemp op3 = newTemp(Ity_I64);
5689 IRTemp result = newTemp(Ity_I64);
5690
5691 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5692 assign(op3, get_gpr_dw0(r3));
5693 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5694
5695 /* Place the addition of second operand and third operand at the
5696 second-operand location everytime */
5697 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5698 Iend_BE, mkexpr(op2addr),
5699 NULL, mkexpr(op2), /* expected value */
5700 NULL, mkexpr(result) /* new value */);
5701 stmt(IRStmt_CAS(cas));
5702
5703 /* Set CC according to bitwise operation */
5704 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5705
5706 /* If old_mem contains the expected value, then the CAS succeeded.
5707 Otherwise, it did not */
5708 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5709 put_gpr_dw0(r1, mkexpr(old_mem));
5710}
5711
5712static const HChar *
5713s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5714{
5715 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005716
5717 return "laa";
5718}
5719
florian55085f82012-11-21 00:36:55 +00005720static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005721s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5722{
florianffc94012012-12-02 21:31:15 +00005723 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005724
5725 return "laag";
5726}
5727
florian55085f82012-11-21 00:36:55 +00005728static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005729s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5730{
florianffc94012012-12-02 21:31:15 +00005731 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005732
5733 return "laal";
5734}
5735
florian55085f82012-11-21 00:36:55 +00005736static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005737s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5738{
florianffc94012012-12-02 21:31:15 +00005739 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005740
5741 return "laalg";
5742}
5743
florian55085f82012-11-21 00:36:55 +00005744static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005745s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5746{
florianffc94012012-12-02 21:31:15 +00005747 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005748
5749 return "lan";
5750}
5751
florian55085f82012-11-21 00:36:55 +00005752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005753s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5754{
florianffc94012012-12-02 21:31:15 +00005755 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005756
5757 return "lang";
5758}
5759
florian55085f82012-11-21 00:36:55 +00005760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005761s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5762{
florianffc94012012-12-02 21:31:15 +00005763 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005764
5765 return "lax";
5766}
5767
florian55085f82012-11-21 00:36:55 +00005768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005769s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5770{
florianffc94012012-12-02 21:31:15 +00005771 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005772
5773 return "laxg";
5774}
5775
florian55085f82012-11-21 00:36:55 +00005776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005777s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5778{
florianffc94012012-12-02 21:31:15 +00005779 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005780
5781 return "lao";
5782}
5783
florian55085f82012-11-21 00:36:55 +00005784static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005785s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5786{
florianffc94012012-12-02 21:31:15 +00005787 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005788
5789 return "laog";
5790}
5791
florian55085f82012-11-21 00:36:55 +00005792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005793s390_irgen_LTR(UChar r1, UChar r2)
5794{
5795 IRTemp op2 = newTemp(Ity_I32);
5796
5797 assign(op2, get_gpr_w1(r2));
5798 put_gpr_w1(r1, mkexpr(op2));
5799 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5800
5801 return "ltr";
5802}
5803
florian55085f82012-11-21 00:36:55 +00005804static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005805s390_irgen_LTGR(UChar r1, UChar r2)
5806{
5807 IRTemp op2 = newTemp(Ity_I64);
5808
5809 assign(op2, get_gpr_dw0(r2));
5810 put_gpr_dw0(r1, mkexpr(op2));
5811 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5812
5813 return "ltgr";
5814}
5815
florian55085f82012-11-21 00:36:55 +00005816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005817s390_irgen_LTGFR(UChar r1, UChar r2)
5818{
5819 IRTemp op2 = newTemp(Ity_I64);
5820
5821 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5822 put_gpr_dw0(r1, mkexpr(op2));
5823 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5824
5825 return "ltgfr";
5826}
5827
florian55085f82012-11-21 00:36:55 +00005828static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005829s390_irgen_LT(UChar r1, IRTemp op2addr)
5830{
5831 IRTemp op2 = newTemp(Ity_I32);
5832
5833 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5834 put_gpr_w1(r1, mkexpr(op2));
5835 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5836
5837 return "lt";
5838}
5839
florian55085f82012-11-21 00:36:55 +00005840static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005841s390_irgen_LTG(UChar r1, IRTemp op2addr)
5842{
5843 IRTemp op2 = newTemp(Ity_I64);
5844
5845 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5846 put_gpr_dw0(r1, mkexpr(op2));
5847 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5848
5849 return "ltg";
5850}
5851
florian55085f82012-11-21 00:36:55 +00005852static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005853s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5854{
5855 IRTemp op2 = newTemp(Ity_I64);
5856
5857 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5858 put_gpr_dw0(r1, mkexpr(op2));
5859 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5860
5861 return "ltgf";
5862}
5863
florian55085f82012-11-21 00:36:55 +00005864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005865s390_irgen_LBR(UChar r1, UChar r2)
5866{
5867 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5868
5869 return "lbr";
5870}
5871
florian55085f82012-11-21 00:36:55 +00005872static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005873s390_irgen_LGBR(UChar r1, UChar r2)
5874{
5875 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5876
5877 return "lgbr";
5878}
5879
florian55085f82012-11-21 00:36:55 +00005880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005881s390_irgen_LB(UChar r1, IRTemp op2addr)
5882{
5883 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5884
5885 return "lb";
5886}
5887
florian55085f82012-11-21 00:36:55 +00005888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005889s390_irgen_LGB(UChar r1, IRTemp op2addr)
5890{
5891 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5892
5893 return "lgb";
5894}
5895
florian55085f82012-11-21 00:36:55 +00005896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005897s390_irgen_LBH(UChar r1, IRTemp op2addr)
5898{
5899 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5900
5901 return "lbh";
5902}
5903
florian55085f82012-11-21 00:36:55 +00005904static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005905s390_irgen_LCR(UChar r1, UChar r2)
5906{
5907 Int op1;
5908 IRTemp op2 = newTemp(Ity_I32);
5909 IRTemp result = newTemp(Ity_I32);
5910
5911 op1 = 0;
5912 assign(op2, get_gpr_w1(r2));
5913 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5914 put_gpr_w1(r1, mkexpr(result));
5915 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5916 op1)), op2);
5917
5918 return "lcr";
5919}
5920
florian55085f82012-11-21 00:36:55 +00005921static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005922s390_irgen_LCGR(UChar r1, UChar r2)
5923{
5924 Long op1;
5925 IRTemp op2 = newTemp(Ity_I64);
5926 IRTemp result = newTemp(Ity_I64);
5927
5928 op1 = 0ULL;
5929 assign(op2, get_gpr_dw0(r2));
5930 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5931 put_gpr_dw0(r1, mkexpr(result));
5932 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5933 op1)), op2);
5934
5935 return "lcgr";
5936}
5937
florian55085f82012-11-21 00:36:55 +00005938static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005939s390_irgen_LCGFR(UChar r1, UChar r2)
5940{
5941 Long op1;
5942 IRTemp op2 = newTemp(Ity_I64);
5943 IRTemp result = newTemp(Ity_I64);
5944
5945 op1 = 0ULL;
5946 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5947 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5948 put_gpr_dw0(r1, mkexpr(result));
5949 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5950 op1)), op2);
5951
5952 return "lcgfr";
5953}
5954
florian55085f82012-11-21 00:36:55 +00005955static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005956s390_irgen_LHR(UChar r1, UChar r2)
5957{
5958 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5959
5960 return "lhr";
5961}
5962
florian55085f82012-11-21 00:36:55 +00005963static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005964s390_irgen_LGHR(UChar r1, UChar r2)
5965{
5966 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5967
5968 return "lghr";
5969}
5970
florian55085f82012-11-21 00:36:55 +00005971static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005972s390_irgen_LH(UChar r1, IRTemp op2addr)
5973{
5974 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5975
5976 return "lh";
5977}
5978
florian55085f82012-11-21 00:36:55 +00005979static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005980s390_irgen_LHY(UChar r1, IRTemp op2addr)
5981{
5982 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
5983
5984 return "lhy";
5985}
5986
florian55085f82012-11-21 00:36:55 +00005987static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005988s390_irgen_LGH(UChar r1, IRTemp op2addr)
5989{
5990 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
5991
5992 return "lgh";
5993}
5994
florian55085f82012-11-21 00:36:55 +00005995static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005996s390_irgen_LHI(UChar r1, UShort i2)
5997{
5998 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
5999
6000 return "lhi";
6001}
6002
florian55085f82012-11-21 00:36:55 +00006003static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006004s390_irgen_LGHI(UChar r1, UShort i2)
6005{
6006 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6007
6008 return "lghi";
6009}
6010
florian55085f82012-11-21 00:36:55 +00006011static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006012s390_irgen_LHRL(UChar r1, UInt i2)
6013{
6014 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6015 ((ULong)(Long)(Int)i2 << 1)))));
6016
6017 return "lhrl";
6018}
6019
florian55085f82012-11-21 00:36:55 +00006020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006021s390_irgen_LGHRL(UChar r1, UInt i2)
6022{
6023 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6024 ((ULong)(Long)(Int)i2 << 1)))));
6025
6026 return "lghrl";
6027}
6028
florian55085f82012-11-21 00:36:55 +00006029static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006030s390_irgen_LHH(UChar r1, IRTemp op2addr)
6031{
6032 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6033
6034 return "lhh";
6035}
6036
florian55085f82012-11-21 00:36:55 +00006037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006038s390_irgen_LFH(UChar r1, IRTemp op2addr)
6039{
6040 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6041
6042 return "lfh";
6043}
6044
florian55085f82012-11-21 00:36:55 +00006045static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006046s390_irgen_LLGFR(UChar r1, UChar r2)
6047{
6048 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6049
6050 return "llgfr";
6051}
6052
florian55085f82012-11-21 00:36:55 +00006053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006054s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6055{
6056 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6057
6058 return "llgf";
6059}
6060
florian55085f82012-11-21 00:36:55 +00006061static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006062s390_irgen_LLGFRL(UChar r1, UInt i2)
6063{
6064 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6065 ((ULong)(Long)(Int)i2 << 1)))));
6066
6067 return "llgfrl";
6068}
6069
florian55085f82012-11-21 00:36:55 +00006070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006071s390_irgen_LLCR(UChar r1, UChar r2)
6072{
6073 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6074
6075 return "llcr";
6076}
6077
florian55085f82012-11-21 00:36:55 +00006078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006079s390_irgen_LLGCR(UChar r1, UChar r2)
6080{
6081 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6082
6083 return "llgcr";
6084}
6085
florian55085f82012-11-21 00:36:55 +00006086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006087s390_irgen_LLC(UChar r1, IRTemp op2addr)
6088{
6089 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6090
6091 return "llc";
6092}
6093
florian55085f82012-11-21 00:36:55 +00006094static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006095s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6096{
6097 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6098
6099 return "llgc";
6100}
6101
florian55085f82012-11-21 00:36:55 +00006102static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006103s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6104{
6105 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6106
6107 return "llch";
6108}
6109
florian55085f82012-11-21 00:36:55 +00006110static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006111s390_irgen_LLHR(UChar r1, UChar r2)
6112{
6113 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6114
6115 return "llhr";
6116}
6117
florian55085f82012-11-21 00:36:55 +00006118static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006119s390_irgen_LLGHR(UChar r1, UChar r2)
6120{
6121 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6122
6123 return "llghr";
6124}
6125
florian55085f82012-11-21 00:36:55 +00006126static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006127s390_irgen_LLH(UChar r1, IRTemp op2addr)
6128{
6129 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6130
6131 return "llh";
6132}
6133
florian55085f82012-11-21 00:36:55 +00006134static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006135s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6136{
6137 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6138
6139 return "llgh";
6140}
6141
florian55085f82012-11-21 00:36:55 +00006142static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006143s390_irgen_LLHRL(UChar r1, UInt i2)
6144{
6145 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6146 ((ULong)(Long)(Int)i2 << 1)))));
6147
6148 return "llhrl";
6149}
6150
florian55085f82012-11-21 00:36:55 +00006151static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006152s390_irgen_LLGHRL(UChar r1, UInt i2)
6153{
6154 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6155 ((ULong)(Long)(Int)i2 << 1)))));
6156
6157 return "llghrl";
6158}
6159
florian55085f82012-11-21 00:36:55 +00006160static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006161s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6162{
6163 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6164
6165 return "llhh";
6166}
6167
florian55085f82012-11-21 00:36:55 +00006168static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006169s390_irgen_LLIHF(UChar r1, UInt i2)
6170{
6171 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6172
6173 return "llihf";
6174}
6175
florian55085f82012-11-21 00:36:55 +00006176static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006177s390_irgen_LLIHH(UChar r1, UShort i2)
6178{
6179 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6180
6181 return "llihh";
6182}
6183
florian55085f82012-11-21 00:36:55 +00006184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006185s390_irgen_LLIHL(UChar r1, UShort i2)
6186{
6187 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6188
6189 return "llihl";
6190}
6191
florian55085f82012-11-21 00:36:55 +00006192static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006193s390_irgen_LLILF(UChar r1, UInt i2)
6194{
6195 put_gpr_dw0(r1, mkU64(i2));
6196
6197 return "llilf";
6198}
6199
florian55085f82012-11-21 00:36:55 +00006200static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006201s390_irgen_LLILH(UChar r1, UShort i2)
6202{
6203 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6204
6205 return "llilh";
6206}
6207
florian55085f82012-11-21 00:36:55 +00006208static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006209s390_irgen_LLILL(UChar r1, UShort i2)
6210{
6211 put_gpr_dw0(r1, mkU64(i2));
6212
6213 return "llill";
6214}
6215
florian55085f82012-11-21 00:36:55 +00006216static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006217s390_irgen_LLGTR(UChar r1, UChar r2)
6218{
6219 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6220 mkU32(2147483647))));
6221
6222 return "llgtr";
6223}
6224
florian55085f82012-11-21 00:36:55 +00006225static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006226s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6227{
6228 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6229 mkexpr(op2addr)), mkU32(2147483647))));
6230
6231 return "llgt";
6232}
6233
florian55085f82012-11-21 00:36:55 +00006234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006235s390_irgen_LNR(UChar r1, UChar r2)
6236{
6237 IRTemp op2 = newTemp(Ity_I32);
6238 IRTemp result = newTemp(Ity_I32);
6239
6240 assign(op2, get_gpr_w1(r2));
6241 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6242 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6243 put_gpr_w1(r1, mkexpr(result));
6244 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6245
6246 return "lnr";
6247}
6248
florian55085f82012-11-21 00:36:55 +00006249static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006250s390_irgen_LNGR(UChar r1, UChar r2)
6251{
6252 IRTemp op2 = newTemp(Ity_I64);
6253 IRTemp result = newTemp(Ity_I64);
6254
6255 assign(op2, get_gpr_dw0(r2));
6256 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6257 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6258 put_gpr_dw0(r1, mkexpr(result));
6259 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6260
6261 return "lngr";
6262}
6263
florian55085f82012-11-21 00:36:55 +00006264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006265s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6266{
6267 IRTemp op2 = newTemp(Ity_I64);
6268 IRTemp result = newTemp(Ity_I64);
6269
6270 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6271 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6272 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6273 put_gpr_dw0(r1, mkexpr(result));
6274 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6275
6276 return "lngfr";
6277}
6278
florian55085f82012-11-21 00:36:55 +00006279static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006280s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6281{
florian6820ba52012-07-26 02:01:50 +00006282 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006283 put_gpr_w1(r1, get_gpr_w1(r2));
6284
6285 return "locr";
6286}
6287
florian55085f82012-11-21 00:36:55 +00006288static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006289s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6290{
florian6820ba52012-07-26 02:01:50 +00006291 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006292 put_gpr_dw0(r1, get_gpr_dw0(r2));
6293
6294 return "locgr";
6295}
6296
florian55085f82012-11-21 00:36:55 +00006297static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006298s390_irgen_LOC(UChar r1, IRTemp op2addr)
6299{
6300 /* condition is checked in format handler */
6301 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6302
6303 return "loc";
6304}
6305
florian55085f82012-11-21 00:36:55 +00006306static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006307s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6308{
6309 /* condition is checked in format handler */
6310 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6311
6312 return "locg";
6313}
6314
florian55085f82012-11-21 00:36:55 +00006315static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006316s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6317{
6318 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6319 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6320 ));
6321
6322 return "lpq";
6323}
6324
florian55085f82012-11-21 00:36:55 +00006325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006326s390_irgen_LPR(UChar r1, UChar r2)
6327{
6328 IRTemp op2 = newTemp(Ity_I32);
6329 IRTemp result = newTemp(Ity_I32);
6330
6331 assign(op2, get_gpr_w1(r2));
6332 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6333 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6334 put_gpr_w1(r1, mkexpr(result));
6335 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6336
6337 return "lpr";
6338}
6339
florian55085f82012-11-21 00:36:55 +00006340static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006341s390_irgen_LPGR(UChar r1, UChar r2)
6342{
6343 IRTemp op2 = newTemp(Ity_I64);
6344 IRTemp result = newTemp(Ity_I64);
6345
6346 assign(op2, get_gpr_dw0(r2));
6347 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6348 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6349 put_gpr_dw0(r1, mkexpr(result));
6350 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6351
6352 return "lpgr";
6353}
6354
florian55085f82012-11-21 00:36:55 +00006355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006356s390_irgen_LPGFR(UChar r1, UChar r2)
6357{
6358 IRTemp op2 = newTemp(Ity_I64);
6359 IRTemp result = newTemp(Ity_I64);
6360
6361 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6362 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6363 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6364 put_gpr_dw0(r1, mkexpr(result));
6365 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6366
6367 return "lpgfr";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006371s390_irgen_LRVR(UChar r1, UChar r2)
6372{
6373 IRTemp b0 = newTemp(Ity_I8);
6374 IRTemp b1 = newTemp(Ity_I8);
6375 IRTemp b2 = newTemp(Ity_I8);
6376 IRTemp b3 = newTemp(Ity_I8);
6377
6378 assign(b3, get_gpr_b7(r2));
6379 assign(b2, get_gpr_b6(r2));
6380 assign(b1, get_gpr_b5(r2));
6381 assign(b0, get_gpr_b4(r2));
6382 put_gpr_b4(r1, mkexpr(b3));
6383 put_gpr_b5(r1, mkexpr(b2));
6384 put_gpr_b6(r1, mkexpr(b1));
6385 put_gpr_b7(r1, mkexpr(b0));
6386
6387 return "lrvr";
6388}
6389
florian55085f82012-11-21 00:36:55 +00006390static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006391s390_irgen_LRVGR(UChar r1, UChar r2)
6392{
6393 IRTemp b0 = newTemp(Ity_I8);
6394 IRTemp b1 = newTemp(Ity_I8);
6395 IRTemp b2 = newTemp(Ity_I8);
6396 IRTemp b3 = newTemp(Ity_I8);
6397 IRTemp b4 = newTemp(Ity_I8);
6398 IRTemp b5 = newTemp(Ity_I8);
6399 IRTemp b6 = newTemp(Ity_I8);
6400 IRTemp b7 = newTemp(Ity_I8);
6401
6402 assign(b7, get_gpr_b7(r2));
6403 assign(b6, get_gpr_b6(r2));
6404 assign(b5, get_gpr_b5(r2));
6405 assign(b4, get_gpr_b4(r2));
6406 assign(b3, get_gpr_b3(r2));
6407 assign(b2, get_gpr_b2(r2));
6408 assign(b1, get_gpr_b1(r2));
6409 assign(b0, get_gpr_b0(r2));
6410 put_gpr_b0(r1, mkexpr(b7));
6411 put_gpr_b1(r1, mkexpr(b6));
6412 put_gpr_b2(r1, mkexpr(b5));
6413 put_gpr_b3(r1, mkexpr(b4));
6414 put_gpr_b4(r1, mkexpr(b3));
6415 put_gpr_b5(r1, mkexpr(b2));
6416 put_gpr_b6(r1, mkexpr(b1));
6417 put_gpr_b7(r1, mkexpr(b0));
6418
6419 return "lrvgr";
6420}
6421
florian55085f82012-11-21 00:36:55 +00006422static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006423s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6424{
6425 IRTemp op2 = newTemp(Ity_I16);
6426
6427 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6428 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6429 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6430
6431 return "lrvh";
6432}
6433
florian55085f82012-11-21 00:36:55 +00006434static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006435s390_irgen_LRV(UChar r1, IRTemp op2addr)
6436{
6437 IRTemp op2 = newTemp(Ity_I32);
6438
6439 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6440 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6441 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6442 mkU8(8)), mkU32(255))));
6443 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6444 mkU8(16)), mkU32(255))));
6445 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6446 mkU8(24)), mkU32(255))));
6447
6448 return "lrv";
6449}
6450
florian55085f82012-11-21 00:36:55 +00006451static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006452s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6453{
6454 IRTemp op2 = newTemp(Ity_I64);
6455
6456 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6457 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6458 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6459 mkU8(8)), mkU64(255))));
6460 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6461 mkU8(16)), mkU64(255))));
6462 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6463 mkU8(24)), mkU64(255))));
6464 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6465 mkU8(32)), mkU64(255))));
6466 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6467 mkU8(40)), mkU64(255))));
6468 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6469 mkU8(48)), mkU64(255))));
6470 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6471 mkU8(56)), mkU64(255))));
6472
6473 return "lrvg";
6474}
6475
florian55085f82012-11-21 00:36:55 +00006476static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006477s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6478{
6479 store(mkexpr(op1addr), mkU16(i2));
6480
6481 return "mvhhi";
6482}
6483
florian55085f82012-11-21 00:36:55 +00006484static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006485s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6486{
6487 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6488
6489 return "mvhi";
6490}
6491
florian55085f82012-11-21 00:36:55 +00006492static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006493s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6494{
6495 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6496
6497 return "mvghi";
6498}
6499
florian55085f82012-11-21 00:36:55 +00006500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006501s390_irgen_MVI(UChar i2, IRTemp op1addr)
6502{
6503 store(mkexpr(op1addr), mkU8(i2));
6504
6505 return "mvi";
6506}
6507
florian55085f82012-11-21 00:36:55 +00006508static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006509s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6510{
6511 store(mkexpr(op1addr), mkU8(i2));
6512
6513 return "mviy";
6514}
6515
florian55085f82012-11-21 00:36:55 +00006516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006517s390_irgen_MR(UChar r1, UChar r2)
6518{
6519 IRTemp op1 = newTemp(Ity_I32);
6520 IRTemp op2 = newTemp(Ity_I32);
6521 IRTemp result = newTemp(Ity_I64);
6522
6523 assign(op1, get_gpr_w1(r1 + 1));
6524 assign(op2, get_gpr_w1(r2));
6525 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6526 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6527 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6528
6529 return "mr";
6530}
6531
florian55085f82012-11-21 00:36:55 +00006532static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006533s390_irgen_M(UChar r1, IRTemp op2addr)
6534{
6535 IRTemp op1 = newTemp(Ity_I32);
6536 IRTemp op2 = newTemp(Ity_I32);
6537 IRTemp result = newTemp(Ity_I64);
6538
6539 assign(op1, get_gpr_w1(r1 + 1));
6540 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6541 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6542 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6543 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6544
6545 return "m";
6546}
6547
florian55085f82012-11-21 00:36:55 +00006548static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006549s390_irgen_MFY(UChar r1, IRTemp op2addr)
6550{
6551 IRTemp op1 = newTemp(Ity_I32);
6552 IRTemp op2 = newTemp(Ity_I32);
6553 IRTemp result = newTemp(Ity_I64);
6554
6555 assign(op1, get_gpr_w1(r1 + 1));
6556 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6557 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6558 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6559 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6560
6561 return "mfy";
6562}
6563
florian55085f82012-11-21 00:36:55 +00006564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006565s390_irgen_MH(UChar r1, IRTemp op2addr)
6566{
6567 IRTemp op1 = newTemp(Ity_I32);
6568 IRTemp op2 = newTemp(Ity_I16);
6569 IRTemp result = newTemp(Ity_I64);
6570
6571 assign(op1, get_gpr_w1(r1));
6572 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6573 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6574 ));
6575 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6576
6577 return "mh";
6578}
6579
florian55085f82012-11-21 00:36:55 +00006580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006581s390_irgen_MHY(UChar r1, IRTemp op2addr)
6582{
6583 IRTemp op1 = newTemp(Ity_I32);
6584 IRTemp op2 = newTemp(Ity_I16);
6585 IRTemp result = newTemp(Ity_I64);
6586
6587 assign(op1, get_gpr_w1(r1));
6588 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6589 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6590 ));
6591 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6592
6593 return "mhy";
6594}
6595
florian55085f82012-11-21 00:36:55 +00006596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006597s390_irgen_MHI(UChar r1, UShort i2)
6598{
6599 IRTemp op1 = newTemp(Ity_I32);
6600 Short op2;
6601 IRTemp result = newTemp(Ity_I64);
6602
6603 assign(op1, get_gpr_w1(r1));
6604 op2 = (Short)i2;
6605 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6606 mkU16((UShort)op2))));
6607 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6608
6609 return "mhi";
6610}
6611
florian55085f82012-11-21 00:36:55 +00006612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006613s390_irgen_MGHI(UChar r1, UShort i2)
6614{
6615 IRTemp op1 = newTemp(Ity_I64);
6616 Short op2;
6617 IRTemp result = newTemp(Ity_I128);
6618
6619 assign(op1, get_gpr_dw0(r1));
6620 op2 = (Short)i2;
6621 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6622 mkU16((UShort)op2))));
6623 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6624
6625 return "mghi";
6626}
6627
florian55085f82012-11-21 00:36:55 +00006628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006629s390_irgen_MLR(UChar r1, UChar r2)
6630{
6631 IRTemp op1 = newTemp(Ity_I32);
6632 IRTemp op2 = newTemp(Ity_I32);
6633 IRTemp result = newTemp(Ity_I64);
6634
6635 assign(op1, get_gpr_w1(r1 + 1));
6636 assign(op2, get_gpr_w1(r2));
6637 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6638 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6639 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6640
6641 return "mlr";
6642}
6643
florian55085f82012-11-21 00:36:55 +00006644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006645s390_irgen_MLGR(UChar r1, UChar r2)
6646{
6647 IRTemp op1 = newTemp(Ity_I64);
6648 IRTemp op2 = newTemp(Ity_I64);
6649 IRTemp result = newTemp(Ity_I128);
6650
6651 assign(op1, get_gpr_dw0(r1 + 1));
6652 assign(op2, get_gpr_dw0(r2));
6653 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6654 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6655 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6656
6657 return "mlgr";
6658}
6659
florian55085f82012-11-21 00:36:55 +00006660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006661s390_irgen_ML(UChar r1, IRTemp op2addr)
6662{
6663 IRTemp op1 = newTemp(Ity_I32);
6664 IRTemp op2 = newTemp(Ity_I32);
6665 IRTemp result = newTemp(Ity_I64);
6666
6667 assign(op1, get_gpr_w1(r1 + 1));
6668 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6669 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6670 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6671 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6672
6673 return "ml";
6674}
6675
florian55085f82012-11-21 00:36:55 +00006676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006677s390_irgen_MLG(UChar r1, IRTemp op2addr)
6678{
6679 IRTemp op1 = newTemp(Ity_I64);
6680 IRTemp op2 = newTemp(Ity_I64);
6681 IRTemp result = newTemp(Ity_I128);
6682
6683 assign(op1, get_gpr_dw0(r1 + 1));
6684 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6685 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6686 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6687 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6688
6689 return "mlg";
6690}
6691
florian55085f82012-11-21 00:36:55 +00006692static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006693s390_irgen_MSR(UChar r1, UChar r2)
6694{
6695 IRTemp op1 = newTemp(Ity_I32);
6696 IRTemp op2 = newTemp(Ity_I32);
6697 IRTemp result = newTemp(Ity_I64);
6698
6699 assign(op1, get_gpr_w1(r1));
6700 assign(op2, get_gpr_w1(r2));
6701 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6702 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6703
6704 return "msr";
6705}
6706
florian55085f82012-11-21 00:36:55 +00006707static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006708s390_irgen_MSGR(UChar r1, UChar r2)
6709{
6710 IRTemp op1 = newTemp(Ity_I64);
6711 IRTemp op2 = newTemp(Ity_I64);
6712 IRTemp result = newTemp(Ity_I128);
6713
6714 assign(op1, get_gpr_dw0(r1));
6715 assign(op2, get_gpr_dw0(r2));
6716 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6717 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6718
6719 return "msgr";
6720}
6721
florian55085f82012-11-21 00:36:55 +00006722static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006723s390_irgen_MSGFR(UChar r1, UChar r2)
6724{
6725 IRTemp op1 = newTemp(Ity_I64);
6726 IRTemp op2 = newTemp(Ity_I32);
6727 IRTemp result = newTemp(Ity_I128);
6728
6729 assign(op1, get_gpr_dw0(r1));
6730 assign(op2, get_gpr_w1(r2));
6731 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6732 ));
6733 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6734
6735 return "msgfr";
6736}
6737
florian55085f82012-11-21 00:36:55 +00006738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006739s390_irgen_MS(UChar r1, IRTemp op2addr)
6740{
6741 IRTemp op1 = newTemp(Ity_I32);
6742 IRTemp op2 = newTemp(Ity_I32);
6743 IRTemp result = newTemp(Ity_I64);
6744
6745 assign(op1, get_gpr_w1(r1));
6746 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6747 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6748 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6749
6750 return "ms";
6751}
6752
florian55085f82012-11-21 00:36:55 +00006753static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006754s390_irgen_MSY(UChar r1, IRTemp op2addr)
6755{
6756 IRTemp op1 = newTemp(Ity_I32);
6757 IRTemp op2 = newTemp(Ity_I32);
6758 IRTemp result = newTemp(Ity_I64);
6759
6760 assign(op1, get_gpr_w1(r1));
6761 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6762 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6763 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6764
6765 return "msy";
6766}
6767
florian55085f82012-11-21 00:36:55 +00006768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006769s390_irgen_MSG(UChar r1, IRTemp op2addr)
6770{
6771 IRTemp op1 = newTemp(Ity_I64);
6772 IRTemp op2 = newTemp(Ity_I64);
6773 IRTemp result = newTemp(Ity_I128);
6774
6775 assign(op1, get_gpr_dw0(r1));
6776 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6777 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6778 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6779
6780 return "msg";
6781}
6782
florian55085f82012-11-21 00:36:55 +00006783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006784s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6785{
6786 IRTemp op1 = newTemp(Ity_I64);
6787 IRTemp op2 = newTemp(Ity_I32);
6788 IRTemp result = newTemp(Ity_I128);
6789
6790 assign(op1, get_gpr_dw0(r1));
6791 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6792 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6793 ));
6794 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6795
6796 return "msgf";
6797}
6798
florian55085f82012-11-21 00:36:55 +00006799static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006800s390_irgen_MSFI(UChar r1, UInt i2)
6801{
6802 IRTemp op1 = newTemp(Ity_I32);
6803 Int op2;
6804 IRTemp result = newTemp(Ity_I64);
6805
6806 assign(op1, get_gpr_w1(r1));
6807 op2 = (Int)i2;
6808 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6809 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6810
6811 return "msfi";
6812}
6813
florian55085f82012-11-21 00:36:55 +00006814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006815s390_irgen_MSGFI(UChar r1, UInt i2)
6816{
6817 IRTemp op1 = newTemp(Ity_I64);
6818 Int op2;
6819 IRTemp result = newTemp(Ity_I128);
6820
6821 assign(op1, get_gpr_dw0(r1));
6822 op2 = (Int)i2;
6823 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6824 op2))));
6825 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6826
6827 return "msgfi";
6828}
6829
florian55085f82012-11-21 00:36:55 +00006830static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006831s390_irgen_OR(UChar r1, UChar r2)
6832{
6833 IRTemp op1 = newTemp(Ity_I32);
6834 IRTemp op2 = newTemp(Ity_I32);
6835 IRTemp result = newTemp(Ity_I32);
6836
6837 assign(op1, get_gpr_w1(r1));
6838 assign(op2, get_gpr_w1(r2));
6839 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6840 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6841 put_gpr_w1(r1, mkexpr(result));
6842
6843 return "or";
6844}
6845
florian55085f82012-11-21 00:36:55 +00006846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006847s390_irgen_OGR(UChar r1, UChar r2)
6848{
6849 IRTemp op1 = newTemp(Ity_I64);
6850 IRTemp op2 = newTemp(Ity_I64);
6851 IRTemp result = newTemp(Ity_I64);
6852
6853 assign(op1, get_gpr_dw0(r1));
6854 assign(op2, get_gpr_dw0(r2));
6855 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6856 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6857 put_gpr_dw0(r1, mkexpr(result));
6858
6859 return "ogr";
6860}
6861
florian55085f82012-11-21 00:36:55 +00006862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006863s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6864{
6865 IRTemp op2 = newTemp(Ity_I32);
6866 IRTemp op3 = newTemp(Ity_I32);
6867 IRTemp result = newTemp(Ity_I32);
6868
6869 assign(op2, get_gpr_w1(r2));
6870 assign(op3, get_gpr_w1(r3));
6871 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6872 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6873 put_gpr_w1(r1, mkexpr(result));
6874
6875 return "ork";
6876}
6877
florian55085f82012-11-21 00:36:55 +00006878static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006879s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6880{
6881 IRTemp op2 = newTemp(Ity_I64);
6882 IRTemp op3 = newTemp(Ity_I64);
6883 IRTemp result = newTemp(Ity_I64);
6884
6885 assign(op2, get_gpr_dw0(r2));
6886 assign(op3, get_gpr_dw0(r3));
6887 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6888 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6889 put_gpr_dw0(r1, mkexpr(result));
6890
6891 return "ogrk";
6892}
6893
florian55085f82012-11-21 00:36:55 +00006894static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006895s390_irgen_O(UChar r1, IRTemp op2addr)
6896{
6897 IRTemp op1 = newTemp(Ity_I32);
6898 IRTemp op2 = newTemp(Ity_I32);
6899 IRTemp result = newTemp(Ity_I32);
6900
6901 assign(op1, get_gpr_w1(r1));
6902 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6903 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6904 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6905 put_gpr_w1(r1, mkexpr(result));
6906
6907 return "o";
6908}
6909
florian55085f82012-11-21 00:36:55 +00006910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006911s390_irgen_OY(UChar r1, IRTemp op2addr)
6912{
6913 IRTemp op1 = newTemp(Ity_I32);
6914 IRTemp op2 = newTemp(Ity_I32);
6915 IRTemp result = newTemp(Ity_I32);
6916
6917 assign(op1, get_gpr_w1(r1));
6918 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6919 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6920 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6921 put_gpr_w1(r1, mkexpr(result));
6922
6923 return "oy";
6924}
6925
florian55085f82012-11-21 00:36:55 +00006926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006927s390_irgen_OG(UChar r1, IRTemp op2addr)
6928{
6929 IRTemp op1 = newTemp(Ity_I64);
6930 IRTemp op2 = newTemp(Ity_I64);
6931 IRTemp result = newTemp(Ity_I64);
6932
6933 assign(op1, get_gpr_dw0(r1));
6934 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6935 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6936 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6937 put_gpr_dw0(r1, mkexpr(result));
6938
6939 return "og";
6940}
6941
florian55085f82012-11-21 00:36:55 +00006942static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006943s390_irgen_OI(UChar i2, IRTemp op1addr)
6944{
6945 IRTemp op1 = newTemp(Ity_I8);
6946 UChar op2;
6947 IRTemp result = newTemp(Ity_I8);
6948
6949 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6950 op2 = i2;
6951 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6952 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6953 store(mkexpr(op1addr), mkexpr(result));
6954
6955 return "oi";
6956}
6957
florian55085f82012-11-21 00:36:55 +00006958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006959s390_irgen_OIY(UChar i2, IRTemp op1addr)
6960{
6961 IRTemp op1 = newTemp(Ity_I8);
6962 UChar op2;
6963 IRTemp result = newTemp(Ity_I8);
6964
6965 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6966 op2 = i2;
6967 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6968 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6969 store(mkexpr(op1addr), mkexpr(result));
6970
6971 return "oiy";
6972}
6973
florian55085f82012-11-21 00:36:55 +00006974static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006975s390_irgen_OIHF(UChar r1, UInt i2)
6976{
6977 IRTemp op1 = newTemp(Ity_I32);
6978 UInt op2;
6979 IRTemp result = newTemp(Ity_I32);
6980
6981 assign(op1, get_gpr_w0(r1));
6982 op2 = i2;
6983 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
6984 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6985 put_gpr_w0(r1, mkexpr(result));
6986
6987 return "oihf";
6988}
6989
florian55085f82012-11-21 00:36:55 +00006990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006991s390_irgen_OIHH(UChar r1, UShort i2)
6992{
6993 IRTemp op1 = newTemp(Ity_I16);
6994 UShort op2;
6995 IRTemp result = newTemp(Ity_I16);
6996
6997 assign(op1, get_gpr_hw0(r1));
6998 op2 = i2;
6999 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7000 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7001 put_gpr_hw0(r1, mkexpr(result));
7002
7003 return "oihh";
7004}
7005
florian55085f82012-11-21 00:36:55 +00007006static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007007s390_irgen_OIHL(UChar r1, UShort i2)
7008{
7009 IRTemp op1 = newTemp(Ity_I16);
7010 UShort op2;
7011 IRTemp result = newTemp(Ity_I16);
7012
7013 assign(op1, get_gpr_hw1(r1));
7014 op2 = i2;
7015 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7016 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7017 put_gpr_hw1(r1, mkexpr(result));
7018
7019 return "oihl";
7020}
7021
florian55085f82012-11-21 00:36:55 +00007022static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007023s390_irgen_OILF(UChar r1, UInt i2)
7024{
7025 IRTemp op1 = newTemp(Ity_I32);
7026 UInt op2;
7027 IRTemp result = newTemp(Ity_I32);
7028
7029 assign(op1, get_gpr_w1(r1));
7030 op2 = i2;
7031 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7032 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7033 put_gpr_w1(r1, mkexpr(result));
7034
7035 return "oilf";
7036}
7037
florian55085f82012-11-21 00:36:55 +00007038static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007039s390_irgen_OILH(UChar r1, UShort i2)
7040{
7041 IRTemp op1 = newTemp(Ity_I16);
7042 UShort op2;
7043 IRTemp result = newTemp(Ity_I16);
7044
7045 assign(op1, get_gpr_hw2(r1));
7046 op2 = i2;
7047 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7048 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7049 put_gpr_hw2(r1, mkexpr(result));
7050
7051 return "oilh";
7052}
7053
florian55085f82012-11-21 00:36:55 +00007054static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007055s390_irgen_OILL(UChar r1, UShort i2)
7056{
7057 IRTemp op1 = newTemp(Ity_I16);
7058 UShort op2;
7059 IRTemp result = newTemp(Ity_I16);
7060
7061 assign(op1, get_gpr_hw3(r1));
7062 op2 = i2;
7063 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7064 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7065 put_gpr_hw3(r1, mkexpr(result));
7066
7067 return "oill";
7068}
7069
florian55085f82012-11-21 00:36:55 +00007070static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007071s390_irgen_PFD(void)
7072{
7073
7074 return "pfd";
7075}
7076
florian55085f82012-11-21 00:36:55 +00007077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007078s390_irgen_PFDRL(void)
7079{
7080
7081 return "pfdrl";
7082}
7083
florian55085f82012-11-21 00:36:55 +00007084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007085s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7086{
7087 IRTemp amount = newTemp(Ity_I64);
7088 IRTemp op = newTemp(Ity_I32);
7089
7090 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7091 assign(op, get_gpr_w1(r3));
7092 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7093 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7094 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7095
7096 return "rll";
7097}
7098
florian55085f82012-11-21 00:36:55 +00007099static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007100s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7101{
7102 IRTemp amount = newTemp(Ity_I64);
7103 IRTemp op = newTemp(Ity_I64);
7104
7105 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7106 assign(op, get_gpr_dw0(r3));
7107 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7108 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7109 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7110
7111 return "rllg";
7112}
7113
florian55085f82012-11-21 00:36:55 +00007114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007115s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7116{
7117 UChar from;
7118 UChar to;
7119 UChar rot;
7120 UChar t_bit;
7121 ULong mask;
7122 ULong maskc;
7123 IRTemp result = newTemp(Ity_I64);
7124 IRTemp op2 = newTemp(Ity_I64);
7125
7126 from = i3 & 63;
7127 to = i4 & 63;
7128 rot = i5 & 63;
7129 t_bit = i3 & 128;
7130 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7131 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7132 mkU8(64 - rot))));
7133 if (from <= to) {
7134 mask = ~0ULL;
7135 mask = (mask >> from) & (mask << (63 - to));
7136 maskc = ~mask;
7137 } else {
7138 maskc = ~0ULL;
7139 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7140 mask = ~maskc;
7141 }
7142 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7143 ), mkU64(mask)));
7144 if (t_bit == 0) {
7145 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7146 mkU64(maskc)), mkexpr(result)));
7147 }
7148 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7149
7150 return "rnsbg";
7151}
7152
florian55085f82012-11-21 00:36:55 +00007153static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007154s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7155{
7156 UChar from;
7157 UChar to;
7158 UChar rot;
7159 UChar t_bit;
7160 ULong mask;
7161 ULong maskc;
7162 IRTemp result = newTemp(Ity_I64);
7163 IRTemp op2 = newTemp(Ity_I64);
7164
7165 from = i3 & 63;
7166 to = i4 & 63;
7167 rot = i5 & 63;
7168 t_bit = i3 & 128;
7169 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7170 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7171 mkU8(64 - rot))));
7172 if (from <= to) {
7173 mask = ~0ULL;
7174 mask = (mask >> from) & (mask << (63 - to));
7175 maskc = ~mask;
7176 } else {
7177 maskc = ~0ULL;
7178 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7179 mask = ~maskc;
7180 }
7181 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7182 ), mkU64(mask)));
7183 if (t_bit == 0) {
7184 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7185 mkU64(maskc)), mkexpr(result)));
7186 }
7187 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7188
7189 return "rxsbg";
7190}
7191
florian55085f82012-11-21 00:36:55 +00007192static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007193s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7194{
7195 UChar from;
7196 UChar to;
7197 UChar rot;
7198 UChar t_bit;
7199 ULong mask;
7200 ULong maskc;
7201 IRTemp result = newTemp(Ity_I64);
7202 IRTemp op2 = newTemp(Ity_I64);
7203
7204 from = i3 & 63;
7205 to = i4 & 63;
7206 rot = i5 & 63;
7207 t_bit = i3 & 128;
7208 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7209 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7210 mkU8(64 - rot))));
7211 if (from <= to) {
7212 mask = ~0ULL;
7213 mask = (mask >> from) & (mask << (63 - to));
7214 maskc = ~mask;
7215 } else {
7216 maskc = ~0ULL;
7217 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7218 mask = ~maskc;
7219 }
7220 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7221 ), mkU64(mask)));
7222 if (t_bit == 0) {
7223 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7224 mkU64(maskc)), mkexpr(result)));
7225 }
7226 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7227
7228 return "rosbg";
7229}
7230
florian55085f82012-11-21 00:36:55 +00007231static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007232s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7233{
7234 UChar from;
7235 UChar to;
7236 UChar rot;
7237 UChar z_bit;
7238 ULong mask;
7239 ULong maskc;
7240 IRTemp op2 = newTemp(Ity_I64);
7241 IRTemp result = newTemp(Ity_I64);
7242
7243 from = i3 & 63;
7244 to = i4 & 63;
7245 rot = i5 & 63;
7246 z_bit = i4 & 128;
7247 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7248 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7249 mkU8(64 - rot))));
7250 if (from <= to) {
7251 mask = ~0ULL;
7252 mask = (mask >> from) & (mask << (63 - to));
7253 maskc = ~mask;
7254 } else {
7255 maskc = ~0ULL;
7256 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7257 mask = ~maskc;
7258 }
7259 if (z_bit == 0) {
7260 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7261 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7262 } else {
7263 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7264 }
7265 assign(result, get_gpr_dw0(r1));
7266 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7267
7268 return "risbg";
7269}
7270
florian55085f82012-11-21 00:36:55 +00007271static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007272s390_irgen_SAR(UChar r1, UChar r2)
7273{
7274 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007275 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007276 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7277
7278 return "sar";
7279}
7280
florian55085f82012-11-21 00:36:55 +00007281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007282s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7283{
7284 IRTemp p1 = newTemp(Ity_I64);
7285 IRTemp p2 = newTemp(Ity_I64);
7286 IRTemp op = newTemp(Ity_I64);
7287 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007288 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007289 IRTemp shift_amount = newTemp(Ity_I64);
7290
7291 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7292 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7293 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7294 ));
7295 sign_mask = 1ULL << 63;
7296 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7297 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007298 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7299 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007300 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7301 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7302 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7303
7304 return "slda";
7305}
7306
florian55085f82012-11-21 00:36:55 +00007307static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007308s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7309{
7310 IRTemp p1 = newTemp(Ity_I64);
7311 IRTemp p2 = newTemp(Ity_I64);
7312 IRTemp result = newTemp(Ity_I64);
7313
7314 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7315 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7316 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7317 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7318 mkexpr(op2addr), mkU64(63)))));
7319 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7320 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7321
7322 return "sldl";
7323}
7324
florian55085f82012-11-21 00:36:55 +00007325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007326s390_irgen_SLA(UChar r1, IRTemp op2addr)
7327{
7328 IRTemp uop = newTemp(Ity_I32);
7329 IRTemp result = newTemp(Ity_I32);
7330 UInt sign_mask;
7331 IRTemp shift_amount = newTemp(Ity_I64);
7332 IRTemp op = newTemp(Ity_I32);
7333
7334 assign(op, get_gpr_w1(r1));
7335 assign(uop, get_gpr_w1(r1));
7336 sign_mask = 2147483648U;
7337 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7338 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7339 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7340 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7341 put_gpr_w1(r1, mkexpr(result));
7342 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7343
7344 return "sla";
7345}
7346
florian55085f82012-11-21 00:36:55 +00007347static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007348s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7349{
7350 IRTemp uop = newTemp(Ity_I32);
7351 IRTemp result = newTemp(Ity_I32);
7352 UInt sign_mask;
7353 IRTemp shift_amount = newTemp(Ity_I64);
7354 IRTemp op = newTemp(Ity_I32);
7355
7356 assign(op, get_gpr_w1(r3));
7357 assign(uop, get_gpr_w1(r3));
7358 sign_mask = 2147483648U;
7359 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7360 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7361 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7362 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7363 put_gpr_w1(r1, mkexpr(result));
7364 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7365
7366 return "slak";
7367}
7368
florian55085f82012-11-21 00:36:55 +00007369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007370s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7371{
7372 IRTemp uop = newTemp(Ity_I64);
7373 IRTemp result = newTemp(Ity_I64);
7374 ULong sign_mask;
7375 IRTemp shift_amount = newTemp(Ity_I64);
7376 IRTemp op = newTemp(Ity_I64);
7377
7378 assign(op, get_gpr_dw0(r3));
7379 assign(uop, get_gpr_dw0(r3));
7380 sign_mask = 9223372036854775808ULL;
7381 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7382 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7383 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7384 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7385 put_gpr_dw0(r1, mkexpr(result));
7386 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7387
7388 return "slag";
7389}
7390
florian55085f82012-11-21 00:36:55 +00007391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007392s390_irgen_SLL(UChar r1, IRTemp op2addr)
7393{
7394 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7395 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7396
7397 return "sll";
7398}
7399
florian55085f82012-11-21 00:36:55 +00007400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007401s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7402{
7403 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7404 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7405
7406 return "sllk";
7407}
7408
florian55085f82012-11-21 00:36:55 +00007409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007410s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7411{
7412 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7413 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7414
7415 return "sllg";
7416}
7417
florian55085f82012-11-21 00:36:55 +00007418static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007419s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7420{
7421 IRTemp p1 = newTemp(Ity_I64);
7422 IRTemp p2 = newTemp(Ity_I64);
7423 IRTemp result = newTemp(Ity_I64);
7424
7425 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7426 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7427 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7428 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7429 mkexpr(op2addr), mkU64(63)))));
7430 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7431 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7432 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7433
7434 return "srda";
7435}
7436
florian55085f82012-11-21 00:36:55 +00007437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007438s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7439{
7440 IRTemp p1 = newTemp(Ity_I64);
7441 IRTemp p2 = newTemp(Ity_I64);
7442 IRTemp result = newTemp(Ity_I64);
7443
7444 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7445 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7446 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7447 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7448 mkexpr(op2addr), mkU64(63)))));
7449 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7450 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7451
7452 return "srdl";
7453}
7454
florian55085f82012-11-21 00:36:55 +00007455static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007456s390_irgen_SRA(UChar r1, IRTemp op2addr)
7457{
7458 IRTemp result = newTemp(Ity_I32);
7459 IRTemp op = newTemp(Ity_I32);
7460
7461 assign(op, get_gpr_w1(r1));
7462 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7463 mkexpr(op2addr), mkU64(63)))));
7464 put_gpr_w1(r1, mkexpr(result));
7465 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7466
7467 return "sra";
7468}
7469
florian55085f82012-11-21 00:36:55 +00007470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007471s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7472{
7473 IRTemp result = newTemp(Ity_I32);
7474 IRTemp op = newTemp(Ity_I32);
7475
7476 assign(op, get_gpr_w1(r3));
7477 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7478 mkexpr(op2addr), mkU64(63)))));
7479 put_gpr_w1(r1, mkexpr(result));
7480 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7481
7482 return "srak";
7483}
7484
florian55085f82012-11-21 00:36:55 +00007485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007486s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7487{
7488 IRTemp result = newTemp(Ity_I64);
7489 IRTemp op = newTemp(Ity_I64);
7490
7491 assign(op, get_gpr_dw0(r3));
7492 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7493 mkexpr(op2addr), mkU64(63)))));
7494 put_gpr_dw0(r1, mkexpr(result));
7495 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7496
7497 return "srag";
7498}
7499
florian55085f82012-11-21 00:36:55 +00007500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007501s390_irgen_SRL(UChar r1, IRTemp op2addr)
7502{
7503 IRTemp op = newTemp(Ity_I32);
7504
7505 assign(op, get_gpr_w1(r1));
7506 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7507 mkexpr(op2addr), mkU64(63)))));
7508
7509 return "srl";
7510}
7511
florian55085f82012-11-21 00:36:55 +00007512static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007513s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7514{
7515 IRTemp op = newTemp(Ity_I32);
7516
7517 assign(op, get_gpr_w1(r3));
7518 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7519 mkexpr(op2addr), mkU64(63)))));
7520
7521 return "srlk";
7522}
7523
florian55085f82012-11-21 00:36:55 +00007524static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007525s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7526{
7527 IRTemp op = newTemp(Ity_I64);
7528
7529 assign(op, get_gpr_dw0(r3));
7530 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7531 mkexpr(op2addr), mkU64(63)))));
7532
7533 return "srlg";
7534}
7535
florian55085f82012-11-21 00:36:55 +00007536static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007537s390_irgen_ST(UChar r1, IRTemp op2addr)
7538{
7539 store(mkexpr(op2addr), get_gpr_w1(r1));
7540
7541 return "st";
7542}
7543
florian55085f82012-11-21 00:36:55 +00007544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007545s390_irgen_STY(UChar r1, IRTemp op2addr)
7546{
7547 store(mkexpr(op2addr), get_gpr_w1(r1));
7548
7549 return "sty";
7550}
7551
florian55085f82012-11-21 00:36:55 +00007552static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007553s390_irgen_STG(UChar r1, IRTemp op2addr)
7554{
7555 store(mkexpr(op2addr), get_gpr_dw0(r1));
7556
7557 return "stg";
7558}
7559
florian55085f82012-11-21 00:36:55 +00007560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007561s390_irgen_STRL(UChar r1, UInt i2)
7562{
7563 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7564 get_gpr_w1(r1));
7565
7566 return "strl";
7567}
7568
florian55085f82012-11-21 00:36:55 +00007569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007570s390_irgen_STGRL(UChar r1, UInt i2)
7571{
7572 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7573 get_gpr_dw0(r1));
7574
7575 return "stgrl";
7576}
7577
florian55085f82012-11-21 00:36:55 +00007578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007579s390_irgen_STC(UChar r1, IRTemp op2addr)
7580{
7581 store(mkexpr(op2addr), get_gpr_b7(r1));
7582
7583 return "stc";
7584}
7585
florian55085f82012-11-21 00:36:55 +00007586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007587s390_irgen_STCY(UChar r1, IRTemp op2addr)
7588{
7589 store(mkexpr(op2addr), get_gpr_b7(r1));
7590
7591 return "stcy";
7592}
7593
florian55085f82012-11-21 00:36:55 +00007594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007595s390_irgen_STCH(UChar r1, IRTemp op2addr)
7596{
7597 store(mkexpr(op2addr), get_gpr_b3(r1));
7598
7599 return "stch";
7600}
7601
florian55085f82012-11-21 00:36:55 +00007602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007603s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7604{
7605 UChar mask;
7606 UChar n;
7607
7608 mask = (UChar)r3;
7609 n = 0;
7610 if ((mask & 8) != 0) {
7611 store(mkexpr(op2addr), get_gpr_b4(r1));
7612 n = n + 1;
7613 }
7614 if ((mask & 4) != 0) {
7615 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7616 n = n + 1;
7617 }
7618 if ((mask & 2) != 0) {
7619 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7620 n = n + 1;
7621 }
7622 if ((mask & 1) != 0) {
7623 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7624 }
7625
7626 return "stcm";
7627}
7628
florian55085f82012-11-21 00:36:55 +00007629static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007630s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7631{
7632 UChar mask;
7633 UChar n;
7634
7635 mask = (UChar)r3;
7636 n = 0;
7637 if ((mask & 8) != 0) {
7638 store(mkexpr(op2addr), get_gpr_b4(r1));
7639 n = n + 1;
7640 }
7641 if ((mask & 4) != 0) {
7642 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7643 n = n + 1;
7644 }
7645 if ((mask & 2) != 0) {
7646 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7647 n = n + 1;
7648 }
7649 if ((mask & 1) != 0) {
7650 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7651 }
7652
7653 return "stcmy";
7654}
7655
florian55085f82012-11-21 00:36:55 +00007656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007657s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7658{
7659 UChar mask;
7660 UChar n;
7661
7662 mask = (UChar)r3;
7663 n = 0;
7664 if ((mask & 8) != 0) {
7665 store(mkexpr(op2addr), get_gpr_b0(r1));
7666 n = n + 1;
7667 }
7668 if ((mask & 4) != 0) {
7669 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7670 n = n + 1;
7671 }
7672 if ((mask & 2) != 0) {
7673 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7674 n = n + 1;
7675 }
7676 if ((mask & 1) != 0) {
7677 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7678 }
7679
7680 return "stcmh";
7681}
7682
florian55085f82012-11-21 00:36:55 +00007683static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007684s390_irgen_STH(UChar r1, IRTemp op2addr)
7685{
7686 store(mkexpr(op2addr), get_gpr_hw3(r1));
7687
7688 return "sth";
7689}
7690
florian55085f82012-11-21 00:36:55 +00007691static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007692s390_irgen_STHY(UChar r1, IRTemp op2addr)
7693{
7694 store(mkexpr(op2addr), get_gpr_hw3(r1));
7695
7696 return "sthy";
7697}
7698
florian55085f82012-11-21 00:36:55 +00007699static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007700s390_irgen_STHRL(UChar r1, UInt i2)
7701{
7702 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7703 get_gpr_hw3(r1));
7704
7705 return "sthrl";
7706}
7707
florian55085f82012-11-21 00:36:55 +00007708static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007709s390_irgen_STHH(UChar r1, IRTemp op2addr)
7710{
7711 store(mkexpr(op2addr), get_gpr_hw1(r1));
7712
7713 return "sthh";
7714}
7715
florian55085f82012-11-21 00:36:55 +00007716static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007717s390_irgen_STFH(UChar r1, IRTemp op2addr)
7718{
7719 store(mkexpr(op2addr), get_gpr_w0(r1));
7720
7721 return "stfh";
7722}
7723
florian55085f82012-11-21 00:36:55 +00007724static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007725s390_irgen_STOC(UChar r1, IRTemp op2addr)
7726{
7727 /* condition is checked in format handler */
7728 store(mkexpr(op2addr), get_gpr_w1(r1));
7729
7730 return "stoc";
7731}
7732
florian55085f82012-11-21 00:36:55 +00007733static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007734s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7735{
7736 /* condition is checked in format handler */
7737 store(mkexpr(op2addr), get_gpr_dw0(r1));
7738
7739 return "stocg";
7740}
7741
florian55085f82012-11-21 00:36:55 +00007742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007743s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7744{
7745 store(mkexpr(op2addr), get_gpr_dw0(r1));
7746 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7747
7748 return "stpq";
7749}
7750
florian55085f82012-11-21 00:36:55 +00007751static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007752s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7753{
7754 store(mkexpr(op2addr), get_gpr_b7(r1));
7755 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7756
7757 return "strvh";
7758}
7759
florian55085f82012-11-21 00:36:55 +00007760static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007761s390_irgen_STRV(UChar r1, IRTemp op2addr)
7762{
7763 store(mkexpr(op2addr), get_gpr_b7(r1));
7764 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7765 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7766 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7767
7768 return "strv";
7769}
7770
florian55085f82012-11-21 00:36:55 +00007771static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007772s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7773{
7774 store(mkexpr(op2addr), get_gpr_b7(r1));
7775 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7776 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7777 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7778 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7779 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7780 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7781 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7782
7783 return "strvg";
7784}
7785
florian55085f82012-11-21 00:36:55 +00007786static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007787s390_irgen_SR(UChar r1, UChar r2)
7788{
7789 IRTemp op1 = newTemp(Ity_I32);
7790 IRTemp op2 = newTemp(Ity_I32);
7791 IRTemp result = newTemp(Ity_I32);
7792
7793 assign(op1, get_gpr_w1(r1));
7794 assign(op2, get_gpr_w1(r2));
7795 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7796 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7797 put_gpr_w1(r1, mkexpr(result));
7798
7799 return "sr";
7800}
7801
florian55085f82012-11-21 00:36:55 +00007802static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007803s390_irgen_SGR(UChar r1, UChar r2)
7804{
7805 IRTemp op1 = newTemp(Ity_I64);
7806 IRTemp op2 = newTemp(Ity_I64);
7807 IRTemp result = newTemp(Ity_I64);
7808
7809 assign(op1, get_gpr_dw0(r1));
7810 assign(op2, get_gpr_dw0(r2));
7811 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7812 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7813 put_gpr_dw0(r1, mkexpr(result));
7814
7815 return "sgr";
7816}
7817
florian55085f82012-11-21 00:36:55 +00007818static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007819s390_irgen_SGFR(UChar r1, UChar r2)
7820{
7821 IRTemp op1 = newTemp(Ity_I64);
7822 IRTemp op2 = newTemp(Ity_I64);
7823 IRTemp result = newTemp(Ity_I64);
7824
7825 assign(op1, get_gpr_dw0(r1));
7826 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7827 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7828 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7829 put_gpr_dw0(r1, mkexpr(result));
7830
7831 return "sgfr";
7832}
7833
florian55085f82012-11-21 00:36:55 +00007834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007835s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7836{
7837 IRTemp op2 = newTemp(Ity_I32);
7838 IRTemp op3 = newTemp(Ity_I32);
7839 IRTemp result = newTemp(Ity_I32);
7840
7841 assign(op2, get_gpr_w1(r2));
7842 assign(op3, get_gpr_w1(r3));
7843 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7844 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7845 put_gpr_w1(r1, mkexpr(result));
7846
7847 return "srk";
7848}
7849
florian55085f82012-11-21 00:36:55 +00007850static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007851s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7852{
7853 IRTemp op2 = newTemp(Ity_I64);
7854 IRTemp op3 = newTemp(Ity_I64);
7855 IRTemp result = newTemp(Ity_I64);
7856
7857 assign(op2, get_gpr_dw0(r2));
7858 assign(op3, get_gpr_dw0(r3));
7859 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7860 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7861 put_gpr_dw0(r1, mkexpr(result));
7862
7863 return "sgrk";
7864}
7865
florian55085f82012-11-21 00:36:55 +00007866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007867s390_irgen_S(UChar r1, IRTemp op2addr)
7868{
7869 IRTemp op1 = newTemp(Ity_I32);
7870 IRTemp op2 = newTemp(Ity_I32);
7871 IRTemp result = newTemp(Ity_I32);
7872
7873 assign(op1, get_gpr_w1(r1));
7874 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7875 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7876 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7877 put_gpr_w1(r1, mkexpr(result));
7878
7879 return "s";
7880}
7881
florian55085f82012-11-21 00:36:55 +00007882static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007883s390_irgen_SY(UChar r1, IRTemp op2addr)
7884{
7885 IRTemp op1 = newTemp(Ity_I32);
7886 IRTemp op2 = newTemp(Ity_I32);
7887 IRTemp result = newTemp(Ity_I32);
7888
7889 assign(op1, get_gpr_w1(r1));
7890 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7891 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7892 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7893 put_gpr_w1(r1, mkexpr(result));
7894
7895 return "sy";
7896}
7897
florian55085f82012-11-21 00:36:55 +00007898static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007899s390_irgen_SG(UChar r1, IRTemp op2addr)
7900{
7901 IRTemp op1 = newTemp(Ity_I64);
7902 IRTemp op2 = newTemp(Ity_I64);
7903 IRTemp result = newTemp(Ity_I64);
7904
7905 assign(op1, get_gpr_dw0(r1));
7906 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7907 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7908 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7909 put_gpr_dw0(r1, mkexpr(result));
7910
7911 return "sg";
7912}
7913
florian55085f82012-11-21 00:36:55 +00007914static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007915s390_irgen_SGF(UChar r1, IRTemp op2addr)
7916{
7917 IRTemp op1 = newTemp(Ity_I64);
7918 IRTemp op2 = newTemp(Ity_I64);
7919 IRTemp result = newTemp(Ity_I64);
7920
7921 assign(op1, get_gpr_dw0(r1));
7922 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7923 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7924 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7925 put_gpr_dw0(r1, mkexpr(result));
7926
7927 return "sgf";
7928}
7929
florian55085f82012-11-21 00:36:55 +00007930static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007931s390_irgen_SH(UChar r1, IRTemp op2addr)
7932{
7933 IRTemp op1 = newTemp(Ity_I32);
7934 IRTemp op2 = newTemp(Ity_I32);
7935 IRTemp result = newTemp(Ity_I32);
7936
7937 assign(op1, get_gpr_w1(r1));
7938 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7939 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7940 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7941 put_gpr_w1(r1, mkexpr(result));
7942
7943 return "sh";
7944}
7945
florian55085f82012-11-21 00:36:55 +00007946static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007947s390_irgen_SHY(UChar r1, IRTemp op2addr)
7948{
7949 IRTemp op1 = newTemp(Ity_I32);
7950 IRTemp op2 = newTemp(Ity_I32);
7951 IRTemp result = newTemp(Ity_I32);
7952
7953 assign(op1, get_gpr_w1(r1));
7954 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7955 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7956 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7957 put_gpr_w1(r1, mkexpr(result));
7958
7959 return "shy";
7960}
7961
florian55085f82012-11-21 00:36:55 +00007962static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007963s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7964{
7965 IRTemp op2 = newTemp(Ity_I32);
7966 IRTemp op3 = newTemp(Ity_I32);
7967 IRTemp result = newTemp(Ity_I32);
7968
7969 assign(op2, get_gpr_w0(r1));
7970 assign(op3, get_gpr_w0(r2));
7971 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7972 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7973 put_gpr_w0(r1, mkexpr(result));
7974
7975 return "shhhr";
7976}
7977
florian55085f82012-11-21 00:36:55 +00007978static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007979s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7980{
7981 IRTemp op2 = newTemp(Ity_I32);
7982 IRTemp op3 = newTemp(Ity_I32);
7983 IRTemp result = newTemp(Ity_I32);
7984
7985 assign(op2, get_gpr_w0(r1));
7986 assign(op3, get_gpr_w1(r2));
7987 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7988 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7989 put_gpr_w0(r1, mkexpr(result));
7990
7991 return "shhlr";
7992}
7993
florian55085f82012-11-21 00:36:55 +00007994static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007995s390_irgen_SLR(UChar r1, UChar r2)
7996{
7997 IRTemp op1 = newTemp(Ity_I32);
7998 IRTemp op2 = newTemp(Ity_I32);
7999 IRTemp result = newTemp(Ity_I32);
8000
8001 assign(op1, get_gpr_w1(r1));
8002 assign(op2, get_gpr_w1(r2));
8003 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8004 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8005 put_gpr_w1(r1, mkexpr(result));
8006
8007 return "slr";
8008}
8009
florian55085f82012-11-21 00:36:55 +00008010static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008011s390_irgen_SLGR(UChar r1, UChar r2)
8012{
8013 IRTemp op1 = newTemp(Ity_I64);
8014 IRTemp op2 = newTemp(Ity_I64);
8015 IRTemp result = newTemp(Ity_I64);
8016
8017 assign(op1, get_gpr_dw0(r1));
8018 assign(op2, get_gpr_dw0(r2));
8019 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8020 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8021 put_gpr_dw0(r1, mkexpr(result));
8022
8023 return "slgr";
8024}
8025
florian55085f82012-11-21 00:36:55 +00008026static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008027s390_irgen_SLGFR(UChar r1, UChar r2)
8028{
8029 IRTemp op1 = newTemp(Ity_I64);
8030 IRTemp op2 = newTemp(Ity_I64);
8031 IRTemp result = newTemp(Ity_I64);
8032
8033 assign(op1, get_gpr_dw0(r1));
8034 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8035 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8036 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8037 put_gpr_dw0(r1, mkexpr(result));
8038
8039 return "slgfr";
8040}
8041
florian55085f82012-11-21 00:36:55 +00008042static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008043s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8044{
8045 IRTemp op2 = newTemp(Ity_I32);
8046 IRTemp op3 = newTemp(Ity_I32);
8047 IRTemp result = newTemp(Ity_I32);
8048
8049 assign(op2, get_gpr_w1(r2));
8050 assign(op3, get_gpr_w1(r3));
8051 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8052 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8053 put_gpr_w1(r1, mkexpr(result));
8054
8055 return "slrk";
8056}
8057
florian55085f82012-11-21 00:36:55 +00008058static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008059s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8060{
8061 IRTemp op2 = newTemp(Ity_I64);
8062 IRTemp op3 = newTemp(Ity_I64);
8063 IRTemp result = newTemp(Ity_I64);
8064
8065 assign(op2, get_gpr_dw0(r2));
8066 assign(op3, get_gpr_dw0(r3));
8067 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8068 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8069 put_gpr_dw0(r1, mkexpr(result));
8070
8071 return "slgrk";
8072}
8073
florian55085f82012-11-21 00:36:55 +00008074static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008075s390_irgen_SL(UChar r1, IRTemp op2addr)
8076{
8077 IRTemp op1 = newTemp(Ity_I32);
8078 IRTemp op2 = newTemp(Ity_I32);
8079 IRTemp result = newTemp(Ity_I32);
8080
8081 assign(op1, get_gpr_w1(r1));
8082 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8083 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8084 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8085 put_gpr_w1(r1, mkexpr(result));
8086
8087 return "sl";
8088}
8089
florian55085f82012-11-21 00:36:55 +00008090static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008091s390_irgen_SLY(UChar r1, IRTemp op2addr)
8092{
8093 IRTemp op1 = newTemp(Ity_I32);
8094 IRTemp op2 = newTemp(Ity_I32);
8095 IRTemp result = newTemp(Ity_I32);
8096
8097 assign(op1, get_gpr_w1(r1));
8098 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8099 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8100 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8101 put_gpr_w1(r1, mkexpr(result));
8102
8103 return "sly";
8104}
8105
florian55085f82012-11-21 00:36:55 +00008106static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008107s390_irgen_SLG(UChar r1, IRTemp op2addr)
8108{
8109 IRTemp op1 = newTemp(Ity_I64);
8110 IRTemp op2 = newTemp(Ity_I64);
8111 IRTemp result = newTemp(Ity_I64);
8112
8113 assign(op1, get_gpr_dw0(r1));
8114 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8115 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8116 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8117 put_gpr_dw0(r1, mkexpr(result));
8118
8119 return "slg";
8120}
8121
florian55085f82012-11-21 00:36:55 +00008122static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008123s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8124{
8125 IRTemp op1 = newTemp(Ity_I64);
8126 IRTemp op2 = newTemp(Ity_I64);
8127 IRTemp result = newTemp(Ity_I64);
8128
8129 assign(op1, get_gpr_dw0(r1));
8130 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8131 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8132 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8133 put_gpr_dw0(r1, mkexpr(result));
8134
8135 return "slgf";
8136}
8137
florian55085f82012-11-21 00:36:55 +00008138static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008139s390_irgen_SLFI(UChar r1, UInt i2)
8140{
8141 IRTemp op1 = newTemp(Ity_I32);
8142 UInt op2;
8143 IRTemp result = newTemp(Ity_I32);
8144
8145 assign(op1, get_gpr_w1(r1));
8146 op2 = i2;
8147 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8148 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8149 mkU32(op2)));
8150 put_gpr_w1(r1, mkexpr(result));
8151
8152 return "slfi";
8153}
8154
florian55085f82012-11-21 00:36:55 +00008155static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008156s390_irgen_SLGFI(UChar r1, UInt i2)
8157{
8158 IRTemp op1 = newTemp(Ity_I64);
8159 ULong op2;
8160 IRTemp result = newTemp(Ity_I64);
8161
8162 assign(op1, get_gpr_dw0(r1));
8163 op2 = (ULong)i2;
8164 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8165 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8166 mkU64(op2)));
8167 put_gpr_dw0(r1, mkexpr(result));
8168
8169 return "slgfi";
8170}
8171
florian55085f82012-11-21 00:36:55 +00008172static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008173s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8174{
8175 IRTemp op2 = newTemp(Ity_I32);
8176 IRTemp op3 = newTemp(Ity_I32);
8177 IRTemp result = newTemp(Ity_I32);
8178
8179 assign(op2, get_gpr_w0(r1));
8180 assign(op3, get_gpr_w0(r2));
8181 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8182 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8183 put_gpr_w0(r1, mkexpr(result));
8184
8185 return "slhhhr";
8186}
8187
florian55085f82012-11-21 00:36:55 +00008188static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008189s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8190{
8191 IRTemp op2 = newTemp(Ity_I32);
8192 IRTemp op3 = newTemp(Ity_I32);
8193 IRTemp result = newTemp(Ity_I32);
8194
8195 assign(op2, get_gpr_w0(r1));
8196 assign(op3, get_gpr_w1(r2));
8197 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8198 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8199 put_gpr_w0(r1, mkexpr(result));
8200
8201 return "slhhlr";
8202}
8203
florian55085f82012-11-21 00:36:55 +00008204static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008205s390_irgen_SLBR(UChar r1, UChar r2)
8206{
8207 IRTemp op1 = newTemp(Ity_I32);
8208 IRTemp op2 = newTemp(Ity_I32);
8209 IRTemp result = newTemp(Ity_I32);
8210 IRTemp borrow_in = newTemp(Ity_I32);
8211
8212 assign(op1, get_gpr_w1(r1));
8213 assign(op2, get_gpr_w1(r2));
8214 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8215 s390_call_calculate_cc(), mkU8(1))));
8216 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8217 mkexpr(borrow_in)));
8218 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8219 put_gpr_w1(r1, mkexpr(result));
8220
8221 return "slbr";
8222}
8223
florian55085f82012-11-21 00:36:55 +00008224static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008225s390_irgen_SLBGR(UChar r1, UChar r2)
8226{
8227 IRTemp op1 = newTemp(Ity_I64);
8228 IRTemp op2 = newTemp(Ity_I64);
8229 IRTemp result = newTemp(Ity_I64);
8230 IRTemp borrow_in = newTemp(Ity_I64);
8231
8232 assign(op1, get_gpr_dw0(r1));
8233 assign(op2, get_gpr_dw0(r2));
8234 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8235 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8236 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8237 mkexpr(borrow_in)));
8238 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8239 put_gpr_dw0(r1, mkexpr(result));
8240
8241 return "slbgr";
8242}
8243
florian55085f82012-11-21 00:36:55 +00008244static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008245s390_irgen_SLB(UChar r1, IRTemp op2addr)
8246{
8247 IRTemp op1 = newTemp(Ity_I32);
8248 IRTemp op2 = newTemp(Ity_I32);
8249 IRTemp result = newTemp(Ity_I32);
8250 IRTemp borrow_in = newTemp(Ity_I32);
8251
8252 assign(op1, get_gpr_w1(r1));
8253 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8254 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8255 s390_call_calculate_cc(), mkU8(1))));
8256 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8257 mkexpr(borrow_in)));
8258 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8259 put_gpr_w1(r1, mkexpr(result));
8260
8261 return "slb";
8262}
8263
florian55085f82012-11-21 00:36:55 +00008264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008265s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8266{
8267 IRTemp op1 = newTemp(Ity_I64);
8268 IRTemp op2 = newTemp(Ity_I64);
8269 IRTemp result = newTemp(Ity_I64);
8270 IRTemp borrow_in = newTemp(Ity_I64);
8271
8272 assign(op1, get_gpr_dw0(r1));
8273 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8274 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8275 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8276 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8277 mkexpr(borrow_in)));
8278 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8279 put_gpr_dw0(r1, mkexpr(result));
8280
8281 return "slbg";
8282}
8283
florian55085f82012-11-21 00:36:55 +00008284static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008285s390_irgen_SVC(UChar i)
8286{
8287 IRTemp sysno = newTemp(Ity_I64);
8288
8289 if (i != 0) {
8290 assign(sysno, mkU64(i));
8291 } else {
8292 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8293 }
8294 system_call(mkexpr(sysno));
8295
8296 return "svc";
8297}
8298
florian55085f82012-11-21 00:36:55 +00008299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008300s390_irgen_TM(UChar i2, IRTemp op1addr)
8301{
8302 UChar mask;
8303 IRTemp value = newTemp(Ity_I8);
8304
8305 mask = i2;
8306 assign(value, load(Ity_I8, mkexpr(op1addr)));
8307 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8308 mkU8(mask)));
8309
8310 return "tm";
8311}
8312
florian55085f82012-11-21 00:36:55 +00008313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008314s390_irgen_TMY(UChar i2, IRTemp op1addr)
8315{
8316 UChar mask;
8317 IRTemp value = newTemp(Ity_I8);
8318
8319 mask = i2;
8320 assign(value, load(Ity_I8, mkexpr(op1addr)));
8321 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8322 mkU8(mask)));
8323
8324 return "tmy";
8325}
8326
florian55085f82012-11-21 00:36:55 +00008327static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008328s390_irgen_TMHH(UChar r1, UShort i2)
8329{
8330 UShort mask;
8331 IRTemp value = newTemp(Ity_I16);
8332
8333 mask = i2;
8334 assign(value, get_gpr_hw0(r1));
8335 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8336 mkU16(mask)));
8337
8338 return "tmhh";
8339}
8340
florian55085f82012-11-21 00:36:55 +00008341static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008342s390_irgen_TMHL(UChar r1, UShort i2)
8343{
8344 UShort mask;
8345 IRTemp value = newTemp(Ity_I16);
8346
8347 mask = i2;
8348 assign(value, get_gpr_hw1(r1));
8349 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8350 mkU16(mask)));
8351
8352 return "tmhl";
8353}
8354
florian55085f82012-11-21 00:36:55 +00008355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008356s390_irgen_TMLH(UChar r1, UShort i2)
8357{
8358 UShort mask;
8359 IRTemp value = newTemp(Ity_I16);
8360
8361 mask = i2;
8362 assign(value, get_gpr_hw2(r1));
8363 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8364 mkU16(mask)));
8365
8366 return "tmlh";
8367}
8368
florian55085f82012-11-21 00:36:55 +00008369static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008370s390_irgen_TMLL(UChar r1, UShort i2)
8371{
8372 UShort mask;
8373 IRTemp value = newTemp(Ity_I16);
8374
8375 mask = i2;
8376 assign(value, get_gpr_hw3(r1));
8377 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8378 mkU16(mask)));
8379
8380 return "tmll";
8381}
8382
florian55085f82012-11-21 00:36:55 +00008383static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008384s390_irgen_EFPC(UChar r1)
8385{
8386 put_gpr_w1(r1, get_fpc_w0());
8387
8388 return "efpc";
8389}
8390
florian55085f82012-11-21 00:36:55 +00008391static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008392s390_irgen_LER(UChar r1, UChar r2)
8393{
8394 put_fpr_w0(r1, get_fpr_w0(r2));
8395
8396 return "ler";
8397}
8398
florian55085f82012-11-21 00:36:55 +00008399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008400s390_irgen_LDR(UChar r1, UChar r2)
8401{
8402 put_fpr_dw0(r1, get_fpr_dw0(r2));
8403
8404 return "ldr";
8405}
8406
florian55085f82012-11-21 00:36:55 +00008407static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008408s390_irgen_LXR(UChar r1, UChar r2)
8409{
8410 put_fpr_dw0(r1, get_fpr_dw0(r2));
8411 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8412
8413 return "lxr";
8414}
8415
florian55085f82012-11-21 00:36:55 +00008416static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008417s390_irgen_LE(UChar r1, IRTemp op2addr)
8418{
8419 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8420
8421 return "le";
8422}
8423
florian55085f82012-11-21 00:36:55 +00008424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008425s390_irgen_LD(UChar r1, IRTemp op2addr)
8426{
8427 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8428
8429 return "ld";
8430}
8431
florian55085f82012-11-21 00:36:55 +00008432static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008433s390_irgen_LEY(UChar r1, IRTemp op2addr)
8434{
8435 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8436
8437 return "ley";
8438}
8439
florian55085f82012-11-21 00:36:55 +00008440static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008441s390_irgen_LDY(UChar r1, IRTemp op2addr)
8442{
8443 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8444
8445 return "ldy";
8446}
8447
florian55085f82012-11-21 00:36:55 +00008448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008449s390_irgen_LFPC(IRTemp op2addr)
8450{
8451 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8452
8453 return "lfpc";
8454}
8455
florian55085f82012-11-21 00:36:55 +00008456static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008457s390_irgen_LZER(UChar r1)
8458{
8459 put_fpr_w0(r1, mkF32i(0x0));
8460
8461 return "lzer";
8462}
8463
florian55085f82012-11-21 00:36:55 +00008464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008465s390_irgen_LZDR(UChar r1)
8466{
8467 put_fpr_dw0(r1, mkF64i(0x0));
8468
8469 return "lzdr";
8470}
8471
florian55085f82012-11-21 00:36:55 +00008472static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008473s390_irgen_LZXR(UChar r1)
8474{
8475 put_fpr_dw0(r1, mkF64i(0x0));
8476 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8477
8478 return "lzxr";
8479}
8480
florian55085f82012-11-21 00:36:55 +00008481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008482s390_irgen_SRNM(IRTemp op2addr)
8483{
florianf0fa1be2012-09-18 20:24:38 +00008484 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008485
florianf0fa1be2012-09-18 20:24:38 +00008486 input_mask = 3;
8487 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008488
florianf0fa1be2012-09-18 20:24:38 +00008489 put_fpc_w0(binop(Iop_Or32,
8490 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8491 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8492 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008493 return "srnm";
8494}
8495
florian55085f82012-11-21 00:36:55 +00008496static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008497s390_irgen_SRNMB(IRTemp op2addr)
8498{
8499 UInt input_mask, fpc_mask;
8500
8501 input_mask = 7;
8502 fpc_mask = 7;
8503
8504 put_fpc_w0(binop(Iop_Or32,
8505 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8506 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8507 mkU32(input_mask))));
8508 return "srnmb";
8509}
8510
florian81a4bfe2012-09-20 01:25:28 +00008511static void
florianf0fa1be2012-09-18 20:24:38 +00008512s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8513{
8514 if (b2 == 0) { /* This is the typical case */
8515 if (d2 > 3) {
8516 if (s390_host_has_fpext && d2 == 7) {
8517 /* ok */
8518 } else {
8519 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008520 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008521 }
8522 }
8523 }
8524
8525 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8526}
8527
8528
florian55085f82012-11-21 00:36:55 +00008529static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008530s390_irgen_SFPC(UChar r1)
8531{
8532 put_fpc_w0(get_gpr_w1(r1));
8533
8534 return "sfpc";
8535}
8536
florian55085f82012-11-21 00:36:55 +00008537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008538s390_irgen_STE(UChar r1, IRTemp op2addr)
8539{
8540 store(mkexpr(op2addr), get_fpr_w0(r1));
8541
8542 return "ste";
8543}
8544
florian55085f82012-11-21 00:36:55 +00008545static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008546s390_irgen_STD(UChar r1, IRTemp op2addr)
8547{
8548 store(mkexpr(op2addr), get_fpr_dw0(r1));
8549
8550 return "std";
8551}
8552
florian55085f82012-11-21 00:36:55 +00008553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008554s390_irgen_STEY(UChar r1, IRTemp op2addr)
8555{
8556 store(mkexpr(op2addr), get_fpr_w0(r1));
8557
8558 return "stey";
8559}
8560
florian55085f82012-11-21 00:36:55 +00008561static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008562s390_irgen_STDY(UChar r1, IRTemp op2addr)
8563{
8564 store(mkexpr(op2addr), get_fpr_dw0(r1));
8565
8566 return "stdy";
8567}
8568
florian55085f82012-11-21 00:36:55 +00008569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008570s390_irgen_STFPC(IRTemp op2addr)
8571{
8572 store(mkexpr(op2addr), get_fpc_w0());
8573
8574 return "stfpc";
8575}
8576
florian55085f82012-11-21 00:36:55 +00008577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008578s390_irgen_AEBR(UChar r1, UChar r2)
8579{
8580 IRTemp op1 = newTemp(Ity_F32);
8581 IRTemp op2 = newTemp(Ity_F32);
8582 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008583 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008584
8585 assign(op1, get_fpr_w0(r1));
8586 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008587 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008588 mkexpr(op2)));
8589 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8590 put_fpr_w0(r1, mkexpr(result));
8591
8592 return "aebr";
8593}
8594
florian55085f82012-11-21 00:36:55 +00008595static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008596s390_irgen_ADBR(UChar r1, UChar r2)
8597{
8598 IRTemp op1 = newTemp(Ity_F64);
8599 IRTemp op2 = newTemp(Ity_F64);
8600 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008601 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008602
8603 assign(op1, get_fpr_dw0(r1));
8604 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008605 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008606 mkexpr(op2)));
8607 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8608 put_fpr_dw0(r1, mkexpr(result));
8609
8610 return "adbr";
8611}
8612
florian55085f82012-11-21 00:36:55 +00008613static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008614s390_irgen_AEB(UChar r1, IRTemp op2addr)
8615{
8616 IRTemp op1 = newTemp(Ity_F32);
8617 IRTemp op2 = newTemp(Ity_F32);
8618 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008619 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008620
8621 assign(op1, get_fpr_w0(r1));
8622 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008623 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008624 mkexpr(op2)));
8625 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8626 put_fpr_w0(r1, mkexpr(result));
8627
8628 return "aeb";
8629}
8630
florian55085f82012-11-21 00:36:55 +00008631static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008632s390_irgen_ADB(UChar r1, IRTemp op2addr)
8633{
8634 IRTemp op1 = newTemp(Ity_F64);
8635 IRTemp op2 = newTemp(Ity_F64);
8636 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008637 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008638
8639 assign(op1, get_fpr_dw0(r1));
8640 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008641 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008642 mkexpr(op2)));
8643 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8644 put_fpr_dw0(r1, mkexpr(result));
8645
8646 return "adb";
8647}
8648
florian55085f82012-11-21 00:36:55 +00008649static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008650s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8651 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008652{
florian125e20d2012-10-07 15:42:37 +00008653 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008654 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008655 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008656 }
sewardj2019a972011-03-07 16:04:07 +00008657 IRTemp op2 = newTemp(Ity_I32);
8658
8659 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008660 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008661 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008662
8663 return "cefbr";
8664}
8665
florian55085f82012-11-21 00:36:55 +00008666static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008667s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8668 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008669{
8670 IRTemp op2 = newTemp(Ity_I32);
8671
8672 assign(op2, get_gpr_w1(r2));
8673 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8674
8675 return "cdfbr";
8676}
8677
florian55085f82012-11-21 00:36:55 +00008678static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008679s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8680 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008681{
florian125e20d2012-10-07 15:42:37 +00008682 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008683 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008684 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008685 }
sewardj2019a972011-03-07 16:04:07 +00008686 IRTemp op2 = newTemp(Ity_I64);
8687
8688 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008689 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008690 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008691
8692 return "cegbr";
8693}
8694
florian55085f82012-11-21 00:36:55 +00008695static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008696s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8697 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008698{
florian125e20d2012-10-07 15:42:37 +00008699 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008700 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008701 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008702 }
sewardj2019a972011-03-07 16:04:07 +00008703 IRTemp op2 = newTemp(Ity_I64);
8704
8705 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008706 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008707 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008708
8709 return "cdgbr";
8710}
8711
florian55085f82012-11-21 00:36:55 +00008712static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008713s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8714 UChar r1, UChar r2)
8715{
floriane75dafa2012-09-01 17:54:09 +00008716 if (! s390_host_has_fpext) {
8717 emulation_failure(EmFail_S390X_fpext);
8718 } else {
8719 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008720
floriane75dafa2012-09-01 17:54:09 +00008721 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008722 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008723 mkexpr(op2)));
8724 }
florian1c8f7ff2012-09-01 00:12:11 +00008725 return "celfbr";
8726}
8727
florian55085f82012-11-21 00:36:55 +00008728static const HChar *
floriand2129202012-09-01 20:01:39 +00008729s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8730 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008731{
floriane75dafa2012-09-01 17:54:09 +00008732 if (! s390_host_has_fpext) {
8733 emulation_failure(EmFail_S390X_fpext);
8734 } else {
8735 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008736
floriane75dafa2012-09-01 17:54:09 +00008737 assign(op2, get_gpr_w1(r2));
8738 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8739 }
florian1c8f7ff2012-09-01 00:12:11 +00008740 return "cdlfbr";
8741}
8742
florian55085f82012-11-21 00:36:55 +00008743static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008744s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8745 UChar r1, UChar r2)
8746{
floriane75dafa2012-09-01 17:54:09 +00008747 if (! s390_host_has_fpext) {
8748 emulation_failure(EmFail_S390X_fpext);
8749 } else {
8750 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008751
floriane75dafa2012-09-01 17:54:09 +00008752 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008753 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008754 mkexpr(op2)));
8755 }
florian1c8f7ff2012-09-01 00:12:11 +00008756 return "celgbr";
8757}
8758
florian55085f82012-11-21 00:36:55 +00008759static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008760s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8761 UChar r1, UChar r2)
8762{
floriane75dafa2012-09-01 17:54:09 +00008763 if (! s390_host_has_fpext) {
8764 emulation_failure(EmFail_S390X_fpext);
8765 } else {
8766 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008767
floriane75dafa2012-09-01 17:54:09 +00008768 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008769 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8770 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008771 mkexpr(op2)));
8772 }
florian1c8f7ff2012-09-01 00:12:11 +00008773 return "cdlgbr";
8774}
8775
florian55085f82012-11-21 00:36:55 +00008776static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008777s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8778 UChar r1, UChar r2)
8779{
floriane75dafa2012-09-01 17:54:09 +00008780 if (! s390_host_has_fpext) {
8781 emulation_failure(EmFail_S390X_fpext);
8782 } else {
8783 IRTemp op = newTemp(Ity_F32);
8784 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008785 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008786
floriane75dafa2012-09-01 17:54:09 +00008787 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008788 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008789 mkexpr(op)));
8790 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008791 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008792 }
florian1c8f7ff2012-09-01 00:12:11 +00008793 return "clfebr";
8794}
8795
florian55085f82012-11-21 00:36:55 +00008796static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008797s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8798 UChar r1, UChar r2)
8799{
floriane75dafa2012-09-01 17:54:09 +00008800 if (! s390_host_has_fpext) {
8801 emulation_failure(EmFail_S390X_fpext);
8802 } else {
8803 IRTemp op = newTemp(Ity_F64);
8804 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008805 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008806
floriane75dafa2012-09-01 17:54:09 +00008807 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008808 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008809 mkexpr(op)));
8810 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008811 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008812 }
florian1c8f7ff2012-09-01 00:12:11 +00008813 return "clfdbr";
8814}
8815
florian55085f82012-11-21 00:36:55 +00008816static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008817s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8818 UChar r1, UChar r2)
8819{
floriane75dafa2012-09-01 17:54:09 +00008820 if (! s390_host_has_fpext) {
8821 emulation_failure(EmFail_S390X_fpext);
8822 } else {
8823 IRTemp op = newTemp(Ity_F32);
8824 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008825 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008826
floriane75dafa2012-09-01 17:54:09 +00008827 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008828 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008829 mkexpr(op)));
8830 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008831 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008832 }
florian1c8f7ff2012-09-01 00:12:11 +00008833 return "clgebr";
8834}
8835
florian55085f82012-11-21 00:36:55 +00008836static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008837s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8838 UChar r1, UChar r2)
8839{
floriane75dafa2012-09-01 17:54:09 +00008840 if (! s390_host_has_fpext) {
8841 emulation_failure(EmFail_S390X_fpext);
8842 } else {
8843 IRTemp op = newTemp(Ity_F64);
8844 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008845 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008846
floriane75dafa2012-09-01 17:54:09 +00008847 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008848 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008849 mkexpr(op)));
8850 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008851 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008852 }
florian1c8f7ff2012-09-01 00:12:11 +00008853 return "clgdbr";
8854}
8855
florian55085f82012-11-21 00:36:55 +00008856static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008857s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8858 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008859{
8860 IRTemp op = newTemp(Ity_F32);
8861 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008862 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008863
8864 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008865 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008866 mkexpr(op)));
8867 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008868 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008869
8870 return "cfebr";
8871}
8872
florian55085f82012-11-21 00:36:55 +00008873static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008874s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8875 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008876{
8877 IRTemp op = newTemp(Ity_F64);
8878 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008879 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008880
8881 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008882 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008883 mkexpr(op)));
8884 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008885 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008886
8887 return "cfdbr";
8888}
8889
florian55085f82012-11-21 00:36:55 +00008890static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008891s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8892 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008893{
8894 IRTemp op = newTemp(Ity_F32);
8895 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008896 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008897
8898 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008899 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008900 mkexpr(op)));
8901 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008902 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008903
8904 return "cgebr";
8905}
8906
florian55085f82012-11-21 00:36:55 +00008907static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008908s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8909 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008910{
8911 IRTemp op = newTemp(Ity_F64);
8912 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008913 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008914
8915 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008916 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008917 mkexpr(op)));
8918 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008919 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008920
8921 return "cgdbr";
8922}
8923
florian55085f82012-11-21 00:36:55 +00008924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008925s390_irgen_DEBR(UChar r1, UChar r2)
8926{
8927 IRTemp op1 = newTemp(Ity_F32);
8928 IRTemp op2 = newTemp(Ity_F32);
8929 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008930 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008931
8932 assign(op1, get_fpr_w0(r1));
8933 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008934 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008935 mkexpr(op2)));
8936 put_fpr_w0(r1, mkexpr(result));
8937
8938 return "debr";
8939}
8940
florian55085f82012-11-21 00:36:55 +00008941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008942s390_irgen_DDBR(UChar r1, UChar r2)
8943{
8944 IRTemp op1 = newTemp(Ity_F64);
8945 IRTemp op2 = newTemp(Ity_F64);
8946 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008947 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008948
8949 assign(op1, get_fpr_dw0(r1));
8950 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008951 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008952 mkexpr(op2)));
8953 put_fpr_dw0(r1, mkexpr(result));
8954
8955 return "ddbr";
8956}
8957
florian55085f82012-11-21 00:36:55 +00008958static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008959s390_irgen_DEB(UChar r1, IRTemp op2addr)
8960{
8961 IRTemp op1 = newTemp(Ity_F32);
8962 IRTemp op2 = newTemp(Ity_F32);
8963 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008964 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008965
8966 assign(op1, get_fpr_w0(r1));
8967 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008968 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008969 mkexpr(op2)));
8970 put_fpr_w0(r1, mkexpr(result));
8971
8972 return "deb";
8973}
8974
florian55085f82012-11-21 00:36:55 +00008975static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008976s390_irgen_DDB(UChar r1, IRTemp op2addr)
8977{
8978 IRTemp op1 = newTemp(Ity_F64);
8979 IRTemp op2 = newTemp(Ity_F64);
8980 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008981 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008982
8983 assign(op1, get_fpr_dw0(r1));
8984 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008985 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008986 mkexpr(op2)));
8987 put_fpr_dw0(r1, mkexpr(result));
8988
8989 return "ddb";
8990}
8991
florian55085f82012-11-21 00:36:55 +00008992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008993s390_irgen_LTEBR(UChar r1, UChar r2)
8994{
8995 IRTemp result = newTemp(Ity_F32);
8996
8997 assign(result, get_fpr_w0(r2));
8998 put_fpr_w0(r1, mkexpr(result));
8999 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9000
9001 return "ltebr";
9002}
9003
florian55085f82012-11-21 00:36:55 +00009004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009005s390_irgen_LTDBR(UChar r1, UChar r2)
9006{
9007 IRTemp result = newTemp(Ity_F64);
9008
9009 assign(result, get_fpr_dw0(r2));
9010 put_fpr_dw0(r1, mkexpr(result));
9011 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9012
9013 return "ltdbr";
9014}
9015
florian55085f82012-11-21 00:36:55 +00009016static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009017s390_irgen_LCEBR(UChar r1, UChar r2)
9018{
9019 IRTemp result = newTemp(Ity_F32);
9020
9021 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9022 put_fpr_w0(r1, mkexpr(result));
9023 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9024
9025 return "lcebr";
9026}
9027
florian55085f82012-11-21 00:36:55 +00009028static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009029s390_irgen_LCDBR(UChar r1, UChar r2)
9030{
9031 IRTemp result = newTemp(Ity_F64);
9032
9033 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9034 put_fpr_dw0(r1, mkexpr(result));
9035 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9036
9037 return "lcdbr";
9038}
9039
florian55085f82012-11-21 00:36:55 +00009040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009041s390_irgen_LDEBR(UChar r1, UChar r2)
9042{
9043 IRTemp op = newTemp(Ity_F32);
9044
9045 assign(op, get_fpr_w0(r2));
9046 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9047
9048 return "ldebr";
9049}
9050
florian55085f82012-11-21 00:36:55 +00009051static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009052s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9053{
9054 IRTemp op = newTemp(Ity_F32);
9055
9056 assign(op, load(Ity_F32, mkexpr(op2addr)));
9057 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9058
9059 return "ldeb";
9060}
9061
florian55085f82012-11-21 00:36:55 +00009062static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009063s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9064 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009065{
florian125e20d2012-10-07 15:42:37 +00009066 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009067 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009068 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009069 }
sewardj2019a972011-03-07 16:04:07 +00009070 IRTemp op = newTemp(Ity_F64);
9071
9072 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009073 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009074 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009075
9076 return "ledbr";
9077}
9078
florian55085f82012-11-21 00:36:55 +00009079static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009080s390_irgen_MEEBR(UChar r1, UChar r2)
9081{
9082 IRTemp op1 = newTemp(Ity_F32);
9083 IRTemp op2 = newTemp(Ity_F32);
9084 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009085 IRRoundingMode rounding_mode =
9086 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009087
9088 assign(op1, get_fpr_w0(r1));
9089 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009090 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009091 mkexpr(op2)));
9092 put_fpr_w0(r1, mkexpr(result));
9093
9094 return "meebr";
9095}
9096
florian55085f82012-11-21 00:36:55 +00009097static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009098s390_irgen_MDBR(UChar r1, UChar r2)
9099{
9100 IRTemp op1 = newTemp(Ity_F64);
9101 IRTemp op2 = newTemp(Ity_F64);
9102 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009103 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009104
9105 assign(op1, get_fpr_dw0(r1));
9106 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009107 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009108 mkexpr(op2)));
9109 put_fpr_dw0(r1, mkexpr(result));
9110
9111 return "mdbr";
9112}
9113
florian55085f82012-11-21 00:36:55 +00009114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009115s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9116{
9117 IRTemp op1 = newTemp(Ity_F32);
9118 IRTemp op2 = newTemp(Ity_F32);
9119 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009120 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009121
9122 assign(op1, get_fpr_w0(r1));
9123 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009124 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009125 mkexpr(op2)));
9126 put_fpr_w0(r1, mkexpr(result));
9127
9128 return "meeb";
9129}
9130
florian55085f82012-11-21 00:36:55 +00009131static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009132s390_irgen_MDB(UChar r1, IRTemp op2addr)
9133{
9134 IRTemp op1 = newTemp(Ity_F64);
9135 IRTemp op2 = newTemp(Ity_F64);
9136 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009137 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009138
9139 assign(op1, get_fpr_dw0(r1));
9140 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009141 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009142 mkexpr(op2)));
9143 put_fpr_dw0(r1, mkexpr(result));
9144
9145 return "mdb";
9146}
9147
florian55085f82012-11-21 00:36:55 +00009148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009149s390_irgen_SEBR(UChar r1, UChar r2)
9150{
9151 IRTemp op1 = newTemp(Ity_F32);
9152 IRTemp op2 = newTemp(Ity_F32);
9153 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009154 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009155
9156 assign(op1, get_fpr_w0(r1));
9157 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009158 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009159 mkexpr(op2)));
9160 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9161 put_fpr_w0(r1, mkexpr(result));
9162
9163 return "sebr";
9164}
9165
florian55085f82012-11-21 00:36:55 +00009166static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009167s390_irgen_SDBR(UChar r1, UChar r2)
9168{
9169 IRTemp op1 = newTemp(Ity_F64);
9170 IRTemp op2 = newTemp(Ity_F64);
9171 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009172 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009173
9174 assign(op1, get_fpr_dw0(r1));
9175 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009176 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009177 mkexpr(op2)));
9178 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9179 put_fpr_dw0(r1, mkexpr(result));
9180
9181 return "sdbr";
9182}
9183
florian55085f82012-11-21 00:36:55 +00009184static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009185s390_irgen_SEB(UChar r1, IRTemp op2addr)
9186{
9187 IRTemp op1 = newTemp(Ity_F32);
9188 IRTemp op2 = newTemp(Ity_F32);
9189 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009190 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009191
9192 assign(op1, get_fpr_w0(r1));
9193 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009194 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009195 mkexpr(op2)));
9196 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9197 put_fpr_w0(r1, mkexpr(result));
9198
9199 return "seb";
9200}
9201
florian55085f82012-11-21 00:36:55 +00009202static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009203s390_irgen_SDB(UChar r1, IRTemp op2addr)
9204{
9205 IRTemp op1 = newTemp(Ity_F64);
9206 IRTemp op2 = newTemp(Ity_F64);
9207 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009208 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009209
9210 assign(op1, get_fpr_dw0(r1));
9211 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009212 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009213 mkexpr(op2)));
9214 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9215 put_fpr_dw0(r1, mkexpr(result));
9216
9217 return "sdb";
9218}
9219
florian55085f82012-11-21 00:36:55 +00009220static const HChar *
florian12390202012-11-10 22:34:14 +00009221s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9222{
9223 IRTemp op1 = newTemp(Ity_D64);
9224 IRTemp op2 = newTemp(Ity_D64);
9225 IRTemp result = newTemp(Ity_D64);
9226 IRTemp rounding_mode;
9227
9228 vassert(s390_host_has_dfp);
9229 vassert(m4 == 0 || s390_host_has_fpext);
9230 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9231 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9232 rounding_mode = encode_dfp_rounding_mode(m4);
9233 assign(op1, get_dpr_dw0(r2));
9234 assign(op2, get_dpr_dw0(r3));
9235 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9236 mkexpr(op2)));
9237 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9238 put_dpr_dw0(r1, mkexpr(result));
9239
9240 return (m4 == 0) ? "adtr" : "adtra";
9241}
9242
florian55085f82012-11-21 00:36:55 +00009243static const HChar *
floriane38f6412012-12-21 17:32:12 +00009244s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9245{
9246 IRTemp op1 = newTemp(Ity_D128);
9247 IRTemp op2 = newTemp(Ity_D128);
9248 IRTemp result = newTemp(Ity_D128);
9249 IRTemp rounding_mode;
9250
9251 vassert(s390_host_has_dfp);
9252 vassert(m4 == 0 || s390_host_has_fpext);
9253 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9254 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9255 rounding_mode = encode_dfp_rounding_mode(m4);
9256 assign(op1, get_dpr_pair(r2));
9257 assign(op2, get_dpr_pair(r3));
9258 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9259 mkexpr(op2)));
9260 put_dpr_pair(r1, mkexpr(result));
9261
9262 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9263
9264 return (m4 == 0) ? "axtr" : "axtra";
9265}
9266
9267static const HChar *
9268s390_irgen_CDTR(UChar r1, UChar r2)
9269{
9270 IRTemp op1 = newTemp(Ity_D64);
9271 IRTemp op2 = newTemp(Ity_D64);
9272 IRTemp cc_vex = newTemp(Ity_I32);
9273 IRTemp cc_s390 = newTemp(Ity_I32);
9274
9275 assign(op1, get_dpr_dw0(r1));
9276 assign(op2, get_dpr_dw0(r2));
9277 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9278
florian2d3d87f2012-12-21 21:05:17 +00009279 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009280 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9281
9282 return "cdtr";
9283}
9284
9285static const HChar *
9286s390_irgen_CXTR(UChar r1, UChar r2)
9287{
9288 IRTemp op1 = newTemp(Ity_D128);
9289 IRTemp op2 = newTemp(Ity_D128);
9290 IRTemp cc_vex = newTemp(Ity_I32);
9291 IRTemp cc_s390 = newTemp(Ity_I32);
9292
9293 assign(op1, get_dpr_pair(r1));
9294 assign(op2, get_dpr_pair(r2));
9295 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9296
florian2d3d87f2012-12-21 21:05:17 +00009297 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009298 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9299
9300 return "cxtr";
9301}
9302
9303static const HChar *
florian5f034622013-01-13 02:29:05 +00009304s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9305 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9306{
9307 vassert(s390_host_has_dfp);
9308
9309 if (! s390_host_has_fpext) {
9310 emulation_failure(EmFail_S390X_fpext);
9311 } else {
9312 IRTemp op2 = newTemp(Ity_I32);
9313
9314 assign(op2, get_gpr_w1(r2));
9315 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9316 }
9317 return "cdftr";
9318}
9319
9320static const HChar *
9321s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9322 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9323{
9324 vassert(s390_host_has_dfp);
9325
9326 if (! s390_host_has_fpext) {
9327 emulation_failure(EmFail_S390X_fpext);
9328 } else {
9329 IRTemp op2 = newTemp(Ity_I32);
9330
9331 assign(op2, get_gpr_w1(r2));
9332 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9333 }
9334 return "cxftr";
9335}
9336
9337static const HChar *
9338s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9339 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9340{
9341 vassert(s390_host_has_dfp);
9342
9343 if (! s390_host_has_fpext) {
9344 emulation_failure(EmFail_S390X_fpext);
9345 } else {
9346 IRTemp op2 = newTemp(Ity_I32);
9347
9348 assign(op2, get_gpr_w1(r2));
9349 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9350 }
9351 return "cdlftr";
9352}
9353
9354static const HChar *
9355s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9356 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9357{
9358 vassert(s390_host_has_dfp);
9359
9360 if (! s390_host_has_fpext) {
9361 emulation_failure(EmFail_S390X_fpext);
9362 } else {
9363 IRTemp op2 = newTemp(Ity_I32);
9364
9365 assign(op2, get_gpr_w1(r2));
9366 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9367 }
9368 return "cxlftr";
9369}
9370
9371static const HChar *
9372s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9373 UChar r1, UChar r2)
9374{
9375 vassert(s390_host_has_dfp);
9376
9377 if (! s390_host_has_fpext) {
9378 emulation_failure(EmFail_S390X_fpext);
9379 } else {
9380 IRTemp op2 = newTemp(Ity_I64);
9381
9382 assign(op2, get_gpr_dw0(r2));
9383 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9384 mkexpr(encode_dfp_rounding_mode(m3)),
9385 mkexpr(op2)));
9386 }
9387 return "cdlgtr";
9388}
9389
9390static const HChar *
9391s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9392 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9393{
9394 vassert(s390_host_has_dfp);
9395
9396 if (! s390_host_has_fpext) {
9397 emulation_failure(EmFail_S390X_fpext);
9398 } else {
9399 IRTemp op2 = newTemp(Ity_I64);
9400
9401 assign(op2, get_gpr_dw0(r2));
9402 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9403 }
9404 return "cxlgtr";
9405}
9406
9407static const HChar *
9408s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9409 UChar r1, UChar r2)
9410{
9411 vassert(s390_host_has_dfp);
9412
9413 if (! s390_host_has_fpext) {
9414 emulation_failure(EmFail_S390X_fpext);
9415 } else {
9416 IRTemp op = newTemp(Ity_D64);
9417 IRTemp result = newTemp(Ity_I32);
9418 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9419
9420 assign(op, get_dpr_dw0(r2));
9421 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9422 mkexpr(op)));
9423 put_gpr_w1(r1, mkexpr(result));
9424 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9425 }
9426 return "cfdtr";
9427}
9428
9429static const HChar *
9430s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9431 UChar r1, UChar r2)
9432{
9433 vassert(s390_host_has_dfp);
9434
9435 if (! s390_host_has_fpext) {
9436 emulation_failure(EmFail_S390X_fpext);
9437 } else {
9438 IRTemp op = newTemp(Ity_D128);
9439 IRTemp result = newTemp(Ity_I32);
9440 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9441
9442 assign(op, get_dpr_pair(r2));
9443 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9444 mkexpr(op)));
9445 put_gpr_w1(r1, mkexpr(result));
9446 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9447 }
9448 return "cfxtr";
9449}
9450
9451static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009452s390_irgen_CEDTR(UChar r1, UChar r2)
9453{
9454 IRTemp op1 = newTemp(Ity_D64);
9455 IRTemp op2 = newTemp(Ity_D64);
9456 IRTemp cc_vex = newTemp(Ity_I32);
9457 IRTemp cc_s390 = newTemp(Ity_I32);
9458
9459 vassert(s390_host_has_dfp);
9460 assign(op1, get_dpr_dw0(r1));
9461 assign(op2, get_dpr_dw0(r2));
9462 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9463
9464 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9465 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9466
9467 return "cedtr";
9468}
9469
9470static const HChar *
9471s390_irgen_CEXTR(UChar r1, UChar r2)
9472{
9473 IRTemp op1 = newTemp(Ity_D128);
9474 IRTemp op2 = newTemp(Ity_D128);
9475 IRTemp cc_vex = newTemp(Ity_I32);
9476 IRTemp cc_s390 = newTemp(Ity_I32);
9477
9478 vassert(s390_host_has_dfp);
9479 assign(op1, get_dpr_pair(r1));
9480 assign(op2, get_dpr_pair(r2));
9481 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9482
9483 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9484 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9485
9486 return "cextr";
9487}
9488
9489static const HChar *
florian5f034622013-01-13 02:29:05 +00009490s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9491 UChar r1, UChar r2)
9492{
9493 vassert(s390_host_has_dfp);
9494
9495 if (! s390_host_has_fpext) {
9496 emulation_failure(EmFail_S390X_fpext);
9497 } else {
9498 IRTemp op = newTemp(Ity_D64);
9499 IRTemp result = newTemp(Ity_I32);
9500 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9501
9502 assign(op, get_dpr_dw0(r2));
9503 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9504 mkexpr(op)));
9505 put_gpr_w1(r1, mkexpr(result));
9506 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9507 }
9508 return "clfdtr";
9509}
9510
9511static const HChar *
9512s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9513 UChar r1, UChar r2)
9514{
9515 vassert(s390_host_has_dfp);
9516
9517 if (! s390_host_has_fpext) {
9518 emulation_failure(EmFail_S390X_fpext);
9519 } else {
9520 IRTemp op = newTemp(Ity_D128);
9521 IRTemp result = newTemp(Ity_I32);
9522 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9523
9524 assign(op, get_dpr_pair(r2));
9525 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9526 mkexpr(op)));
9527 put_gpr_w1(r1, mkexpr(result));
9528 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9529 }
9530 return "clfxtr";
9531}
9532
9533static const HChar *
9534s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9535 UChar r1, UChar r2)
9536{
9537 vassert(s390_host_has_dfp);
9538
9539 if (! s390_host_has_fpext) {
9540 emulation_failure(EmFail_S390X_fpext);
9541 } else {
9542 IRTemp op = newTemp(Ity_D64);
9543 IRTemp result = newTemp(Ity_I64);
9544 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9545
9546 assign(op, get_dpr_dw0(r2));
9547 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
9548 mkexpr(op)));
9549 put_gpr_dw0(r1, mkexpr(result));
9550 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
9551 }
9552 return "clgdtr";
9553}
9554
9555static const HChar *
9556s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
9557 UChar r1, UChar r2)
9558{
9559 vassert(s390_host_has_dfp);
9560
9561 if (! s390_host_has_fpext) {
9562 emulation_failure(EmFail_S390X_fpext);
9563 } else {
9564 IRTemp op = newTemp(Ity_D128);
9565 IRTemp result = newTemp(Ity_I64);
9566 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9567
9568 assign(op, get_dpr_pair(r2));
9569 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
9570 mkexpr(op)));
9571 put_gpr_dw0(r1, mkexpr(result));
9572 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
9573 rounding_mode);
9574 }
9575 return "clgxtr";
9576}
9577
9578static const HChar *
florian12390202012-11-10 22:34:14 +00009579s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9580{
9581 IRTemp op1 = newTemp(Ity_D64);
9582 IRTemp op2 = newTemp(Ity_D64);
9583 IRTemp result = newTemp(Ity_D64);
9584 IRTemp rounding_mode;
9585
9586 vassert(s390_host_has_dfp);
9587 vassert(m4 == 0 || s390_host_has_fpext);
9588 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9589 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9590 rounding_mode = encode_dfp_rounding_mode(m4);
9591 assign(op1, get_dpr_dw0(r2));
9592 assign(op2, get_dpr_dw0(r3));
9593 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9594 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009595 put_dpr_dw0(r1, mkexpr(result));
9596
9597 return (m4 == 0) ? "ddtr" : "ddtra";
9598}
9599
florian55085f82012-11-21 00:36:55 +00009600static const HChar *
floriane38f6412012-12-21 17:32:12 +00009601s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9602{
9603 IRTemp op1 = newTemp(Ity_D128);
9604 IRTemp op2 = newTemp(Ity_D128);
9605 IRTemp result = newTemp(Ity_D128);
9606 IRTemp rounding_mode;
9607
9608 vassert(s390_host_has_dfp);
9609 vassert(m4 == 0 || s390_host_has_fpext);
9610 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9611 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9612 rounding_mode = encode_dfp_rounding_mode(m4);
9613 assign(op1, get_dpr_pair(r2));
9614 assign(op2, get_dpr_pair(r3));
9615 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9616 mkexpr(op2)));
9617 put_dpr_pair(r1, mkexpr(result));
9618
9619 return (m4 == 0) ? "dxtr" : "dxtra";
9620}
9621
9622static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009623s390_irgen_ESDTR(UChar r1, UChar r2)
9624{
9625 vassert(s390_host_has_dfp);
9626 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
9627 return "esdtr";
9628}
9629
9630static const HChar *
9631s390_irgen_ESXTR(UChar r1, UChar r2)
9632{
9633 vassert(s390_host_has_dfp);
9634 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
9635 return "esxtr";
9636}
9637
9638static const HChar *
floriane38f6412012-12-21 17:32:12 +00009639s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9640{
9641 IRTemp op = newTemp(Ity_D32);
9642
9643 vassert(s390_host_has_dfp);
9644
9645 assign(op, get_dpr_w0(r2));
9646 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
9647
9648 return "ldetr";
9649}
9650
9651static const HChar *
9652s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9653{
9654 IRTemp op = newTemp(Ity_D64);
9655
9656 assign(op, get_dpr_dw0(r2));
9657 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
9658
9659 return "lxdtr";
9660}
9661
9662static const HChar *
9663s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
9664 UChar r1, UChar r2)
9665{
9666 vassert(s390_host_has_dfp);
9667 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9668 emulation_warning(EmWarn_S390X_fpext_rounding);
9669 m3 = S390_DFP_ROUND_PER_FPC_0;
9670 }
9671 IRTemp result = newTemp(Ity_D64);
9672
9673 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
9674 get_dpr_pair(r2)));
9675 put_dpr_dw0(r1, mkexpr(result));
9676
9677 return "ldxtr";
9678}
9679
9680static const HChar *
9681s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
9682 UChar r1, UChar r2)
9683{
9684 vassert(s390_host_has_dfp);
9685 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9686 emulation_warning(EmWarn_S390X_fpext_rounding);
9687 m3 = S390_DFP_ROUND_PER_FPC_0;
9688 }
9689 IRTemp op = newTemp(Ity_D64);
9690
9691 assign(op, get_dpr_dw0(r2));
9692 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
9693 mkexpr(op)));
9694
9695 return "ledtr";
9696}
9697
9698static const HChar *
9699s390_irgen_LTDTR(UChar r1, UChar r2)
9700{
9701 IRTemp result = newTemp(Ity_D64);
9702
9703 assign(result, get_dpr_dw0(r2));
9704 put_dpr_dw0(r1, mkexpr(result));
9705 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9706
9707 return "ltdtr";
9708}
9709
9710static const HChar *
9711s390_irgen_LTXTR(UChar r1, UChar r2)
9712{
9713 IRTemp result = newTemp(Ity_D128);
9714
9715 assign(result, get_dpr_pair(r2));
9716 put_dpr_pair(r1, mkexpr(result));
9717 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9718
9719 return "ltxtr";
9720}
9721
9722static const HChar *
florian12390202012-11-10 22:34:14 +00009723s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9724{
9725 IRTemp op1 = newTemp(Ity_D64);
9726 IRTemp op2 = newTemp(Ity_D64);
9727 IRTemp result = newTemp(Ity_D64);
9728 IRTemp rounding_mode;
9729
9730 vassert(s390_host_has_dfp);
9731 vassert(m4 == 0 || s390_host_has_fpext);
9732 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9733 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9734 rounding_mode = encode_dfp_rounding_mode(m4);
9735 assign(op1, get_dpr_dw0(r2));
9736 assign(op2, get_dpr_dw0(r3));
9737 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9738 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009739 put_dpr_dw0(r1, mkexpr(result));
9740
9741 return (m4 == 0) ? "mdtr" : "mdtra";
9742}
9743
florian55085f82012-11-21 00:36:55 +00009744static const HChar *
floriane38f6412012-12-21 17:32:12 +00009745s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9746{
9747 IRTemp op1 = newTemp(Ity_D128);
9748 IRTemp op2 = newTemp(Ity_D128);
9749 IRTemp result = newTemp(Ity_D128);
9750 IRTemp rounding_mode;
9751
9752 vassert(s390_host_has_dfp);
9753 vassert(m4 == 0 || s390_host_has_fpext);
9754 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9755 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9756 rounding_mode = encode_dfp_rounding_mode(m4);
9757 assign(op1, get_dpr_pair(r2));
9758 assign(op2, get_dpr_pair(r3));
9759 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
9760 mkexpr(op2)));
9761 put_dpr_pair(r1, mkexpr(result));
9762
9763 return (m4 == 0) ? "mxtr" : "mxtra";
9764}
9765
9766static const HChar *
florian12390202012-11-10 22:34:14 +00009767s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9768{
9769 IRTemp op1 = newTemp(Ity_D64);
9770 IRTemp op2 = newTemp(Ity_D64);
9771 IRTemp result = newTemp(Ity_D64);
9772 IRTemp rounding_mode;
9773
9774 vassert(s390_host_has_dfp);
9775 vassert(m4 == 0 || s390_host_has_fpext);
9776 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9777 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9778 rounding_mode = encode_dfp_rounding_mode(m4);
9779 assign(op1, get_dpr_dw0(r2));
9780 assign(op2, get_dpr_dw0(r3));
9781 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
9782 mkexpr(op2)));
9783 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9784 put_dpr_dw0(r1, mkexpr(result));
9785
9786 return (m4 == 0) ? "sdtr" : "sdtra";
9787}
9788
floriane38f6412012-12-21 17:32:12 +00009789static const HChar *
9790s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9791{
9792 IRTemp op1 = newTemp(Ity_D128);
9793 IRTemp op2 = newTemp(Ity_D128);
9794 IRTemp result = newTemp(Ity_D128);
9795 IRTemp rounding_mode;
9796
9797 vassert(s390_host_has_dfp);
9798 vassert(m4 == 0 || s390_host_has_fpext);
9799 /* when m4 = 0, S390_DFP_ROUND_PER_FPC_0 should be set.
9800 since S390_DFP_ROUND_PER_FPC_0 is also 0, passing m4 is sufficient */
9801 rounding_mode = encode_dfp_rounding_mode(m4);
9802 assign(op1, get_dpr_pair(r2));
9803 assign(op2, get_dpr_pair(r3));
9804 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
9805 mkexpr(op2)));
9806 put_dpr_pair(r1, mkexpr(result));
9807
9808 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9809
9810 return (m4 == 0) ? "sxtr" : "sxtra";
9811}
sewardj2019a972011-03-07 16:04:07 +00009812
florian55085f82012-11-21 00:36:55 +00009813static const HChar *
florian1b901d42013-01-01 22:19:24 +00009814s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
9815{
9816 IRTemp op = newTemp(Ity_D64);
9817
9818 vassert(s390_host_has_dfp);
9819
9820 assign(op, get_dpr_dw0(r3));
9821 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
9822 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9823
9824 return "sldt";
9825}
9826
9827static const HChar *
9828s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
9829{
9830 IRTemp op = newTemp(Ity_D128);
9831
9832 vassert(s390_host_has_dfp);
9833
9834 assign(op, get_dpr_pair(r3));
9835 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
9836 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9837
9838 return "slxt";
9839}
9840
9841static const HChar *
9842s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
9843{
9844 IRTemp op = newTemp(Ity_D64);
9845
9846 vassert(s390_host_has_dfp);
9847
9848 assign(op, get_dpr_dw0(r3));
9849 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
9850 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9851
9852 return "srdt";
9853}
9854
9855static const HChar *
9856s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
9857{
9858 IRTemp op = newTemp(Ity_D128);
9859
9860 vassert(s390_host_has_dfp);
9861
9862 assign(op, get_dpr_pair(r3));
9863 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
9864 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
9865
9866 return "srxt";
9867}
9868
9869static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009870s390_irgen_TDCET(UChar r1, IRTemp op2addr)
9871{
9872 IRTemp value = newTemp(Ity_D32);
9873
9874 vassert(s390_host_has_dfp);
9875 assign(value, get_dpr_w0(r1));
9876
9877 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
9878
9879 return "tdcet";
9880}
9881
9882static const HChar *
9883s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
9884{
9885 IRTemp value = newTemp(Ity_D64);
9886
9887 vassert(s390_host_has_dfp);
9888 assign(value, get_dpr_dw0(r1));
9889
9890 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
9891
9892 return "tdcdt";
9893}
9894
9895static const HChar *
9896s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
9897{
9898 IRTemp value = newTemp(Ity_D128);
9899
9900 vassert(s390_host_has_dfp);
9901 assign(value, get_dpr_pair(r1));
9902
9903 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
9904
9905 return "tdcxt";
9906}
9907
9908static const HChar *
9909s390_irgen_TDGET(UChar r1, IRTemp op2addr)
9910{
9911 IRTemp value = newTemp(Ity_D32);
9912
9913 vassert(s390_host_has_dfp);
9914 assign(value, get_dpr_w0(r1));
9915
9916 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
9917
9918 return "tdget";
9919}
9920
9921static const HChar *
9922s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
9923{
9924 IRTemp value = newTemp(Ity_D64);
9925
9926 vassert(s390_host_has_dfp);
9927 assign(value, get_dpr_dw0(r1));
9928
9929 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
9930
9931 return "tdgdt";
9932}
9933
9934static const HChar *
9935s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
9936{
9937 IRTemp value = newTemp(Ity_D128);
9938
9939 vassert(s390_host_has_dfp);
9940 assign(value, get_dpr_pair(r1));
9941
9942 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
9943
9944 return "tdgxt";
9945}
9946
9947static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009948s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
9949{
florian79e839e2012-05-05 02:20:30 +00009950 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00009951
florian79e839e2012-05-05 02:20:30 +00009952 assign(len, mkU64(length));
9953 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +00009954
9955 return "clc";
9956}
9957
florian55085f82012-11-21 00:36:55 +00009958static const HChar *
florianb0c9a132011-09-08 15:37:39 +00009959s390_irgen_CLCL(UChar r1, UChar r2)
9960{
9961 IRTemp addr1 = newTemp(Ity_I64);
9962 IRTemp addr2 = newTemp(Ity_I64);
9963 IRTemp addr1_load = newTemp(Ity_I64);
9964 IRTemp addr2_load = newTemp(Ity_I64);
9965 IRTemp len1 = newTemp(Ity_I32);
9966 IRTemp len2 = newTemp(Ity_I32);
9967 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
9968 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
9969 IRTemp single1 = newTemp(Ity_I8);
9970 IRTemp single2 = newTemp(Ity_I8);
9971 IRTemp pad = newTemp(Ity_I8);
9972
9973 assign(addr1, get_gpr_dw0(r1));
9974 assign(r1p1, get_gpr_w1(r1 + 1));
9975 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
9976 assign(addr2, get_gpr_dw0(r2));
9977 assign(r2p1, get_gpr_w1(r2 + 1));
9978 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
9979 assign(pad, get_gpr_b4(r2 + 1));
9980
9981 /* len1 == 0 and len2 == 0? Exit */
9982 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +00009983 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
9984 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +00009985
9986 /* Because mkite evaluates both the then-clause and the else-clause
9987 we cannot load directly from addr1 here. If len1 is 0, then adddr1
9988 may be NULL and loading from there would segfault. So we provide a
9989 valid dummy address in that case. Loading from there does no harm and
9990 the value will be discarded at runtime. */
9991 assign(addr1_load,
9992 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9993 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
9994 assign(single1,
9995 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
9996 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
9997
9998 assign(addr2_load,
9999 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10000 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10001 assign(single2,
10002 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10003 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10004
10005 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10006 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010007 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010008
10009 /* Update len1 and addr1, unless len1 == 0. */
10010 put_gpr_dw0(r1,
10011 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10012 mkexpr(addr1),
10013 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10014
10015 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10016 put_gpr_w1(r1 + 1,
10017 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10018 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10019 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10020
10021 /* Update len2 and addr2, unless len2 == 0. */
10022 put_gpr_dw0(r2,
10023 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10024 mkexpr(addr2),
10025 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10026
10027 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10028 put_gpr_w1(r2 + 1,
10029 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10030 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10031 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10032
florian6820ba52012-07-26 02:01:50 +000010033 iterate();
florianb0c9a132011-09-08 15:37:39 +000010034
10035 return "clcl";
10036}
10037
florian55085f82012-11-21 00:36:55 +000010038static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010039s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10040{
10041 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10042
10043 addr1 = newTemp(Ity_I64);
10044 addr3 = newTemp(Ity_I64);
10045 addr1_load = newTemp(Ity_I64);
10046 addr3_load = newTemp(Ity_I64);
10047 len1 = newTemp(Ity_I64);
10048 len3 = newTemp(Ity_I64);
10049 single1 = newTemp(Ity_I8);
10050 single3 = newTemp(Ity_I8);
10051
10052 assign(addr1, get_gpr_dw0(r1));
10053 assign(len1, get_gpr_dw0(r1 + 1));
10054 assign(addr3, get_gpr_dw0(r3));
10055 assign(len3, get_gpr_dw0(r3 + 1));
10056
10057 /* len1 == 0 and len3 == 0? Exit */
10058 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010059 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10060 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010061
10062 /* A mux requires both ways to be possible. This is a way to prevent clcle
10063 from reading from addr1 if it should read from the pad. Since the pad
10064 has no address, just read from the instruction, we discard that anyway */
10065 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010066 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10067 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010068
10069 /* same for addr3 */
10070 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010071 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10072 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010073
10074 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010075 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10076 unop(Iop_64to8, mkexpr(pad2)),
10077 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010078
10079 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010080 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10081 unop(Iop_64to8, mkexpr(pad2)),
10082 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010083
10084 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10085 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010086 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010087
10088 /* If a length in 0 we must not change this length and the address */
10089 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010090 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10091 mkexpr(addr1),
10092 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010093
10094 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010095 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10096 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010097
10098 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010099 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10100 mkexpr(addr3),
10101 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010102
10103 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010104 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10105 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010106
florian6820ba52012-07-26 02:01:50 +000010107 iterate();
sewardj2019a972011-03-07 16:04:07 +000010108
10109 return "clcle";
10110}
floriana64c2432011-07-16 02:11:50 +000010111
florianb0bf6602012-05-05 00:01:16 +000010112
sewardj2019a972011-03-07 16:04:07 +000010113static void
10114s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10115{
florianb0bf6602012-05-05 00:01:16 +000010116 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10117}
sewardj2019a972011-03-07 16:04:07 +000010118
sewardj2019a972011-03-07 16:04:07 +000010119
florianb0bf6602012-05-05 00:01:16 +000010120static void
10121s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10122{
10123 s390_irgen_xonc(Iop_And8, length, start1, start2);
10124}
sewardj2019a972011-03-07 16:04:07 +000010125
sewardj2019a972011-03-07 16:04:07 +000010126
florianb0bf6602012-05-05 00:01:16 +000010127static void
10128s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10129{
10130 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010131}
10132
10133
10134static void
10135s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10136{
10137 IRTemp current1 = newTemp(Ity_I8);
10138 IRTemp current2 = newTemp(Ity_I8);
10139 IRTemp counter = newTemp(Ity_I64);
10140
10141 assign(counter, get_counter_dw0());
10142 put_counter_dw0(mkU64(0));
10143
10144 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10145 mkexpr(counter))));
10146 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10147 mkexpr(counter))));
10148 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10149 False);
10150
10151 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010152 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010153
10154 /* Check for end of field */
10155 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010156 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010157 put_counter_dw0(mkU64(0));
10158}
10159
10160static void
10161s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10162{
10163 IRTemp counter = newTemp(Ity_I64);
10164
10165 assign(counter, get_counter_dw0());
10166
10167 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10168 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10169
10170 /* Check for end of field */
10171 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010172 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010173 put_counter_dw0(mkU64(0));
10174}
10175
florianf87d4fb2012-05-05 02:55:24 +000010176static void
10177s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10178{
10179 IRTemp op = newTemp(Ity_I8);
10180 IRTemp op1 = newTemp(Ity_I8);
10181 IRTemp result = newTemp(Ity_I64);
10182 IRTemp counter = newTemp(Ity_I64);
10183
10184 assign(counter, get_counter_dw0());
10185
10186 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10187
10188 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10189
10190 assign(op1, load(Ity_I8, mkexpr(result)));
10191 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10192
10193 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010194 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010195 put_counter_dw0(mkU64(0));
10196}
sewardj2019a972011-03-07 16:04:07 +000010197
10198
10199static void
10200s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010201 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010202 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010203{
10204 struct SS {
10205 unsigned int op : 8;
10206 unsigned int l : 8;
10207 unsigned int b1 : 4;
10208 unsigned int d1 : 12;
10209 unsigned int b2 : 4;
10210 unsigned int d2 : 12;
10211 };
10212 union {
10213 struct SS dec;
10214 unsigned long bytes;
10215 } ss;
10216 IRTemp cond;
10217 IRDirty *d;
10218 IRTemp torun;
10219
10220 IRTemp start1 = newTemp(Ity_I64);
10221 IRTemp start2 = newTemp(Ity_I64);
10222 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10223 cond = newTemp(Ity_I1);
10224 torun = newTemp(Ity_I64);
10225
10226 assign(torun, load(Ity_I64, mkexpr(addr2)));
10227 /* Start with a check that the saved code is still correct */
10228 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10229 /* If not, save the new value */
10230 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10231 mkIRExprVec_1(mkexpr(torun)));
10232 d->guard = mkexpr(cond);
10233 stmt(IRStmt_Dirty(d));
10234
10235 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010236 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10237 mkU64(guest_IA_curr_instr)));
10238 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010239 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010240
10241 ss.bytes = last_execute_target;
10242 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10243 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10244 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10245 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10246 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10247 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10248 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010249
sewardj2019a972011-03-07 16:04:07 +000010250 last_execute_target = 0;
10251}
10252
florian55085f82012-11-21 00:36:55 +000010253static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010254s390_irgen_EX(UChar r1, IRTemp addr2)
10255{
10256 switch(last_execute_target & 0xff00000000000000ULL) {
10257 case 0:
10258 {
10259 /* no code information yet */
10260 IRDirty *d;
10261
10262 /* so safe the code... */
10263 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10264 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10265 stmt(IRStmt_Dirty(d));
10266 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010267 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10268 mkU64(guest_IA_curr_instr)));
10269 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010270 restart_if(IRExpr_Const(IRConst_U1(True)));
10271
sewardj2019a972011-03-07 16:04:07 +000010272 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010273 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010274 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000010275 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000010276 break;
10277 }
10278
10279 case 0xd200000000000000ULL:
10280 /* special case MVC */
10281 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010282 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010283
10284 case 0xd500000000000000ULL:
10285 /* special case CLC */
10286 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010287 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010288
10289 case 0xd700000000000000ULL:
10290 /* special case XC */
10291 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010292 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010293
florianb0bf6602012-05-05 00:01:16 +000010294 case 0xd600000000000000ULL:
10295 /* special case OC */
10296 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010297 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010298
10299 case 0xd400000000000000ULL:
10300 /* special case NC */
10301 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010302 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010303
florianf87d4fb2012-05-05 02:55:24 +000010304 case 0xdc00000000000000ULL:
10305 /* special case TR */
10306 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010307 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010308
sewardj2019a972011-03-07 16:04:07 +000010309 default:
10310 {
10311 /* everything else will get a self checking prefix that also checks the
10312 register content */
10313 IRDirty *d;
10314 UChar *bytes;
10315 IRTemp cond;
10316 IRTemp orperand;
10317 IRTemp torun;
10318
10319 cond = newTemp(Ity_I1);
10320 orperand = newTemp(Ity_I64);
10321 torun = newTemp(Ity_I64);
10322
10323 if (r1 == 0)
10324 assign(orperand, mkU64(0));
10325 else
10326 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10327 /* This code is going to be translated */
10328 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10329 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10330
10331 /* Start with a check that saved code is still correct */
10332 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10333 mkU64(last_execute_target)));
10334 /* If not, save the new value */
10335 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10336 mkIRExprVec_1(mkexpr(torun)));
10337 d->guard = mkexpr(cond);
10338 stmt(IRStmt_Dirty(d));
10339
10340 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010341 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10342 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010343 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010344
10345 /* Now comes the actual translation */
10346 bytes = (UChar *) &last_execute_target;
10347 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10348 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010349 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010350 vex_printf(" which was executed by\n");
10351 /* dont make useless translations in the next execute */
10352 last_execute_target = 0;
10353 }
10354 }
10355 return "ex";
10356}
10357
florian55085f82012-11-21 00:36:55 +000010358static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010359s390_irgen_EXRL(UChar r1, UInt offset)
10360{
10361 IRTemp addr = newTemp(Ity_I64);
10362 /* we might save one round trip because we know the target */
10363 if (!last_execute_target)
10364 last_execute_target = *(ULong *)(HWord)
10365 (guest_IA_curr_instr + offset * 2UL);
10366 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10367 s390_irgen_EX(r1, addr);
10368 return "exrl";
10369}
10370
florian55085f82012-11-21 00:36:55 +000010371static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010372s390_irgen_IPM(UChar r1)
10373{
10374 // As long as we dont support SPM, lets just assume 0 as program mask
10375 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
10376 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
10377
10378 return "ipm";
10379}
10380
10381
florian55085f82012-11-21 00:36:55 +000010382static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010383s390_irgen_SRST(UChar r1, UChar r2)
10384{
10385 IRTemp address = newTemp(Ity_I64);
10386 IRTemp next = newTemp(Ity_I64);
10387 IRTemp delim = newTemp(Ity_I8);
10388 IRTemp counter = newTemp(Ity_I64);
10389 IRTemp byte = newTemp(Ity_I8);
10390
10391 assign(address, get_gpr_dw0(r2));
10392 assign(next, get_gpr_dw0(r1));
10393
10394 assign(counter, get_counter_dw0());
10395 put_counter_dw0(mkU64(0));
10396
10397 // start = next? CC=2 and out r1 and r2 unchanged
10398 s390_cc_set(2);
10399 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010400 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000010401
10402 assign(byte, load(Ity_I8, mkexpr(address)));
10403 assign(delim, get_gpr_b7(0));
10404
10405 // byte = delim? CC=1, R1=address
10406 s390_cc_set(1);
10407 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000010408 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010409
10410 // else: all equal, no end yet, loop
10411 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10412 put_gpr_dw0(r1, mkexpr(next));
10413 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010414
florian6820ba52012-07-26 02:01:50 +000010415 iterate();
sewardj2019a972011-03-07 16:04:07 +000010416
10417 return "srst";
10418}
10419
florian55085f82012-11-21 00:36:55 +000010420static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010421s390_irgen_CLST(UChar r1, UChar r2)
10422{
10423 IRTemp address1 = newTemp(Ity_I64);
10424 IRTemp address2 = newTemp(Ity_I64);
10425 IRTemp end = newTemp(Ity_I8);
10426 IRTemp counter = newTemp(Ity_I64);
10427 IRTemp byte1 = newTemp(Ity_I8);
10428 IRTemp byte2 = newTemp(Ity_I8);
10429
10430 assign(address1, get_gpr_dw0(r1));
10431 assign(address2, get_gpr_dw0(r2));
10432 assign(end, get_gpr_b7(0));
10433 assign(counter, get_counter_dw0());
10434 put_counter_dw0(mkU64(0));
10435 assign(byte1, load(Ity_I8, mkexpr(address1)));
10436 assign(byte2, load(Ity_I8, mkexpr(address2)));
10437
10438 // end in both? all equal, reset r1 and r2 to start values
10439 s390_cc_set(0);
10440 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
10441 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010442 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10443 binop(Iop_Or8,
10444 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10445 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010446
10447 put_gpr_dw0(r1, mkexpr(address1));
10448 put_gpr_dw0(r2, mkexpr(address2));
10449
10450 // End found in string1
10451 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010452 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010453
10454 // End found in string2
10455 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010456 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010457
10458 // string1 < string2
10459 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010460 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10461 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010462
10463 // string2 < string1
10464 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010465 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10466 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010467
10468 // else: all equal, no end yet, loop
10469 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10470 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10471 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010472
florian6820ba52012-07-26 02:01:50 +000010473 iterate();
sewardj2019a972011-03-07 16:04:07 +000010474
10475 return "clst";
10476}
10477
10478static void
10479s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10480{
10481 UChar reg;
10482 IRTemp addr = newTemp(Ity_I64);
10483
10484 assign(addr, mkexpr(op2addr));
10485 reg = r1;
10486 do {
10487 IRTemp old = addr;
10488
10489 reg %= 16;
10490 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10491 addr = newTemp(Ity_I64);
10492 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10493 reg++;
10494 } while (reg != (r3 + 1));
10495}
10496
florian55085f82012-11-21 00:36:55 +000010497static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010498s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10499{
10500 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10501
10502 return "lm";
10503}
10504
florian55085f82012-11-21 00:36:55 +000010505static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010506s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
10507{
10508 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10509
10510 return "lmy";
10511}
10512
florian55085f82012-11-21 00:36:55 +000010513static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010514s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
10515{
10516 UChar reg;
10517 IRTemp addr = newTemp(Ity_I64);
10518
10519 assign(addr, mkexpr(op2addr));
10520 reg = r1;
10521 do {
10522 IRTemp old = addr;
10523
10524 reg %= 16;
10525 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
10526 addr = newTemp(Ity_I64);
10527 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10528 reg++;
10529 } while (reg != (r3 + 1));
10530
10531 return "lmh";
10532}
10533
florian55085f82012-11-21 00:36:55 +000010534static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010535s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
10536{
10537 UChar reg;
10538 IRTemp addr = newTemp(Ity_I64);
10539
10540 assign(addr, mkexpr(op2addr));
10541 reg = r1;
10542 do {
10543 IRTemp old = addr;
10544
10545 reg %= 16;
10546 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
10547 addr = newTemp(Ity_I64);
10548 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10549 reg++;
10550 } while (reg != (r3 + 1));
10551
10552 return "lmg";
10553}
10554
10555static void
10556s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10557{
10558 UChar reg;
10559 IRTemp addr = newTemp(Ity_I64);
10560
10561 assign(addr, mkexpr(op2addr));
10562 reg = r1;
10563 do {
10564 IRTemp old = addr;
10565
10566 reg %= 16;
10567 store(mkexpr(addr), get_gpr_w1(reg));
10568 addr = newTemp(Ity_I64);
10569 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10570 reg++;
10571 } while( reg != (r3 + 1));
10572}
10573
florian55085f82012-11-21 00:36:55 +000010574static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010575s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
10576{
10577 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10578
10579 return "stm";
10580}
10581
florian55085f82012-11-21 00:36:55 +000010582static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010583s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
10584{
10585 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10586
10587 return "stmy";
10588}
10589
florian55085f82012-11-21 00:36:55 +000010590static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010591s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
10592{
10593 UChar reg;
10594 IRTemp addr = newTemp(Ity_I64);
10595
10596 assign(addr, mkexpr(op2addr));
10597 reg = r1;
10598 do {
10599 IRTemp old = addr;
10600
10601 reg %= 16;
10602 store(mkexpr(addr), get_gpr_w0(reg));
10603 addr = newTemp(Ity_I64);
10604 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10605 reg++;
10606 } while( reg != (r3 + 1));
10607
10608 return "stmh";
10609}
10610
florian55085f82012-11-21 00:36:55 +000010611static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010612s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
10613{
10614 UChar reg;
10615 IRTemp addr = newTemp(Ity_I64);
10616
10617 assign(addr, mkexpr(op2addr));
10618 reg = r1;
10619 do {
10620 IRTemp old = addr;
10621
10622 reg %= 16;
10623 store(mkexpr(addr), get_gpr_dw0(reg));
10624 addr = newTemp(Ity_I64);
10625 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10626 reg++;
10627 } while( reg != (r3 + 1));
10628
10629 return "stmg";
10630}
10631
10632static void
florianb0bf6602012-05-05 00:01:16 +000010633s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000010634{
10635 IRTemp old1 = newTemp(Ity_I8);
10636 IRTemp old2 = newTemp(Ity_I8);
10637 IRTemp new1 = newTemp(Ity_I8);
10638 IRTemp counter = newTemp(Ity_I32);
10639 IRTemp addr1 = newTemp(Ity_I64);
10640
10641 assign(counter, get_counter_w0());
10642
10643 assign(addr1, binop(Iop_Add64, mkexpr(start1),
10644 unop(Iop_32Uto64, mkexpr(counter))));
10645
10646 assign(old1, load(Ity_I8, mkexpr(addr1)));
10647 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10648 unop(Iop_32Uto64,mkexpr(counter)))));
10649 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
10650
10651 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000010652 if (op == Iop_Xor8) {
10653 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000010654 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
10655 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000010656 } else
10657 store(mkexpr(addr1), mkexpr(new1));
10658 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
10659 get_counter_w1()));
10660
10661 /* Check for end of field */
10662 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010663 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010664 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
10665 False);
10666 put_counter_dw0(mkU64(0));
10667}
10668
florian55085f82012-11-21 00:36:55 +000010669static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010670s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
10671{
florianb0bf6602012-05-05 00:01:16 +000010672 IRTemp len = newTemp(Ity_I32);
10673
10674 assign(len, mkU32(length));
10675 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010676
10677 return "xc";
10678}
10679
sewardjb63967e2011-03-24 08:50:04 +000010680static void
10681s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
10682{
10683 IRTemp counter = newTemp(Ity_I32);
10684 IRTemp start = newTemp(Ity_I64);
10685 IRTemp addr = newTemp(Ity_I64);
10686
10687 assign(start,
10688 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
10689
10690 if (length < 8) {
10691 UInt i;
10692
10693 for (i = 0; i <= length; ++i) {
10694 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
10695 }
10696 } else {
10697 assign(counter, get_counter_w0());
10698
10699 assign(addr, binop(Iop_Add64, mkexpr(start),
10700 unop(Iop_32Uto64, mkexpr(counter))));
10701
10702 store(mkexpr(addr), mkU8(0));
10703
10704 /* Check for end of field */
10705 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010706 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000010707
10708 /* Reset counter */
10709 put_counter_dw0(mkU64(0));
10710 }
10711
10712 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
10713
sewardj7ee97522011-05-09 21:45:04 +000010714 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000010715 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
10716}
10717
florian55085f82012-11-21 00:36:55 +000010718static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010719s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
10720{
florianb0bf6602012-05-05 00:01:16 +000010721 IRTemp len = newTemp(Ity_I32);
10722
10723 assign(len, mkU32(length));
10724 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010725
10726 return "nc";
10727}
10728
florian55085f82012-11-21 00:36:55 +000010729static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010730s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
10731{
florianb0bf6602012-05-05 00:01:16 +000010732 IRTemp len = newTemp(Ity_I32);
10733
10734 assign(len, mkU32(length));
10735 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010736
10737 return "oc";
10738}
10739
10740
florian55085f82012-11-21 00:36:55 +000010741static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010742s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
10743{
florian79e839e2012-05-05 02:20:30 +000010744 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010745
florian79e839e2012-05-05 02:20:30 +000010746 assign(len, mkU64(length));
10747 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010748
10749 return "mvc";
10750}
10751
florian55085f82012-11-21 00:36:55 +000010752static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010753s390_irgen_MVCL(UChar r1, UChar r2)
10754{
10755 IRTemp addr1 = newTemp(Ity_I64);
10756 IRTemp addr2 = newTemp(Ity_I64);
10757 IRTemp addr2_load = newTemp(Ity_I64);
10758 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10759 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10760 IRTemp len1 = newTemp(Ity_I32);
10761 IRTemp len2 = newTemp(Ity_I32);
10762 IRTemp pad = newTemp(Ity_I8);
10763 IRTemp single = newTemp(Ity_I8);
10764
10765 assign(addr1, get_gpr_dw0(r1));
10766 assign(r1p1, get_gpr_w1(r1 + 1));
10767 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10768 assign(addr2, get_gpr_dw0(r2));
10769 assign(r2p1, get_gpr_w1(r2 + 1));
10770 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10771 assign(pad, get_gpr_b4(r2 + 1));
10772
10773 /* len1 == 0 ? */
10774 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010775 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010776
10777 /* Check for destructive overlap:
10778 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
10779 s390_cc_set(3);
10780 IRTemp cond1 = newTemp(Ity_I32);
10781 assign(cond1, unop(Iop_1Uto32,
10782 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
10783 IRTemp cond2 = newTemp(Ity_I32);
10784 assign(cond2, unop(Iop_1Uto32,
10785 binop(Iop_CmpLT64U, mkexpr(addr1),
10786 binop(Iop_Add64, mkexpr(addr2),
10787 unop(Iop_32Uto64, mkexpr(len1))))));
10788 IRTemp cond3 = newTemp(Ity_I32);
10789 assign(cond3, unop(Iop_1Uto32,
10790 binop(Iop_CmpLT64U,
10791 mkexpr(addr1),
10792 binop(Iop_Add64, mkexpr(addr2),
10793 unop(Iop_32Uto64, mkexpr(len2))))));
10794
florian6820ba52012-07-26 02:01:50 +000010795 next_insn_if(binop(Iop_CmpEQ32,
10796 binop(Iop_And32,
10797 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
10798 mkexpr(cond3)),
10799 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010800
10801 /* See s390_irgen_CLCL for explanation why we cannot load directly
10802 and need two steps. */
10803 assign(addr2_load,
10804 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10805 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10806 assign(single,
10807 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10808 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10809
10810 store(mkexpr(addr1), mkexpr(single));
10811
10812 /* Update addr1 and len1 */
10813 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10814 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
10815
10816 /* Update addr2 and len2 */
10817 put_gpr_dw0(r2,
10818 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10819 mkexpr(addr2),
10820 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10821
10822 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10823 put_gpr_w1(r2 + 1,
10824 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10825 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10826 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10827
10828 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000010829 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000010830
10831 return "mvcl";
10832}
10833
10834
florian55085f82012-11-21 00:36:55 +000010835static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010836s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
10837{
10838 IRTemp addr1, addr3, addr3_load, len1, len3, single;
10839
10840 addr1 = newTemp(Ity_I64);
10841 addr3 = newTemp(Ity_I64);
10842 addr3_load = newTemp(Ity_I64);
10843 len1 = newTemp(Ity_I64);
10844 len3 = newTemp(Ity_I64);
10845 single = newTemp(Ity_I8);
10846
10847 assign(addr1, get_gpr_dw0(r1));
10848 assign(len1, get_gpr_dw0(r1 + 1));
10849 assign(addr3, get_gpr_dw0(r3));
10850 assign(len3, get_gpr_dw0(r3 + 1));
10851
10852 // len1 == 0 ?
10853 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010854 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010855
10856 /* This is a hack to prevent mvcle from reading from addr3 if it
10857 should read from the pad. Since the pad has no address, just
10858 read from the instruction, we discard that anyway */
10859 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010860 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10861 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010862
10863 assign(single,
florian6ad49522011-09-09 02:38:55 +000010864 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10865 unop(Iop_64to8, mkexpr(pad2)),
10866 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010867 store(mkexpr(addr1), mkexpr(single));
10868
10869 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
10870
10871 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
10872
10873 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010874 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10875 mkexpr(addr3),
10876 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010877
10878 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010879 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10880 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010881
sewardj2019a972011-03-07 16:04:07 +000010882 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000010883 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000010884
10885 return "mvcle";
10886}
10887
florian55085f82012-11-21 00:36:55 +000010888static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010889s390_irgen_MVST(UChar r1, UChar r2)
10890{
10891 IRTemp addr1 = newTemp(Ity_I64);
10892 IRTemp addr2 = newTemp(Ity_I64);
10893 IRTemp end = newTemp(Ity_I8);
10894 IRTemp byte = newTemp(Ity_I8);
10895 IRTemp counter = newTemp(Ity_I64);
10896
10897 assign(addr1, get_gpr_dw0(r1));
10898 assign(addr2, get_gpr_dw0(r2));
10899 assign(counter, get_counter_dw0());
10900 assign(end, get_gpr_b7(0));
10901 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
10902 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
10903
10904 // We use unlimited as cpu-determined number
10905 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010906 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010907
10908 // and always set cc=1 at the end + update r1
10909 s390_cc_set(1);
10910 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
10911 put_counter_dw0(mkU64(0));
10912
10913 return "mvst";
10914}
10915
10916static void
10917s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
10918{
10919 IRTemp op1 = newTemp(Ity_I64);
10920 IRTemp result = newTemp(Ity_I64);
10921
10922 assign(op1, binop(Iop_32HLto64,
10923 get_gpr_w1(r1), // high 32 bits
10924 get_gpr_w1(r1 + 1))); // low 32 bits
10925 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10926 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
10927 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
10928}
10929
10930static void
10931s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
10932{
10933 IRTemp op1 = newTemp(Ity_I128);
10934 IRTemp result = newTemp(Ity_I128);
10935
10936 assign(op1, binop(Iop_64HLto128,
10937 get_gpr_dw0(r1), // high 64 bits
10938 get_gpr_dw0(r1 + 1))); // low 64 bits
10939 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10940 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10941 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10942}
10943
10944static void
10945s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
10946{
10947 IRTemp op1 = newTemp(Ity_I64);
10948 IRTemp result = newTemp(Ity_I128);
10949
10950 assign(op1, get_gpr_dw0(r1 + 1));
10951 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
10952 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
10953 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
10954}
10955
florian55085f82012-11-21 00:36:55 +000010956static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010957s390_irgen_DR(UChar r1, UChar r2)
10958{
10959 IRTemp op2 = newTemp(Ity_I32);
10960
10961 assign(op2, get_gpr_w1(r2));
10962
10963 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10964
10965 return "dr";
10966}
10967
florian55085f82012-11-21 00:36:55 +000010968static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010969s390_irgen_D(UChar r1, IRTemp op2addr)
10970{
10971 IRTemp op2 = newTemp(Ity_I32);
10972
10973 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10974
10975 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
10976
10977 return "d";
10978}
10979
florian55085f82012-11-21 00:36:55 +000010980static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010981s390_irgen_DLR(UChar r1, UChar r2)
10982{
10983 IRTemp op2 = newTemp(Ity_I32);
10984
10985 assign(op2, get_gpr_w1(r2));
10986
10987 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
10988
florian7cd1cde2012-08-16 23:57:43 +000010989 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000010990}
10991
florian55085f82012-11-21 00:36:55 +000010992static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010993s390_irgen_DL(UChar r1, IRTemp op2addr)
10994{
10995 IRTemp op2 = newTemp(Ity_I32);
10996
10997 assign(op2, load(Ity_I32, mkexpr(op2addr)));
10998
10999 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11000
11001 return "dl";
11002}
11003
florian55085f82012-11-21 00:36:55 +000011004static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011005s390_irgen_DLG(UChar r1, IRTemp op2addr)
11006{
11007 IRTemp op2 = newTemp(Ity_I64);
11008
11009 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11010
11011 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11012
11013 return "dlg";
11014}
11015
florian55085f82012-11-21 00:36:55 +000011016static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011017s390_irgen_DLGR(UChar r1, UChar r2)
11018{
11019 IRTemp op2 = newTemp(Ity_I64);
11020
11021 assign(op2, get_gpr_dw0(r2));
11022
11023 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11024
11025 return "dlgr";
11026}
11027
florian55085f82012-11-21 00:36:55 +000011028static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011029s390_irgen_DSGR(UChar r1, UChar r2)
11030{
11031 IRTemp op2 = newTemp(Ity_I64);
11032
11033 assign(op2, get_gpr_dw0(r2));
11034
11035 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11036
11037 return "dsgr";
11038}
11039
florian55085f82012-11-21 00:36:55 +000011040static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011041s390_irgen_DSG(UChar r1, IRTemp op2addr)
11042{
11043 IRTemp op2 = newTemp(Ity_I64);
11044
11045 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11046
11047 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11048
11049 return "dsg";
11050}
11051
florian55085f82012-11-21 00:36:55 +000011052static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011053s390_irgen_DSGFR(UChar r1, UChar r2)
11054{
11055 IRTemp op2 = newTemp(Ity_I64);
11056
11057 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11058
11059 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11060
11061 return "dsgfr";
11062}
11063
florian55085f82012-11-21 00:36:55 +000011064static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011065s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11066{
11067 IRTemp op2 = newTemp(Ity_I64);
11068
11069 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11070
11071 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11072
11073 return "dsgf";
11074}
11075
11076static void
11077s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11078{
11079 UChar reg;
11080 IRTemp addr = newTemp(Ity_I64);
11081
11082 assign(addr, mkexpr(op2addr));
11083 reg = r1;
11084 do {
11085 IRTemp old = addr;
11086
11087 reg %= 16;
11088 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11089 addr = newTemp(Ity_I64);
11090 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11091 reg++;
11092 } while (reg != (r3 + 1));
11093}
11094
florian55085f82012-11-21 00:36:55 +000011095static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011096s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11097{
11098 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11099
11100 return "lam";
11101}
11102
florian55085f82012-11-21 00:36:55 +000011103static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011104s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11105{
11106 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11107
11108 return "lamy";
11109}
11110
11111static void
11112s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11113{
11114 UChar reg;
11115 IRTemp addr = newTemp(Ity_I64);
11116
11117 assign(addr, mkexpr(op2addr));
11118 reg = r1;
11119 do {
11120 IRTemp old = addr;
11121
11122 reg %= 16;
11123 store(mkexpr(addr), get_ar_w0(reg));
11124 addr = newTemp(Ity_I64);
11125 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11126 reg++;
11127 } while (reg != (r3 + 1));
11128}
11129
florian55085f82012-11-21 00:36:55 +000011130static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011131s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11132{
11133 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11134
11135 return "stam";
11136}
11137
florian55085f82012-11-21 00:36:55 +000011138static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011139s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11140{
11141 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11142
11143 return "stamy";
11144}
11145
11146
11147/* Implementation for 32-bit compare-and-swap */
11148static void
11149s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11150{
11151 IRCAS *cas;
11152 IRTemp op1 = newTemp(Ity_I32);
11153 IRTemp old_mem = newTemp(Ity_I32);
11154 IRTemp op3 = newTemp(Ity_I32);
11155 IRTemp result = newTemp(Ity_I32);
11156 IRTemp nequal = newTemp(Ity_I1);
11157
11158 assign(op1, get_gpr_w1(r1));
11159 assign(op3, get_gpr_w1(r3));
11160
11161 /* The first and second operands are compared. If they are equal,
11162 the third operand is stored at the second- operand location. */
11163 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11164 Iend_BE, mkexpr(op2addr),
11165 NULL, mkexpr(op1), /* expected value */
11166 NULL, mkexpr(op3) /* new value */);
11167 stmt(IRStmt_CAS(cas));
11168
11169 /* Set CC. Operands compared equal -> 0, else 1. */
11170 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11171 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11172
11173 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11174 Otherwise, store the old_value from memory in r1 and yield. */
11175 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11176 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011177 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011178}
11179
florian55085f82012-11-21 00:36:55 +000011180static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011181s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11182{
11183 s390_irgen_cas_32(r1, r3, op2addr);
11184
11185 return "cs";
11186}
11187
florian55085f82012-11-21 00:36:55 +000011188static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011189s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11190{
11191 s390_irgen_cas_32(r1, r3, op2addr);
11192
11193 return "csy";
11194}
11195
florian55085f82012-11-21 00:36:55 +000011196static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011197s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11198{
11199 IRCAS *cas;
11200 IRTemp op1 = newTemp(Ity_I64);
11201 IRTemp old_mem = newTemp(Ity_I64);
11202 IRTemp op3 = newTemp(Ity_I64);
11203 IRTemp result = newTemp(Ity_I64);
11204 IRTemp nequal = newTemp(Ity_I1);
11205
11206 assign(op1, get_gpr_dw0(r1));
11207 assign(op3, get_gpr_dw0(r3));
11208
11209 /* The first and second operands are compared. If they are equal,
11210 the third operand is stored at the second- operand location. */
11211 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11212 Iend_BE, mkexpr(op2addr),
11213 NULL, mkexpr(op1), /* expected value */
11214 NULL, mkexpr(op3) /* new value */);
11215 stmt(IRStmt_CAS(cas));
11216
11217 /* Set CC. Operands compared equal -> 0, else 1. */
11218 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11219 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11220
11221 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11222 Otherwise, store the old_value from memory in r1 and yield. */
11223 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11224 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011225 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011226
11227 return "csg";
11228}
11229
florian448cbba2012-06-06 02:26:01 +000011230/* Implementation for 32-bit compare-double-and-swap */
11231static void
11232s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11233{
11234 IRCAS *cas;
11235 IRTemp op1_high = newTemp(Ity_I32);
11236 IRTemp op1_low = newTemp(Ity_I32);
11237 IRTemp old_mem_high = newTemp(Ity_I32);
11238 IRTemp old_mem_low = newTemp(Ity_I32);
11239 IRTemp op3_high = newTemp(Ity_I32);
11240 IRTemp op3_low = newTemp(Ity_I32);
11241 IRTemp result = newTemp(Ity_I32);
11242 IRTemp nequal = newTemp(Ity_I1);
11243
11244 assign(op1_high, get_gpr_w1(r1));
11245 assign(op1_low, get_gpr_w1(r1+1));
11246 assign(op3_high, get_gpr_w1(r3));
11247 assign(op3_low, get_gpr_w1(r3+1));
11248
11249 /* The first and second operands are compared. If they are equal,
11250 the third operand is stored at the second-operand location. */
11251 cas = mkIRCAS(old_mem_high, old_mem_low,
11252 Iend_BE, mkexpr(op2addr),
11253 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11254 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11255 stmt(IRStmt_CAS(cas));
11256
11257 /* Set CC. Operands compared equal -> 0, else 1. */
11258 assign(result, unop(Iop_1Uto32,
11259 binop(Iop_CmpNE32,
11260 binop(Iop_Or32,
11261 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11262 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11263 mkU32(0))));
11264
11265 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11266
11267 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11268 Otherwise, store the old_value from memory in r1 and yield. */
11269 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11270 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11271 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011272 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011273}
11274
florian55085f82012-11-21 00:36:55 +000011275static const HChar *
florian448cbba2012-06-06 02:26:01 +000011276s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11277{
11278 s390_irgen_cdas_32(r1, r3, op2addr);
11279
11280 return "cds";
11281}
11282
florian55085f82012-11-21 00:36:55 +000011283static const HChar *
florian448cbba2012-06-06 02:26:01 +000011284s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11285{
11286 s390_irgen_cdas_32(r1, r3, op2addr);
11287
11288 return "cdsy";
11289}
11290
florian55085f82012-11-21 00:36:55 +000011291static const HChar *
florian448cbba2012-06-06 02:26:01 +000011292s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11293{
11294 IRCAS *cas;
11295 IRTemp op1_high = newTemp(Ity_I64);
11296 IRTemp op1_low = newTemp(Ity_I64);
11297 IRTemp old_mem_high = newTemp(Ity_I64);
11298 IRTemp old_mem_low = newTemp(Ity_I64);
11299 IRTemp op3_high = newTemp(Ity_I64);
11300 IRTemp op3_low = newTemp(Ity_I64);
11301 IRTemp result = newTemp(Ity_I64);
11302 IRTemp nequal = newTemp(Ity_I1);
11303
11304 assign(op1_high, get_gpr_dw0(r1));
11305 assign(op1_low, get_gpr_dw0(r1+1));
11306 assign(op3_high, get_gpr_dw0(r3));
11307 assign(op3_low, get_gpr_dw0(r3+1));
11308
11309 /* The first and second operands are compared. If they are equal,
11310 the third operand is stored at the second-operand location. */
11311 cas = mkIRCAS(old_mem_high, old_mem_low,
11312 Iend_BE, mkexpr(op2addr),
11313 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11314 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11315 stmt(IRStmt_CAS(cas));
11316
11317 /* Set CC. Operands compared equal -> 0, else 1. */
11318 assign(result, unop(Iop_1Uto64,
11319 binop(Iop_CmpNE64,
11320 binop(Iop_Or64,
11321 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11322 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11323 mkU64(0))));
11324
11325 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11326
11327 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11328 Otherwise, store the old_value from memory in r1 and yield. */
11329 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11330 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11331 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011332 yield_if(mkexpr(nequal));
11333
florian448cbba2012-06-06 02:26:01 +000011334 return "cdsg";
11335}
11336
sewardj2019a972011-03-07 16:04:07 +000011337
11338/* Binary floating point */
11339
florian55085f82012-11-21 00:36:55 +000011340static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011341s390_irgen_AXBR(UChar r1, UChar r2)
11342{
11343 IRTemp op1 = newTemp(Ity_F128);
11344 IRTemp op2 = newTemp(Ity_F128);
11345 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011346 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011347
11348 assign(op1, get_fpr_pair(r1));
11349 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011350 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011351 mkexpr(op2)));
11352 put_fpr_pair(r1, mkexpr(result));
11353
11354 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11355
11356 return "axbr";
11357}
11358
florian55085f82012-11-21 00:36:55 +000011359static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011360s390_irgen_CEBR(UChar r1, UChar r2)
11361{
11362 IRTemp op1 = newTemp(Ity_F32);
11363 IRTemp op2 = newTemp(Ity_F32);
11364 IRTemp cc_vex = newTemp(Ity_I32);
11365 IRTemp cc_s390 = newTemp(Ity_I32);
11366
11367 assign(op1, get_fpr_w0(r1));
11368 assign(op2, get_fpr_w0(r2));
11369 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11370
florian2d3d87f2012-12-21 21:05:17 +000011371 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011372 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11373
11374 return "cebr";
11375}
11376
florian55085f82012-11-21 00:36:55 +000011377static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011378s390_irgen_CDBR(UChar r1, UChar r2)
11379{
11380 IRTemp op1 = newTemp(Ity_F64);
11381 IRTemp op2 = newTemp(Ity_F64);
11382 IRTemp cc_vex = newTemp(Ity_I32);
11383 IRTemp cc_s390 = newTemp(Ity_I32);
11384
11385 assign(op1, get_fpr_dw0(r1));
11386 assign(op2, get_fpr_dw0(r2));
11387 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11388
florian2d3d87f2012-12-21 21:05:17 +000011389 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011390 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11391
11392 return "cdbr";
11393}
11394
florian55085f82012-11-21 00:36:55 +000011395static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011396s390_irgen_CXBR(UChar r1, UChar r2)
11397{
11398 IRTemp op1 = newTemp(Ity_F128);
11399 IRTemp op2 = newTemp(Ity_F128);
11400 IRTemp cc_vex = newTemp(Ity_I32);
11401 IRTemp cc_s390 = newTemp(Ity_I32);
11402
11403 assign(op1, get_fpr_pair(r1));
11404 assign(op2, get_fpr_pair(r2));
11405 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
11406
florian2d3d87f2012-12-21 21:05:17 +000011407 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011408 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11409
11410 return "cxbr";
11411}
11412
florian55085f82012-11-21 00:36:55 +000011413static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011414s390_irgen_CEB(UChar r1, IRTemp op2addr)
11415{
11416 IRTemp op1 = newTemp(Ity_F32);
11417 IRTemp op2 = newTemp(Ity_F32);
11418 IRTemp cc_vex = newTemp(Ity_I32);
11419 IRTemp cc_s390 = newTemp(Ity_I32);
11420
11421 assign(op1, get_fpr_w0(r1));
11422 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11423 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11424
florian2d3d87f2012-12-21 21:05:17 +000011425 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011426 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11427
11428 return "ceb";
11429}
11430
florian55085f82012-11-21 00:36:55 +000011431static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011432s390_irgen_CDB(UChar r1, IRTemp op2addr)
11433{
11434 IRTemp op1 = newTemp(Ity_F64);
11435 IRTemp op2 = newTemp(Ity_F64);
11436 IRTemp cc_vex = newTemp(Ity_I32);
11437 IRTemp cc_s390 = newTemp(Ity_I32);
11438
11439 assign(op1, get_fpr_dw0(r1));
11440 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11441 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11442
florian2d3d87f2012-12-21 21:05:17 +000011443 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011444 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11445
11446 return "cdb";
11447}
11448
florian55085f82012-11-21 00:36:55 +000011449static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011450s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11451 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011452{
11453 IRTemp op2 = newTemp(Ity_I32);
11454
11455 assign(op2, get_gpr_w1(r2));
11456 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11457
11458 return "cxfbr";
11459}
11460
florian55085f82012-11-21 00:36:55 +000011461static const HChar *
floriand2129202012-09-01 20:01:39 +000011462s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11463 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011464{
floriane75dafa2012-09-01 17:54:09 +000011465 if (! s390_host_has_fpext) {
11466 emulation_failure(EmFail_S390X_fpext);
11467 } else {
11468 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011469
floriane75dafa2012-09-01 17:54:09 +000011470 assign(op2, get_gpr_w1(r2));
11471 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11472 }
florian1c8f7ff2012-09-01 00:12:11 +000011473 return "cxlfbr";
11474}
11475
11476
florian55085f82012-11-21 00:36:55 +000011477static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011478s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11479 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011480{
11481 IRTemp op2 = newTemp(Ity_I64);
11482
11483 assign(op2, get_gpr_dw0(r2));
11484 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11485
11486 return "cxgbr";
11487}
11488
florian55085f82012-11-21 00:36:55 +000011489static const HChar *
floriand2129202012-09-01 20:01:39 +000011490s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11491 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011492{
floriane75dafa2012-09-01 17:54:09 +000011493 if (! s390_host_has_fpext) {
11494 emulation_failure(EmFail_S390X_fpext);
11495 } else {
11496 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011497
floriane75dafa2012-09-01 17:54:09 +000011498 assign(op2, get_gpr_dw0(r2));
11499 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11500 }
florian1c8f7ff2012-09-01 00:12:11 +000011501 return "cxlgbr";
11502}
11503
florian55085f82012-11-21 00:36:55 +000011504static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011505s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11506 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011507{
11508 IRTemp op = newTemp(Ity_F128);
11509 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011510 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011511
11512 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011513 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011514 mkexpr(op)));
11515 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011516 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011517
11518 return "cfxbr";
11519}
11520
florian55085f82012-11-21 00:36:55 +000011521static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011522s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
11523 UChar r1, UChar r2)
11524{
floriane75dafa2012-09-01 17:54:09 +000011525 if (! s390_host_has_fpext) {
11526 emulation_failure(EmFail_S390X_fpext);
11527 } else {
11528 IRTemp op = newTemp(Ity_F128);
11529 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011530 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011531
floriane75dafa2012-09-01 17:54:09 +000011532 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011533 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011534 mkexpr(op)));
11535 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011536 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011537 }
florian1c8f7ff2012-09-01 00:12:11 +000011538 return "clfxbr";
11539}
11540
11541
florian55085f82012-11-21 00:36:55 +000011542static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011543s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
11544 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011545{
11546 IRTemp op = newTemp(Ity_F128);
11547 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011548 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011549
11550 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011551 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011552 mkexpr(op)));
11553 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011554 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011555
11556 return "cgxbr";
11557}
11558
florian55085f82012-11-21 00:36:55 +000011559static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011560s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
11561 UChar r1, UChar r2)
11562{
floriane75dafa2012-09-01 17:54:09 +000011563 if (! s390_host_has_fpext) {
11564 emulation_failure(EmFail_S390X_fpext);
11565 } else {
11566 IRTemp op = newTemp(Ity_F128);
11567 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011568 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011569
floriane75dafa2012-09-01 17:54:09 +000011570 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011571 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011572 mkexpr(op)));
11573 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011574 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
11575 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011576 }
florian1c8f7ff2012-09-01 00:12:11 +000011577 return "clgxbr";
11578}
11579
florian55085f82012-11-21 00:36:55 +000011580static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011581s390_irgen_DXBR(UChar r1, UChar r2)
11582{
11583 IRTemp op1 = newTemp(Ity_F128);
11584 IRTemp op2 = newTemp(Ity_F128);
11585 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011586 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011587
11588 assign(op1, get_fpr_pair(r1));
11589 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011590 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011591 mkexpr(op2)));
11592 put_fpr_pair(r1, mkexpr(result));
11593
11594 return "dxbr";
11595}
11596
florian55085f82012-11-21 00:36:55 +000011597static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011598s390_irgen_LTXBR(UChar r1, UChar r2)
11599{
11600 IRTemp result = newTemp(Ity_F128);
11601
11602 assign(result, get_fpr_pair(r2));
11603 put_fpr_pair(r1, mkexpr(result));
11604 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11605
11606 return "ltxbr";
11607}
11608
florian55085f82012-11-21 00:36:55 +000011609static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011610s390_irgen_LCXBR(UChar r1, UChar r2)
11611{
11612 IRTemp result = newTemp(Ity_F128);
11613
11614 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
11615 put_fpr_pair(r1, mkexpr(result));
11616 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11617
11618 return "lcxbr";
11619}
11620
florian55085f82012-11-21 00:36:55 +000011621static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011622s390_irgen_LXDBR(UChar r1, UChar r2)
11623{
11624 IRTemp op = newTemp(Ity_F64);
11625
11626 assign(op, get_fpr_dw0(r2));
11627 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11628
11629 return "lxdbr";
11630}
11631
florian55085f82012-11-21 00:36:55 +000011632static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011633s390_irgen_LXEBR(UChar r1, UChar r2)
11634{
11635 IRTemp op = newTemp(Ity_F32);
11636
11637 assign(op, get_fpr_w0(r2));
11638 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11639
11640 return "lxebr";
11641}
11642
florian55085f82012-11-21 00:36:55 +000011643static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011644s390_irgen_LXDB(UChar r1, IRTemp op2addr)
11645{
11646 IRTemp op = newTemp(Ity_F64);
11647
11648 assign(op, load(Ity_F64, mkexpr(op2addr)));
11649 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11650
11651 return "lxdb";
11652}
11653
florian55085f82012-11-21 00:36:55 +000011654static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011655s390_irgen_LXEB(UChar r1, IRTemp op2addr)
11656{
11657 IRTemp op = newTemp(Ity_F32);
11658
11659 assign(op, load(Ity_F32, mkexpr(op2addr)));
11660 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11661
11662 return "lxeb";
11663}
11664
florian55085f82012-11-21 00:36:55 +000011665static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011666s390_irgen_LNEBR(UChar r1, UChar r2)
11667{
11668 IRTemp result = newTemp(Ity_F32);
11669
11670 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
11671 put_fpr_w0(r1, mkexpr(result));
11672 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11673
11674 return "lnebr";
11675}
11676
florian55085f82012-11-21 00:36:55 +000011677static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011678s390_irgen_LNDBR(UChar r1, UChar r2)
11679{
11680 IRTemp result = newTemp(Ity_F64);
11681
11682 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11683 put_fpr_dw0(r1, mkexpr(result));
11684 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11685
11686 return "lndbr";
11687}
11688
florian55085f82012-11-21 00:36:55 +000011689static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011690s390_irgen_LNXBR(UChar r1, UChar r2)
11691{
11692 IRTemp result = newTemp(Ity_F128);
11693
11694 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
11695 put_fpr_pair(r1, mkexpr(result));
11696 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11697
11698 return "lnxbr";
11699}
11700
florian55085f82012-11-21 00:36:55 +000011701static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011702s390_irgen_LPEBR(UChar r1, UChar r2)
11703{
11704 IRTemp result = newTemp(Ity_F32);
11705
11706 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
11707 put_fpr_w0(r1, mkexpr(result));
11708 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11709
11710 return "lpebr";
11711}
11712
florian55085f82012-11-21 00:36:55 +000011713static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011714s390_irgen_LPDBR(UChar r1, UChar r2)
11715{
11716 IRTemp result = newTemp(Ity_F64);
11717
11718 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
11719 put_fpr_dw0(r1, mkexpr(result));
11720 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
11721
11722 return "lpdbr";
11723}
11724
florian55085f82012-11-21 00:36:55 +000011725static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011726s390_irgen_LPXBR(UChar r1, UChar r2)
11727{
11728 IRTemp result = newTemp(Ity_F128);
11729
11730 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
11731 put_fpr_pair(r1, mkexpr(result));
11732 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11733
11734 return "lpxbr";
11735}
11736
florian55085f82012-11-21 00:36:55 +000011737static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011738s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
11739 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011740{
florian125e20d2012-10-07 15:42:37 +000011741 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011742 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011743 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011744 }
sewardj2019a972011-03-07 16:04:07 +000011745 IRTemp result = newTemp(Ity_F64);
11746
floriandb4fcaa2012-09-05 19:54:08 +000011747 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011748 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011749 put_fpr_dw0(r1, mkexpr(result));
11750
11751 return "ldxbr";
11752}
11753
florian55085f82012-11-21 00:36:55 +000011754static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011755s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
11756 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011757{
florian125e20d2012-10-07 15:42:37 +000011758 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000011759 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000011760 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000011761 }
sewardj2019a972011-03-07 16:04:07 +000011762 IRTemp result = newTemp(Ity_F32);
11763
floriandb4fcaa2012-09-05 19:54:08 +000011764 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000011765 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011766 put_fpr_w0(r1, mkexpr(result));
11767
11768 return "lexbr";
11769}
11770
florian55085f82012-11-21 00:36:55 +000011771static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011772s390_irgen_MXBR(UChar r1, UChar r2)
11773{
11774 IRTemp op1 = newTemp(Ity_F128);
11775 IRTemp op2 = newTemp(Ity_F128);
11776 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011777 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011778
11779 assign(op1, get_fpr_pair(r1));
11780 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011781 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011782 mkexpr(op2)));
11783 put_fpr_pair(r1, mkexpr(result));
11784
11785 return "mxbr";
11786}
11787
florian55085f82012-11-21 00:36:55 +000011788static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011789s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
11790{
florian125e20d2012-10-07 15:42:37 +000011791 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011792
floriandb4fcaa2012-09-05 19:54:08 +000011793 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011794 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011795
11796 return "maebr";
11797}
11798
florian55085f82012-11-21 00:36:55 +000011799static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011800s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
11801{
florian125e20d2012-10-07 15:42:37 +000011802 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011803
floriandb4fcaa2012-09-05 19:54:08 +000011804 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011805 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011806
11807 return "madbr";
11808}
11809
florian55085f82012-11-21 00:36:55 +000011810static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011811s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
11812{
11813 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011814 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011815
floriandb4fcaa2012-09-05 19:54:08 +000011816 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011817 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011818
11819 return "maeb";
11820}
11821
florian55085f82012-11-21 00:36:55 +000011822static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011823s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
11824{
11825 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011826 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011827
floriandb4fcaa2012-09-05 19:54:08 +000011828 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011829 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011830
11831 return "madb";
11832}
11833
florian55085f82012-11-21 00:36:55 +000011834static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011835s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
11836{
florian125e20d2012-10-07 15:42:37 +000011837 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011838
floriandb4fcaa2012-09-05 19:54:08 +000011839 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011840 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011841
11842 return "msebr";
11843}
11844
florian55085f82012-11-21 00:36:55 +000011845static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011846s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
11847{
florian125e20d2012-10-07 15:42:37 +000011848 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000011849
floriandb4fcaa2012-09-05 19:54:08 +000011850 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011851 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011852
11853 return "msdbr";
11854}
11855
florian55085f82012-11-21 00:36:55 +000011856static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011857s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
11858{
11859 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011860 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011861
floriandb4fcaa2012-09-05 19:54:08 +000011862 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011863 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011864
11865 return "mseb";
11866}
11867
florian55085f82012-11-21 00:36:55 +000011868static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011869s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
11870{
11871 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000011872 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011873
floriandb4fcaa2012-09-05 19:54:08 +000011874 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000011875 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000011876
11877 return "msdb";
11878}
11879
florian55085f82012-11-21 00:36:55 +000011880static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011881s390_irgen_SQEBR(UChar r1, UChar r2)
11882{
11883 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011884 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011885
floriandb4fcaa2012-09-05 19:54:08 +000011886 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011887 put_fpr_w0(r1, mkexpr(result));
11888
11889 return "sqebr";
11890}
11891
florian55085f82012-11-21 00:36:55 +000011892static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011893s390_irgen_SQDBR(UChar r1, UChar r2)
11894{
11895 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011896 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011897
floriandb4fcaa2012-09-05 19:54:08 +000011898 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000011899 put_fpr_dw0(r1, mkexpr(result));
11900
11901 return "sqdbr";
11902}
11903
florian55085f82012-11-21 00:36:55 +000011904static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011905s390_irgen_SQXBR(UChar r1, UChar r2)
11906{
11907 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011908 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011909
floriandb4fcaa2012-09-05 19:54:08 +000011910 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
11911 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000011912 put_fpr_pair(r1, mkexpr(result));
11913
11914 return "sqxbr";
11915}
11916
florian55085f82012-11-21 00:36:55 +000011917static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011918s390_irgen_SQEB(UChar r1, IRTemp op2addr)
11919{
11920 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000011921 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011922
11923 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011924 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011925
11926 return "sqeb";
11927}
11928
florian55085f82012-11-21 00:36:55 +000011929static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011930s390_irgen_SQDB(UChar r1, IRTemp op2addr)
11931{
11932 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000011933 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011934
11935 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000011936 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000011937
11938 return "sqdb";
11939}
11940
florian55085f82012-11-21 00:36:55 +000011941static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011942s390_irgen_SXBR(UChar r1, UChar r2)
11943{
11944 IRTemp op1 = newTemp(Ity_F128);
11945 IRTemp op2 = newTemp(Ity_F128);
11946 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011947 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011948
11949 assign(op1, get_fpr_pair(r1));
11950 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011951 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011952 mkexpr(op2)));
11953 put_fpr_pair(r1, mkexpr(result));
11954 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11955
11956 return "sxbr";
11957}
11958
florian55085f82012-11-21 00:36:55 +000011959static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011960s390_irgen_TCEB(UChar r1, IRTemp op2addr)
11961{
11962 IRTemp value = newTemp(Ity_F32);
11963
11964 assign(value, get_fpr_w0(r1));
11965
11966 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
11967
11968 return "tceb";
11969}
11970
florian55085f82012-11-21 00:36:55 +000011971static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011972s390_irgen_TCDB(UChar r1, IRTemp op2addr)
11973{
11974 IRTemp value = newTemp(Ity_F64);
11975
11976 assign(value, get_fpr_dw0(r1));
11977
11978 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
11979
11980 return "tcdb";
11981}
11982
florian55085f82012-11-21 00:36:55 +000011983static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011984s390_irgen_TCXB(UChar r1, IRTemp op2addr)
11985{
11986 IRTemp value = newTemp(Ity_F128);
11987
11988 assign(value, get_fpr_pair(r1));
11989
11990 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
11991
11992 return "tcxb";
11993}
11994
florian55085f82012-11-21 00:36:55 +000011995static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011996s390_irgen_LCDFR(UChar r1, UChar r2)
11997{
11998 IRTemp result = newTemp(Ity_F64);
11999
12000 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12001 put_fpr_dw0(r1, mkexpr(result));
12002
12003 return "lcdfr";
12004}
12005
florian55085f82012-11-21 00:36:55 +000012006static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012007s390_irgen_LNDFR(UChar r1, UChar r2)
12008{
12009 IRTemp result = newTemp(Ity_F64);
12010
12011 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12012 put_fpr_dw0(r1, mkexpr(result));
12013
12014 return "lndfr";
12015}
12016
florian55085f82012-11-21 00:36:55 +000012017static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012018s390_irgen_LPDFR(UChar r1, UChar r2)
12019{
12020 IRTemp result = newTemp(Ity_F64);
12021
12022 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12023 put_fpr_dw0(r1, mkexpr(result));
12024
12025 return "lpdfr";
12026}
12027
florian55085f82012-11-21 00:36:55 +000012028static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012029s390_irgen_LDGR(UChar r1, UChar r2)
12030{
12031 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12032
12033 return "ldgr";
12034}
12035
florian55085f82012-11-21 00:36:55 +000012036static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012037s390_irgen_LGDR(UChar r1, UChar r2)
12038{
12039 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12040
12041 return "lgdr";
12042}
12043
12044
florian55085f82012-11-21 00:36:55 +000012045static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012046s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12047{
12048 IRTemp sign = newTemp(Ity_I64);
12049 IRTemp value = newTemp(Ity_I64);
12050
12051 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12052 mkU64(1ULL << 63)));
12053 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12054 mkU64((1ULL << 63) - 1)));
12055 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12056 mkexpr(sign))));
12057
12058 return "cpsdr";
12059}
12060
12061
sewardj2019a972011-03-07 16:04:07 +000012062static IRExpr *
12063s390_call_cvb(IRExpr *in)
12064{
12065 IRExpr **args, *call;
12066
12067 args = mkIRExprVec_1(in);
12068 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12069 "s390_do_cvb", &s390_do_cvb, args);
12070
12071 /* Nothing is excluded from definedness checking. */
12072 call->Iex.CCall.cee->mcx_mask = 0;
12073
12074 return call;
12075}
12076
florian55085f82012-11-21 00:36:55 +000012077static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012078s390_irgen_CVB(UChar r1, IRTemp op2addr)
12079{
12080 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12081
12082 return "cvb";
12083}
12084
florian55085f82012-11-21 00:36:55 +000012085static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012086s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12087{
12088 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12089
12090 return "cvby";
12091}
12092
12093
sewardj2019a972011-03-07 16:04:07 +000012094static IRExpr *
12095s390_call_cvd(IRExpr *in)
12096{
12097 IRExpr **args, *call;
12098
12099 args = mkIRExprVec_1(in);
12100 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12101 "s390_do_cvd", &s390_do_cvd, args);
12102
12103 /* Nothing is excluded from definedness checking. */
12104 call->Iex.CCall.cee->mcx_mask = 0;
12105
12106 return call;
12107}
12108
florian55085f82012-11-21 00:36:55 +000012109static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012110s390_irgen_CVD(UChar r1, IRTemp op2addr)
12111{
florian11b8ee82012-08-06 13:35:33 +000012112 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012113
12114 return "cvd";
12115}
12116
florian55085f82012-11-21 00:36:55 +000012117static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012118s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12119{
12120 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12121
12122 return "cvdy";
12123}
12124
florian55085f82012-11-21 00:36:55 +000012125static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012126s390_irgen_FLOGR(UChar r1, UChar r2)
12127{
12128 IRTemp input = newTemp(Ity_I64);
12129 IRTemp not_zero = newTemp(Ity_I64);
12130 IRTemp tmpnum = newTemp(Ity_I64);
12131 IRTemp num = newTemp(Ity_I64);
12132 IRTemp shift_amount = newTemp(Ity_I8);
12133
12134 /* We use the "count leading zeroes" operator because the number of
12135 leading zeroes is identical with the bit position of the first '1' bit.
12136 However, that operator does not work when the input value is zero.
12137 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12138 the modified value. If input == 0, then the result is 64. Otherwise,
12139 the result of Clz64 is what we want. */
12140
12141 assign(input, get_gpr_dw0(r2));
12142 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12143 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12144
12145 /* num = (input == 0) ? 64 : tmpnum */
12146 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12147 /* == 0 */ mkU64(64),
12148 /* != 0 */ mkexpr(tmpnum)));
12149
12150 put_gpr_dw0(r1, mkexpr(num));
12151
12152 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12153 is to first shift the input value by NUM + 1 bits to the left which
12154 causes the leftmost '1' bit to disappear. Then we shift logically to
12155 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12156 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12157 the width of the value-to-be-shifted, we need to special case
12158 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12159 For both such INPUT values the result will be 0. */
12160
12161 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12162 mkU64(1))));
12163
12164 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012165 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12166 /* == 0 || == 1*/ mkU64(0),
12167 /* otherwise */
12168 binop(Iop_Shr64,
12169 binop(Iop_Shl64, mkexpr(input),
12170 mkexpr(shift_amount)),
12171 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012172
12173 /* Compare the original value as an unsigned integer with 0. */
12174 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12175 mktemp(Ity_I64, mkU64(0)), False);
12176
12177 return "flogr";
12178}
12179
florian55085f82012-11-21 00:36:55 +000012180static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012181s390_irgen_STCK(IRTemp op2addr)
12182{
12183 IRDirty *d;
12184 IRTemp cc = newTemp(Ity_I64);
12185
12186 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12187 &s390x_dirtyhelper_STCK,
12188 mkIRExprVec_1(mkexpr(op2addr)));
12189 d->mFx = Ifx_Write;
12190 d->mAddr = mkexpr(op2addr);
12191 d->mSize = 8;
12192 stmt(IRStmt_Dirty(d));
12193 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12194 mkexpr(cc), mkU64(0), mkU64(0));
12195 return "stck";
12196}
12197
florian55085f82012-11-21 00:36:55 +000012198static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012199s390_irgen_STCKF(IRTemp op2addr)
12200{
florianc5c669b2012-08-26 14:32:28 +000012201 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012202 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012203 } else {
12204 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012205
florianc5c669b2012-08-26 14:32:28 +000012206 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12207 &s390x_dirtyhelper_STCKF,
12208 mkIRExprVec_1(mkexpr(op2addr)));
12209 d->mFx = Ifx_Write;
12210 d->mAddr = mkexpr(op2addr);
12211 d->mSize = 8;
12212 stmt(IRStmt_Dirty(d));
12213 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12214 mkexpr(cc), mkU64(0), mkU64(0));
12215 }
sewardj1e5fea62011-05-17 16:18:36 +000012216 return "stckf";
12217}
12218
florian55085f82012-11-21 00:36:55 +000012219static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012220s390_irgen_STCKE(IRTemp op2addr)
12221{
12222 IRDirty *d;
12223 IRTemp cc = newTemp(Ity_I64);
12224
12225 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12226 &s390x_dirtyhelper_STCKE,
12227 mkIRExprVec_1(mkexpr(op2addr)));
12228 d->mFx = Ifx_Write;
12229 d->mAddr = mkexpr(op2addr);
12230 d->mSize = 16;
12231 stmt(IRStmt_Dirty(d));
12232 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12233 mkexpr(cc), mkU64(0), mkU64(0));
12234 return "stcke";
12235}
12236
florian55085f82012-11-21 00:36:55 +000012237static const HChar *
florian933065d2011-07-11 01:48:02 +000012238s390_irgen_STFLE(IRTemp op2addr)
12239{
florian4e0083e2012-08-26 03:41:56 +000012240 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012241 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012242 return "stfle";
12243 }
12244
florian933065d2011-07-11 01:48:02 +000012245 IRDirty *d;
12246 IRTemp cc = newTemp(Ity_I64);
12247
12248 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12249 &s390x_dirtyhelper_STFLE,
12250 mkIRExprVec_1(mkexpr(op2addr)));
12251
12252 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
12253
sewardjc9069f22012-06-01 16:09:50 +000012254 d->nFxState = 1;
12255 vex_bzero(&d->fxState, sizeof(d->fxState));
12256
florian933065d2011-07-11 01:48:02 +000012257 d->fxState[0].fx = Ifx_Modify; /* read then write */
12258 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12259 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012260
12261 d->mAddr = mkexpr(op2addr);
12262 /* Pretend all double words are written */
12263 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12264 d->mFx = Ifx_Write;
12265
12266 stmt(IRStmt_Dirty(d));
12267
12268 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12269
12270 return "stfle";
12271}
12272
florian55085f82012-11-21 00:36:55 +000012273static const HChar *
floriana4384a32011-08-11 16:58:45 +000012274s390_irgen_CKSM(UChar r1,UChar r2)
12275{
12276 IRTemp addr = newTemp(Ity_I64);
12277 IRTemp op = newTemp(Ity_I32);
12278 IRTemp len = newTemp(Ity_I64);
12279 IRTemp oldval = newTemp(Ity_I32);
12280 IRTemp mask = newTemp(Ity_I32);
12281 IRTemp newop = newTemp(Ity_I32);
12282 IRTemp result = newTemp(Ity_I32);
12283 IRTemp result1 = newTemp(Ity_I32);
12284 IRTemp inc = newTemp(Ity_I64);
12285
12286 assign(oldval, get_gpr_w1(r1));
12287 assign(addr, get_gpr_dw0(r2));
12288 assign(len, get_gpr_dw0(r2+1));
12289
12290 /* Condition code is always zero. */
12291 s390_cc_set(0);
12292
12293 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012294 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012295
12296 /* Assiging the increment variable to adjust address and length
12297 later on. */
12298 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12299 mkexpr(len), mkU64(4)));
12300
12301 /* If length < 4 the final 4-byte 2nd operand value is computed by
12302 appending the remaining bytes to the right with 0. This is done
12303 by AND'ing the 4 bytes loaded from memory with an appropriate
12304 mask. If length >= 4, that mask is simply 0xffffffff. */
12305
12306 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12307 /* Mask computation when len < 4:
12308 0xffffffff << (32 - (len % 4)*8) */
12309 binop(Iop_Shl32, mkU32(0xffffffff),
12310 unop(Iop_32to8,
12311 binop(Iop_Sub32, mkU32(32),
12312 binop(Iop_Shl32,
12313 unop(Iop_64to32,
12314 binop(Iop_And64,
12315 mkexpr(len), mkU64(3))),
12316 mkU8(3))))),
12317 mkU32(0xffffffff)));
12318
12319 assign(op, load(Ity_I32, mkexpr(addr)));
12320 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12321 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12322
12323 /* Checking for carry */
12324 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12325 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12326 mkexpr(result)));
12327
12328 put_gpr_w1(r1, mkexpr(result1));
12329 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12330 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12331
florian6820ba52012-07-26 02:01:50 +000012332 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012333
12334 return "cksm";
12335}
12336
florian55085f82012-11-21 00:36:55 +000012337static const HChar *
florian9af37692012-01-15 21:01:16 +000012338s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12339{
12340 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12341 src_addr = newTemp(Ity_I64);
12342 des_addr = newTemp(Ity_I64);
12343 tab_addr = newTemp(Ity_I64);
12344 test_byte = newTemp(Ity_I8);
12345 src_len = newTemp(Ity_I64);
12346
12347 assign(src_addr, get_gpr_dw0(r2));
12348 assign(des_addr, get_gpr_dw0(r1));
12349 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012350 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012351 assign(test_byte, get_gpr_b7(0));
12352
12353 IRTemp op = newTemp(Ity_I8);
12354 IRTemp op1 = newTemp(Ity_I8);
12355 IRTemp result = newTemp(Ity_I64);
12356
12357 /* End of source string? We're done; proceed to next insn */
12358 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012359 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012360
12361 /* Load character from source string, index translation table and
12362 store translated character in op1. */
12363 assign(op, load(Ity_I8, mkexpr(src_addr)));
12364
12365 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12366 mkexpr(tab_addr)));
12367 assign(op1, load(Ity_I8, mkexpr(result)));
12368
12369 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12370 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012371 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000012372 }
12373 store(get_gpr_dw0(r1), mkexpr(op1));
12374
12375 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12376 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12377 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12378
florian6820ba52012-07-26 02:01:50 +000012379 iterate();
florian9af37692012-01-15 21:01:16 +000012380
12381 return "troo";
12382}
12383
florian55085f82012-11-21 00:36:55 +000012384static const HChar *
florian730448f2012-02-04 17:07:07 +000012385s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
12386{
12387 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12388 src_addr = newTemp(Ity_I64);
12389 des_addr = newTemp(Ity_I64);
12390 tab_addr = newTemp(Ity_I64);
12391 test_byte = newTemp(Ity_I8);
12392 src_len = newTemp(Ity_I64);
12393
12394 assign(src_addr, get_gpr_dw0(r2));
12395 assign(des_addr, get_gpr_dw0(r1));
12396 assign(tab_addr, get_gpr_dw0(1));
12397 assign(src_len, get_gpr_dw0(r1+1));
12398 assign(test_byte, get_gpr_b7(0));
12399
12400 IRTemp op = newTemp(Ity_I16);
12401 IRTemp op1 = newTemp(Ity_I8);
12402 IRTemp result = newTemp(Ity_I64);
12403
12404 /* End of source string? We're done; proceed to next insn */
12405 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012406 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012407
12408 /* Load character from source string, index translation table and
12409 store translated character in op1. */
12410 assign(op, load(Ity_I16, mkexpr(src_addr)));
12411
12412 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12413 mkexpr(tab_addr)));
12414
12415 assign(op1, load(Ity_I8, mkexpr(result)));
12416
12417 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12418 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012419 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012420 }
12421 store(get_gpr_dw0(r1), mkexpr(op1));
12422
12423 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12424 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12425 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12426
florian6820ba52012-07-26 02:01:50 +000012427 iterate();
florian730448f2012-02-04 17:07:07 +000012428
12429 return "trto";
12430}
12431
florian55085f82012-11-21 00:36:55 +000012432static const HChar *
florian730448f2012-02-04 17:07:07 +000012433s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
12434{
12435 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12436 src_addr = newTemp(Ity_I64);
12437 des_addr = newTemp(Ity_I64);
12438 tab_addr = newTemp(Ity_I64);
12439 test_byte = newTemp(Ity_I16);
12440 src_len = newTemp(Ity_I64);
12441
12442 assign(src_addr, get_gpr_dw0(r2));
12443 assign(des_addr, get_gpr_dw0(r1));
12444 assign(tab_addr, get_gpr_dw0(1));
12445 assign(src_len, get_gpr_dw0(r1+1));
12446 assign(test_byte, get_gpr_hw3(0));
12447
12448 IRTemp op = newTemp(Ity_I8);
12449 IRTemp op1 = newTemp(Ity_I16);
12450 IRTemp result = newTemp(Ity_I64);
12451
12452 /* End of source string? We're done; proceed to next insn */
12453 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012454 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012455
12456 /* Load character from source string, index translation table and
12457 store translated character in op1. */
12458 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12459
12460 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12461 mkexpr(tab_addr)));
12462 assign(op1, load(Ity_I16, mkexpr(result)));
12463
12464 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12465 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012466 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012467 }
12468 store(get_gpr_dw0(r1), mkexpr(op1));
12469
12470 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12471 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12472 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12473
florian6820ba52012-07-26 02:01:50 +000012474 iterate();
florian730448f2012-02-04 17:07:07 +000012475
12476 return "trot";
12477}
12478
florian55085f82012-11-21 00:36:55 +000012479static const HChar *
florian730448f2012-02-04 17:07:07 +000012480s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12481{
12482 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12483 src_addr = newTemp(Ity_I64);
12484 des_addr = newTemp(Ity_I64);
12485 tab_addr = newTemp(Ity_I64);
12486 test_byte = newTemp(Ity_I16);
12487 src_len = newTemp(Ity_I64);
12488
12489 assign(src_addr, get_gpr_dw0(r2));
12490 assign(des_addr, get_gpr_dw0(r1));
12491 assign(tab_addr, get_gpr_dw0(1));
12492 assign(src_len, get_gpr_dw0(r1+1));
12493 assign(test_byte, get_gpr_hw3(0));
12494
12495 IRTemp op = newTemp(Ity_I16);
12496 IRTemp op1 = newTemp(Ity_I16);
12497 IRTemp result = newTemp(Ity_I64);
12498
12499 /* End of source string? We're done; proceed to next insn */
12500 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012501 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012502
12503 /* Load character from source string, index translation table and
12504 store translated character in op1. */
12505 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12506
12507 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12508 mkexpr(tab_addr)));
12509 assign(op1, load(Ity_I16, mkexpr(result)));
12510
12511 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12512 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012513 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012514 }
12515
12516 store(get_gpr_dw0(r1), mkexpr(op1));
12517
12518 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12519 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12520 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12521
florian6820ba52012-07-26 02:01:50 +000012522 iterate();
florian730448f2012-02-04 17:07:07 +000012523
12524 return "trtt";
12525}
12526
florian55085f82012-11-21 00:36:55 +000012527static const HChar *
florian730448f2012-02-04 17:07:07 +000012528s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
12529{
florianf87d4fb2012-05-05 02:55:24 +000012530 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000012531
florianf87d4fb2012-05-05 02:55:24 +000012532 assign(len, mkU64(length));
12533 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000012534
12535 return "tr";
12536}
12537
florian55085f82012-11-21 00:36:55 +000012538static const HChar *
florian730448f2012-02-04 17:07:07 +000012539s390_irgen_TRE(UChar r1,UChar r2)
12540{
12541 IRTemp src_addr, tab_addr, src_len, test_byte;
12542 src_addr = newTemp(Ity_I64);
12543 tab_addr = newTemp(Ity_I64);
12544 src_len = newTemp(Ity_I64);
12545 test_byte = newTemp(Ity_I8);
12546
12547 assign(src_addr, get_gpr_dw0(r1));
12548 assign(src_len, get_gpr_dw0(r1+1));
12549 assign(tab_addr, get_gpr_dw0(r2));
12550 assign(test_byte, get_gpr_b7(0));
12551
12552 IRTemp op = newTemp(Ity_I8);
12553 IRTemp op1 = newTemp(Ity_I8);
12554 IRTemp result = newTemp(Ity_I64);
12555
12556 /* End of source string? We're done; proceed to next insn */
12557 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012558 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012559
12560 /* Load character from source string and compare with test byte */
12561 assign(op, load(Ity_I8, mkexpr(src_addr)));
12562
12563 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012564 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012565
12566 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12567 mkexpr(tab_addr)));
12568
12569 assign(op1, load(Ity_I8, mkexpr(result)));
12570
12571 store(get_gpr_dw0(r1), mkexpr(op1));
12572 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12573 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12574
florian6820ba52012-07-26 02:01:50 +000012575 iterate();
florian730448f2012-02-04 17:07:07 +000012576
12577 return "tre";
12578}
12579
floriana0100c92012-07-20 00:06:35 +000012580static IRExpr *
12581s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
12582{
12583 IRExpr **args, *call;
12584 args = mkIRExprVec_2(srcval, low_surrogate);
12585 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12586 "s390_do_cu21", &s390_do_cu21, args);
12587
12588 /* Nothing is excluded from definedness checking. */
12589 call->Iex.CCall.cee->mcx_mask = 0;
12590
12591 return call;
12592}
12593
florian55085f82012-11-21 00:36:55 +000012594static const HChar *
floriana0100c92012-07-20 00:06:35 +000012595s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
12596{
12597 IRTemp addr1 = newTemp(Ity_I64);
12598 IRTemp addr2 = newTemp(Ity_I64);
12599 IRTemp len1 = newTemp(Ity_I64);
12600 IRTemp len2 = newTemp(Ity_I64);
12601
12602 assign(addr1, get_gpr_dw0(r1));
12603 assign(addr2, get_gpr_dw0(r2));
12604 assign(len1, get_gpr_dw0(r1 + 1));
12605 assign(len2, get_gpr_dw0(r2 + 1));
12606
12607 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12608 there are less than 2 bytes left, then the 2nd operand is exhausted
12609 and we're done here. cc = 0 */
12610 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012611 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000012612
12613 /* There are at least two bytes there. Read them. */
12614 IRTemp srcval = newTemp(Ity_I32);
12615 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12616
12617 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12618 inside the interval [0xd800 - 0xdbff] */
12619 IRTemp is_high_surrogate = newTemp(Ity_I32);
12620 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12621 mkU32(1), mkU32(0));
12622 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12623 mkU32(1), mkU32(0));
12624 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12625
12626 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12627 then the 2nd operand is exhausted and we're done here. cc = 0 */
12628 IRExpr *not_enough_bytes =
12629 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12630
florian6820ba52012-07-26 02:01:50 +000012631 next_insn_if(binop(Iop_CmpEQ32,
12632 binop(Iop_And32, mkexpr(is_high_surrogate),
12633 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000012634
12635 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12636 surrogate, read the next two bytes (low surrogate). */
12637 IRTemp low_surrogate = newTemp(Ity_I32);
12638 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12639
12640 assign(low_surrogate,
12641 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12642 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12643 mkU32(0))); // any value is fine; it will not be used
12644
12645 /* Call the helper */
12646 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012647 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
12648 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000012649
12650 /* Before we can test whether the 1st operand is exhausted we need to
12651 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12652 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12653 IRExpr *invalid_low_surrogate =
12654 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12655
12656 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012657 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000012658 }
12659
12660 /* Now test whether the 1st operand is exhausted */
12661 IRTemp num_bytes = newTemp(Ity_I64);
12662 assign(num_bytes, binop(Iop_And64,
12663 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12664 mkU64(0xff)));
12665 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012666 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000012667
12668 /* Extract the bytes to be stored at addr1 */
12669 IRTemp data = newTemp(Ity_I64);
12670 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12671
12672 /* To store the bytes construct 4 dirty helper calls. The helper calls
12673 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12674 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012675 UInt i;
floriana0100c92012-07-20 00:06:35 +000012676 for (i = 1; i <= 4; ++i) {
12677 IRDirty *d;
12678
12679 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12680 &s390x_dirtyhelper_CUxy,
12681 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12682 mkexpr(num_bytes)));
12683 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12684 d->mFx = Ifx_Write;
12685 d->mAddr = mkexpr(addr1);
12686 d->mSize = i;
12687 stmt(IRStmt_Dirty(d));
12688 }
12689
12690 /* Update source address and length */
12691 IRTemp num_src_bytes = newTemp(Ity_I64);
12692 assign(num_src_bytes,
12693 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12694 mkU64(4), mkU64(2)));
12695 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12696 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12697
12698 /* Update destination address and length */
12699 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12700 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12701
florian6820ba52012-07-26 02:01:50 +000012702 iterate();
floriana0100c92012-07-20 00:06:35 +000012703
12704 return "cu21";
12705}
12706
florian2a415a12012-07-21 17:41:36 +000012707static IRExpr *
12708s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
12709{
12710 IRExpr **args, *call;
12711 args = mkIRExprVec_2(srcval, low_surrogate);
12712 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12713 "s390_do_cu24", &s390_do_cu24, args);
12714
12715 /* Nothing is excluded from definedness checking. */
12716 call->Iex.CCall.cee->mcx_mask = 0;
12717
12718 return call;
12719}
12720
florian55085f82012-11-21 00:36:55 +000012721static const HChar *
florian2a415a12012-07-21 17:41:36 +000012722s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
12723{
12724 IRTemp addr1 = newTemp(Ity_I64);
12725 IRTemp addr2 = newTemp(Ity_I64);
12726 IRTemp len1 = newTemp(Ity_I64);
12727 IRTemp len2 = newTemp(Ity_I64);
12728
12729 assign(addr1, get_gpr_dw0(r1));
12730 assign(addr2, get_gpr_dw0(r2));
12731 assign(len1, get_gpr_dw0(r1 + 1));
12732 assign(len2, get_gpr_dw0(r2 + 1));
12733
12734 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12735 there are less than 2 bytes left, then the 2nd operand is exhausted
12736 and we're done here. cc = 0 */
12737 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012738 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000012739
12740 /* There are at least two bytes there. Read them. */
12741 IRTemp srcval = newTemp(Ity_I32);
12742 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12743
12744 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12745 inside the interval [0xd800 - 0xdbff] */
12746 IRTemp is_high_surrogate = newTemp(Ity_I32);
12747 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12748 mkU32(1), mkU32(0));
12749 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12750 mkU32(1), mkU32(0));
12751 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12752
12753 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12754 then the 2nd operand is exhausted and we're done here. cc = 0 */
12755 IRExpr *not_enough_bytes =
12756 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12757
florian6820ba52012-07-26 02:01:50 +000012758 next_insn_if(binop(Iop_CmpEQ32,
12759 binop(Iop_And32, mkexpr(is_high_surrogate),
12760 not_enough_bytes),
12761 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000012762
12763 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12764 surrogate, read the next two bytes (low surrogate). */
12765 IRTemp low_surrogate = newTemp(Ity_I32);
12766 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12767
12768 assign(low_surrogate,
12769 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12770 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12771 mkU32(0))); // any value is fine; it will not be used
12772
12773 /* Call the helper */
12774 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012775 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
12776 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000012777
12778 /* Before we can test whether the 1st operand is exhausted we need to
12779 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12780 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12781 IRExpr *invalid_low_surrogate =
12782 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12783
12784 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012785 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000012786 }
12787
12788 /* Now test whether the 1st operand is exhausted */
12789 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012790 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000012791
12792 /* Extract the bytes to be stored at addr1 */
12793 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
12794
12795 store(mkexpr(addr1), data);
12796
12797 /* Update source address and length */
12798 IRTemp num_src_bytes = newTemp(Ity_I64);
12799 assign(num_src_bytes,
12800 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12801 mkU64(4), mkU64(2)));
12802 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
12803 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
12804
12805 /* Update destination address and length */
12806 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
12807 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
12808
florian6820ba52012-07-26 02:01:50 +000012809 iterate();
florian2a415a12012-07-21 17:41:36 +000012810
12811 return "cu24";
12812}
floriana4384a32011-08-11 16:58:45 +000012813
florian956194b2012-07-28 22:18:32 +000012814static IRExpr *
12815s390_call_cu42(IRExpr *srcval)
12816{
12817 IRExpr **args, *call;
12818 args = mkIRExprVec_1(srcval);
12819 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12820 "s390_do_cu42", &s390_do_cu42, args);
12821
12822 /* Nothing is excluded from definedness checking. */
12823 call->Iex.CCall.cee->mcx_mask = 0;
12824
12825 return call;
12826}
12827
florian55085f82012-11-21 00:36:55 +000012828static const HChar *
florian956194b2012-07-28 22:18:32 +000012829s390_irgen_CU42(UChar r1, UChar r2)
12830{
12831 IRTemp addr1 = newTemp(Ity_I64);
12832 IRTemp addr2 = newTemp(Ity_I64);
12833 IRTemp len1 = newTemp(Ity_I64);
12834 IRTemp len2 = newTemp(Ity_I64);
12835
12836 assign(addr1, get_gpr_dw0(r1));
12837 assign(addr2, get_gpr_dw0(r2));
12838 assign(len1, get_gpr_dw0(r1 + 1));
12839 assign(len2, get_gpr_dw0(r2 + 1));
12840
12841 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12842 there are less than 4 bytes left, then the 2nd operand is exhausted
12843 and we're done here. cc = 0 */
12844 s390_cc_set(0);
12845 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12846
12847 /* Read the 2nd operand. */
12848 IRTemp srcval = newTemp(Ity_I32);
12849 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12850
12851 /* Call the helper */
12852 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012853 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000012854
12855 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12856 cc=2 outranks cc=1 (1st operand exhausted) */
12857 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12858
12859 s390_cc_set(2);
12860 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12861
12862 /* Now test whether the 1st operand is exhausted */
12863 IRTemp num_bytes = newTemp(Ity_I64);
12864 assign(num_bytes, binop(Iop_And64,
12865 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12866 mkU64(0xff)));
12867 s390_cc_set(1);
12868 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12869
12870 /* Extract the bytes to be stored at addr1 */
12871 IRTemp data = newTemp(Ity_I64);
12872 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12873
12874 /* To store the bytes construct 2 dirty helper calls. The helper calls
12875 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
12876 that only one of them will be called at runtime. */
12877
12878 Int i;
12879 for (i = 2; i <= 4; ++i) {
12880 IRDirty *d;
12881
12882 if (i == 3) continue; // skip this one
12883
12884 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12885 &s390x_dirtyhelper_CUxy,
12886 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12887 mkexpr(num_bytes)));
12888 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12889 d->mFx = Ifx_Write;
12890 d->mAddr = mkexpr(addr1);
12891 d->mSize = i;
12892 stmt(IRStmt_Dirty(d));
12893 }
12894
12895 /* Update source address and length */
12896 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12897 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12898
12899 /* Update destination address and length */
12900 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12901 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12902
12903 iterate();
12904
12905 return "cu42";
12906}
12907
florian6d9b9b22012-08-03 18:35:39 +000012908static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000012909s390_call_cu41(IRExpr *srcval)
12910{
12911 IRExpr **args, *call;
12912 args = mkIRExprVec_1(srcval);
12913 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12914 "s390_do_cu41", &s390_do_cu41, args);
12915
12916 /* Nothing is excluded from definedness checking. */
12917 call->Iex.CCall.cee->mcx_mask = 0;
12918
12919 return call;
12920}
12921
florian55085f82012-11-21 00:36:55 +000012922static const HChar *
florianaf2194f2012-08-06 00:07:54 +000012923s390_irgen_CU41(UChar r1, UChar r2)
12924{
12925 IRTemp addr1 = newTemp(Ity_I64);
12926 IRTemp addr2 = newTemp(Ity_I64);
12927 IRTemp len1 = newTemp(Ity_I64);
12928 IRTemp len2 = newTemp(Ity_I64);
12929
12930 assign(addr1, get_gpr_dw0(r1));
12931 assign(addr2, get_gpr_dw0(r2));
12932 assign(len1, get_gpr_dw0(r1 + 1));
12933 assign(len2, get_gpr_dw0(r2 + 1));
12934
12935 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
12936 there are less than 4 bytes left, then the 2nd operand is exhausted
12937 and we're done here. cc = 0 */
12938 s390_cc_set(0);
12939 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
12940
12941 /* Read the 2nd operand. */
12942 IRTemp srcval = newTemp(Ity_I32);
12943 assign(srcval, load(Ity_I32, mkexpr(addr2)));
12944
12945 /* Call the helper */
12946 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012947 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000012948
12949 /* If the UTF-32 character was invalid, set cc=2 and we're done.
12950 cc=2 outranks cc=1 (1st operand exhausted) */
12951 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12952
12953 s390_cc_set(2);
12954 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
12955
12956 /* Now test whether the 1st operand is exhausted */
12957 IRTemp num_bytes = newTemp(Ity_I64);
12958 assign(num_bytes, binop(Iop_And64,
12959 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12960 mkU64(0xff)));
12961 s390_cc_set(1);
12962 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
12963
12964 /* Extract the bytes to be stored at addr1 */
12965 IRTemp data = newTemp(Ity_I64);
12966 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12967
12968 /* To store the bytes construct 4 dirty helper calls. The helper calls
12969 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12970 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012971 UInt i;
florianaf2194f2012-08-06 00:07:54 +000012972 for (i = 1; i <= 4; ++i) {
12973 IRDirty *d;
12974
12975 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12976 &s390x_dirtyhelper_CUxy,
12977 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12978 mkexpr(num_bytes)));
12979 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
12980 d->mFx = Ifx_Write;
12981 d->mAddr = mkexpr(addr1);
12982 d->mSize = i;
12983 stmt(IRStmt_Dirty(d));
12984 }
12985
12986 /* Update source address and length */
12987 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
12988 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
12989
12990 /* Update destination address and length */
12991 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
12992 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
12993
12994 iterate();
12995
12996 return "cu41";
12997}
12998
12999static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013000s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013001{
13002 IRExpr **args, *call;
13003 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013004 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13005 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013006
13007 /* Nothing is excluded from definedness checking. */
13008 call->Iex.CCall.cee->mcx_mask = 0;
13009
13010 return call;
13011}
13012
13013static IRExpr *
13014s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13015 IRExpr *byte4, IRExpr *stuff)
13016{
13017 IRExpr **args, *call;
13018 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13019 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13020 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13021
13022 /* Nothing is excluded from definedness checking. */
13023 call->Iex.CCall.cee->mcx_mask = 0;
13024
13025 return call;
13026}
13027
florian3f8a96a2012-08-05 02:59:55 +000013028static IRExpr *
13029s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13030 IRExpr *byte4, IRExpr *stuff)
13031{
13032 IRExpr **args, *call;
13033 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13034 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13035 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13036
13037 /* Nothing is excluded from definedness checking. */
13038 call->Iex.CCall.cee->mcx_mask = 0;
13039
13040 return call;
13041}
13042
13043static void
13044s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013045{
13046 IRTemp addr1 = newTemp(Ity_I64);
13047 IRTemp addr2 = newTemp(Ity_I64);
13048 IRTemp len1 = newTemp(Ity_I64);
13049 IRTemp len2 = newTemp(Ity_I64);
13050
13051 assign(addr1, get_gpr_dw0(r1));
13052 assign(addr2, get_gpr_dw0(r2));
13053 assign(len1, get_gpr_dw0(r1 + 1));
13054 assign(len2, get_gpr_dw0(r2 + 1));
13055
13056 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13057
13058 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13059 there is less than 1 byte left, then the 2nd operand is exhausted
13060 and we're done here. cc = 0 */
13061 s390_cc_set(0);
13062 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13063
13064 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013065 IRTemp byte1 = newTemp(Ity_I64);
13066 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013067
13068 /* Call the helper to get number of bytes and invalid byte indicator */
13069 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013070 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013071 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013072
13073 /* Check for invalid 1st byte */
13074 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13075 s390_cc_set(2);
13076 next_insn_if(is_invalid);
13077
13078 /* How many bytes do we have to read? */
13079 IRTemp num_src_bytes = newTemp(Ity_I64);
13080 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13081
13082 /* Now test whether the 2nd operand is exhausted */
13083 s390_cc_set(0);
13084 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13085
13086 /* Read the remaining bytes */
13087 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13088
13089 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13090 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013091 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013092 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13093 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013094 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013095 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13096 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013097 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013098
13099 /* Call the helper to get the converted value and invalid byte indicator.
13100 We can pass at most 5 arguments; therefore some encoding is needed
13101 here */
13102 IRExpr *stuff = binop(Iop_Or64,
13103 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13104 mkU64(extended_checking));
13105 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013106
13107 if (is_cu12) {
13108 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13109 byte4, stuff));
13110 } else {
13111 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13112 byte4, stuff));
13113 }
florian6d9b9b22012-08-03 18:35:39 +000013114
13115 /* Check for invalid character */
13116 s390_cc_set(2);
13117 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13118 next_insn_if(is_invalid);
13119
13120 /* Now test whether the 1st operand is exhausted */
13121 IRTemp num_bytes = newTemp(Ity_I64);
13122 assign(num_bytes, binop(Iop_And64,
13123 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13124 mkU64(0xff)));
13125 s390_cc_set(1);
13126 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13127
13128 /* Extract the bytes to be stored at addr1 */
13129 IRTemp data = newTemp(Ity_I64);
13130 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13131
florian3f8a96a2012-08-05 02:59:55 +000013132 if (is_cu12) {
13133 /* To store the bytes construct 2 dirty helper calls. The helper calls
13134 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13135 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013136
florian3f8a96a2012-08-05 02:59:55 +000013137 Int i;
13138 for (i = 2; i <= 4; ++i) {
13139 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013140
florian3f8a96a2012-08-05 02:59:55 +000013141 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013142
florian3f8a96a2012-08-05 02:59:55 +000013143 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13144 &s390x_dirtyhelper_CUxy,
13145 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13146 mkexpr(num_bytes)));
13147 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13148 d->mFx = Ifx_Write;
13149 d->mAddr = mkexpr(addr1);
13150 d->mSize = i;
13151 stmt(IRStmt_Dirty(d));
13152 }
13153 } else {
13154 // cu14
13155 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013156 }
13157
13158 /* Update source address and length */
13159 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13160 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13161
13162 /* Update destination address and length */
13163 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13164 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13165
13166 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013167}
13168
florian55085f82012-11-21 00:36:55 +000013169static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013170s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13171{
13172 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013173
13174 return "cu12";
13175}
13176
florian55085f82012-11-21 00:36:55 +000013177static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013178s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13179{
13180 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13181
13182 return "cu14";
13183}
13184
florian8c88cb62012-08-26 18:58:13 +000013185static IRExpr *
13186s390_call_ecag(IRExpr *op2addr)
13187{
13188 IRExpr **args, *call;
13189
13190 args = mkIRExprVec_1(op2addr);
13191 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13192 "s390_do_ecag", &s390_do_ecag, args);
13193
13194 /* Nothing is excluded from definedness checking. */
13195 call->Iex.CCall.cee->mcx_mask = 0;
13196
13197 return call;
13198}
13199
florian55085f82012-11-21 00:36:55 +000013200static const HChar *
floriand2129202012-09-01 20:01:39 +000013201s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013202{
13203 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013204 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013205 } else {
13206 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13207 }
13208
13209 return "ecag";
13210}
13211
13212
florianb7def222012-12-04 04:45:32 +000013213/* New insns are added here.
13214 If an insn is contingent on a facility being installed also
13215 check whether the list of supported facilities in function
13216 s390x_dirtyhelper_STFLE needs updating */
13217
sewardj2019a972011-03-07 16:04:07 +000013218/*------------------------------------------------------------*/
13219/*--- Build IR for special instructions ---*/
13220/*------------------------------------------------------------*/
13221
florianb4df7682011-07-05 02:09:01 +000013222static void
sewardj2019a972011-03-07 16:04:07 +000013223s390_irgen_client_request(void)
13224{
13225 if (0)
13226 vex_printf("%%R3 = client_request ( %%R2 )\n");
13227
florianf9e1ed72012-04-17 02:41:56 +000013228 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13229 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013230
florianf9e1ed72012-04-17 02:41:56 +000013231 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013232 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013233
13234 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013235}
13236
florianb4df7682011-07-05 02:09:01 +000013237static void
sewardj2019a972011-03-07 16:04:07 +000013238s390_irgen_guest_NRADDR(void)
13239{
13240 if (0)
13241 vex_printf("%%R3 = guest_NRADDR\n");
13242
floriane88b3c92011-07-05 02:48:39 +000013243 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013244}
13245
florianb4df7682011-07-05 02:09:01 +000013246static void
sewardj2019a972011-03-07 16:04:07 +000013247s390_irgen_call_noredir(void)
13248{
florianf9e1ed72012-04-17 02:41:56 +000013249 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13250 + S390_SPECIAL_OP_SIZE;
13251
sewardj2019a972011-03-07 16:04:07 +000013252 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013253 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013254
13255 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013256 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013257
13258 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013259 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013260}
13261
13262/* Force proper alignment for the structures below. */
13263#pragma pack(1)
13264
13265
13266static s390_decode_t
13267s390_decode_2byte_and_irgen(UChar *bytes)
13268{
13269 typedef union {
13270 struct {
13271 unsigned int op : 16;
13272 } E;
13273 struct {
13274 unsigned int op : 8;
13275 unsigned int i : 8;
13276 } I;
13277 struct {
13278 unsigned int op : 8;
13279 unsigned int r1 : 4;
13280 unsigned int r2 : 4;
13281 } RR;
13282 } formats;
13283 union {
13284 formats fmt;
13285 UShort value;
13286 } ovl;
13287
13288 vassert(sizeof(formats) == 2);
13289
florianffbd84d2012-12-09 02:06:29 +000013290 ((UChar *)(&ovl.value))[0] = bytes[0];
13291 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013292
13293 switch (ovl.value & 0xffff) {
13294 case 0x0101: /* PR */ goto unimplemented;
13295 case 0x0102: /* UPT */ goto unimplemented;
13296 case 0x0104: /* PTFF */ goto unimplemented;
13297 case 0x0107: /* SCKPF */ goto unimplemented;
13298 case 0x010a: /* PFPO */ goto unimplemented;
13299 case 0x010b: /* TAM */ goto unimplemented;
13300 case 0x010c: /* SAM24 */ goto unimplemented;
13301 case 0x010d: /* SAM31 */ goto unimplemented;
13302 case 0x010e: /* SAM64 */ goto unimplemented;
13303 case 0x01ff: /* TRAP2 */ goto unimplemented;
13304 }
13305
13306 switch ((ovl.value & 0xff00) >> 8) {
13307 case 0x04: /* SPM */ goto unimplemented;
13308 case 0x05: /* BALR */ goto unimplemented;
13309 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13310 goto ok;
13311 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13312 goto ok;
13313 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13314 case 0x0b: /* BSM */ goto unimplemented;
13315 case 0x0c: /* BASSM */ goto unimplemented;
13316 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13317 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013318 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13319 goto ok;
13320 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13321 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013322 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13323 goto ok;
13324 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13325 goto ok;
13326 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13327 goto ok;
13328 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13329 goto ok;
13330 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13331 goto ok;
13332 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13333 goto ok;
13334 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13335 goto ok;
13336 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13337 goto ok;
13338 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13339 goto ok;
13340 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13341 goto ok;
13342 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13343 goto ok;
13344 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13345 goto ok;
13346 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13347 goto ok;
13348 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13349 goto ok;
13350 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13351 goto ok;
13352 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13353 goto ok;
13354 case 0x20: /* LPDR */ goto unimplemented;
13355 case 0x21: /* LNDR */ goto unimplemented;
13356 case 0x22: /* LTDR */ goto unimplemented;
13357 case 0x23: /* LCDR */ goto unimplemented;
13358 case 0x24: /* HDR */ goto unimplemented;
13359 case 0x25: /* LDXR */ goto unimplemented;
13360 case 0x26: /* MXR */ goto unimplemented;
13361 case 0x27: /* MXDR */ goto unimplemented;
13362 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13363 goto ok;
13364 case 0x29: /* CDR */ goto unimplemented;
13365 case 0x2a: /* ADR */ goto unimplemented;
13366 case 0x2b: /* SDR */ goto unimplemented;
13367 case 0x2c: /* MDR */ goto unimplemented;
13368 case 0x2d: /* DDR */ goto unimplemented;
13369 case 0x2e: /* AWR */ goto unimplemented;
13370 case 0x2f: /* SWR */ goto unimplemented;
13371 case 0x30: /* LPER */ goto unimplemented;
13372 case 0x31: /* LNER */ goto unimplemented;
13373 case 0x32: /* LTER */ goto unimplemented;
13374 case 0x33: /* LCER */ goto unimplemented;
13375 case 0x34: /* HER */ goto unimplemented;
13376 case 0x35: /* LEDR */ goto unimplemented;
13377 case 0x36: /* AXR */ goto unimplemented;
13378 case 0x37: /* SXR */ goto unimplemented;
13379 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13380 goto ok;
13381 case 0x39: /* CER */ goto unimplemented;
13382 case 0x3a: /* AER */ goto unimplemented;
13383 case 0x3b: /* SER */ goto unimplemented;
13384 case 0x3c: /* MDER */ goto unimplemented;
13385 case 0x3d: /* DER */ goto unimplemented;
13386 case 0x3e: /* AUR */ goto unimplemented;
13387 case 0x3f: /* SUR */ goto unimplemented;
13388 }
13389
13390 return S390_DECODE_UNKNOWN_INSN;
13391
13392ok:
13393 return S390_DECODE_OK;
13394
13395unimplemented:
13396 return S390_DECODE_UNIMPLEMENTED_INSN;
13397}
13398
13399static s390_decode_t
13400s390_decode_4byte_and_irgen(UChar *bytes)
13401{
13402 typedef union {
13403 struct {
13404 unsigned int op1 : 8;
13405 unsigned int r1 : 4;
13406 unsigned int op2 : 4;
13407 unsigned int i2 : 16;
13408 } RI;
13409 struct {
13410 unsigned int op : 16;
13411 unsigned int : 8;
13412 unsigned int r1 : 4;
13413 unsigned int r2 : 4;
13414 } RRE;
13415 struct {
13416 unsigned int op : 16;
13417 unsigned int r1 : 4;
13418 unsigned int : 4;
13419 unsigned int r3 : 4;
13420 unsigned int r2 : 4;
13421 } RRF;
13422 struct {
13423 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000013424 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000013425 unsigned int m4 : 4;
13426 unsigned int r1 : 4;
13427 unsigned int r2 : 4;
13428 } RRF2;
13429 struct {
13430 unsigned int op : 16;
13431 unsigned int r3 : 4;
13432 unsigned int : 4;
13433 unsigned int r1 : 4;
13434 unsigned int r2 : 4;
13435 } RRF3;
13436 struct {
13437 unsigned int op : 16;
13438 unsigned int r3 : 4;
13439 unsigned int : 4;
13440 unsigned int r1 : 4;
13441 unsigned int r2 : 4;
13442 } RRR;
13443 struct {
13444 unsigned int op : 16;
13445 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013446 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013447 unsigned int r1 : 4;
13448 unsigned int r2 : 4;
13449 } RRF4;
13450 struct {
floriane38f6412012-12-21 17:32:12 +000013451 unsigned int op : 16;
13452 unsigned int : 4;
13453 unsigned int m4 : 4;
13454 unsigned int r1 : 4;
13455 unsigned int r2 : 4;
13456 } RRF5;
13457 struct {
sewardj2019a972011-03-07 16:04:07 +000013458 unsigned int op : 8;
13459 unsigned int r1 : 4;
13460 unsigned int r3 : 4;
13461 unsigned int b2 : 4;
13462 unsigned int d2 : 12;
13463 } RS;
13464 struct {
13465 unsigned int op : 8;
13466 unsigned int r1 : 4;
13467 unsigned int r3 : 4;
13468 unsigned int i2 : 16;
13469 } RSI;
13470 struct {
13471 unsigned int op : 8;
13472 unsigned int r1 : 4;
13473 unsigned int x2 : 4;
13474 unsigned int b2 : 4;
13475 unsigned int d2 : 12;
13476 } RX;
13477 struct {
13478 unsigned int op : 16;
13479 unsigned int b2 : 4;
13480 unsigned int d2 : 12;
13481 } S;
13482 struct {
13483 unsigned int op : 8;
13484 unsigned int i2 : 8;
13485 unsigned int b1 : 4;
13486 unsigned int d1 : 12;
13487 } SI;
13488 } formats;
13489 union {
13490 formats fmt;
13491 UInt value;
13492 } ovl;
13493
13494 vassert(sizeof(formats) == 4);
13495
florianffbd84d2012-12-09 02:06:29 +000013496 ((UChar *)(&ovl.value))[0] = bytes[0];
13497 ((UChar *)(&ovl.value))[1] = bytes[1];
13498 ((UChar *)(&ovl.value))[2] = bytes[2];
13499 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013500
13501 switch ((ovl.value & 0xff0f0000) >> 16) {
13502 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13503 ovl.fmt.RI.i2); goto ok;
13504 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13505 ovl.fmt.RI.i2); goto ok;
13506 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
13507 ovl.fmt.RI.i2); goto ok;
13508 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
13509 ovl.fmt.RI.i2); goto ok;
13510 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
13511 ovl.fmt.RI.i2); goto ok;
13512 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
13513 ovl.fmt.RI.i2); goto ok;
13514 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
13515 ovl.fmt.RI.i2); goto ok;
13516 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
13517 ovl.fmt.RI.i2); goto ok;
13518 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
13519 ovl.fmt.RI.i2); goto ok;
13520 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
13521 ovl.fmt.RI.i2); goto ok;
13522 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
13523 ovl.fmt.RI.i2); goto ok;
13524 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
13525 ovl.fmt.RI.i2); goto ok;
13526 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
13527 ovl.fmt.RI.i2); goto ok;
13528 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
13529 ovl.fmt.RI.i2); goto ok;
13530 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
13531 ovl.fmt.RI.i2); goto ok;
13532 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
13533 ovl.fmt.RI.i2); goto ok;
13534 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
13535 ovl.fmt.RI.i2); goto ok;
13536 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
13537 ovl.fmt.RI.i2); goto ok;
13538 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
13539 ovl.fmt.RI.i2); goto ok;
13540 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
13541 ovl.fmt.RI.i2); goto ok;
13542 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13543 goto ok;
13544 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
13545 ovl.fmt.RI.i2); goto ok;
13546 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
13547 ovl.fmt.RI.i2); goto ok;
13548 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
13549 ovl.fmt.RI.i2); goto ok;
13550 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13551 goto ok;
13552 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
13553 ovl.fmt.RI.i2); goto ok;
13554 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13555 goto ok;
13556 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
13557 ovl.fmt.RI.i2); goto ok;
13558 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13559 goto ok;
13560 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
13561 ovl.fmt.RI.i2); goto ok;
13562 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13563 goto ok;
13564 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
13565 ovl.fmt.RI.i2); goto ok;
13566 }
13567
13568 switch ((ovl.value & 0xffff0000) >> 16) {
13569 case 0x8000: /* SSM */ goto unimplemented;
13570 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013571 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013572 case 0xb202: /* STIDP */ goto unimplemented;
13573 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013574 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
13575 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013576 case 0xb206: /* SCKC */ goto unimplemented;
13577 case 0xb207: /* STCKC */ goto unimplemented;
13578 case 0xb208: /* SPT */ goto unimplemented;
13579 case 0xb209: /* STPT */ goto unimplemented;
13580 case 0xb20a: /* SPKA */ goto unimplemented;
13581 case 0xb20b: /* IPK */ goto unimplemented;
13582 case 0xb20d: /* PTLB */ goto unimplemented;
13583 case 0xb210: /* SPX */ goto unimplemented;
13584 case 0xb211: /* STPX */ goto unimplemented;
13585 case 0xb212: /* STAP */ goto unimplemented;
13586 case 0xb214: /* SIE */ goto unimplemented;
13587 case 0xb218: /* PC */ goto unimplemented;
13588 case 0xb219: /* SAC */ goto unimplemented;
13589 case 0xb21a: /* CFC */ goto unimplemented;
13590 case 0xb221: /* IPTE */ goto unimplemented;
13591 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
13592 case 0xb223: /* IVSK */ goto unimplemented;
13593 case 0xb224: /* IAC */ goto unimplemented;
13594 case 0xb225: /* SSAR */ goto unimplemented;
13595 case 0xb226: /* EPAR */ goto unimplemented;
13596 case 0xb227: /* ESAR */ goto unimplemented;
13597 case 0xb228: /* PT */ goto unimplemented;
13598 case 0xb229: /* ISKE */ goto unimplemented;
13599 case 0xb22a: /* RRBE */ goto unimplemented;
13600 case 0xb22b: /* SSKE */ goto unimplemented;
13601 case 0xb22c: /* TB */ goto unimplemented;
13602 case 0xb22d: /* DXR */ goto unimplemented;
13603 case 0xb22e: /* PGIN */ goto unimplemented;
13604 case 0xb22f: /* PGOUT */ goto unimplemented;
13605 case 0xb230: /* CSCH */ goto unimplemented;
13606 case 0xb231: /* HSCH */ goto unimplemented;
13607 case 0xb232: /* MSCH */ goto unimplemented;
13608 case 0xb233: /* SSCH */ goto unimplemented;
13609 case 0xb234: /* STSCH */ goto unimplemented;
13610 case 0xb235: /* TSCH */ goto unimplemented;
13611 case 0xb236: /* TPI */ goto unimplemented;
13612 case 0xb237: /* SAL */ goto unimplemented;
13613 case 0xb238: /* RSCH */ goto unimplemented;
13614 case 0xb239: /* STCRW */ goto unimplemented;
13615 case 0xb23a: /* STCPS */ goto unimplemented;
13616 case 0xb23b: /* RCHP */ goto unimplemented;
13617 case 0xb23c: /* SCHM */ goto unimplemented;
13618 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000013619 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
13620 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013621 case 0xb244: /* SQDR */ goto unimplemented;
13622 case 0xb245: /* SQER */ goto unimplemented;
13623 case 0xb246: /* STURA */ goto unimplemented;
13624 case 0xb247: /* MSTA */ goto unimplemented;
13625 case 0xb248: /* PALB */ goto unimplemented;
13626 case 0xb249: /* EREG */ goto unimplemented;
13627 case 0xb24a: /* ESTA */ goto unimplemented;
13628 case 0xb24b: /* LURA */ goto unimplemented;
13629 case 0xb24c: /* TAR */ goto unimplemented;
13630 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
13631 ovl.fmt.RRE.r2); goto ok;
13632 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13633 goto ok;
13634 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13635 goto ok;
13636 case 0xb250: /* CSP */ goto unimplemented;
13637 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
13638 ovl.fmt.RRE.r2); goto ok;
13639 case 0xb254: /* MVPG */ goto unimplemented;
13640 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
13641 ovl.fmt.RRE.r2); goto ok;
13642 case 0xb257: /* CUSE */ goto unimplemented;
13643 case 0xb258: /* BSG */ goto unimplemented;
13644 case 0xb25a: /* BSA */ goto unimplemented;
13645 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
13646 ovl.fmt.RRE.r2); goto ok;
13647 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
13648 ovl.fmt.RRE.r2); goto ok;
13649 case 0xb263: /* CMPSC */ goto unimplemented;
13650 case 0xb274: /* SIGA */ goto unimplemented;
13651 case 0xb276: /* XSCH */ goto unimplemented;
13652 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013653 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 +000013654 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013655 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 +000013656 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013657 case 0xb280: /* LPP */ goto unimplemented;
13658 case 0xb284: /* LCCTL */ goto unimplemented;
13659 case 0xb285: /* LPCTL */ goto unimplemented;
13660 case 0xb286: /* QSI */ goto unimplemented;
13661 case 0xb287: /* LSCTL */ goto unimplemented;
13662 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013663 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
13664 goto ok;
13665 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13666 goto ok;
13667 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13668 goto ok;
florian730448f2012-02-04 17:07:07 +000013669 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 +000013670 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
13671 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13672 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000013673 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
13674 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13675 goto ok;
florian933065d2011-07-11 01:48:02 +000013676 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
13677 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013678 case 0xb2b1: /* STFL */ goto unimplemented;
13679 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000013680 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
13681 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013682 case 0xb2b9: /* SRNMT */ goto unimplemented;
13683 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013684 case 0xb2e0: /* SCCTR */ goto unimplemented;
13685 case 0xb2e1: /* SPCTR */ goto unimplemented;
13686 case 0xb2e4: /* ECCTR */ goto unimplemented;
13687 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013688 case 0xb2e8: /* PPA */ goto unimplemented;
13689 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013690 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000013691 case 0xb2f8: /* TEND */ goto unimplemented;
13692 case 0xb2fa: /* NIAI */ goto unimplemented;
13693 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013694 case 0xb2ff: /* TRAP4 */ goto unimplemented;
13695 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
13696 ovl.fmt.RRE.r2); goto ok;
13697 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
13698 ovl.fmt.RRE.r2); goto ok;
13699 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
13700 ovl.fmt.RRE.r2); goto ok;
13701 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
13702 ovl.fmt.RRE.r2); goto ok;
13703 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
13704 ovl.fmt.RRE.r2); goto ok;
13705 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
13706 ovl.fmt.RRE.r2); goto ok;
13707 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
13708 ovl.fmt.RRE.r2); goto ok;
13709 case 0xb307: /* MXDBR */ goto unimplemented;
13710 case 0xb308: /* KEBR */ goto unimplemented;
13711 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
13712 ovl.fmt.RRE.r2); goto ok;
13713 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
13714 ovl.fmt.RRE.r2); goto ok;
13715 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
13716 ovl.fmt.RRE.r2); goto ok;
13717 case 0xb30c: /* MDEBR */ goto unimplemented;
13718 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
13719 ovl.fmt.RRE.r2); goto ok;
13720 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
13721 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13722 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
13723 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13724 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
13725 ovl.fmt.RRE.r2); goto ok;
13726 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
13727 ovl.fmt.RRE.r2); goto ok;
13728 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
13729 ovl.fmt.RRE.r2); goto ok;
13730 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
13731 ovl.fmt.RRE.r2); goto ok;
13732 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
13733 ovl.fmt.RRE.r2); goto ok;
13734 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
13735 ovl.fmt.RRE.r2); goto ok;
13736 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
13737 ovl.fmt.RRE.r2); goto ok;
13738 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
13739 ovl.fmt.RRE.r2); goto ok;
13740 case 0xb318: /* KDBR */ goto unimplemented;
13741 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
13742 ovl.fmt.RRE.r2); goto ok;
13743 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
13744 ovl.fmt.RRE.r2); goto ok;
13745 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
13746 ovl.fmt.RRE.r2); goto ok;
13747 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
13748 ovl.fmt.RRE.r2); goto ok;
13749 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
13750 ovl.fmt.RRE.r2); goto ok;
13751 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
13752 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13753 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
13754 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
13755 case 0xb324: /* LDER */ goto unimplemented;
13756 case 0xb325: /* LXDR */ goto unimplemented;
13757 case 0xb326: /* LXER */ goto unimplemented;
13758 case 0xb32e: /* MAER */ goto unimplemented;
13759 case 0xb32f: /* MSER */ goto unimplemented;
13760 case 0xb336: /* SQXR */ goto unimplemented;
13761 case 0xb337: /* MEER */ goto unimplemented;
13762 case 0xb338: /* MAYLR */ goto unimplemented;
13763 case 0xb339: /* MYLR */ goto unimplemented;
13764 case 0xb33a: /* MAYR */ goto unimplemented;
13765 case 0xb33b: /* MYR */ goto unimplemented;
13766 case 0xb33c: /* MAYHR */ goto unimplemented;
13767 case 0xb33d: /* MYHR */ goto unimplemented;
13768 case 0xb33e: /* MADR */ goto unimplemented;
13769 case 0xb33f: /* MSDR */ goto unimplemented;
13770 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
13771 ovl.fmt.RRE.r2); goto ok;
13772 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
13773 ovl.fmt.RRE.r2); goto ok;
13774 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
13775 ovl.fmt.RRE.r2); goto ok;
13776 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
13777 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013778 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
13779 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13780 ovl.fmt.RRF2.r2); goto ok;
13781 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
13782 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13783 ovl.fmt.RRF2.r2); goto ok;
13784 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
13785 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13786 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013787 case 0xb347: /* FIXBR */ goto unimplemented;
13788 case 0xb348: /* KXBR */ goto unimplemented;
13789 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
13790 ovl.fmt.RRE.r2); goto ok;
13791 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
13792 ovl.fmt.RRE.r2); goto ok;
13793 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
13794 ovl.fmt.RRE.r2); goto ok;
13795 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
13796 ovl.fmt.RRE.r2); goto ok;
13797 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
13798 ovl.fmt.RRE.r2); goto ok;
13799 case 0xb350: /* TBEDR */ goto unimplemented;
13800 case 0xb351: /* TBDR */ goto unimplemented;
13801 case 0xb353: /* DIEBR */ goto unimplemented;
13802 case 0xb357: /* FIEBR */ goto unimplemented;
13803 case 0xb358: /* THDER */ goto unimplemented;
13804 case 0xb359: /* THDR */ goto unimplemented;
13805 case 0xb35b: /* DIDBR */ goto unimplemented;
13806 case 0xb35f: /* FIDBR */ goto unimplemented;
13807 case 0xb360: /* LPXR */ goto unimplemented;
13808 case 0xb361: /* LNXR */ goto unimplemented;
13809 case 0xb362: /* LTXR */ goto unimplemented;
13810 case 0xb363: /* LCXR */ goto unimplemented;
13811 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
13812 ovl.fmt.RRE.r2); goto ok;
13813 case 0xb366: /* LEXR */ goto unimplemented;
13814 case 0xb367: /* FIXR */ goto unimplemented;
13815 case 0xb369: /* CXR */ goto unimplemented;
13816 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
13817 ovl.fmt.RRE.r2); goto ok;
13818 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
13819 ovl.fmt.RRE.r2); goto ok;
13820 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
13821 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13822 goto ok;
13823 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
13824 ovl.fmt.RRE.r2); goto ok;
13825 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
13826 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
13827 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
13828 case 0xb377: /* FIER */ goto unimplemented;
13829 case 0xb37f: /* FIDR */ goto unimplemented;
13830 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
13831 case 0xb385: /* SFASR */ goto unimplemented;
13832 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013833 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
13834 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13835 ovl.fmt.RRF2.r2); goto ok;
13836 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
13837 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13838 ovl.fmt.RRF2.r2); goto ok;
13839 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
13840 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13841 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013842 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
13843 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13844 ovl.fmt.RRF2.r2); goto ok;
13845 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
13846 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13847 ovl.fmt.RRF2.r2); goto ok;
13848 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
13849 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13850 ovl.fmt.RRF2.r2); goto ok;
13851 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
13852 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13853 ovl.fmt.RRF2.r2); goto ok;
13854 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
13855 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13856 ovl.fmt.RRF2.r2); goto ok;
13857 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
13858 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13859 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013860 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
13861 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13862 ovl.fmt.RRF2.r2); goto ok;
13863 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
13864 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13865 ovl.fmt.RRF2.r2); goto ok;
13866 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
13867 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13868 ovl.fmt.RRF2.r2); goto ok;
13869 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
13870 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13871 ovl.fmt.RRF2.r2); goto ok;
13872 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
13873 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13874 ovl.fmt.RRF2.r2); goto ok;
13875 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
13876 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13877 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000013878 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
13879 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13880 ovl.fmt.RRF2.r2); goto ok;
13881 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
13882 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13883 ovl.fmt.RRF2.r2); goto ok;
13884 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
13885 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13886 ovl.fmt.RRF2.r2); goto ok;
13887 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
13888 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13889 ovl.fmt.RRF2.r2); goto ok;
13890 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
13891 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13892 ovl.fmt.RRF2.r2); goto ok;
13893 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
13894 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13895 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000013896 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
13897 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13898 ovl.fmt.RRF2.r2); goto ok;
13899 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
13900 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13901 ovl.fmt.RRF2.r2); goto ok;
13902 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
13903 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13904 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013905 case 0xb3b4: /* CEFR */ goto unimplemented;
13906 case 0xb3b5: /* CDFR */ goto unimplemented;
13907 case 0xb3b6: /* CXFR */ goto unimplemented;
13908 case 0xb3b8: /* CFER */ goto unimplemented;
13909 case 0xb3b9: /* CFDR */ goto unimplemented;
13910 case 0xb3ba: /* CFXR */ goto unimplemented;
13911 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
13912 ovl.fmt.RRE.r2); goto ok;
13913 case 0xb3c4: /* CEGR */ goto unimplemented;
13914 case 0xb3c5: /* CDGR */ goto unimplemented;
13915 case 0xb3c6: /* CXGR */ goto unimplemented;
13916 case 0xb3c8: /* CGER */ goto unimplemented;
13917 case 0xb3c9: /* CGDR */ goto unimplemented;
13918 case 0xb3ca: /* CGXR */ goto unimplemented;
13919 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
13920 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013921 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
13922 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13923 ovl.fmt.RRF4.r2); goto ok;
13924 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
13925 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13926 ovl.fmt.RRF4.r2); goto ok;
13927 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
13928 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13929 ovl.fmt.RRF4.r2); goto ok;
13930 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
13931 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13932 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000013933 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
13934 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13935 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
13936 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13937 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000013938 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
13939 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013940 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013941 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
13942 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13943 ovl.fmt.RRF4.r2); goto ok;
13944 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
13945 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13946 ovl.fmt.RRF4.r2); goto ok;
13947 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
13948 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13949 ovl.fmt.RRF4.r2); goto ok;
13950 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
13951 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
13952 ovl.fmt.RRF4.r2); goto ok;
13953 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
13954 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
13955 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
13956 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
13957 ovl.fmt.RRF2.r2); goto ok;
13958 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
13959 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013960 case 0xb3df: /* FIXTR */ goto unimplemented;
13961 case 0xb3e0: /* KDTR */ goto unimplemented;
13962 case 0xb3e1: /* CGDTR */ goto unimplemented;
13963 case 0xb3e2: /* CUDTR */ goto unimplemented;
13964 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013965 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
13966 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013967 case 0xb3e5: /* EEDTR */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000013968 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
13969 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013970 case 0xb3e8: /* KXTR */ goto unimplemented;
13971 case 0xb3e9: /* CGXTR */ goto unimplemented;
13972 case 0xb3ea: /* CUXTR */ goto unimplemented;
13973 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000013974 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
13975 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013976 case 0xb3ed: /* EEXTR */ goto unimplemented;
floriance9e3db2012-12-27 20:14:03 +000013977 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
13978 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013979 case 0xb3f1: /* CDGTR */ goto unimplemented;
13980 case 0xb3f2: /* CDUTR */ goto unimplemented;
13981 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000013982 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
13983 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013984 case 0xb3f5: /* QADTR */ goto unimplemented;
13985 case 0xb3f6: /* IEDTR */ goto unimplemented;
13986 case 0xb3f7: /* RRDTR */ goto unimplemented;
13987 case 0xb3f9: /* CXGTR */ goto unimplemented;
13988 case 0xb3fa: /* CXUTR */ goto unimplemented;
13989 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000013990 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
13991 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013992 case 0xb3fd: /* QAXTR */ goto unimplemented;
13993 case 0xb3fe: /* IEXTR */ goto unimplemented;
13994 case 0xb3ff: /* RRXTR */ goto unimplemented;
13995 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
13996 ovl.fmt.RRE.r2); goto ok;
13997 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
13998 ovl.fmt.RRE.r2); goto ok;
13999 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14000 ovl.fmt.RRE.r2); goto ok;
14001 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14002 ovl.fmt.RRE.r2); goto ok;
14003 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14004 ovl.fmt.RRE.r2); goto ok;
14005 case 0xb905: /* LURAG */ goto unimplemented;
14006 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14007 ovl.fmt.RRE.r2); goto ok;
14008 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14009 ovl.fmt.RRE.r2); goto ok;
14010 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14011 ovl.fmt.RRE.r2); goto ok;
14012 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14013 ovl.fmt.RRE.r2); goto ok;
14014 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14015 ovl.fmt.RRE.r2); goto ok;
14016 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14017 ovl.fmt.RRE.r2); goto ok;
14018 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14019 ovl.fmt.RRE.r2); goto ok;
14020 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14021 ovl.fmt.RRE.r2); goto ok;
14022 case 0xb90e: /* EREGG */ goto unimplemented;
14023 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14024 ovl.fmt.RRE.r2); goto ok;
14025 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14026 ovl.fmt.RRE.r2); goto ok;
14027 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14028 ovl.fmt.RRE.r2); goto ok;
14029 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14030 ovl.fmt.RRE.r2); goto ok;
14031 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14032 ovl.fmt.RRE.r2); goto ok;
14033 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14034 ovl.fmt.RRE.r2); goto ok;
14035 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14036 ovl.fmt.RRE.r2); goto ok;
14037 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14038 ovl.fmt.RRE.r2); goto ok;
14039 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14040 ovl.fmt.RRE.r2); goto ok;
14041 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14042 ovl.fmt.RRE.r2); goto ok;
14043 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14044 ovl.fmt.RRE.r2); goto ok;
14045 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14046 ovl.fmt.RRE.r2); goto ok;
14047 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14048 ovl.fmt.RRE.r2); goto ok;
14049 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14050 ovl.fmt.RRE.r2); goto ok;
14051 case 0xb91e: /* KMAC */ goto unimplemented;
14052 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14053 ovl.fmt.RRE.r2); goto ok;
14054 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14055 ovl.fmt.RRE.r2); goto ok;
14056 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14057 ovl.fmt.RRE.r2); goto ok;
14058 case 0xb925: /* STURG */ goto unimplemented;
14059 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14060 ovl.fmt.RRE.r2); goto ok;
14061 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14062 ovl.fmt.RRE.r2); goto ok;
14063 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014064 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014065 case 0xb92b: /* KMO */ goto unimplemented;
14066 case 0xb92c: /* PCC */ goto unimplemented;
14067 case 0xb92d: /* KMCTR */ goto unimplemented;
14068 case 0xb92e: /* KM */ goto unimplemented;
14069 case 0xb92f: /* KMC */ goto unimplemented;
14070 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14071 ovl.fmt.RRE.r2); goto ok;
14072 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14073 ovl.fmt.RRE.r2); goto ok;
14074 case 0xb93e: /* KIMD */ goto unimplemented;
14075 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014076 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14077 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14078 ovl.fmt.RRF2.r2); goto ok;
14079 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14080 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14081 ovl.fmt.RRF2.r2); goto ok;
14082 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14083 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14084 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014085 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14086 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014087 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14088 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14089 ovl.fmt.RRF2.r2); goto ok;
14090 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14091 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14092 ovl.fmt.RRF2.r2); goto ok;
14093 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14094 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14095 ovl.fmt.RRF2.r2); goto ok;
14096 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14097 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14098 ovl.fmt.RRF2.r2); goto ok;
14099 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14100 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14101 ovl.fmt.RRF2.r2); goto ok;
14102 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14103 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14104 ovl.fmt.RRF2.r2); goto ok;
14105 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14106 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14107 ovl.fmt.RRF2.r2); goto ok;
14108 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14109 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14110 ovl.fmt.RRF2.r2); goto ok;
14111 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14112 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14113 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014114 case 0xb960: /* CGRT */ goto unimplemented;
14115 case 0xb961: /* CLGRT */ goto unimplemented;
14116 case 0xb972: /* CRT */ goto unimplemented;
14117 case 0xb973: /* CLRT */ goto unimplemented;
14118 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14119 ovl.fmt.RRE.r2); goto ok;
14120 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14121 ovl.fmt.RRE.r2); goto ok;
14122 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14123 ovl.fmt.RRE.r2); goto ok;
14124 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14125 ovl.fmt.RRE.r2); goto ok;
14126 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14127 ovl.fmt.RRE.r2); goto ok;
14128 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14129 ovl.fmt.RRE.r2); goto ok;
14130 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14131 ovl.fmt.RRE.r2); goto ok;
14132 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14133 ovl.fmt.RRE.r2); goto ok;
14134 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14135 ovl.fmt.RRE.r2); goto ok;
14136 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14137 ovl.fmt.RRE.r2); goto ok;
14138 case 0xb98a: /* CSPG */ goto unimplemented;
14139 case 0xb98d: /* EPSW */ goto unimplemented;
14140 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014141 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014142 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14143 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14144 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14145 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14146 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14147 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014148 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14149 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014150 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14151 ovl.fmt.RRE.r2); goto ok;
14152 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14153 ovl.fmt.RRE.r2); goto ok;
14154 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14155 ovl.fmt.RRE.r2); goto ok;
14156 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14157 ovl.fmt.RRE.r2); goto ok;
14158 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14159 ovl.fmt.RRE.r2); goto ok;
14160 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14161 ovl.fmt.RRE.r2); goto ok;
14162 case 0xb99a: /* EPAIR */ goto unimplemented;
14163 case 0xb99b: /* ESAIR */ goto unimplemented;
14164 case 0xb99d: /* ESEA */ goto unimplemented;
14165 case 0xb99e: /* PTI */ goto unimplemented;
14166 case 0xb99f: /* SSAIR */ goto unimplemented;
14167 case 0xb9a2: /* PTF */ goto unimplemented;
14168 case 0xb9aa: /* LPTEA */ goto unimplemented;
14169 case 0xb9ae: /* RRBM */ goto unimplemented;
14170 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014171 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14172 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14173 goto ok;
florian2a415a12012-07-21 17:41:36 +000014174 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14175 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14176 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014177 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14178 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014179 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14180 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014181 case 0xb9bd: /* TRTRE */ goto unimplemented;
14182 case 0xb9be: /* SRSTU */ goto unimplemented;
14183 case 0xb9bf: /* TRTE */ goto unimplemented;
14184 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14185 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14186 goto ok;
14187 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14188 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14189 goto ok;
14190 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14191 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14192 goto ok;
14193 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14194 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14195 goto ok;
14196 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14197 ovl.fmt.RRE.r2); goto ok;
14198 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14199 ovl.fmt.RRE.r2); goto ok;
14200 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14201 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14202 goto ok;
14203 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14204 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14205 goto ok;
14206 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14207 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14208 goto ok;
14209 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14210 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14211 goto ok;
14212 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14213 ovl.fmt.RRE.r2); goto ok;
14214 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14215 ovl.fmt.RRE.r2); goto ok;
14216 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014217 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14218 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14219 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014220 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14221 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14222 goto ok;
14223 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14224 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14225 goto ok;
14226 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14227 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14228 goto ok;
14229 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14230 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14231 goto ok;
14232 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14233 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14234 goto ok;
14235 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14236 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14237 goto ok;
14238 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14239 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14240 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014241 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14242 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14243 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014244 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14245 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14246 goto ok;
14247 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14248 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14249 goto ok;
14250 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14251 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14252 goto ok;
14253 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14254 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14255 goto ok;
14256 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14257 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14258 goto ok;
14259 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14260 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14261 goto ok;
14262 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14263 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14264 goto ok;
14265 }
14266
14267 switch ((ovl.value & 0xff000000) >> 24) {
14268 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14269 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14270 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14271 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14272 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14273 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14274 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14275 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14276 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14277 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14278 case 0x45: /* BAL */ goto unimplemented;
14279 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14280 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14281 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14282 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14283 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14284 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14285 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14286 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14287 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14288 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14289 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14290 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14291 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14292 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14293 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14294 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14295 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14296 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14297 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14298 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14299 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14300 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14301 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14302 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14303 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14304 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14305 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14306 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14307 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14308 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14309 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14310 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14311 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14312 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14313 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14314 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14315 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14316 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14317 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14318 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14319 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14320 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14321 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14322 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14323 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14324 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14325 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14326 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14327 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14328 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14329 case 0x67: /* MXD */ goto unimplemented;
14330 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14331 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14332 case 0x69: /* CD */ goto unimplemented;
14333 case 0x6a: /* AD */ goto unimplemented;
14334 case 0x6b: /* SD */ goto unimplemented;
14335 case 0x6c: /* MD */ goto unimplemented;
14336 case 0x6d: /* DD */ goto unimplemented;
14337 case 0x6e: /* AW */ goto unimplemented;
14338 case 0x6f: /* SW */ goto unimplemented;
14339 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14340 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14341 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14342 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14343 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14344 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14345 case 0x79: /* CE */ goto unimplemented;
14346 case 0x7a: /* AE */ goto unimplemented;
14347 case 0x7b: /* SE */ goto unimplemented;
14348 case 0x7c: /* MDE */ goto unimplemented;
14349 case 0x7d: /* DE */ goto unimplemented;
14350 case 0x7e: /* AU */ goto unimplemented;
14351 case 0x7f: /* SU */ goto unimplemented;
14352 case 0x83: /* DIAG */ goto unimplemented;
14353 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
14354 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14355 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
14356 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14357 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14358 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14359 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14360 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14361 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14362 ovl.fmt.RS.d2); goto ok;
14363 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14364 ovl.fmt.RS.d2); goto ok;
14365 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14366 ovl.fmt.RS.d2); goto ok;
14367 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14368 ovl.fmt.RS.d2); goto ok;
14369 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14370 ovl.fmt.RS.d2); goto ok;
14371 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14372 ovl.fmt.RS.d2); goto ok;
14373 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14374 ovl.fmt.RS.d2); goto ok;
14375 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14376 ovl.fmt.RS.d2); goto ok;
14377 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14378 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14379 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14380 ovl.fmt.SI.d1); goto ok;
14381 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14382 ovl.fmt.SI.d1); goto ok;
14383 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14384 ovl.fmt.SI.d1); goto ok;
14385 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14386 ovl.fmt.SI.d1); goto ok;
14387 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14388 ovl.fmt.SI.d1); goto ok;
14389 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14390 ovl.fmt.SI.d1); goto ok;
14391 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14392 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14393 case 0x99: /* TRACE */ goto unimplemented;
14394 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14395 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14396 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14397 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14398 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
14399 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14400 goto ok;
14401 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
14402 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14403 goto ok;
14404 case 0xac: /* STNSM */ goto unimplemented;
14405 case 0xad: /* STOSM */ goto unimplemented;
14406 case 0xae: /* SIGP */ goto unimplemented;
14407 case 0xaf: /* MC */ goto unimplemented;
14408 case 0xb1: /* LRA */ goto unimplemented;
14409 case 0xb6: /* STCTL */ goto unimplemented;
14410 case 0xb7: /* LCTL */ goto unimplemented;
14411 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14412 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014413 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14414 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014415 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14416 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14417 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14418 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14419 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14420 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14421 }
14422
14423 return S390_DECODE_UNKNOWN_INSN;
14424
14425ok:
14426 return S390_DECODE_OK;
14427
14428unimplemented:
14429 return S390_DECODE_UNIMPLEMENTED_INSN;
14430}
14431
14432static s390_decode_t
14433s390_decode_6byte_and_irgen(UChar *bytes)
14434{
14435 typedef union {
14436 struct {
14437 unsigned int op1 : 8;
14438 unsigned int r1 : 4;
14439 unsigned int r3 : 4;
14440 unsigned int i2 : 16;
14441 unsigned int : 8;
14442 unsigned int op2 : 8;
14443 } RIE;
14444 struct {
14445 unsigned int op1 : 8;
14446 unsigned int r1 : 4;
14447 unsigned int r2 : 4;
14448 unsigned int i3 : 8;
14449 unsigned int i4 : 8;
14450 unsigned int i5 : 8;
14451 unsigned int op2 : 8;
14452 } RIE_RRUUU;
14453 struct {
14454 unsigned int op1 : 8;
14455 unsigned int r1 : 4;
14456 unsigned int : 4;
14457 unsigned int i2 : 16;
14458 unsigned int m3 : 4;
14459 unsigned int : 4;
14460 unsigned int op2 : 8;
14461 } RIEv1;
14462 struct {
14463 unsigned int op1 : 8;
14464 unsigned int r1 : 4;
14465 unsigned int r2 : 4;
14466 unsigned int i4 : 16;
14467 unsigned int m3 : 4;
14468 unsigned int : 4;
14469 unsigned int op2 : 8;
14470 } RIE_RRPU;
14471 struct {
14472 unsigned int op1 : 8;
14473 unsigned int r1 : 4;
14474 unsigned int m3 : 4;
14475 unsigned int i4 : 16;
14476 unsigned int i2 : 8;
14477 unsigned int op2 : 8;
14478 } RIEv3;
14479 struct {
14480 unsigned int op1 : 8;
14481 unsigned int r1 : 4;
14482 unsigned int op2 : 4;
14483 unsigned int i2 : 32;
14484 } RIL;
14485 struct {
14486 unsigned int op1 : 8;
14487 unsigned int r1 : 4;
14488 unsigned int m3 : 4;
14489 unsigned int b4 : 4;
14490 unsigned int d4 : 12;
14491 unsigned int i2 : 8;
14492 unsigned int op2 : 8;
14493 } RIS;
14494 struct {
14495 unsigned int op1 : 8;
14496 unsigned int r1 : 4;
14497 unsigned int r2 : 4;
14498 unsigned int b4 : 4;
14499 unsigned int d4 : 12;
14500 unsigned int m3 : 4;
14501 unsigned int : 4;
14502 unsigned int op2 : 8;
14503 } RRS;
14504 struct {
14505 unsigned int op1 : 8;
14506 unsigned int l1 : 4;
14507 unsigned int : 4;
14508 unsigned int b1 : 4;
14509 unsigned int d1 : 12;
14510 unsigned int : 8;
14511 unsigned int op2 : 8;
14512 } RSL;
14513 struct {
14514 unsigned int op1 : 8;
14515 unsigned int r1 : 4;
14516 unsigned int r3 : 4;
14517 unsigned int b2 : 4;
14518 unsigned int dl2 : 12;
14519 unsigned int dh2 : 8;
14520 unsigned int op2 : 8;
14521 } RSY;
14522 struct {
14523 unsigned int op1 : 8;
14524 unsigned int r1 : 4;
14525 unsigned int x2 : 4;
14526 unsigned int b2 : 4;
14527 unsigned int d2 : 12;
14528 unsigned int : 8;
14529 unsigned int op2 : 8;
14530 } RXE;
14531 struct {
14532 unsigned int op1 : 8;
14533 unsigned int r3 : 4;
14534 unsigned int x2 : 4;
14535 unsigned int b2 : 4;
14536 unsigned int d2 : 12;
14537 unsigned int r1 : 4;
14538 unsigned int : 4;
14539 unsigned int op2 : 8;
14540 } RXF;
14541 struct {
14542 unsigned int op1 : 8;
14543 unsigned int r1 : 4;
14544 unsigned int x2 : 4;
14545 unsigned int b2 : 4;
14546 unsigned int dl2 : 12;
14547 unsigned int dh2 : 8;
14548 unsigned int op2 : 8;
14549 } RXY;
14550 struct {
14551 unsigned int op1 : 8;
14552 unsigned int i2 : 8;
14553 unsigned int b1 : 4;
14554 unsigned int dl1 : 12;
14555 unsigned int dh1 : 8;
14556 unsigned int op2 : 8;
14557 } SIY;
14558 struct {
14559 unsigned int op : 8;
14560 unsigned int l : 8;
14561 unsigned int b1 : 4;
14562 unsigned int d1 : 12;
14563 unsigned int b2 : 4;
14564 unsigned int d2 : 12;
14565 } SS;
14566 struct {
14567 unsigned int op : 8;
14568 unsigned int l1 : 4;
14569 unsigned int l2 : 4;
14570 unsigned int b1 : 4;
14571 unsigned int d1 : 12;
14572 unsigned int b2 : 4;
14573 unsigned int d2 : 12;
14574 } SS_LLRDRD;
14575 struct {
14576 unsigned int op : 8;
14577 unsigned int r1 : 4;
14578 unsigned int r3 : 4;
14579 unsigned int b2 : 4;
14580 unsigned int d2 : 12;
14581 unsigned int b4 : 4;
14582 unsigned int d4 : 12;
14583 } SS_RRRDRD2;
14584 struct {
14585 unsigned int op : 16;
14586 unsigned int b1 : 4;
14587 unsigned int d1 : 12;
14588 unsigned int b2 : 4;
14589 unsigned int d2 : 12;
14590 } SSE;
14591 struct {
14592 unsigned int op1 : 8;
14593 unsigned int r3 : 4;
14594 unsigned int op2 : 4;
14595 unsigned int b1 : 4;
14596 unsigned int d1 : 12;
14597 unsigned int b2 : 4;
14598 unsigned int d2 : 12;
14599 } SSF;
14600 struct {
14601 unsigned int op : 16;
14602 unsigned int b1 : 4;
14603 unsigned int d1 : 12;
14604 unsigned int i2 : 16;
14605 } SIL;
14606 } formats;
14607 union {
14608 formats fmt;
14609 ULong value;
14610 } ovl;
14611
14612 vassert(sizeof(formats) == 6);
14613
florianffbd84d2012-12-09 02:06:29 +000014614 ((UChar *)(&ovl.value))[0] = bytes[0];
14615 ((UChar *)(&ovl.value))[1] = bytes[1];
14616 ((UChar *)(&ovl.value))[2] = bytes[2];
14617 ((UChar *)(&ovl.value))[3] = bytes[3];
14618 ((UChar *)(&ovl.value))[4] = bytes[4];
14619 ((UChar *)(&ovl.value))[5] = bytes[5];
14620 ((UChar *)(&ovl.value))[6] = 0x0;
14621 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000014622
14623 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
14624 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, ovl.fmt.RXY.r1,
14625 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14626 ovl.fmt.RXY.dl2,
14627 ovl.fmt.RXY.dh2); goto ok;
14628 case 0xe30000000003ULL: /* LRAG */ goto unimplemented;
14629 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
14630 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14631 ovl.fmt.RXY.dl2,
14632 ovl.fmt.RXY.dh2); goto ok;
14633 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, ovl.fmt.RXY.r1,
14634 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14635 ovl.fmt.RXY.dl2,
14636 ovl.fmt.RXY.dh2); goto ok;
14637 case 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, ovl.fmt.RXY.r1,
14638 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14639 ovl.fmt.RXY.dl2,
14640 ovl.fmt.RXY.dh2); goto ok;
14641 case 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, ovl.fmt.RXY.r1,
14642 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14643 ovl.fmt.RXY.dl2,
14644 ovl.fmt.RXY.dh2); goto ok;
14645 case 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, ovl.fmt.RXY.r1,
14646 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14647 ovl.fmt.RXY.dl2,
14648 ovl.fmt.RXY.dh2); goto ok;
14649 case 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
14650 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14651 ovl.fmt.RXY.dl2,
14652 ovl.fmt.RXY.dh2); goto ok;
14653 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
14654 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14655 ovl.fmt.RXY.dl2,
14656 ovl.fmt.RXY.dh2); goto ok;
14657 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
14658 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14659 ovl.fmt.RXY.dl2,
14660 ovl.fmt.RXY.dh2); goto ok;
14661 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
14662 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
14663 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14664 ovl.fmt.RXY.dl2,
14665 ovl.fmt.RXY.dh2); goto ok;
14666 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
14667 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14668 ovl.fmt.RXY.dl2,
14669 ovl.fmt.RXY.dh2); goto ok;
14670 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
14671 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
14672 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14673 ovl.fmt.RXY.dl2,
14674 ovl.fmt.RXY.dh2); goto ok;
14675 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
14676 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14677 ovl.fmt.RXY.dl2,
14678 ovl.fmt.RXY.dh2); goto ok;
14679 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
14680 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14681 ovl.fmt.RXY.dl2,
14682 ovl.fmt.RXY.dh2); goto ok;
14683 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
14684 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14685 ovl.fmt.RXY.dl2,
14686 ovl.fmt.RXY.dh2); goto ok;
14687 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
14688 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14689 ovl.fmt.RXY.dl2,
14690 ovl.fmt.RXY.dh2); goto ok;
14691 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
14692 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14693 ovl.fmt.RXY.dl2,
14694 ovl.fmt.RXY.dh2); goto ok;
14695 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
14696 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14697 ovl.fmt.RXY.dl2,
14698 ovl.fmt.RXY.dh2); goto ok;
14699 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
14700 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14701 ovl.fmt.RXY.dl2,
14702 ovl.fmt.RXY.dh2); goto ok;
14703 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
14704 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14705 ovl.fmt.RXY.dl2,
14706 ovl.fmt.RXY.dh2); goto ok;
14707 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
14708 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14709 ovl.fmt.RXY.dl2,
14710 ovl.fmt.RXY.dh2); goto ok;
14711 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
14712 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14713 ovl.fmt.RXY.dl2,
14714 ovl.fmt.RXY.dh2); goto ok;
14715 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
14716 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14717 ovl.fmt.RXY.dl2,
14718 ovl.fmt.RXY.dh2); goto ok;
14719 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
14720 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14721 ovl.fmt.RXY.dl2,
14722 ovl.fmt.RXY.dh2); goto ok;
14723 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
14724 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14725 ovl.fmt.RXY.dl2,
14726 ovl.fmt.RXY.dh2); goto ok;
14727 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
14728 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14729 ovl.fmt.RXY.dl2,
14730 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014731 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014732 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
14733 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14734 ovl.fmt.RXY.dl2,
14735 ovl.fmt.RXY.dh2); goto ok;
14736 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
14737 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
14738 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14739 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14740 ovl.fmt.RXY.dh2); goto ok;
14741 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
14742 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14743 ovl.fmt.RXY.dl2,
14744 ovl.fmt.RXY.dh2); goto ok;
14745 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
14746 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14747 ovl.fmt.RXY.dl2,
14748 ovl.fmt.RXY.dh2); goto ok;
14749 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
14750 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14751 ovl.fmt.RXY.dl2,
14752 ovl.fmt.RXY.dh2); goto ok;
14753 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
14754 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14755 ovl.fmt.RXY.dl2,
14756 ovl.fmt.RXY.dh2); goto ok;
14757 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
14758 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14759 ovl.fmt.RXY.dl2,
14760 ovl.fmt.RXY.dh2); goto ok;
14761 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
14762 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14763 ovl.fmt.RXY.dl2,
14764 ovl.fmt.RXY.dh2); goto ok;
14765 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
14766 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
14767 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
14768 ovl.fmt.RXY.dh2); goto ok;
14769 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
14770 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14771 ovl.fmt.RXY.dl2,
14772 ovl.fmt.RXY.dh2); goto ok;
14773 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
14774 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14775 ovl.fmt.RXY.dl2,
14776 ovl.fmt.RXY.dh2); goto ok;
14777 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
14778 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14779 ovl.fmt.RXY.dl2,
14780 ovl.fmt.RXY.dh2); goto ok;
14781 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
14782 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14783 ovl.fmt.RXY.dl2,
14784 ovl.fmt.RXY.dh2); goto ok;
14785 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
14786 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14787 ovl.fmt.RXY.dl2,
14788 ovl.fmt.RXY.dh2); goto ok;
14789 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
14790 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14791 ovl.fmt.RXY.dl2,
14792 ovl.fmt.RXY.dh2); goto ok;
14793 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
14794 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14795 ovl.fmt.RXY.dl2,
14796 ovl.fmt.RXY.dh2); goto ok;
14797 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
14798 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14799 ovl.fmt.RXY.dl2,
14800 ovl.fmt.RXY.dh2); goto ok;
14801 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
14802 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14803 ovl.fmt.RXY.dl2,
14804 ovl.fmt.RXY.dh2); goto ok;
14805 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
14806 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14807 ovl.fmt.RXY.dl2,
14808 ovl.fmt.RXY.dh2); goto ok;
14809 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
14810 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14811 ovl.fmt.RXY.dl2,
14812 ovl.fmt.RXY.dh2); goto ok;
14813 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
14814 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14815 ovl.fmt.RXY.dl2,
14816 ovl.fmt.RXY.dh2); goto ok;
14817 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
14818 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14819 ovl.fmt.RXY.dl2,
14820 ovl.fmt.RXY.dh2); goto ok;
14821 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
14822 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14823 ovl.fmt.RXY.dl2,
14824 ovl.fmt.RXY.dh2); goto ok;
14825 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
14826 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14827 ovl.fmt.RXY.dl2,
14828 ovl.fmt.RXY.dh2); goto ok;
14829 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
14830 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14831 ovl.fmt.RXY.dl2,
14832 ovl.fmt.RXY.dh2); goto ok;
14833 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
14834 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14835 ovl.fmt.RXY.dl2,
14836 ovl.fmt.RXY.dh2); goto ok;
14837 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
14838 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14839 ovl.fmt.RXY.dl2,
14840 ovl.fmt.RXY.dh2); goto ok;
14841 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
14842 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14843 ovl.fmt.RXY.dl2,
14844 ovl.fmt.RXY.dh2); goto ok;
14845 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
14846 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14847 ovl.fmt.RXY.dl2,
14848 ovl.fmt.RXY.dh2); goto ok;
14849 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
14850 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14851 ovl.fmt.RXY.dl2,
14852 ovl.fmt.RXY.dh2); goto ok;
14853 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
14854 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14855 ovl.fmt.RXY.dl2,
14856 ovl.fmt.RXY.dh2); goto ok;
14857 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
14858 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14859 ovl.fmt.RXY.dl2,
14860 ovl.fmt.RXY.dh2); goto ok;
14861 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
14862 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14863 ovl.fmt.RXY.dl2,
14864 ovl.fmt.RXY.dh2); goto ok;
14865 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
14866 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14867 ovl.fmt.RXY.dl2,
14868 ovl.fmt.RXY.dh2); goto ok;
14869 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
14870 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14871 ovl.fmt.RXY.dl2,
14872 ovl.fmt.RXY.dh2); goto ok;
14873 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
14874 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14875 ovl.fmt.RXY.dl2,
14876 ovl.fmt.RXY.dh2); goto ok;
14877 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
14878 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14879 ovl.fmt.RXY.dl2,
14880 ovl.fmt.RXY.dh2); goto ok;
14881 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
14882 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14883 ovl.fmt.RXY.dl2,
14884 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014885 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014886 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
14887 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14888 ovl.fmt.RXY.dl2,
14889 ovl.fmt.RXY.dh2); goto ok;
14890 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
14891 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14892 ovl.fmt.RXY.dl2,
14893 ovl.fmt.RXY.dh2); goto ok;
14894 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
14895 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14896 ovl.fmt.RXY.dl2,
14897 ovl.fmt.RXY.dh2); goto ok;
14898 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
14899 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14900 ovl.fmt.RXY.dl2,
14901 ovl.fmt.RXY.dh2); goto ok;
14902 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
14903 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14904 ovl.fmt.RXY.dl2,
14905 ovl.fmt.RXY.dh2); goto ok;
14906 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
14907 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14908 ovl.fmt.RXY.dl2,
14909 ovl.fmt.RXY.dh2); goto ok;
14910 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
14911 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14912 ovl.fmt.RXY.dl2,
14913 ovl.fmt.RXY.dh2); goto ok;
14914 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
14915 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14916 ovl.fmt.RXY.dl2,
14917 ovl.fmt.RXY.dh2); goto ok;
14918 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
14919 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14920 ovl.fmt.RXY.dl2,
14921 ovl.fmt.RXY.dh2); goto ok;
14922 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
14923 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14924 ovl.fmt.RXY.dl2,
14925 ovl.fmt.RXY.dh2); goto ok;
14926 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
14927 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14928 ovl.fmt.RXY.dl2,
14929 ovl.fmt.RXY.dh2); goto ok;
14930 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
14931 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14932 ovl.fmt.RXY.dl2,
14933 ovl.fmt.RXY.dh2); goto ok;
14934 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
14935 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14936 ovl.fmt.RXY.dl2,
14937 ovl.fmt.RXY.dh2); goto ok;
14938 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
14939 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14940 ovl.fmt.RXY.dl2,
14941 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014942 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
14943 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
14944 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014945 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
14946 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14947 ovl.fmt.RXY.dl2,
14948 ovl.fmt.RXY.dh2); goto ok;
14949 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
14950 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14951 ovl.fmt.RXY.dl2,
14952 ovl.fmt.RXY.dh2); goto ok;
14953 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
14954 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14955 ovl.fmt.RXY.dl2,
14956 ovl.fmt.RXY.dh2); goto ok;
14957 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
14958 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14959 ovl.fmt.RXY.dl2,
14960 ovl.fmt.RXY.dh2); goto ok;
14961 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
14962 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14963 ovl.fmt.RXY.dl2,
14964 ovl.fmt.RXY.dh2); goto ok;
14965 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
14966 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14967 ovl.fmt.RXY.dl2,
14968 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000014969 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014970 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
14971 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14972 ovl.fmt.RXY.dl2,
14973 ovl.fmt.RXY.dh2); goto ok;
14974 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
14975 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14976 ovl.fmt.RXY.dl2,
14977 ovl.fmt.RXY.dh2); goto ok;
14978 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
14979 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14980 ovl.fmt.RXY.dl2,
14981 ovl.fmt.RXY.dh2); goto ok;
14982 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
14983 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14984 ovl.fmt.RXY.dl2,
14985 ovl.fmt.RXY.dh2); goto ok;
14986 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
14987 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14988 ovl.fmt.RSY.dl2,
14989 ovl.fmt.RSY.dh2); goto ok;
14990 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
14991 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14992 ovl.fmt.RSY.dl2,
14993 ovl.fmt.RSY.dh2); goto ok;
14994 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
14995 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
14996 ovl.fmt.RSY.dl2,
14997 ovl.fmt.RSY.dh2); goto ok;
14998 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
14999 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15000 ovl.fmt.RSY.dl2,
15001 ovl.fmt.RSY.dh2); goto ok;
15002 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15003 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15004 ovl.fmt.RSY.dl2,
15005 ovl.fmt.RSY.dh2); goto ok;
15006 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15007 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15008 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15009 ovl.fmt.RSY.dl2,
15010 ovl.fmt.RSY.dh2); goto ok;
15011 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15012 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15013 ovl.fmt.RSY.dl2,
15014 ovl.fmt.RSY.dh2); goto ok;
15015 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15016 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15017 ovl.fmt.RSY.dl2,
15018 ovl.fmt.RSY.dh2); goto ok;
15019 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15020 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15021 ovl.fmt.RSY.dl2,
15022 ovl.fmt.RSY.dh2); goto ok;
15023 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15024 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15025 ovl.fmt.RSY.dl2,
15026 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015027 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015028 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15029 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15030 ovl.fmt.RSY.dl2,
15031 ovl.fmt.RSY.dh2); goto ok;
15032 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15033 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15034 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15035 ovl.fmt.RSY.dl2,
15036 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015037 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015038 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15039 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15040 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15041 ovl.fmt.RSY.dh2); goto ok;
15042 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15043 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15044 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15045 ovl.fmt.RSY.dh2); goto ok;
15046 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15047 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15048 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15049 ovl.fmt.RSY.dl2,
15050 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015051 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15052 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15053 ovl.fmt.RSY.dl2,
15054 ovl.fmt.RSY.dh2); goto ok;
15055 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15056 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15057 ovl.fmt.RSY.dl2,
15058 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015059 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15060 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15061 ovl.fmt.RSY.dl2,
15062 ovl.fmt.RSY.dh2); goto ok;
15063 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15064 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15065 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15066 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015067 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15068 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15069 ovl.fmt.RSY.dl2,
15070 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015071 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15072 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15073 ovl.fmt.SIY.dh1); goto ok;
15074 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15075 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15076 ovl.fmt.SIY.dh1); goto ok;
15077 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15078 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15079 ovl.fmt.SIY.dh1); goto ok;
15080 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15081 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15082 ovl.fmt.SIY.dh1); goto ok;
15083 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15084 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15085 ovl.fmt.SIY.dh1); goto ok;
15086 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15087 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15088 ovl.fmt.SIY.dh1); goto ok;
15089 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15090 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15091 ovl.fmt.SIY.dh1); goto ok;
15092 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15093 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15094 ovl.fmt.SIY.dh1); goto ok;
15095 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15096 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15097 ovl.fmt.SIY.dh1); goto ok;
15098 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15099 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15100 ovl.fmt.SIY.dh1); goto ok;
15101 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15102 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15103 ovl.fmt.RSY.dl2,
15104 ovl.fmt.RSY.dh2); goto ok;
15105 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15106 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15107 ovl.fmt.RSY.dl2,
15108 ovl.fmt.RSY.dh2); goto ok;
15109 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15110 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15111 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15112 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15113 ovl.fmt.RSY.dl2,
15114 ovl.fmt.RSY.dh2); goto ok;
15115 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15116 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15117 ovl.fmt.RSY.dl2,
15118 ovl.fmt.RSY.dh2); goto ok;
15119 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15120 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15121 ovl.fmt.RSY.dl2,
15122 ovl.fmt.RSY.dh2); goto ok;
15123 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15124 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15125 ovl.fmt.RSY.dl2,
15126 ovl.fmt.RSY.dh2); goto ok;
15127 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15128 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15129 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15130 ovl.fmt.RSY.dh2); goto ok;
15131 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15132 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15133 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15134 ovl.fmt.RSY.dl2,
15135 ovl.fmt.RSY.dh2); goto ok;
15136 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15137 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15138 ovl.fmt.RSY.dl2,
15139 ovl.fmt.RSY.dh2); goto ok;
15140 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15141 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15142 ovl.fmt.RSY.dl2,
15143 ovl.fmt.RSY.dh2); goto ok;
15144 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15145 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15146 ovl.fmt.RSY.dl2,
15147 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015148 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15149 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15150 ovl.fmt.RSY.dl2,
15151 ovl.fmt.RSY.dh2,
15152 S390_XMNM_LOCG); goto ok;
15153 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15154 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15155 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15156 ovl.fmt.RSY.dh2,
15157 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015158 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15159 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15160 ovl.fmt.RSY.dl2,
15161 ovl.fmt.RSY.dh2); goto ok;
15162 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15163 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15164 ovl.fmt.RSY.dl2,
15165 ovl.fmt.RSY.dh2); goto ok;
15166 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15167 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15168 ovl.fmt.RSY.dl2,
15169 ovl.fmt.RSY.dh2); goto ok;
15170 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15171 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15172 ovl.fmt.RSY.dl2,
15173 ovl.fmt.RSY.dh2); goto ok;
15174 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15175 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15176 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15177 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015178 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15179 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15180 ovl.fmt.RSY.dl2,
15181 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15182 goto ok;
15183 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15184 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15185 ovl.fmt.RSY.dl2,
15186 ovl.fmt.RSY.dh2,
15187 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015188 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15189 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15190 ovl.fmt.RSY.dl2,
15191 ovl.fmt.RSY.dh2); goto ok;
15192 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15193 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15194 ovl.fmt.RSY.dl2,
15195 ovl.fmt.RSY.dh2); goto ok;
15196 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15197 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15198 ovl.fmt.RSY.dl2,
15199 ovl.fmt.RSY.dh2); goto ok;
15200 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15201 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15202 ovl.fmt.RSY.dl2,
15203 ovl.fmt.RSY.dh2); goto ok;
15204 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15205 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15206 ovl.fmt.RSY.dl2,
15207 ovl.fmt.RSY.dh2); goto ok;
15208 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15209 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15210 goto ok;
15211 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15212 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15213 goto ok;
15214 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15215 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15216 ovl.fmt.RIE_RRUUU.r1,
15217 ovl.fmt.RIE_RRUUU.r2,
15218 ovl.fmt.RIE_RRUUU.i3,
15219 ovl.fmt.RIE_RRUUU.i4,
15220 ovl.fmt.RIE_RRUUU.i5);
15221 goto ok;
15222 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15223 ovl.fmt.RIE_RRUUU.r1,
15224 ovl.fmt.RIE_RRUUU.r2,
15225 ovl.fmt.RIE_RRUUU.i3,
15226 ovl.fmt.RIE_RRUUU.i4,
15227 ovl.fmt.RIE_RRUUU.i5);
15228 goto ok;
15229 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15230 ovl.fmt.RIE_RRUUU.r1,
15231 ovl.fmt.RIE_RRUUU.r2,
15232 ovl.fmt.RIE_RRUUU.i3,
15233 ovl.fmt.RIE_RRUUU.i4,
15234 ovl.fmt.RIE_RRUUU.i5);
15235 goto ok;
15236 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15237 ovl.fmt.RIE_RRUUU.r1,
15238 ovl.fmt.RIE_RRUUU.r2,
15239 ovl.fmt.RIE_RRUUU.i3,
15240 ovl.fmt.RIE_RRUUU.i4,
15241 ovl.fmt.RIE_RRUUU.i5);
15242 goto ok;
florian2289cd42012-12-05 04:23:42 +000015243 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015244 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15245 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15246 ovl.fmt.RIE_RRPU.r1,
15247 ovl.fmt.RIE_RRPU.r2,
15248 ovl.fmt.RIE_RRPU.i4,
15249 ovl.fmt.RIE_RRPU.m3); goto ok;
15250 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15251 ovl.fmt.RIE_RRPU.r1,
15252 ovl.fmt.RIE_RRPU.r2,
15253 ovl.fmt.RIE_RRPU.i4,
15254 ovl.fmt.RIE_RRPU.m3); goto ok;
15255 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15256 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15257 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15258 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15259 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15260 ovl.fmt.RIE_RRPU.r1,
15261 ovl.fmt.RIE_RRPU.r2,
15262 ovl.fmt.RIE_RRPU.i4,
15263 ovl.fmt.RIE_RRPU.m3); goto ok;
15264 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15265 ovl.fmt.RIE_RRPU.r1,
15266 ovl.fmt.RIE_RRPU.r2,
15267 ovl.fmt.RIE_RRPU.i4,
15268 ovl.fmt.RIE_RRPU.m3); goto ok;
15269 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15270 ovl.fmt.RIEv3.r1,
15271 ovl.fmt.RIEv3.m3,
15272 ovl.fmt.RIEv3.i4,
15273 ovl.fmt.RIEv3.i2); goto ok;
15274 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15275 ovl.fmt.RIEv3.r1,
15276 ovl.fmt.RIEv3.m3,
15277 ovl.fmt.RIEv3.i4,
15278 ovl.fmt.RIEv3.i2); goto ok;
15279 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15280 ovl.fmt.RIEv3.r1,
15281 ovl.fmt.RIEv3.m3,
15282 ovl.fmt.RIEv3.i4,
15283 ovl.fmt.RIEv3.i2); goto ok;
15284 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15285 ovl.fmt.RIEv3.r1,
15286 ovl.fmt.RIEv3.m3,
15287 ovl.fmt.RIEv3.i4,
15288 ovl.fmt.RIEv3.i2); goto ok;
15289 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15290 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15291 goto ok;
15292 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15293 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15294 ovl.fmt.RIE.i2); goto ok;
15295 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15296 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15297 ovl.fmt.RIE.i2); goto ok;
15298 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15299 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15300 ovl.fmt.RIE.i2); goto ok;
15301 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15302 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15303 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15304 goto ok;
15305 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15306 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15307 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15308 goto ok;
15309 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15310 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15311 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15312 goto ok;
15313 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15314 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15315 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15316 goto ok;
15317 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15318 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15319 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15320 ovl.fmt.RIS.i2); goto ok;
15321 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15322 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15323 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15324 ovl.fmt.RIS.i2); goto ok;
15325 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15326 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15327 ovl.fmt.RIS.d4,
15328 ovl.fmt.RIS.i2); goto ok;
15329 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15330 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15331 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15332 ovl.fmt.RIS.i2); goto ok;
15333 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15334 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15335 ovl.fmt.RXE.d2); goto ok;
15336 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15337 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15338 ovl.fmt.RXE.d2); goto ok;
15339 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15340 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15341 ovl.fmt.RXE.d2); goto ok;
15342 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15343 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15344 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15345 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15346 ovl.fmt.RXE.d2); goto ok;
15347 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15348 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15349 ovl.fmt.RXE.d2); goto ok;
15350 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
15351 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15352 ovl.fmt.RXE.d2); goto ok;
15353 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
15354 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
15355 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15356 ovl.fmt.RXE.d2); goto ok;
15357 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
15358 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15359 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15360 ovl.fmt.RXF.r1); goto ok;
15361 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
15362 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15363 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15364 ovl.fmt.RXF.r1); goto ok;
15365 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
15366 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15367 ovl.fmt.RXE.d2); goto ok;
15368 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
15369 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15370 ovl.fmt.RXE.d2); goto ok;
15371 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
15372 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15373 ovl.fmt.RXE.d2); goto ok;
15374 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
15375 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15376 ovl.fmt.RXE.d2); goto ok;
15377 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
15378 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15379 ovl.fmt.RXE.d2); goto ok;
15380 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
15381 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15382 ovl.fmt.RXE.d2); goto ok;
15383 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
15384 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
15385 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15386 ovl.fmt.RXE.d2); goto ok;
15387 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
15388 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15389 ovl.fmt.RXE.d2); goto ok;
15390 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
15391 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15392 ovl.fmt.RXE.d2); goto ok;
15393 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
15394 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15395 ovl.fmt.RXE.d2); goto ok;
15396 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
15397 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15398 ovl.fmt.RXE.d2); goto ok;
15399 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
15400 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15401 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15402 ovl.fmt.RXF.r1); goto ok;
15403 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
15404 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15405 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15406 ovl.fmt.RXF.r1); goto ok;
15407 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
15408 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
15409 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
15410 case 0xed000000002eULL: /* MAE */ goto unimplemented;
15411 case 0xed000000002fULL: /* MSE */ goto unimplemented;
15412 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
15413 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
15414 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
15415 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
15416 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
15417 case 0xed000000003aULL: /* MAY */ goto unimplemented;
15418 case 0xed000000003bULL: /* MY */ goto unimplemented;
15419 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
15420 case 0xed000000003dULL: /* MYH */ goto unimplemented;
15421 case 0xed000000003eULL: /* MAD */ goto unimplemented;
15422 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000015423 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
15424 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15425 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15426 ovl.fmt.RXF.r1); goto ok;
15427 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
15428 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15429 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15430 ovl.fmt.RXF.r1); goto ok;
15431 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
15432 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15433 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15434 ovl.fmt.RXF.r1); goto ok;
15435 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
15436 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15437 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15438 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000015439 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
15440 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15441 ovl.fmt.RXE.d2); goto ok;
15442 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
15443 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15444 ovl.fmt.RXE.d2); goto ok;
15445 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
15446 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15447 ovl.fmt.RXE.d2); goto ok;
15448 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
15449 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15450 ovl.fmt.RXE.d2); goto ok;
15451 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
15452 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15453 ovl.fmt.RXE.d2); goto ok;
15454 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
15455 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15456 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015457 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
15458 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15459 ovl.fmt.RXY.dl2,
15460 ovl.fmt.RXY.dh2); goto ok;
15461 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
15462 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15463 ovl.fmt.RXY.dl2,
15464 ovl.fmt.RXY.dh2); goto ok;
15465 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
15466 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15467 ovl.fmt.RXY.dl2,
15468 ovl.fmt.RXY.dh2); goto ok;
15469 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
15470 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15471 ovl.fmt.RXY.dl2,
15472 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015473 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
15474 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
15475 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
15476 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015477 }
15478
15479 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
15480 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
15481 ovl.fmt.RIL.i2); goto ok;
15482 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
15483 ovl.fmt.RIL.i2); goto ok;
15484 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
15485 ovl.fmt.RIL.i2); goto ok;
15486 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
15487 ovl.fmt.RIL.i2); goto ok;
15488 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
15489 ovl.fmt.RIL.i2); goto ok;
15490 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
15491 ovl.fmt.RIL.i2); goto ok;
15492 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
15493 ovl.fmt.RIL.i2); goto ok;
15494 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
15495 ovl.fmt.RIL.i2); goto ok;
15496 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
15497 ovl.fmt.RIL.i2); goto ok;
15498 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
15499 ovl.fmt.RIL.i2); goto ok;
15500 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
15501 ovl.fmt.RIL.i2); goto ok;
15502 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
15503 ovl.fmt.RIL.i2); goto ok;
15504 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
15505 ovl.fmt.RIL.i2); goto ok;
15506 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
15507 ovl.fmt.RIL.i2); goto ok;
15508 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
15509 ovl.fmt.RIL.i2); goto ok;
15510 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
15511 ovl.fmt.RIL.i2); goto ok;
15512 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
15513 ovl.fmt.RIL.i2); goto ok;
15514 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
15515 ovl.fmt.RIL.i2); goto ok;
15516 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
15517 ovl.fmt.RIL.i2); goto ok;
15518 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
15519 ovl.fmt.RIL.i2); goto ok;
15520 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
15521 ovl.fmt.RIL.i2); goto ok;
15522 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
15523 ovl.fmt.RIL.i2); goto ok;
15524 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
15525 ovl.fmt.RIL.i2); goto ok;
15526 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
15527 ovl.fmt.RIL.i2); goto ok;
15528 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
15529 ovl.fmt.RIL.i2); goto ok;
15530 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
15531 ovl.fmt.RIL.i2); goto ok;
15532 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
15533 ovl.fmt.RIL.i2); goto ok;
15534 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
15535 ovl.fmt.RIL.i2); goto ok;
15536 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
15537 ovl.fmt.RIL.i2); goto ok;
15538 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
15539 ovl.fmt.RIL.i2); goto ok;
15540 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
15541 ovl.fmt.RIL.i2); goto ok;
15542 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
15543 ovl.fmt.RIL.i2); goto ok;
15544 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
15545 ovl.fmt.RIL.i2); goto ok;
15546 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
15547 ovl.fmt.RIL.i2); goto ok;
15548 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
15549 ovl.fmt.RIL.i2); goto ok;
15550 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
15551 ovl.fmt.RIL.i2); goto ok;
15552 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
15553 ovl.fmt.RIL.i2); goto ok;
15554 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
15555 ovl.fmt.RIL.i2); goto ok;
15556 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
15557 ovl.fmt.RIL.i2); goto ok;
15558 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
15559 ovl.fmt.RIL.i2); goto ok;
15560 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
15561 ovl.fmt.RIL.i2); goto ok;
15562 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
15563 ovl.fmt.RIL.i2); goto ok;
15564 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
15565 ovl.fmt.RIL.i2); goto ok;
15566 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
15567 ovl.fmt.RIL.i2); goto ok;
15568 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
15569 ovl.fmt.RIL.i2); goto ok;
15570 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
15571 ovl.fmt.RIL.i2); goto ok;
15572 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
15573 ovl.fmt.RIL.i2); goto ok;
15574 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
15575 ovl.fmt.RIL.i2); goto ok;
15576 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
15577 ovl.fmt.RIL.i2); goto ok;
15578 case 0xc800ULL: /* MVCOS */ goto unimplemented;
15579 case 0xc801ULL: /* ECTG */ goto unimplemented;
15580 case 0xc802ULL: /* CSST */ goto unimplemented;
15581 case 0xc804ULL: /* LPD */ goto unimplemented;
15582 case 0xc805ULL: /* LPDG */ goto unimplemented;
15583 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
15584 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
15585 ovl.fmt.RIL.i2); goto ok;
15586 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
15587 ovl.fmt.RIL.i2); goto ok;
15588 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
15589 ovl.fmt.RIL.i2); goto ok;
15590 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
15591 ovl.fmt.RIL.i2); goto ok;
15592 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
15593 ovl.fmt.RIL.i2); goto ok;
15594 }
15595
15596 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000015597 case 0xc5ULL: /* BPRP */ goto unimplemented;
15598 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015599 case 0xd0ULL: /* TRTR */ goto unimplemented;
15600 case 0xd1ULL: /* MVN */ goto unimplemented;
15601 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
15602 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15603 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15604 case 0xd3ULL: /* MVZ */ goto unimplemented;
15605 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
15606 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15607 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15608 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
15609 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15610 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15611 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
15612 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15613 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000015614 case 0xd7ULL:
15615 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
15616 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
15617 else
15618 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
15619 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15620 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
15621 goto ok;
sewardj2019a972011-03-07 16:04:07 +000015622 case 0xd9ULL: /* MVCK */ goto unimplemented;
15623 case 0xdaULL: /* MVCP */ goto unimplemented;
15624 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015625 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
15626 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15627 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015628 case 0xddULL: /* TRT */ goto unimplemented;
15629 case 0xdeULL: /* ED */ goto unimplemented;
15630 case 0xdfULL: /* EDMK */ goto unimplemented;
15631 case 0xe1ULL: /* PKU */ goto unimplemented;
15632 case 0xe2ULL: /* UNPKU */ goto unimplemented;
15633 case 0xe8ULL: /* MVCIN */ goto unimplemented;
15634 case 0xe9ULL: /* PKA */ goto unimplemented;
15635 case 0xeaULL: /* UNPKA */ goto unimplemented;
15636 case 0xeeULL: /* PLO */ goto unimplemented;
15637 case 0xefULL: /* LMD */ goto unimplemented;
15638 case 0xf0ULL: /* SRP */ goto unimplemented;
15639 case 0xf1ULL: /* MVO */ goto unimplemented;
15640 case 0xf2ULL: /* PACK */ goto unimplemented;
15641 case 0xf3ULL: /* UNPK */ goto unimplemented;
15642 case 0xf8ULL: /* ZAP */ goto unimplemented;
15643 case 0xf9ULL: /* CP */ goto unimplemented;
15644 case 0xfaULL: /* AP */ goto unimplemented;
15645 case 0xfbULL: /* SP */ goto unimplemented;
15646 case 0xfcULL: /* MP */ goto unimplemented;
15647 case 0xfdULL: /* DP */ goto unimplemented;
15648 }
15649
15650 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
15651 case 0xe500ULL: /* LASP */ goto unimplemented;
15652 case 0xe501ULL: /* TPROT */ goto unimplemented;
15653 case 0xe502ULL: /* STRAG */ goto unimplemented;
15654 case 0xe50eULL: /* MVCSK */ goto unimplemented;
15655 case 0xe50fULL: /* MVCDK */ goto unimplemented;
15656 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
15657 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15658 goto ok;
15659 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
15660 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15661 goto ok;
15662 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
15663 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15664 goto ok;
15665 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
15666 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15667 goto ok;
15668 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
15669 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15670 goto ok;
15671 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
15672 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15673 goto ok;
15674 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
15675 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15676 goto ok;
15677 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
15678 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15679 goto ok;
15680 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
15681 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15682 goto ok;
florian2289cd42012-12-05 04:23:42 +000015683 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
15684 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015685 }
15686
15687 return S390_DECODE_UNKNOWN_INSN;
15688
15689ok:
15690 return S390_DECODE_OK;
15691
15692unimplemented:
15693 return S390_DECODE_UNIMPLEMENTED_INSN;
15694}
15695
15696/* Handle "special" instructions. */
15697static s390_decode_t
15698s390_decode_special_and_irgen(UChar *bytes)
15699{
15700 s390_decode_t status = S390_DECODE_OK;
15701
15702 /* Got a "Special" instruction preamble. Which one is it? */
15703 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
15704 s390_irgen_client_request();
15705 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
15706 s390_irgen_guest_NRADDR();
15707 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
15708 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000015709 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
15710 vex_inject_ir(irsb, Iend_BE);
15711
15712 /* Invalidate the current insn. The reason is that the IRop we're
15713 injecting here can change. In which case the translation has to
15714 be redone. For ease of handling, we simply invalidate all the
15715 time. */
15716 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
15717 mkU64(guest_IA_curr_instr)));
15718 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
15719 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
15720 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
15721 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
15722
15723 put_IA(mkaddr_expr(guest_IA_next_instr));
15724 dis_res->whatNext = Dis_StopHere;
15725 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000015726 } else {
15727 /* We don't know what it is. */
15728 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
15729 }
15730
15731 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15732
15733 return status;
15734}
15735
15736
15737/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000015738static UInt
sewardj2019a972011-03-07 16:04:07 +000015739s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
15740{
15741 s390_decode_t status;
15742
15743 dis_res = dres;
15744
15745 /* Spot the 8-byte preamble: 18ff lr r15,r15
15746 1811 lr r1,r1
15747 1822 lr r2,r2
15748 1833 lr r3,r3 */
15749 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
15750 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
15751 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
15752
15753 /* Handle special instruction that follows that preamble. */
15754 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000015755
15756 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
15757 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15758
15759 status =
15760 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000015761 } else {
15762 /* Handle normal instructions. */
15763 switch (insn_length) {
15764 case 2:
15765 status = s390_decode_2byte_and_irgen(bytes);
15766 break;
15767
15768 case 4:
15769 status = s390_decode_4byte_and_irgen(bytes);
15770 break;
15771
15772 case 6:
15773 status = s390_decode_6byte_and_irgen(bytes);
15774 break;
15775
15776 default:
15777 status = S390_DECODE_ERROR;
15778 break;
15779 }
15780 }
florian5fcbba22011-07-27 20:40:22 +000015781 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000015782 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
15783 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000015784 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000015785 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000015786 }
15787
15788 if (status == S390_DECODE_OK) return insn_length; /* OK */
15789
15790 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000015791 if (sigill_diag) {
15792 vex_printf("vex s390->IR: ");
15793 switch (status) {
15794 case S390_DECODE_UNKNOWN_INSN:
15795 vex_printf("unknown insn: ");
15796 break;
sewardj2019a972011-03-07 16:04:07 +000015797
sewardj442e51a2012-12-06 18:08:04 +000015798 case S390_DECODE_UNIMPLEMENTED_INSN:
15799 vex_printf("unimplemented insn: ");
15800 break;
sewardj2019a972011-03-07 16:04:07 +000015801
sewardj442e51a2012-12-06 18:08:04 +000015802 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
15803 vex_printf("unimplemented special insn: ");
15804 break;
sewardj2019a972011-03-07 16:04:07 +000015805
sewardj442e51a2012-12-06 18:08:04 +000015806 default:
15807 case S390_DECODE_ERROR:
15808 vex_printf("decoding error: ");
15809 break;
15810 }
15811
15812 vex_printf("%02x%02x", bytes[0], bytes[1]);
15813 if (insn_length > 2) {
15814 vex_printf(" %02x%02x", bytes[2], bytes[3]);
15815 }
15816 if (insn_length > 4) {
15817 vex_printf(" %02x%02x", bytes[4], bytes[5]);
15818 }
15819 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000015820 }
15821
sewardj2019a972011-03-07 16:04:07 +000015822 return 0; /* Failed */
15823}
15824
15825
sewardj2019a972011-03-07 16:04:07 +000015826/* Disassemble a single instruction INSN into IR. */
15827static DisResult
florian420c5012011-07-22 02:12:28 +000015828disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000015829{
15830 UChar byte;
15831 UInt insn_length;
15832 DisResult dres;
15833
15834 /* ---------------------------------------------------- */
15835 /* --- Compute instruction length -- */
15836 /* ---------------------------------------------------- */
15837
15838 /* Get the first byte of the insn. */
15839 byte = insn[0];
15840
15841 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
15842 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
15843 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
15844
15845 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
15846
15847 /* ---------------------------------------------------- */
15848 /* --- Initialise the DisResult data -- */
15849 /* ---------------------------------------------------- */
15850 dres.whatNext = Dis_Continue;
15851 dres.len = insn_length;
15852 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000015853 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000015854
floriana99f20e2011-07-17 14:16:41 +000015855 /* fixs390: consider chasing of conditional jumps */
15856
sewardj2019a972011-03-07 16:04:07 +000015857 /* Normal and special instruction handling starts here. */
15858 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
15859 /* All decode failures end up here. The decoder has already issued an
15860 error message.
15861 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000015862 not been executed, and (is currently) the next to be executed.
15863 The insn address in the guest state needs to be set to
15864 guest_IA_curr_instr, otherwise the complaint will report an
15865 incorrect address. */
15866 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000015867
florian8844a632012-04-13 04:04:06 +000015868 dres.whatNext = Dis_StopHere;
15869 dres.jk_StopHere = Ijk_NoDecode;
15870 dres.continueAt = 0;
15871 dres.len = 0;
15872 } else {
15873 /* Decode success */
15874 switch (dres.whatNext) {
15875 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000015876 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000015877 break;
15878 case Dis_ResteerU:
15879 case Dis_ResteerC:
15880 put_IA(mkaddr_expr(dres.continueAt));
15881 break;
15882 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000015883 if (dres.jk_StopHere == Ijk_EmWarn ||
15884 dres.jk_StopHere == Ijk_EmFail) {
15885 /* We assume here, that emulation warnings are not given for
15886 insns that transfer control. There is no good way to
15887 do that. */
15888 put_IA(mkaddr_expr(guest_IA_next_instr));
15889 }
florian8844a632012-04-13 04:04:06 +000015890 break;
15891 default:
15892 vassert(0);
15893 }
sewardj2019a972011-03-07 16:04:07 +000015894 }
15895
15896 return dres;
15897}
15898
15899
15900/*------------------------------------------------------------*/
15901/*--- Top-level fn ---*/
15902/*------------------------------------------------------------*/
15903
15904/* Disassemble a single instruction into IR. The instruction
15905 is located in host memory at &guest_code[delta]. */
15906
15907DisResult
15908disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000015909 Bool (*resteerOkFn)(void *, Addr64),
15910 Bool resteerCisOk,
15911 void *callback_opaque,
15912 UChar *guest_code,
15913 Long delta,
15914 Addr64 guest_IP,
15915 VexArch guest_arch,
15916 VexArchInfo *archinfo,
15917 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000015918 Bool host_bigendian,
15919 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000015920{
15921 vassert(guest_arch == VexArchS390X);
15922
15923 /* The instruction decoder requires a big-endian machine. */
15924 vassert(host_bigendian == True);
15925
15926 /* Set globals (see top of this file) */
15927 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000015928 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000015929 resteer_fn = resteerOkFn;
15930 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000015931 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000015932
florian420c5012011-07-22 02:12:28 +000015933 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000015934}
15935
15936/*---------------------------------------------------------------*/
15937/*--- end guest_s390_toIR.c ---*/
15938/*---------------------------------------------------------------*/