blob: 7ffeef3214495f890e42d0e9ece397279f1dfd0f [file] [log] [blame]
sewardj2019a972011-03-07 16:04:07 +00001/* -*- mode: C; c-basic-offset: 3; -*- */
2
3/*---------------------------------------------------------------*/
4/*--- begin guest_s390_toIR.c ---*/
5/*---------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
florian61f23c12012-08-06 18:33:21 +000011 Copyright IBM Corp. 2010-2012
sewardj2019a972011-03-07 16:04:07 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Florian Krohm and Christian Borntraeger */
32
33/* Translates s390 code to IR. */
34
35#include "libvex_basictypes.h"
36#include "libvex_ir.h"
florian58a637b2012-09-30 20:30:17 +000037#include "libvex_emnote.h"
florian933065d2011-07-11 01:48:02 +000038#include "libvex_s390x_common.h"
sewardj2019a972011-03-07 16:04:07 +000039#include "main_util.h" /* vassert */
40#include "main_globals.h" /* vex_traceflags */
41#include "guest_generic_bb_to_IR.h" /* DisResult */
42#include "guest_s390_defs.h" /* prototypes for this file's functions */
florian79af5752012-09-20 01:22:10 +000043#include "s390_disasm.h"
florianb0b67102012-12-24 00:14:31 +000044#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */
45#include "host_s390_defs.h" /* s390_host_has_xyzzy */
sewardj2019a972011-03-07 16:04:07 +000046
sewardj2019a972011-03-07 16:04:07 +000047
48/*------------------------------------------------------------*/
florianb4df7682011-07-05 02:09:01 +000049/*--- Forward declarations ---*/
50/*------------------------------------------------------------*/
51static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
florianb0bf6602012-05-05 00:01:16 +000052static void s390_irgen_xonc(IROp, IRTemp, IRTemp, IRTemp);
florian79e839e2012-05-05 02:20:30 +000053static void s390_irgen_CLC_EX(IRTemp, IRTemp, IRTemp);
florianb4df7682011-07-05 02:09:01 +000054
55
56/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +000057/*--- Globals ---*/
58/*------------------------------------------------------------*/
59
60/* The IRSB* into which we're generating code. */
61static IRSB *irsb;
62
63/* The guest address for the instruction currently being
64 translated. */
65static Addr64 guest_IA_curr_instr;
66
67/* The guest address for the instruction following the current instruction. */
68static Addr64 guest_IA_next_instr;
69
70/* Result of disassembly step. */
71static DisResult *dis_res;
72
floriana64c2432011-07-16 02:11:50 +000073/* Resteer function and callback data */
74static Bool (*resteer_fn)(void *, Addr64);
75static void *resteer_data;
76
sewardj442e51a2012-12-06 18:08:04 +000077/* Whether to print diagnostics for illegal instructions. */
78static Bool sigill_diag;
79
sewardj2019a972011-03-07 16:04:07 +000080/* The last seen execute target instruction */
81ULong last_execute_target;
82
83/* The possible outcomes of a decoding operation */
84typedef enum {
85 S390_DECODE_OK,
86 S390_DECODE_UNKNOWN_INSN,
87 S390_DECODE_UNIMPLEMENTED_INSN,
88 S390_DECODE_UNKNOWN_SPECIAL_INSN,
89 S390_DECODE_ERROR
90} s390_decode_t;
91
florian428dfdd2012-03-27 03:09:49 +000092
sewardj2019a972011-03-07 16:04:07 +000093/*------------------------------------------------------------*/
94/*--- Helpers for constructing IR. ---*/
95/*------------------------------------------------------------*/
96
97/* Sign extend a value with the given number of bits. This is a
98 macro because it allows us to overload the type of the value.
99 Note that VALUE must have a signed type! */
100#undef sign_extend
101#define sign_extend(value,num_bits) \
102(((value) << (sizeof(__typeof__(value)) * 8 - (num_bits))) >> \
103 (sizeof(__typeof__(value)) * 8 - (num_bits)))
104
105
106/* Add a statement to the current irsb. */
107static __inline__ void
108stmt(IRStmt *st)
109{
110 addStmtToIRSB(irsb, st);
111}
112
113/* Allocate a new temporary of the given type. */
114static __inline__ IRTemp
115newTemp(IRType type)
116{
117 vassert(isPlausibleIRType(type));
118
119 return newIRTemp(irsb->tyenv, type);
120}
121
122/* Create an expression node for a temporary */
123static __inline__ IRExpr *
124mkexpr(IRTemp tmp)
125{
126 return IRExpr_RdTmp(tmp);
127}
128
florian8844a632012-04-13 04:04:06 +0000129/* Generate an expression node for an address. */
130static __inline__ IRExpr *
131mkaddr_expr(Addr64 addr)
132{
133 return IRExpr_Const(IRConst_U64(addr));
134}
135
sewardj2019a972011-03-07 16:04:07 +0000136/* Add a statement that assigns to a temporary */
137static __inline__ void
138assign(IRTemp dst, IRExpr *expr)
139{
140 stmt(IRStmt_WrTmp(dst, expr));
141}
142
florian8844a632012-04-13 04:04:06 +0000143/* Write an address into the guest_IA */
144static __inline__ void
145put_IA(IRExpr *address)
146{
147 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IA), address));
148}
149
sewardj2019a972011-03-07 16:04:07 +0000150/* Create a temporary of the given type and assign the expression to it */
151static __inline__ IRTemp
152mktemp(IRType type, IRExpr *expr)
153{
154 IRTemp temp = newTemp(type);
155
156 assign(temp, expr);
157
158 return temp;
159}
160
161/* Create a unary expression */
162static __inline__ IRExpr *
163unop(IROp kind, IRExpr *op)
164{
165 return IRExpr_Unop(kind, op);
166}
167
168/* Create a binary expression */
169static __inline__ IRExpr *
170binop(IROp kind, IRExpr *op1, IRExpr *op2)
171{
172 return IRExpr_Binop(kind, op1, op2);
173}
174
175/* Create a ternary expression */
176static __inline__ IRExpr *
177triop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3)
178{
179 return IRExpr_Triop(kind, op1, op2, op3);
180}
181
182/* Create a quaternary expression */
183static __inline__ IRExpr *
184qop(IROp kind, IRExpr *op1, IRExpr *op2, IRExpr *op3, IRExpr *op4)
185{
186 return IRExpr_Qop(kind, op1, op2, op3, op4);
187}
188
189/* Create an expression node for an 8-bit integer constant */
190static __inline__ IRExpr *
191mkU8(UInt value)
192{
193 vassert(value < 256);
194
195 return IRExpr_Const(IRConst_U8((UChar)value));
196}
197
198/* Create an expression node for a 16-bit integer constant */
199static __inline__ IRExpr *
200mkU16(UInt value)
201{
202 vassert(value < 65536);
203
204 return IRExpr_Const(IRConst_U16((UShort)value));
205}
206
207/* Create an expression node for a 32-bit integer constant */
208static __inline__ IRExpr *
209mkU32(UInt value)
210{
211 return IRExpr_Const(IRConst_U32(value));
212}
213
214/* Create an expression node for a 64-bit integer constant */
215static __inline__ IRExpr *
216mkU64(ULong value)
217{
218 return IRExpr_Const(IRConst_U64(value));
219}
220
221/* Create an expression node for a 32-bit floating point constant
222 whose value is given by a bit pattern. */
223static __inline__ IRExpr *
224mkF32i(UInt value)
225{
226 return IRExpr_Const(IRConst_F32i(value));
227}
228
229/* Create an expression node for a 32-bit floating point constant
230 whose value is given by a bit pattern. */
231static __inline__ IRExpr *
232mkF64i(ULong value)
233{
234 return IRExpr_Const(IRConst_F64i(value));
235}
236
237/* Little helper function for my sanity. ITE = if-then-else */
238static IRExpr *
239mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse)
240{
241 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
242
florian99dd03e2013-01-29 03:56:06 +0000243 return IRExpr_ITE(condition, iftrue, iffalse);
sewardj2019a972011-03-07 16:04:07 +0000244}
245
246/* Add a statement that stores DATA at ADDR. This is a big-endian machine. */
247static void __inline__
248store(IRExpr *addr, IRExpr *data)
249{
250 stmt(IRStmt_Store(Iend_BE, addr, data));
251}
252
253/* Create an expression that loads a TYPE sized value from ADDR.
254 This is a big-endian machine. */
255static __inline__ IRExpr *
256load(IRType type, IRExpr *addr)
257{
258 return IRExpr_Load(Iend_BE, type, addr);
259}
260
261/* Function call */
262static void
263call_function(IRExpr *callee_address)
264{
florian8844a632012-04-13 04:04:06 +0000265 put_IA(callee_address);
sewardj2019a972011-03-07 16:04:07 +0000266
florian8844a632012-04-13 04:04:06 +0000267 dis_res->whatNext = Dis_StopHere;
268 dis_res->jk_StopHere = Ijk_Call;
sewardj2019a972011-03-07 16:04:07 +0000269}
270
floriana64c2432011-07-16 02:11:50 +0000271/* Function call with known target. */
272static void
273call_function_and_chase(Addr64 callee_address)
274{
275 if (resteer_fn(resteer_data, callee_address)) {
276 dis_res->whatNext = Dis_ResteerU;
277 dis_res->continueAt = callee_address;
278 } else {
florian8844a632012-04-13 04:04:06 +0000279 put_IA(mkaddr_expr(callee_address));
280
floriana64c2432011-07-16 02:11:50 +0000281 dis_res->whatNext = Dis_StopHere;
florian8844a632012-04-13 04:04:06 +0000282 dis_res->jk_StopHere = Ijk_Call;
floriana64c2432011-07-16 02:11:50 +0000283 }
284}
285
sewardj2019a972011-03-07 16:04:07 +0000286/* Function return sequence */
287static void
288return_from_function(IRExpr *return_address)
289{
florian8844a632012-04-13 04:04:06 +0000290 put_IA(return_address);
sewardj2019a972011-03-07 16:04:07 +0000291
florian8844a632012-04-13 04:04:06 +0000292 dis_res->whatNext = Dis_StopHere;
293 dis_res->jk_StopHere = Ijk_Ret;
sewardj2019a972011-03-07 16:04:07 +0000294}
295
296/* A conditional branch whose target is not known at instrumentation time.
297
298 if (condition) goto computed_target;
299
300 Needs to be represented as:
301
302 if (! condition) goto next_instruction;
303 goto computed_target;
sewardj2019a972011-03-07 16:04:07 +0000304*/
305static void
florianf321da72012-07-21 20:32:57 +0000306if_condition_goto_computed(IRExpr *condition, IRExpr *target)
sewardj2019a972011-03-07 16:04:07 +0000307{
308 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
309
florianf321da72012-07-21 20:32:57 +0000310 condition = unop(Iop_Not1, condition);
311
florian8844a632012-04-13 04:04:06 +0000312 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
313 S390X_GUEST_OFFSET(guest_IA)));
sewardj2019a972011-03-07 16:04:07 +0000314
florian8844a632012-04-13 04:04:06 +0000315 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000316
florian8844a632012-04-13 04:04:06 +0000317 dis_res->whatNext = Dis_StopHere;
318 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000319}
320
321/* A conditional branch whose target is known at instrumentation time. */
322static void
323if_condition_goto(IRExpr *condition, Addr64 target)
324{
325 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
326
florian8844a632012-04-13 04:04:06 +0000327 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(target),
328 S390X_GUEST_OFFSET(guest_IA)));
329
florian7346c7a2012-04-13 21:14:24 +0000330 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +0000331
332 dis_res->whatNext = Dis_StopHere;
333 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000334}
335
336/* An unconditional branch. Target may or may not be known at instrumentation
337 time. */
338static void
339always_goto(IRExpr *target)
340{
florian8844a632012-04-13 04:04:06 +0000341 put_IA(target);
sewardj2019a972011-03-07 16:04:07 +0000342
florian8844a632012-04-13 04:04:06 +0000343 dis_res->whatNext = Dis_StopHere;
344 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +0000345}
346
florian8844a632012-04-13 04:04:06 +0000347
floriana64c2432011-07-16 02:11:50 +0000348/* An unconditional branch to a known target. */
349static void
350always_goto_and_chase(Addr64 target)
351{
352 if (resteer_fn(resteer_data, target)) {
florian8844a632012-04-13 04:04:06 +0000353 /* Follow into the target */
floriana64c2432011-07-16 02:11:50 +0000354 dis_res->whatNext = Dis_ResteerU;
355 dis_res->continueAt = target;
356 } else {
florian8844a632012-04-13 04:04:06 +0000357 put_IA(mkaddr_expr(target));
358
359 dis_res->whatNext = Dis_StopHere;
360 dis_res->jk_StopHere = Ijk_Boring;
floriana64c2432011-07-16 02:11:50 +0000361 }
362}
363
sewardj2019a972011-03-07 16:04:07 +0000364/* A system call */
365static void
366system_call(IRExpr *sysno)
367{
368 /* Store the system call number in the pseudo register. */
florian428dfdd2012-03-27 03:09:49 +0000369 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_SYSNO), sysno));
sewardj2019a972011-03-07 16:04:07 +0000370
sewardj69007022011-04-28 20:13:45 +0000371 /* Store the current IA into guest_IP_AT_SYSCALL. libvex_ir.h says so. */
florian428dfdd2012-03-27 03:09:49 +0000372 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_IP_AT_SYSCALL),
373 mkU64(guest_IA_curr_instr)));
sewardj2019a972011-03-07 16:04:07 +0000374
florian8844a632012-04-13 04:04:06 +0000375 put_IA(mkaddr_expr(guest_IA_next_instr));
376
sewardj2019a972011-03-07 16:04:07 +0000377 /* It's important that all ArchRegs carry their up-to-date value
378 at this point. So we declare an end-of-block here, which
379 forces any TempRegs caching ArchRegs to be flushed. */
florian8844a632012-04-13 04:04:06 +0000380 dis_res->whatNext = Dis_StopHere;
381 dis_res->jk_StopHere = Ijk_Sys_syscall;
sewardj2019a972011-03-07 16:04:07 +0000382}
383
florian6820ba52012-07-26 02:01:50 +0000384/* A side exit that branches back to the current insn if CONDITION is
385 true. Does not set DisResult. */
386static void
387iterate_if(IRExpr *condition)
388{
389 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
390
391 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_curr_instr),
392 S390X_GUEST_OFFSET(guest_IA)));
393}
394
395/* A side exit that branches back to the current insn.
396 Does not set DisResult. */
397static __inline__ void
398iterate(void)
399{
400 iterate_if(IRExpr_Const(IRConst_U1(True)));
401}
402
403/* A side exit that branches back to the insn immediately following the
404 current insn if CONDITION is true. Does not set DisResult. */
405static void
406next_insn_if(IRExpr *condition)
407{
408 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
409
410 stmt(IRStmt_Exit(condition, Ijk_Boring, IRConst_U64(guest_IA_next_instr),
411 S390X_GUEST_OFFSET(guest_IA)));
412}
413
414/* Convenience function to restart the current insn */
415static void
416restart_if(IRExpr *condition)
417{
418 vassert(typeOfIRExpr(irsb->tyenv, condition) == Ity_I1);
419
420 stmt(IRStmt_Exit(condition, Ijk_TInval, IRConst_U64(guest_IA_curr_instr),
421 S390X_GUEST_OFFSET(guest_IA)));
422}
423
424/* Convenience function to yield to thread scheduler */
425static void
426yield_if(IRExpr *condition)
427{
428 stmt(IRStmt_Exit(condition, Ijk_Yield, IRConst_U64(guest_IA_next_instr),
429 S390X_GUEST_OFFSET(guest_IA)));
430}
431
sewardj2019a972011-03-07 16:04:07 +0000432static __inline__ IRExpr *get_fpr_dw0(UInt);
433static __inline__ void put_fpr_dw0(UInt, IRExpr *);
florian12390202012-11-10 22:34:14 +0000434static __inline__ IRExpr *get_dpr_dw0(UInt);
435static __inline__ void put_dpr_dw0(UInt, IRExpr *);
sewardj2019a972011-03-07 16:04:07 +0000436
437/* Read a floating point register pair and combine their contents into a
438 128-bit value */
439static IRExpr *
440get_fpr_pair(UInt archreg)
441{
442 IRExpr *high = get_fpr_dw0(archreg);
443 IRExpr *low = get_fpr_dw0(archreg + 2);
444
445 return binop(Iop_F64HLtoF128, high, low);
446}
447
448/* Write a 128-bit floating point value into a register pair. */
449static void
450put_fpr_pair(UInt archreg, IRExpr *expr)
451{
452 IRExpr *high = unop(Iop_F128HItoF64, expr);
453 IRExpr *low = unop(Iop_F128LOtoF64, expr);
454
455 put_fpr_dw0(archreg, high);
456 put_fpr_dw0(archreg + 2, low);
457}
458
floriane38f6412012-12-21 17:32:12 +0000459/* Read a floating point register pair cointaining DFP value
460 and combine their contents into a 128-bit value */
461
462static IRExpr *
463get_dpr_pair(UInt archreg)
464{
465 IRExpr *high = get_dpr_dw0(archreg);
466 IRExpr *low = get_dpr_dw0(archreg + 2);
467
468 return binop(Iop_D64HLtoD128, high, low);
469}
470
471/* Write a 128-bit decimal floating point value into a register pair. */
472static void
473put_dpr_pair(UInt archreg, IRExpr *expr)
474{
475 IRExpr *high = unop(Iop_D128HItoD64, expr);
476 IRExpr *low = unop(Iop_D128LOtoD64, expr);
477
478 put_dpr_dw0(archreg, high);
479 put_dpr_dw0(archreg + 2, low);
480}
481
floriane75dafa2012-09-01 17:54:09 +0000482/* Terminate the current IRSB with an emulation failure. */
483static void
484emulation_failure(VexEmNote fail_kind)
485{
486 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(fail_kind)));
floriane75dafa2012-09-01 17:54:09 +0000487 dis_res->whatNext = Dis_StopHere;
488 dis_res->jk_StopHere = Ijk_EmFail;
489}
sewardj2019a972011-03-07 16:04:07 +0000490
florian4b8efad2012-09-02 18:07:08 +0000491/* Terminate the current IRSB with an emulation warning. */
492static void
493emulation_warning(VexEmNote warn_kind)
494{
495 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_EMNOTE), mkU32(warn_kind)));
496 dis_res->whatNext = Dis_StopHere;
497 dis_res->jk_StopHere = Ijk_EmWarn;
498}
499
sewardj2019a972011-03-07 16:04:07 +0000500/*------------------------------------------------------------*/
florianf3410f92012-08-03 18:41:58 +0000501/*--- IR Debugging aids. ---*/
502/*------------------------------------------------------------*/
503#if 0
504
505static ULong
506s390_do_print(HChar *text, ULong value)
507{
508 vex_printf("%s %llu\n", text, value);
509 return 0;
510}
511
512static void
513s390_print(HChar *text, IRExpr *value)
514{
515 IRDirty *d;
516
517 d = unsafeIRDirty_0_N(0 /* regparms */, "s390_do_print", &s390_do_print,
518 mkIRExprVec_2(mkU64((ULong)text), value));
519 stmt(IRStmt_Dirty(d));
520}
521#endif
522
523
524/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +0000525/*--- Build the flags thunk. ---*/
526/*------------------------------------------------------------*/
527
528/* Completely fill the flags thunk. We're always filling all fields.
529 Apparently, that is better for redundant PUT elimination. */
530static void
531s390_cc_thunk_fill(IRExpr *op, IRExpr *dep1, IRExpr *dep2, IRExpr *ndep)
532{
533 UInt op_off, dep1_off, dep2_off, ndep_off;
534
florian428dfdd2012-03-27 03:09:49 +0000535 op_off = S390X_GUEST_OFFSET(guest_CC_OP);
536 dep1_off = S390X_GUEST_OFFSET(guest_CC_DEP1);
537 dep2_off = S390X_GUEST_OFFSET(guest_CC_DEP2);
538 ndep_off = S390X_GUEST_OFFSET(guest_CC_NDEP);
sewardj2019a972011-03-07 16:04:07 +0000539
540 stmt(IRStmt_Put(op_off, op));
541 stmt(IRStmt_Put(dep1_off, dep1));
542 stmt(IRStmt_Put(dep2_off, dep2));
543 stmt(IRStmt_Put(ndep_off, ndep));
544}
545
546
547/* Create an expression for V and widen the result to 64 bit. */
548static IRExpr *
549s390_cc_widen(IRTemp v, Bool sign_extend)
550{
551 IRExpr *expr;
552
553 expr = mkexpr(v);
554
555 switch (typeOfIRTemp(irsb->tyenv, v)) {
556 case Ity_I64:
557 break;
558 case Ity_I32:
559 expr = unop(sign_extend ? Iop_32Sto64 : Iop_32Uto64, expr);
560 break;
561 case Ity_I16:
562 expr = unop(sign_extend ? Iop_16Sto64 : Iop_16Uto64, expr);
563 break;
564 case Ity_I8:
565 expr = unop(sign_extend ? Iop_8Sto64 : Iop_8Uto64, expr);
566 break;
567 default:
568 vpanic("s390_cc_widen");
569 }
570
571 return expr;
572}
573
574static void
575s390_cc_thunk_put1(UInt opc, IRTemp d1, Bool sign_extend)
576{
577 IRExpr *op, *dep1, *dep2, *ndep;
578
579 op = mkU64(opc);
580 dep1 = s390_cc_widen(d1, sign_extend);
581 dep2 = mkU64(0);
582 ndep = mkU64(0);
583
584 s390_cc_thunk_fill(op, dep1, dep2, ndep);
585}
586
587
588static void
589s390_cc_thunk_put2(UInt opc, IRTemp d1, IRTemp d2, Bool sign_extend)
590{
591 IRExpr *op, *dep1, *dep2, *ndep;
592
593 op = mkU64(opc);
594 dep1 = s390_cc_widen(d1, sign_extend);
595 dep2 = s390_cc_widen(d2, sign_extend);
596 ndep = mkU64(0);
597
598 s390_cc_thunk_fill(op, dep1, dep2, ndep);
599}
600
601
602/* memcheck believes that the NDEP field in the flags thunk is always
603 defined. But for some flag computations (e.g. add with carry) that is
604 just not true. We therefore need to convey to memcheck that the value
605 of the ndep field does matter and therefore we make the DEP2 field
606 depend on it:
607
608 DEP2 = original_DEP2 ^ NDEP
609
610 In s390_calculate_cc we exploit that (a^b)^b == a
611 I.e. we xor the DEP2 value with the NDEP value to recover the
612 original_DEP2 value. */
613static void
614s390_cc_thunk_put3(UInt opc, IRTemp d1, IRTemp d2, IRTemp nd, Bool sign_extend)
615{
616 IRExpr *op, *dep1, *dep2, *ndep, *dep2x;
617
618 op = mkU64(opc);
619 dep1 = s390_cc_widen(d1, sign_extend);
620 dep2 = s390_cc_widen(d2, sign_extend);
621 ndep = s390_cc_widen(nd, sign_extend);
622
623 dep2x = binop(Iop_Xor64, dep2, ndep);
624
625 s390_cc_thunk_fill(op, dep1, dep2x, ndep);
626}
627
628
629/* Write one floating point value into the flags thunk */
630static void
631s390_cc_thunk_put1f(UInt opc, IRTemp d1)
632{
633 IRExpr *op, *dep1, *dep2, *ndep;
634
635 op = mkU64(opc);
636 dep1 = mkexpr(d1);
637 dep2 = mkU64(0);
638 ndep = mkU64(0);
639
640 s390_cc_thunk_fill(op, dep1, dep2, ndep);
641}
642
643
644/* Write a floating point value and an integer into the flags thunk. The
645 integer value is zero-extended first. */
646static void
647s390_cc_thunk_putFZ(UInt opc, IRTemp d1, IRTemp d2)
648{
649 IRExpr *op, *dep1, *dep2, *ndep;
650
651 op = mkU64(opc);
652 dep1 = mkexpr(d1);
653 dep2 = s390_cc_widen(d2, False);
654 ndep = mkU64(0);
655
656 s390_cc_thunk_fill(op, dep1, dep2, ndep);
657}
658
659
660/* Write a 128-bit floating point value into the flags thunk. This is
661 done by splitting the value into two 64-bits values. */
662static void
663s390_cc_thunk_put1f128(UInt opc, IRTemp d1)
664{
665 IRExpr *op, *hi, *lo, *ndep;
666
667 op = mkU64(opc);
668 hi = unop(Iop_F128HItoF64, mkexpr(d1));
669 lo = unop(Iop_F128LOtoF64, mkexpr(d1));
670 ndep = mkU64(0);
671
672 s390_cc_thunk_fill(op, hi, lo, ndep);
673}
674
675
676/* Write a 128-bit floating point value and an integer into the flags thunk.
677 The integer value is zero-extended first. */
678static void
679s390_cc_thunk_put1f128Z(UInt opc, IRTemp d1, IRTemp nd)
680{
681 IRExpr *op, *hi, *lo, *lox, *ndep;
682
683 op = mkU64(opc);
684 hi = unop(Iop_F128HItoF64, mkexpr(d1));
685 lo = unop(Iop_ReinterpF64asI64, unop(Iop_F128LOtoF64, mkexpr(d1)));
686 ndep = s390_cc_widen(nd, False);
687
688 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
689
690 s390_cc_thunk_fill(op, hi, lox, ndep);
691}
692
693
floriane38f6412012-12-21 17:32:12 +0000694/* Write a 128-bit decimal floating point value into the flags thunk.
695 This is done by splitting the value into two 64-bits values. */
696static void
697s390_cc_thunk_put1d128(UInt opc, IRTemp d1)
698{
699 IRExpr *op, *hi, *lo, *ndep;
700
701 op = mkU64(opc);
702 hi = unop(Iop_D128HItoD64, mkexpr(d1));
703 lo = unop(Iop_D128LOtoD64, mkexpr(d1));
704 ndep = mkU64(0);
705
706 s390_cc_thunk_fill(op, hi, lo, ndep);
707}
708
709
floriance9e3db2012-12-27 20:14:03 +0000710/* Write a 128-bit decimal floating point value and an integer into the flags
711 thunk. The integer value is zero-extended first. */
712static void
713s390_cc_thunk_put1d128Z(UInt opc, IRTemp d1, IRTemp nd)
714{
715 IRExpr *op, *hi, *lo, *lox, *ndep;
716
717 op = mkU64(opc);
718 hi = unop(Iop_D128HItoD64, mkexpr(d1));
719 lo = unop(Iop_ReinterpD64asI64, unop(Iop_D128LOtoD64, mkexpr(d1)));
720 ndep = s390_cc_widen(nd, False);
721
722 lox = binop(Iop_Xor64, lo, ndep); /* convey dependency */
723
724 s390_cc_thunk_fill(op, hi, lox, ndep);
725}
726
727
sewardj2019a972011-03-07 16:04:07 +0000728static void
729s390_cc_set(UInt val)
730{
731 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
732 mkU64(val), mkU64(0), mkU64(0));
733}
734
735/* Build IR to calculate the condition code from flags thunk.
736 Returns an expression of type Ity_I32 */
737static IRExpr *
738s390_call_calculate_cc(void)
739{
740 IRExpr **args, *call, *op, *dep1, *dep2, *ndep;
741
florian428dfdd2012-03-27 03:09:49 +0000742 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
743 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
744 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
745 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000746
747 args = mkIRExprVec_4(op, dep1, dep2, ndep);
748 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
749 "s390_calculate_cc", &s390_calculate_cc, args);
750
751 /* Exclude OP and NDEP from definedness checking. We're only
752 interested in DEP1 and DEP2. */
753 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<3);
754
755 return call;
756}
757
758/* Build IR to calculate the internal condition code for a "compare and branch"
759 insn. Returns an expression of type Ity_I32 */
760static IRExpr *
florianff9613f2012-05-12 15:26:44 +0000761s390_call_calculate_icc(UInt m, UInt opc, IRTemp op1, IRTemp op2)
sewardj2019a972011-03-07 16:04:07 +0000762{
florianff9613f2012-05-12 15:26:44 +0000763 IRExpr **args, *call, *op, *dep1, *dep2, *mask;
sewardj2019a972011-03-07 16:04:07 +0000764
florianff9613f2012-05-12 15:26:44 +0000765 switch (opc) {
766 case S390_CC_OP_SIGNED_COMPARE:
767 dep1 = s390_cc_widen(op1, True);
768 dep2 = s390_cc_widen(op2, True);
769 break;
770
771 case S390_CC_OP_UNSIGNED_COMPARE:
772 dep1 = s390_cc_widen(op1, False);
773 dep2 = s390_cc_widen(op2, False);
774 break;
775
776 default:
777 vpanic("s390_call_calculate_icc");
778 }
779
780 mask = mkU64(m);
sewardj2019a972011-03-07 16:04:07 +0000781 op = mkU64(opc);
sewardj2019a972011-03-07 16:04:07 +0000782
florianff9613f2012-05-12 15:26:44 +0000783 args = mkIRExprVec_5(mask, op, dep1, dep2, mkU64(0) /* unused */);
sewardj2019a972011-03-07 16:04:07 +0000784 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
florianff9613f2012-05-12 15:26:44 +0000785 "s390_calculate_cond", &s390_calculate_cond, args);
sewardj2019a972011-03-07 16:04:07 +0000786
florianff9613f2012-05-12 15:26:44 +0000787 /* Exclude the requested condition, OP and NDEP from definedness
788 checking. We're only interested in DEP1 and DEP2. */
789 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
sewardj2019a972011-03-07 16:04:07 +0000790
791 return call;
792}
793
794/* Build IR to calculate the condition code from flags thunk.
795 Returns an expression of type Ity_I32 */
796static IRExpr *
797s390_call_calculate_cond(UInt m)
798{
799 IRExpr **args, *call, *op, *dep1, *dep2, *ndep, *mask;
800
801 mask = mkU64(m);
florian428dfdd2012-03-27 03:09:49 +0000802 op = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_OP), Ity_I64);
803 dep1 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP1), Ity_I64);
804 dep2 = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_DEP2), Ity_I64);
805 ndep = IRExpr_Get(S390X_GUEST_OFFSET(guest_CC_NDEP), Ity_I64);
sewardj2019a972011-03-07 16:04:07 +0000806
807 args = mkIRExprVec_5(mask, op, dep1, dep2, ndep);
808 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
809 "s390_calculate_cond", &s390_calculate_cond, args);
810
811 /* Exclude the requested condition, OP and NDEP from definedness
812 checking. We're only interested in DEP1 and DEP2. */
813 call->Iex.CCall.cee->mcx_mask = (1<<0) | (1<<1) | (1<<4);
814
815 return call;
816}
817
818#define s390_cc_thunk_putZ(op,dep1) s390_cc_thunk_put1(op,dep1,False)
819#define s390_cc_thunk_putS(op,dep1) s390_cc_thunk_put1(op,dep1,True)
820#define s390_cc_thunk_putF(op,dep1) s390_cc_thunk_put1f(op,dep1)
821#define s390_cc_thunk_putZZ(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,False)
822#define s390_cc_thunk_putSS(op,dep1,dep2) s390_cc_thunk_put2(op,dep1,dep2,True)
823#define s390_cc_thunk_putFF(op,dep1,dep2) s390_cc_thunk_put2f(op,dep1,dep2)
824#define s390_cc_thunk_putZZZ(op,dep1,dep2,ndep) \
825 s390_cc_thunk_put3(op,dep1,dep2,ndep,False)
826#define s390_cc_thunk_putSSS(op,dep1,dep2,ndep) \
827 s390_cc_thunk_put3(op,dep1,dep2,ndep,True)
sewardj2019a972011-03-07 16:04:07 +0000828
829
sewardj2019a972011-03-07 16:04:07 +0000830
831
832/*------------------------------------------------------------*/
833/*--- Guest register access ---*/
834/*------------------------------------------------------------*/
835
836
837/*------------------------------------------------------------*/
838/*--- ar registers ---*/
839/*------------------------------------------------------------*/
840
841/* Return the guest state offset of a ar register. */
842static UInt
843ar_offset(UInt archreg)
844{
845 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000846 S390X_GUEST_OFFSET(guest_a0),
847 S390X_GUEST_OFFSET(guest_a1),
848 S390X_GUEST_OFFSET(guest_a2),
849 S390X_GUEST_OFFSET(guest_a3),
850 S390X_GUEST_OFFSET(guest_a4),
851 S390X_GUEST_OFFSET(guest_a5),
852 S390X_GUEST_OFFSET(guest_a6),
853 S390X_GUEST_OFFSET(guest_a7),
854 S390X_GUEST_OFFSET(guest_a8),
855 S390X_GUEST_OFFSET(guest_a9),
856 S390X_GUEST_OFFSET(guest_a10),
857 S390X_GUEST_OFFSET(guest_a11),
858 S390X_GUEST_OFFSET(guest_a12),
859 S390X_GUEST_OFFSET(guest_a13),
860 S390X_GUEST_OFFSET(guest_a14),
861 S390X_GUEST_OFFSET(guest_a15),
sewardj2019a972011-03-07 16:04:07 +0000862 };
863
864 vassert(archreg < 16);
865
866 return offset[archreg];
867}
868
869
870/* Return the guest state offset of word #0 of a ar register. */
871static __inline__ UInt
872ar_w0_offset(UInt archreg)
873{
874 return ar_offset(archreg) + 0;
875}
876
877/* Write word #0 of a ar to the guest state. */
878static __inline__ void
879put_ar_w0(UInt archreg, IRExpr *expr)
880{
881 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
882
883 stmt(IRStmt_Put(ar_w0_offset(archreg), expr));
884}
885
886/* Read word #0 of a ar register. */
887static __inline__ IRExpr *
888get_ar_w0(UInt archreg)
889{
890 return IRExpr_Get(ar_w0_offset(archreg), Ity_I32);
891}
892
893
894/*------------------------------------------------------------*/
895/*--- fpr registers ---*/
896/*------------------------------------------------------------*/
897
898/* Return the guest state offset of a fpr register. */
899static UInt
900fpr_offset(UInt archreg)
901{
902 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +0000903 S390X_GUEST_OFFSET(guest_f0),
904 S390X_GUEST_OFFSET(guest_f1),
905 S390X_GUEST_OFFSET(guest_f2),
906 S390X_GUEST_OFFSET(guest_f3),
907 S390X_GUEST_OFFSET(guest_f4),
908 S390X_GUEST_OFFSET(guest_f5),
909 S390X_GUEST_OFFSET(guest_f6),
910 S390X_GUEST_OFFSET(guest_f7),
911 S390X_GUEST_OFFSET(guest_f8),
912 S390X_GUEST_OFFSET(guest_f9),
913 S390X_GUEST_OFFSET(guest_f10),
914 S390X_GUEST_OFFSET(guest_f11),
915 S390X_GUEST_OFFSET(guest_f12),
916 S390X_GUEST_OFFSET(guest_f13),
917 S390X_GUEST_OFFSET(guest_f14),
918 S390X_GUEST_OFFSET(guest_f15),
sewardj2019a972011-03-07 16:04:07 +0000919 };
920
921 vassert(archreg < 16);
922
923 return offset[archreg];
924}
925
926
927/* Return the guest state offset of word #0 of a fpr register. */
928static __inline__ UInt
929fpr_w0_offset(UInt archreg)
930{
931 return fpr_offset(archreg) + 0;
932}
933
934/* Write word #0 of a fpr to the guest state. */
935static __inline__ void
936put_fpr_w0(UInt archreg, IRExpr *expr)
937{
938 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F32);
939
940 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
941}
942
943/* Read word #0 of a fpr register. */
944static __inline__ IRExpr *
945get_fpr_w0(UInt archreg)
946{
947 return IRExpr_Get(fpr_w0_offset(archreg), Ity_F32);
948}
949
950/* Return the guest state offset of double word #0 of a fpr register. */
951static __inline__ UInt
952fpr_dw0_offset(UInt archreg)
953{
954 return fpr_offset(archreg) + 0;
955}
956
957/* Write double word #0 of a fpr to the guest state. */
958static __inline__ void
959put_fpr_dw0(UInt archreg, IRExpr *expr)
960{
961 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_F64);
962
963 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
964}
965
966/* Read double word #0 of a fpr register. */
967static __inline__ IRExpr *
968get_fpr_dw0(UInt archreg)
969{
970 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_F64);
971}
972
floriane38f6412012-12-21 17:32:12 +0000973/* Write word #0 of a dpr to the guest state. */
974static __inline__ void
975put_dpr_w0(UInt archreg, IRExpr *expr)
976{
977 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D32);
978
979 stmt(IRStmt_Put(fpr_w0_offset(archreg), expr));
980}
981
982/* Read word #0 of a dpr register. */
983static __inline__ IRExpr *
984get_dpr_w0(UInt archreg)
985{
986 return IRExpr_Get(fpr_w0_offset(archreg), Ity_D32);
987}
988
florian12390202012-11-10 22:34:14 +0000989/* Write double word #0 of a fpr containg DFP value to the guest state. */
990static __inline__ void
991put_dpr_dw0(UInt archreg, IRExpr *expr)
992{
993 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_D64);
994
995 stmt(IRStmt_Put(fpr_dw0_offset(archreg), expr));
996}
997
998/* Read double word #0 of a fpr register containing DFP value. */
999static __inline__ IRExpr *
1000get_dpr_dw0(UInt archreg)
1001{
1002 return IRExpr_Get(fpr_dw0_offset(archreg), Ity_D64);
1003}
sewardj2019a972011-03-07 16:04:07 +00001004
1005/*------------------------------------------------------------*/
1006/*--- gpr registers ---*/
1007/*------------------------------------------------------------*/
1008
1009/* Return the guest state offset of a gpr register. */
1010static UInt
1011gpr_offset(UInt archreg)
1012{
1013 static const UInt offset[16] = {
floriane88b3c92011-07-05 02:48:39 +00001014 S390X_GUEST_OFFSET(guest_r0),
1015 S390X_GUEST_OFFSET(guest_r1),
1016 S390X_GUEST_OFFSET(guest_r2),
1017 S390X_GUEST_OFFSET(guest_r3),
1018 S390X_GUEST_OFFSET(guest_r4),
1019 S390X_GUEST_OFFSET(guest_r5),
1020 S390X_GUEST_OFFSET(guest_r6),
1021 S390X_GUEST_OFFSET(guest_r7),
1022 S390X_GUEST_OFFSET(guest_r8),
1023 S390X_GUEST_OFFSET(guest_r9),
1024 S390X_GUEST_OFFSET(guest_r10),
1025 S390X_GUEST_OFFSET(guest_r11),
1026 S390X_GUEST_OFFSET(guest_r12),
1027 S390X_GUEST_OFFSET(guest_r13),
1028 S390X_GUEST_OFFSET(guest_r14),
1029 S390X_GUEST_OFFSET(guest_r15),
sewardj2019a972011-03-07 16:04:07 +00001030 };
1031
1032 vassert(archreg < 16);
1033
1034 return offset[archreg];
1035}
1036
1037
1038/* Return the guest state offset of word #0 of a gpr register. */
1039static __inline__ UInt
1040gpr_w0_offset(UInt archreg)
1041{
1042 return gpr_offset(archreg) + 0;
1043}
1044
1045/* Write word #0 of a gpr to the guest state. */
1046static __inline__ void
1047put_gpr_w0(UInt archreg, IRExpr *expr)
1048{
1049 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1050
1051 stmt(IRStmt_Put(gpr_w0_offset(archreg), expr));
1052}
1053
1054/* Read word #0 of a gpr register. */
1055static __inline__ IRExpr *
1056get_gpr_w0(UInt archreg)
1057{
1058 return IRExpr_Get(gpr_w0_offset(archreg), Ity_I32);
1059}
1060
1061/* Return the guest state offset of double word #0 of a gpr register. */
1062static __inline__ UInt
1063gpr_dw0_offset(UInt archreg)
1064{
1065 return gpr_offset(archreg) + 0;
1066}
1067
1068/* Write double word #0 of a gpr to the guest state. */
1069static __inline__ void
1070put_gpr_dw0(UInt archreg, IRExpr *expr)
1071{
1072 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1073
1074 stmt(IRStmt_Put(gpr_dw0_offset(archreg), expr));
1075}
1076
1077/* Read double word #0 of a gpr register. */
1078static __inline__ IRExpr *
1079get_gpr_dw0(UInt archreg)
1080{
1081 return IRExpr_Get(gpr_dw0_offset(archreg), Ity_I64);
1082}
1083
1084/* Return the guest state offset of half word #1 of a gpr register. */
1085static __inline__ UInt
1086gpr_hw1_offset(UInt archreg)
1087{
1088 return gpr_offset(archreg) + 2;
1089}
1090
1091/* Write half word #1 of a gpr to the guest state. */
1092static __inline__ void
1093put_gpr_hw1(UInt archreg, IRExpr *expr)
1094{
1095 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1096
1097 stmt(IRStmt_Put(gpr_hw1_offset(archreg), expr));
1098}
1099
1100/* Read half word #1 of a gpr register. */
1101static __inline__ IRExpr *
1102get_gpr_hw1(UInt archreg)
1103{
1104 return IRExpr_Get(gpr_hw1_offset(archreg), Ity_I16);
1105}
1106
1107/* Return the guest state offset of byte #6 of a gpr register. */
1108static __inline__ UInt
1109gpr_b6_offset(UInt archreg)
1110{
1111 return gpr_offset(archreg) + 6;
1112}
1113
1114/* Write byte #6 of a gpr to the guest state. */
1115static __inline__ void
1116put_gpr_b6(UInt archreg, IRExpr *expr)
1117{
1118 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1119
1120 stmt(IRStmt_Put(gpr_b6_offset(archreg), expr));
1121}
1122
1123/* Read byte #6 of a gpr register. */
1124static __inline__ IRExpr *
1125get_gpr_b6(UInt archreg)
1126{
1127 return IRExpr_Get(gpr_b6_offset(archreg), Ity_I8);
1128}
1129
1130/* Return the guest state offset of byte #3 of a gpr register. */
1131static __inline__ UInt
1132gpr_b3_offset(UInt archreg)
1133{
1134 return gpr_offset(archreg) + 3;
1135}
1136
1137/* Write byte #3 of a gpr to the guest state. */
1138static __inline__ void
1139put_gpr_b3(UInt archreg, IRExpr *expr)
1140{
1141 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1142
1143 stmt(IRStmt_Put(gpr_b3_offset(archreg), expr));
1144}
1145
1146/* Read byte #3 of a gpr register. */
1147static __inline__ IRExpr *
1148get_gpr_b3(UInt archreg)
1149{
1150 return IRExpr_Get(gpr_b3_offset(archreg), Ity_I8);
1151}
1152
1153/* Return the guest state offset of byte #0 of a gpr register. */
1154static __inline__ UInt
1155gpr_b0_offset(UInt archreg)
1156{
1157 return gpr_offset(archreg) + 0;
1158}
1159
1160/* Write byte #0 of a gpr to the guest state. */
1161static __inline__ void
1162put_gpr_b0(UInt archreg, IRExpr *expr)
1163{
1164 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1165
1166 stmt(IRStmt_Put(gpr_b0_offset(archreg), expr));
1167}
1168
1169/* Read byte #0 of a gpr register. */
1170static __inline__ IRExpr *
1171get_gpr_b0(UInt archreg)
1172{
1173 return IRExpr_Get(gpr_b0_offset(archreg), Ity_I8);
1174}
1175
1176/* Return the guest state offset of word #1 of a gpr register. */
1177static __inline__ UInt
1178gpr_w1_offset(UInt archreg)
1179{
1180 return gpr_offset(archreg) + 4;
1181}
1182
1183/* Write word #1 of a gpr to the guest state. */
1184static __inline__ void
1185put_gpr_w1(UInt archreg, IRExpr *expr)
1186{
1187 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1188
1189 stmt(IRStmt_Put(gpr_w1_offset(archreg), expr));
1190}
1191
1192/* Read word #1 of a gpr register. */
1193static __inline__ IRExpr *
1194get_gpr_w1(UInt archreg)
1195{
1196 return IRExpr_Get(gpr_w1_offset(archreg), Ity_I32);
1197}
1198
1199/* Return the guest state offset of half word #3 of a gpr register. */
1200static __inline__ UInt
1201gpr_hw3_offset(UInt archreg)
1202{
1203 return gpr_offset(archreg) + 6;
1204}
1205
1206/* Write half word #3 of a gpr to the guest state. */
1207static __inline__ void
1208put_gpr_hw3(UInt archreg, IRExpr *expr)
1209{
1210 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1211
1212 stmt(IRStmt_Put(gpr_hw3_offset(archreg), expr));
1213}
1214
1215/* Read half word #3 of a gpr register. */
1216static __inline__ IRExpr *
1217get_gpr_hw3(UInt archreg)
1218{
1219 return IRExpr_Get(gpr_hw3_offset(archreg), Ity_I16);
1220}
1221
1222/* Return the guest state offset of byte #7 of a gpr register. */
1223static __inline__ UInt
1224gpr_b7_offset(UInt archreg)
1225{
1226 return gpr_offset(archreg) + 7;
1227}
1228
1229/* Write byte #7 of a gpr to the guest state. */
1230static __inline__ void
1231put_gpr_b7(UInt archreg, IRExpr *expr)
1232{
1233 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1234
1235 stmt(IRStmt_Put(gpr_b7_offset(archreg), expr));
1236}
1237
1238/* Read byte #7 of a gpr register. */
1239static __inline__ IRExpr *
1240get_gpr_b7(UInt archreg)
1241{
1242 return IRExpr_Get(gpr_b7_offset(archreg), Ity_I8);
1243}
1244
1245/* Return the guest state offset of half word #0 of a gpr register. */
1246static __inline__ UInt
1247gpr_hw0_offset(UInt archreg)
1248{
1249 return gpr_offset(archreg) + 0;
1250}
1251
1252/* Write half word #0 of a gpr to the guest state. */
1253static __inline__ void
1254put_gpr_hw0(UInt archreg, IRExpr *expr)
1255{
1256 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1257
1258 stmt(IRStmt_Put(gpr_hw0_offset(archreg), expr));
1259}
1260
1261/* Read half word #0 of a gpr register. */
1262static __inline__ IRExpr *
1263get_gpr_hw0(UInt archreg)
1264{
1265 return IRExpr_Get(gpr_hw0_offset(archreg), Ity_I16);
1266}
1267
1268/* Return the guest state offset of byte #4 of a gpr register. */
1269static __inline__ UInt
1270gpr_b4_offset(UInt archreg)
1271{
1272 return gpr_offset(archreg) + 4;
1273}
1274
1275/* Write byte #4 of a gpr to the guest state. */
1276static __inline__ void
1277put_gpr_b4(UInt archreg, IRExpr *expr)
1278{
1279 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1280
1281 stmt(IRStmt_Put(gpr_b4_offset(archreg), expr));
1282}
1283
1284/* Read byte #4 of a gpr register. */
1285static __inline__ IRExpr *
1286get_gpr_b4(UInt archreg)
1287{
1288 return IRExpr_Get(gpr_b4_offset(archreg), Ity_I8);
1289}
1290
1291/* Return the guest state offset of byte #1 of a gpr register. */
1292static __inline__ UInt
1293gpr_b1_offset(UInt archreg)
1294{
1295 return gpr_offset(archreg) + 1;
1296}
1297
1298/* Write byte #1 of a gpr to the guest state. */
1299static __inline__ void
1300put_gpr_b1(UInt archreg, IRExpr *expr)
1301{
1302 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1303
1304 stmt(IRStmt_Put(gpr_b1_offset(archreg), expr));
1305}
1306
1307/* Read byte #1 of a gpr register. */
1308static __inline__ IRExpr *
1309get_gpr_b1(UInt archreg)
1310{
1311 return IRExpr_Get(gpr_b1_offset(archreg), Ity_I8);
1312}
1313
1314/* Return the guest state offset of half word #2 of a gpr register. */
1315static __inline__ UInt
1316gpr_hw2_offset(UInt archreg)
1317{
1318 return gpr_offset(archreg) + 4;
1319}
1320
1321/* Write half word #2 of a gpr to the guest state. */
1322static __inline__ void
1323put_gpr_hw2(UInt archreg, IRExpr *expr)
1324{
1325 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I16);
1326
1327 stmt(IRStmt_Put(gpr_hw2_offset(archreg), expr));
1328}
1329
1330/* Read half word #2 of a gpr register. */
1331static __inline__ IRExpr *
1332get_gpr_hw2(UInt archreg)
1333{
1334 return IRExpr_Get(gpr_hw2_offset(archreg), Ity_I16);
1335}
1336
1337/* Return the guest state offset of byte #5 of a gpr register. */
1338static __inline__ UInt
1339gpr_b5_offset(UInt archreg)
1340{
1341 return gpr_offset(archreg) + 5;
1342}
1343
1344/* Write byte #5 of a gpr to the guest state. */
1345static __inline__ void
1346put_gpr_b5(UInt archreg, IRExpr *expr)
1347{
1348 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1349
1350 stmt(IRStmt_Put(gpr_b5_offset(archreg), expr));
1351}
1352
1353/* Read byte #5 of a gpr register. */
1354static __inline__ IRExpr *
1355get_gpr_b5(UInt archreg)
1356{
1357 return IRExpr_Get(gpr_b5_offset(archreg), Ity_I8);
1358}
1359
1360/* Return the guest state offset of byte #2 of a gpr register. */
1361static __inline__ UInt
1362gpr_b2_offset(UInt archreg)
1363{
1364 return gpr_offset(archreg) + 2;
1365}
1366
1367/* Write byte #2 of a gpr to the guest state. */
1368static __inline__ void
1369put_gpr_b2(UInt archreg, IRExpr *expr)
1370{
1371 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I8);
1372
1373 stmt(IRStmt_Put(gpr_b2_offset(archreg), expr));
1374}
1375
1376/* Read byte #2 of a gpr register. */
1377static __inline__ IRExpr *
1378get_gpr_b2(UInt archreg)
1379{
1380 return IRExpr_Get(gpr_b2_offset(archreg), Ity_I8);
1381}
1382
1383/* Return the guest state offset of the counter register. */
1384static UInt
1385counter_offset(void)
1386{
floriane88b3c92011-07-05 02:48:39 +00001387 return S390X_GUEST_OFFSET(guest_counter);
sewardj2019a972011-03-07 16:04:07 +00001388}
1389
1390/* Return the guest state offset of double word #0 of the counter register. */
1391static __inline__ UInt
1392counter_dw0_offset(void)
1393{
1394 return counter_offset() + 0;
1395}
1396
1397/* Write double word #0 of the counter to the guest state. */
1398static __inline__ void
1399put_counter_dw0(IRExpr *expr)
1400{
1401 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I64);
1402
1403 stmt(IRStmt_Put(counter_dw0_offset(), expr));
1404}
1405
1406/* Read double word #0 of the counter register. */
1407static __inline__ IRExpr *
1408get_counter_dw0(void)
1409{
1410 return IRExpr_Get(counter_dw0_offset(), Ity_I64);
1411}
1412
1413/* Return the guest state offset of word #0 of the counter register. */
1414static __inline__ UInt
1415counter_w0_offset(void)
1416{
1417 return counter_offset() + 0;
1418}
1419
1420/* Return the guest state offset of word #1 of the counter register. */
1421static __inline__ UInt
1422counter_w1_offset(void)
1423{
1424 return counter_offset() + 4;
1425}
1426
1427/* Write word #0 of the counter to the guest state. */
1428static __inline__ void
1429put_counter_w0(IRExpr *expr)
1430{
1431 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1432
1433 stmt(IRStmt_Put(counter_w0_offset(), expr));
1434}
1435
1436/* Read word #0 of the counter register. */
1437static __inline__ IRExpr *
1438get_counter_w0(void)
1439{
1440 return IRExpr_Get(counter_w0_offset(), Ity_I32);
1441}
1442
1443/* Write word #1 of the counter to the guest state. */
1444static __inline__ void
1445put_counter_w1(IRExpr *expr)
1446{
1447 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1448
1449 stmt(IRStmt_Put(counter_w1_offset(), expr));
1450}
1451
1452/* Read word #1 of the counter register. */
1453static __inline__ IRExpr *
1454get_counter_w1(void)
1455{
1456 return IRExpr_Get(counter_w1_offset(), Ity_I32);
1457}
1458
1459/* Return the guest state offset of the fpc register. */
1460static UInt
1461fpc_offset(void)
1462{
floriane88b3c92011-07-05 02:48:39 +00001463 return S390X_GUEST_OFFSET(guest_fpc);
sewardj2019a972011-03-07 16:04:07 +00001464}
1465
1466/* Return the guest state offset of word #0 of the fpc register. */
1467static __inline__ UInt
1468fpc_w0_offset(void)
1469{
1470 return fpc_offset() + 0;
1471}
1472
1473/* Write word #0 of the fpc to the guest state. */
1474static __inline__ void
1475put_fpc_w0(IRExpr *expr)
1476{
1477 vassert(typeOfIRExpr(irsb->tyenv, expr) == Ity_I32);
1478
1479 stmt(IRStmt_Put(fpc_w0_offset(), expr));
1480}
1481
1482/* Read word #0 of the fpc register. */
1483static __inline__ IRExpr *
1484get_fpc_w0(void)
1485{
1486 return IRExpr_Get(fpc_w0_offset(), Ity_I32);
1487}
1488
1489
1490/*------------------------------------------------------------*/
florian2c74d242012-09-12 19:38:42 +00001491/*--- Rounding modes ---*/
1492/*------------------------------------------------------------*/
1493
florian125e20d2012-10-07 15:42:37 +00001494/* Extract the bfp rounding mode from the guest FPC reg and encode it as an
florian2c74d242012-09-12 19:38:42 +00001495 IRRoundingMode:
1496
1497 rounding mode | s390 | IR
1498 -------------------------
1499 to nearest | 00 | 00
1500 to zero | 01 | 11
1501 to +infinity | 10 | 10
1502 to -infinity | 11 | 01
1503
1504 So: IR = (4 - s390) & 3
1505*/
1506static IRExpr *
florian125e20d2012-10-07 15:42:37 +00001507get_bfp_rounding_mode_from_fpc(void)
florian2c74d242012-09-12 19:38:42 +00001508{
1509 IRTemp fpc_bits = newTemp(Ity_I32);
1510
1511 /* For z196 and later the bfp rounding mode is stored in bits [29:31].
1512 Prior to that bits [30:31] contained the bfp rounding mode with
1513 bit 29 being unused and having a value of 0. So we can always
1514 extract the least significant 3 bits. */
1515 assign(fpc_bits, binop(Iop_And32, get_fpc_w0(), mkU32(7)));
1516
1517 /* fixs390:
1518
1519
1520 if (! s390_host_has_fpext && rounding_mode > 3) {
1521 emulation warning @ runtime and
1522 set fpc to round nearest
1523 }
1524 */
1525
1526 /* For now silently adjust an unsupported rounding mode to "nearest" */
1527 IRExpr *rm_s390 = mkite(binop(Iop_CmpLE32S, mkexpr(fpc_bits), mkU32(3)),
1528 mkexpr(fpc_bits),
florian125e20d2012-10-07 15:42:37 +00001529 mkU32(S390_FPC_BFP_ROUND_NEAREST_EVEN));
florian2c74d242012-09-12 19:38:42 +00001530
1531 // rm_IR = (4 - rm_s390) & 3;
1532 return binop(Iop_And32, binop(Iop_Sub32, mkU32(4), rm_s390), mkU32(3));
1533}
1534
1535/* Encode the s390 rounding mode as it appears in the m3 field of certain
1536 instructions to VEX's IRRoundingMode. Rounding modes that cannot be
1537 represented in VEX are converted to Irrm_NEAREST. The rationale is, that
1538 Irrm_NEAREST refers to IEEE 754's roundTiesToEven which the standard
1539 considers the default rounding mode (4.3.3). */
1540static IRTemp
1541encode_bfp_rounding_mode(UChar mode)
1542{
1543 IRExpr *rm;
1544
1545 switch (mode) {
florian125e20d2012-10-07 15:42:37 +00001546 case S390_BFP_ROUND_PER_FPC:
1547 rm = get_bfp_rounding_mode_from_fpc();
1548 break;
1549 case S390_BFP_ROUND_NEAREST_AWAY: /* not supported */
1550 case S390_BFP_ROUND_PREPARE_SHORT: /* not supported */
1551 case S390_BFP_ROUND_NEAREST_EVEN: rm = mkU32(Irrm_NEAREST); break;
1552 case S390_BFP_ROUND_ZERO: rm = mkU32(Irrm_ZERO); break;
1553 case S390_BFP_ROUND_POSINF: rm = mkU32(Irrm_PosINF); break;
1554 case S390_BFP_ROUND_NEGINF: rm = mkU32(Irrm_NegINF); break;
florian2c74d242012-09-12 19:38:42 +00001555 default:
1556 vpanic("encode_bfp_rounding_mode");
1557 }
1558
1559 return mktemp(Ity_I32, rm);
1560}
1561
florianc8e4f562012-10-27 16:19:31 +00001562/* Extract the DFP rounding mode from the guest FPC reg and encode it as an
1563 IRRoundingMode:
1564
1565 rounding mode | s390 | IR
1566 ------------------------------------------------
1567 to nearest, ties to even | 000 | 000
1568 to zero | 001 | 011
1569 to +infinity | 010 | 010
1570 to -infinity | 011 | 001
1571 to nearest, ties away from 0 | 100 | 100
1572 to nearest, ties toward 0 | 101 | 111
1573 to away from 0 | 110 | 110
1574 to prepare for shorter precision | 111 | 101
1575
1576 So: IR = (s390 ^ ((s390 << 1) & 2))
1577*/
florianc8e4f562012-10-27 16:19:31 +00001578static IRExpr *
1579get_dfp_rounding_mode_from_fpc(void)
1580{
1581 IRTemp fpc_bits = newTemp(Ity_I32);
1582
1583 /* The dfp rounding mode is stored in bits [25:27].
1584 extract the bits at 25:27 and right shift 4 times. */
1585 assign(fpc_bits, binop(Iop_Shr32,
1586 binop(Iop_And32, get_fpc_w0(), mkU32(0x70)),
1587 mkU8(4)));
1588
1589 IRExpr *rm_s390 = mkexpr(fpc_bits);
1590 // rm_IR = (rm_s390 ^ ((rm_s390 << 1) & 2));
1591
1592 return binop(Iop_Xor32, rm_s390,
1593 binop( Iop_And32,
1594 binop(Iop_Shl32, rm_s390, mkU8(1)),
1595 mkU32(2)));
1596}
1597
1598/* Encode the s390 rounding mode as it appears in the m3 field of certain
1599 instructions to VEX's IRRoundingMode. */
1600static IRTemp
1601encode_dfp_rounding_mode(UChar mode)
1602{
1603 IRExpr *rm;
1604
1605 switch (mode) {
1606 case S390_DFP_ROUND_PER_FPC_0:
1607 case S390_DFP_ROUND_PER_FPC_2:
1608 rm = get_dfp_rounding_mode_from_fpc(); break;
1609 case S390_DFP_ROUND_NEAREST_EVEN_4:
1610 case S390_DFP_ROUND_NEAREST_EVEN_8:
1611 rm = mkU32(Irrm_DFP_NEAREST); break;
1612 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1:
1613 case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12:
1614 rm = mkU32(Irrm_DFP_NEAREST_TIE_AWAY_0); break;
1615 case S390_DFP_ROUND_PREPARE_SHORT_3:
1616 case S390_DFP_ROUND_PREPARE_SHORT_15:
1617 rm = mkU32(Irrm_DFP_PREPARE_SHORTER); break;
1618 case S390_DFP_ROUND_ZERO_5:
1619 case S390_DFP_ROUND_ZERO_9:
1620 rm = mkU32(Irrm_DFP_ZERO ); break;
1621 case S390_DFP_ROUND_POSINF_6:
1622 case S390_DFP_ROUND_POSINF_10:
1623 rm = mkU32(Irrm_DFP_PosINF); break;
1624 case S390_DFP_ROUND_NEGINF_7:
1625 case S390_DFP_ROUND_NEGINF_11:
1626 rm = mkU32(Irrm_DFP_NegINF); break;
1627 case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0:
1628 rm = mkU32(Irrm_DFP_NEAREST_TIE_TOWARD_0); break;
1629 case S390_DFP_ROUND_AWAY_0:
1630 rm = mkU32(Irrm_DFP_AWAY_FROM_ZERO); break;
1631 default:
1632 vpanic("encode_dfp_rounding_mode");
1633 }
1634
1635 return mktemp(Ity_I32, rm);
1636}
florian12390202012-11-10 22:34:14 +00001637
florianc8e4f562012-10-27 16:19:31 +00001638
florian2c74d242012-09-12 19:38:42 +00001639/*------------------------------------------------------------*/
florian2d3d87f2012-12-21 21:05:17 +00001640/*--- Condition code helpers ---*/
1641/*------------------------------------------------------------*/
1642
1643/* The result of a Iop_CmpFxx operation is a condition code. It is
1644 encoded using the values defined in type IRCmpFxxResult.
1645 Before we can store the condition code into the guest state (or do
1646 anything else with it for that matter) we need to convert it to
1647 the encoding that s390 uses. This is what this function does.
1648
1649 s390 VEX b6 b2 b0 cc.1 cc.0
1650 0 0x40 EQ 1 0 0 0 0
1651 1 0x01 LT 0 0 1 0 1
1652 2 0x00 GT 0 0 0 1 0
1653 3 0x45 Unordered 1 1 1 1 1
1654
1655 The following bits from the VEX encoding are interesting:
1656 b0, b2, b6 with b0 being the LSB. We observe:
1657
1658 cc.0 = b0;
1659 cc.1 = b2 | (~b0 & ~b6)
1660
1661 with cc being the s390 condition code.
1662*/
1663static IRExpr *
1664convert_vex_bfpcc_to_s390(IRTemp vex_cc)
1665{
1666 IRTemp cc0 = newTemp(Ity_I32);
1667 IRTemp cc1 = newTemp(Ity_I32);
1668 IRTemp b0 = newTemp(Ity_I32);
1669 IRTemp b2 = newTemp(Ity_I32);
1670 IRTemp b6 = newTemp(Ity_I32);
1671
1672 assign(b0, binop(Iop_And32, mkexpr(vex_cc), mkU32(1)));
1673 assign(b2, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(2)),
1674 mkU32(1)));
1675 assign(b6, binop(Iop_And32, binop(Iop_Shr32, mkexpr(vex_cc), mkU8(6)),
1676 mkU32(1)));
1677
1678 assign(cc0, mkexpr(b0));
1679 assign(cc1, binop(Iop_Or32, mkexpr(b2),
1680 binop(Iop_And32,
1681 binop(Iop_Sub32, mkU32(1), mkexpr(b0)), /* ~b0 */
1682 binop(Iop_Sub32, mkU32(1), mkexpr(b6)) /* ~b6 */
1683 )));
1684
1685 return binop(Iop_Or32, mkexpr(cc0), binop(Iop_Shl32, mkexpr(cc1), mkU8(1)));
1686}
1687
1688
1689/* The result of a Iop_CmpDxx operation is a condition code. It is
1690 encoded using the values defined in type IRCmpDxxResult.
1691 Before we can store the condition code into the guest state (or do
1692 anything else with it for that matter) we need to convert it to
1693 the encoding that s390 uses. This is what this function does. */
1694static IRExpr *
1695convert_vex_dfpcc_to_s390(IRTemp vex_cc)
1696{
1697 /* The VEX encodings for IRCmpDxxResult and IRCmpFxxResult are the
1698 same. currently. */
floriana77451c2012-12-22 14:50:41 +00001699 return convert_vex_bfpcc_to_s390(vex_cc);
florian2d3d87f2012-12-21 21:05:17 +00001700}
1701
1702
1703/*------------------------------------------------------------*/
sewardj2019a972011-03-07 16:04:07 +00001704/*--- Build IR for formats ---*/
1705/*------------------------------------------------------------*/
1706static void
florian55085f82012-11-21 00:36:55 +00001707s390_format_I(const HChar *(*irgen)(UChar i),
sewardj2019a972011-03-07 16:04:07 +00001708 UChar i)
1709{
florian55085f82012-11-21 00:36:55 +00001710 const HChar *mnm = irgen(i);
sewardj2019a972011-03-07 16:04:07 +00001711
sewardj7ee97522011-05-09 21:45:04 +00001712 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001713 s390_disasm(ENC2(MNM, UINT), mnm, i);
1714}
1715
1716static void
florian55085f82012-11-21 00:36:55 +00001717s390_format_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001718 UChar r1, UShort i2)
1719{
1720 irgen(r1, i2);
1721}
1722
1723static void
florian55085f82012-11-21 00:36:55 +00001724s390_format_RI_RU(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001725 UChar r1, UShort i2)
1726{
florian55085f82012-11-21 00:36:55 +00001727 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001728
sewardj7ee97522011-05-09 21:45:04 +00001729 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001730 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1731}
1732
1733static void
florian55085f82012-11-21 00:36:55 +00001734s390_format_RI_RI(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001735 UChar r1, UShort i2)
1736{
florian55085f82012-11-21 00:36:55 +00001737 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001738
sewardj7ee97522011-05-09 21:45:04 +00001739 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001740 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, (Int)(Short)i2);
1741}
1742
1743static void
florian55085f82012-11-21 00:36:55 +00001744s390_format_RI_RP(const HChar *(*irgen)(UChar r1, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001745 UChar r1, UShort i2)
1746{
florian55085f82012-11-21 00:36:55 +00001747 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001748
sewardj7ee97522011-05-09 21:45:04 +00001749 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001750 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, (Int)(Short)i2);
1751}
1752
1753static void
florian55085f82012-11-21 00:36:55 +00001754s390_format_RIE_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001755 UChar r1, UChar r3, UShort i2)
1756{
florian55085f82012-11-21 00:36:55 +00001757 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001758
sewardj7ee97522011-05-09 21:45:04 +00001759 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001760 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
1761}
1762
1763static void
florian55085f82012-11-21 00:36:55 +00001764s390_format_RIE_RRI0(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00001765 UChar r1, UChar r3, UShort i2)
1766{
florian55085f82012-11-21 00:36:55 +00001767 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00001768
sewardj7ee97522011-05-09 21:45:04 +00001769 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001770 s390_disasm(ENC4(MNM, GPR, GPR, INT), mnm, r1, r3, (Int)(Short)i2);
1771}
1772
1773static void
florian55085f82012-11-21 00:36:55 +00001774s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3,
1775 UChar i4, UChar i5),
sewardj2019a972011-03-07 16:04:07 +00001776 UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
1777{
florian55085f82012-11-21 00:36:55 +00001778 const HChar *mnm = irgen(r1, r2, i3, i4, i5);
sewardj2019a972011-03-07 16:04:07 +00001779
sewardj7ee97522011-05-09 21:45:04 +00001780 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001781 s390_disasm(ENC6(MNM, GPR, GPR, UINT, UINT, UINT), mnm, r1, r2, i3, i4,
1782 i5);
1783}
1784
1785static void
florian55085f82012-11-21 00:36:55 +00001786s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4,
1787 UChar m3),
sewardj2019a972011-03-07 16:04:07 +00001788 UChar r1, UChar r2, UShort i4, UChar m3)
1789{
florian55085f82012-11-21 00:36:55 +00001790 const HChar *mnm = irgen(r1, r2, i4, m3);
sewardj2019a972011-03-07 16:04:07 +00001791
sewardj7ee97522011-05-09 21:45:04 +00001792 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001793 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1794 r2, m3, (Int)(Short)i4);
1795}
1796
1797static void
florian55085f82012-11-21 00:36:55 +00001798s390_format_RIE_RUPU(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1799 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001800 UChar r1, UChar m3, UShort i4, UChar i2)
1801{
florian55085f82012-11-21 00:36:55 +00001802 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001803
sewardj7ee97522011-05-09 21:45:04 +00001804 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001805 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, PCREL), S390_XMNM_CAB, mnm, m3,
1806 r1, i2, m3, (Int)(Short)i4);
1807}
1808
1809static void
florian55085f82012-11-21 00:36:55 +00001810s390_format_RIE_RUPI(const HChar *(*irgen)(UChar r1, UChar m3, UShort i4,
1811 UChar i2),
sewardj2019a972011-03-07 16:04:07 +00001812 UChar r1, UChar m3, UShort i4, UChar i2)
1813{
florian55085f82012-11-21 00:36:55 +00001814 const HChar *mnm = irgen(r1, m3, i4, i2);
sewardj2019a972011-03-07 16:04:07 +00001815
sewardj7ee97522011-05-09 21:45:04 +00001816 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001817 s390_disasm(ENC5(XMNM, GPR, INT, CABM, PCREL), S390_XMNM_CAB, mnm, m3, r1,
1818 (Int)(Char)i2, m3, (Int)(Short)i4);
1819}
1820
1821static void
florian55085f82012-11-21 00:36:55 +00001822s390_format_RIL(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001823 UChar r1, UInt i2)
1824{
1825 irgen(r1, i2);
1826}
1827
1828static void
florian55085f82012-11-21 00:36:55 +00001829s390_format_RIL_RU(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001830 UChar r1, UInt i2)
1831{
florian55085f82012-11-21 00:36:55 +00001832 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001833
sewardj7ee97522011-05-09 21:45:04 +00001834 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001835 s390_disasm(ENC3(MNM, GPR, UINT), mnm, r1, i2);
1836}
1837
1838static void
florian55085f82012-11-21 00:36:55 +00001839s390_format_RIL_RI(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001840 UChar r1, UInt i2)
1841{
florian55085f82012-11-21 00:36:55 +00001842 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001843
sewardj7ee97522011-05-09 21:45:04 +00001844 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001845 s390_disasm(ENC3(MNM, GPR, INT), mnm, r1, i2);
1846}
1847
1848static void
florian55085f82012-11-21 00:36:55 +00001849s390_format_RIL_RP(const HChar *(*irgen)(UChar r1, UInt i2),
sewardj2019a972011-03-07 16:04:07 +00001850 UChar r1, UInt i2)
1851{
florian55085f82012-11-21 00:36:55 +00001852 const HChar *mnm = irgen(r1, i2);
sewardj2019a972011-03-07 16:04:07 +00001853
sewardj7ee97522011-05-09 21:45:04 +00001854 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001855 s390_disasm(ENC3(MNM, GPR, PCREL), mnm, r1, i2);
1856}
1857
1858static void
florian55085f82012-11-21 00:36:55 +00001859s390_format_RIL_UP(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00001860 UChar r1, UInt i2)
1861{
florian55085f82012-11-21 00:36:55 +00001862 const HChar *mnm = irgen();
sewardj2019a972011-03-07 16:04:07 +00001863
sewardj7ee97522011-05-09 21:45:04 +00001864 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001865 s390_disasm(ENC3(MNM, UINT, PCREL), mnm, r1, i2);
1866}
1867
1868static void
florian55085f82012-11-21 00:36:55 +00001869s390_format_RIS_RURDI(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001870 IRTemp op4addr),
1871 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1872{
florian55085f82012-11-21 00:36:55 +00001873 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001874 IRTemp op4addr = newTemp(Ity_I64);
1875
1876 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1877 mkU64(0)));
1878
1879 mnm = irgen(r1, m3, i2, op4addr);
1880
sewardj7ee97522011-05-09 21:45:04 +00001881 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001882 s390_disasm(ENC5(XMNM, GPR, INT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1883 (Int)(Char)i2, m3, d4, 0, b4);
1884}
1885
1886static void
florian55085f82012-11-21 00:36:55 +00001887s390_format_RIS_RURDU(const HChar *(*irgen)(UChar r1, UChar m3, UChar i2,
sewardj2019a972011-03-07 16:04:07 +00001888 IRTemp op4addr),
1889 UChar r1, UChar m3, UChar b4, UShort d4, UChar i2)
1890{
florian55085f82012-11-21 00:36:55 +00001891 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00001892 IRTemp op4addr = newTemp(Ity_I64);
1893
1894 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
1895 mkU64(0)));
1896
1897 mnm = irgen(r1, m3, i2, op4addr);
1898
sewardj7ee97522011-05-09 21:45:04 +00001899 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001900 s390_disasm(ENC5(XMNM, GPR, UINT, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
1901 i2, m3, d4, 0, b4);
1902}
1903
1904static void
florian55085f82012-11-21 00:36:55 +00001905s390_format_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001906 UChar r1, UChar r2)
1907{
1908 irgen(r1, r2);
1909}
1910
1911static void
florian55085f82012-11-21 00:36:55 +00001912s390_format_RR_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001913 UChar r1, UChar r2)
1914{
florian55085f82012-11-21 00:36:55 +00001915 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001916
sewardj7ee97522011-05-09 21:45:04 +00001917 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001918 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1919}
1920
1921static void
florian55085f82012-11-21 00:36:55 +00001922s390_format_RR_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001923 UChar r1, UChar r2)
1924{
florian55085f82012-11-21 00:36:55 +00001925 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001926
sewardj7ee97522011-05-09 21:45:04 +00001927 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001928 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1929}
1930
1931static void
florian55085f82012-11-21 00:36:55 +00001932s390_format_RRE(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001933 UChar r1, UChar r2)
1934{
1935 irgen(r1, r2);
1936}
1937
1938static void
florian55085f82012-11-21 00:36:55 +00001939s390_format_RRE_RR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001940 UChar r1, UChar r2)
1941{
florian55085f82012-11-21 00:36:55 +00001942 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001943
sewardj7ee97522011-05-09 21:45:04 +00001944 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001945 s390_disasm(ENC3(MNM, GPR, GPR), mnm, r1, r2);
1946}
1947
1948static void
florian55085f82012-11-21 00:36:55 +00001949s390_format_RRE_FF(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001950 UChar r1, UChar r2)
1951{
florian55085f82012-11-21 00:36:55 +00001952 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001953
sewardj7ee97522011-05-09 21:45:04 +00001954 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001955 s390_disasm(ENC3(MNM, FPR, FPR), mnm, r1, r2);
1956}
1957
1958static void
florian55085f82012-11-21 00:36:55 +00001959s390_format_RRE_RF(const HChar *(*irgen)(UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00001960 UChar r1, UChar r2)
1961{
florian55085f82012-11-21 00:36:55 +00001962 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001963
sewardj7ee97522011-05-09 21:45:04 +00001964 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001965 s390_disasm(ENC3(MNM, GPR, FPR), mnm, r1, r2);
1966}
1967
1968static void
florian55085f82012-11-21 00:36:55 +00001969s390_format_RRE_FR(const HChar *(*irgen)(UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00001970 UChar r1, UChar r2)
1971{
florian55085f82012-11-21 00:36:55 +00001972 const HChar *mnm = irgen(r1, r2);
sewardj2019a972011-03-07 16:04:07 +00001973
sewardj7ee97522011-05-09 21:45:04 +00001974 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001975 s390_disasm(ENC3(MNM, FPR, GPR), mnm, r1, r2);
1976}
1977
1978static void
florian55085f82012-11-21 00:36:55 +00001979s390_format_RRE_R0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001980 UChar r1)
1981{
florian55085f82012-11-21 00:36:55 +00001982 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001983
sewardj7ee97522011-05-09 21:45:04 +00001984 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001985 s390_disasm(ENC2(MNM, GPR), mnm, r1);
1986}
1987
1988static void
florian55085f82012-11-21 00:36:55 +00001989s390_format_RRE_F0(const HChar *(*irgen)(UChar r1),
sewardj2019a972011-03-07 16:04:07 +00001990 UChar r1)
1991{
florian55085f82012-11-21 00:36:55 +00001992 const HChar *mnm = irgen(r1);
sewardj2019a972011-03-07 16:04:07 +00001993
sewardj7ee97522011-05-09 21:45:04 +00001994 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00001995 s390_disasm(ENC2(MNM, FPR), mnm, r1);
1996}
1997
1998static void
florian55085f82012-11-21 00:36:55 +00001999s390_format_RRF_M0RERE(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
florian9af37692012-01-15 21:01:16 +00002000 UChar m3, UChar r1, UChar r2)
2001{
florian55085f82012-11-21 00:36:55 +00002002 const HChar *mnm = irgen(m3, r1, r2);
florian9af37692012-01-15 21:01:16 +00002003
2004 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
florianfed3ea32012-07-19 14:54:03 +00002005 s390_disasm(ENC4(MNM, GPR, GPR, UINT), mnm, r1, r2, m3);
florian9af37692012-01-15 21:01:16 +00002006}
2007
2008static void
florian55085f82012-11-21 00:36:55 +00002009s390_format_RRF_F0FF(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002010 UChar r1, UChar r3, UChar r2)
2011{
florian55085f82012-11-21 00:36:55 +00002012 const HChar *mnm = irgen(r1, r3, r2);
sewardj2019a972011-03-07 16:04:07 +00002013
sewardj7ee97522011-05-09 21:45:04 +00002014 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002015 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2016}
2017
2018static void
florian5c539732013-02-14 14:27:12 +00002019s390_format_RRF_F0FR(const HChar *(*irgen)(UChar, UChar, UChar),
2020 UChar r3, UChar r1, UChar r2)
2021{
2022 const HChar *mnm = irgen(r3, r1, r2);
2023
2024 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2025 s390_disasm(ENC4(MNM, FPR, FPR, GPR), mnm, r1, r3, r2);
2026}
2027
2028static void
florian55085f82012-11-21 00:36:55 +00002029s390_format_RRF_UUFF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2030 UChar r2),
florian4b8efad2012-09-02 18:07:08 +00002031 UChar m3, UChar m4, UChar r1, UChar r2)
2032{
florian55085f82012-11-21 00:36:55 +00002033 const HChar *mnm = irgen(m3, m4, r1, r2);
florian4b8efad2012-09-02 18:07:08 +00002034
2035 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2036 s390_disasm(ENC5(MNM, FPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2037}
2038
2039static void
floriane38f6412012-12-21 17:32:12 +00002040s390_format_RRF_0UFF(const HChar *(*irgen)(UChar m4, UChar r1, UChar r2),
2041 UChar m4, UChar r1, UChar r2)
2042{
2043 const HChar *mnm = irgen(m4, r1, r2);
2044
2045 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2046 s390_disasm(ENC4(MNM, FPR, FPR, UINT), mnm, r1, r2, m4);
2047}
2048
2049static void
florian55085f82012-11-21 00:36:55 +00002050s390_format_RRF_UUFR(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2051 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002052 UChar m3, UChar m4, UChar r1, UChar r2)
2053{
florian55085f82012-11-21 00:36:55 +00002054 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002055
2056 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2057 s390_disasm(ENC5(MNM, FPR, UINT, GPR, UINT), mnm, r1, m3, r2, m4);
2058}
2059
2060static void
florian55085f82012-11-21 00:36:55 +00002061s390_format_RRF_UURF(const HChar *(*irgen)(UChar m3, UChar m4, UChar r1,
2062 UChar r2),
florian1c8f7ff2012-09-01 00:12:11 +00002063 UChar m3, UChar m4, UChar r1, UChar r2)
2064{
florian55085f82012-11-21 00:36:55 +00002065 const HChar *mnm = irgen(m3, m4, r1, r2);
florian1c8f7ff2012-09-01 00:12:11 +00002066
2067 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2068 s390_disasm(ENC5(MNM, GPR, UINT, FPR, UINT), mnm, r1, m3, r2, m4);
2069}
2070
2071
2072static void
florian55085f82012-11-21 00:36:55 +00002073s390_format_RRF_U0RR(const HChar *(*irgen)(UChar m3, UChar r1, UChar r2),
sewardjd7bde722011-04-05 13:19:33 +00002074 UChar m3, UChar r1, UChar r2, Int xmnm_kind)
2075{
2076 irgen(m3, r1, r2);
2077
sewardj7ee97522011-05-09 21:45:04 +00002078 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002079 s390_disasm(ENC3(XMNM, GPR, GPR), xmnm_kind, m3, r1, r2);
2080}
2081
2082static void
florian55085f82012-11-21 00:36:55 +00002083s390_format_RRF_F0FF2(const HChar *(*irgen)(UChar, UChar, UChar),
sewardj2019a972011-03-07 16:04:07 +00002084 UChar r3, UChar r1, UChar r2)
2085{
florian55085f82012-11-21 00:36:55 +00002086 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002087
sewardj7ee97522011-05-09 21:45:04 +00002088 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002089 s390_disasm(ENC4(MNM, FPR, FPR, FPR), mnm, r1, r3, r2);
2090}
2091
2092static void
florian5c539732013-02-14 14:27:12 +00002093s390_format_RRF_FFRU(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2094 UChar r3, UChar m4, UChar r1, UChar r2)
2095{
2096 const HChar *mnm = irgen(r3, m4, r1, r2);
2097
2098 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2099 s390_disasm(ENC5(MNM, FPR, FPR, GPR, UINT), mnm, r1, r3, r2, m4);
2100}
2101
2102static void
2103s390_format_RRF_FUFF(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
2104 UChar r3, UChar m4, UChar r1, UChar r2)
2105{
2106 const HChar *mnm = irgen(r3, m4, r1, r2);
2107
2108 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2109 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r3, r2, m4);
2110}
2111
2112static void
florian55085f82012-11-21 00:36:55 +00002113s390_format_RRF_FUFF2(const HChar *(*irgen)(UChar, UChar, UChar, UChar),
florian12390202012-11-10 22:34:14 +00002114 UChar r3, UChar m4, UChar r1, UChar r2)
2115{
florian55085f82012-11-21 00:36:55 +00002116 const HChar *mnm = irgen(r3, m4, r1, r2);
florian12390202012-11-10 22:34:14 +00002117
2118 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
2119 s390_disasm(ENC5(MNM, FPR, FPR, FPR, UINT), mnm, r1, r2, r3, m4);
2120}
2121
2122static void
florian55085f82012-11-21 00:36:55 +00002123s390_format_RRF_R0RR2(const HChar *(*irgen)(UChar r3, UChar r1, UChar r2),
sewardj2019a972011-03-07 16:04:07 +00002124 UChar r3, UChar r1, UChar r2)
2125{
florian55085f82012-11-21 00:36:55 +00002126 const HChar *mnm = irgen(r3, r1, r2);
sewardj2019a972011-03-07 16:04:07 +00002127
sewardj7ee97522011-05-09 21:45:04 +00002128 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002129 s390_disasm(ENC4(MNM, GPR, GPR, GPR), mnm, r1, r2, r3);
2130}
2131
2132static void
florian55085f82012-11-21 00:36:55 +00002133s390_format_RRS(const HChar *(*irgen)(UChar r1, UChar r2, UChar m3,
2134 IRTemp op4addr),
sewardj2019a972011-03-07 16:04:07 +00002135 UChar r1, UChar r2, UChar b4, UShort d4, UChar m3)
2136{
florian55085f82012-11-21 00:36:55 +00002137 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002138 IRTemp op4addr = newTemp(Ity_I64);
2139
2140 assign(op4addr, binop(Iop_Add64, mkU64(d4), b4 != 0 ? get_gpr_dw0(b4) :
2141 mkU64(0)));
2142
2143 mnm = irgen(r1, r2, m3, op4addr);
2144
sewardj7ee97522011-05-09 21:45:04 +00002145 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002146 s390_disasm(ENC5(XMNM, GPR, GPR, CABM, UDXB), S390_XMNM_CAB, mnm, m3, r1,
2147 r2, m3, d4, 0, b4);
2148}
2149
2150static void
florian55085f82012-11-21 00:36:55 +00002151s390_format_RS_R0RD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002152 UChar r1, UChar b2, UShort d2)
2153{
florian55085f82012-11-21 00:36:55 +00002154 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002155 IRTemp op2addr = newTemp(Ity_I64);
2156
2157 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2158 mkU64(0)));
2159
2160 mnm = irgen(r1, op2addr);
2161
sewardj7ee97522011-05-09 21:45:04 +00002162 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002163 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, 0, b2);
2164}
2165
2166static void
florian55085f82012-11-21 00:36:55 +00002167s390_format_RS_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002168 UChar r1, UChar r3, UChar b2, UShort d2)
2169{
florian55085f82012-11-21 00:36:55 +00002170 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002171 IRTemp op2addr = newTemp(Ity_I64);
2172
2173 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2174 mkU64(0)));
2175
2176 mnm = irgen(r1, r3, op2addr);
2177
sewardj7ee97522011-05-09 21:45:04 +00002178 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002179 s390_disasm(ENC4(MNM, GPR, GPR, UDXB), mnm, r1, r3, d2, 0, b2);
2180}
2181
2182static void
florian55085f82012-11-21 00:36:55 +00002183s390_format_RS_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002184 UChar r1, UChar r3, UChar b2, UShort d2)
2185{
florian55085f82012-11-21 00:36:55 +00002186 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002187 IRTemp op2addr = newTemp(Ity_I64);
2188
2189 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2190 mkU64(0)));
2191
2192 mnm = irgen(r1, r3, op2addr);
2193
sewardj7ee97522011-05-09 21:45:04 +00002194 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002195 s390_disasm(ENC4(MNM, GPR, UINT, UDXB), mnm, r1, r3, d2, 0, b2);
2196}
2197
2198static void
florian55085f82012-11-21 00:36:55 +00002199s390_format_RS_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002200 UChar r1, UChar r3, UChar b2, UShort d2)
2201{
florian55085f82012-11-21 00:36:55 +00002202 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002203 IRTemp op2addr = newTemp(Ity_I64);
2204
2205 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2206 mkU64(0)));
2207
2208 mnm = irgen(r1, r3, op2addr);
2209
sewardj7ee97522011-05-09 21:45:04 +00002210 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002211 s390_disasm(ENC4(MNM, AR, AR, UDXB), mnm, r1, r3, d2, 0, b2);
2212}
2213
2214static void
florian55085f82012-11-21 00:36:55 +00002215s390_format_RSI_RRP(const HChar *(*irgen)(UChar r1, UChar r3, UShort i2),
sewardj2019a972011-03-07 16:04:07 +00002216 UChar r1, UChar r3, UShort i2)
2217{
florian55085f82012-11-21 00:36:55 +00002218 const HChar *mnm = irgen(r1, r3, i2);
sewardj2019a972011-03-07 16:04:07 +00002219
sewardj7ee97522011-05-09 21:45:04 +00002220 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002221 s390_disasm(ENC4(MNM, GPR, GPR, PCREL), mnm, r1, r3, (Int)(Short)i2);
2222}
2223
2224static void
florian55085f82012-11-21 00:36:55 +00002225s390_format_RSY_RRRD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002226 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2227{
florian55085f82012-11-21 00:36:55 +00002228 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002229 IRTemp op2addr = newTemp(Ity_I64);
2230 IRTemp d2 = newTemp(Ity_I64);
2231
2232 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2233 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2234 mkU64(0)));
2235
2236 mnm = irgen(r1, r3, op2addr);
2237
sewardj7ee97522011-05-09 21:45:04 +00002238 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002239 s390_disasm(ENC4(MNM, GPR, GPR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2240}
2241
2242static void
florian55085f82012-11-21 00:36:55 +00002243s390_format_RSY_AARD(const HChar *(*irgen)(UChar, UChar, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002244 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2245{
florian55085f82012-11-21 00:36:55 +00002246 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002247 IRTemp op2addr = newTemp(Ity_I64);
2248 IRTemp d2 = newTemp(Ity_I64);
2249
2250 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2251 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2252 mkU64(0)));
2253
2254 mnm = irgen(r1, r3, op2addr);
2255
sewardj7ee97522011-05-09 21:45:04 +00002256 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002257 s390_disasm(ENC4(MNM, AR, AR, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2258}
2259
2260static void
florian55085f82012-11-21 00:36:55 +00002261s390_format_RSY_RURD(const HChar *(*irgen)(UChar r1, UChar r3, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002262 UChar r1, UChar r3, UChar b2, UShort dl2, UChar dh2)
2263{
florian55085f82012-11-21 00:36:55 +00002264 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002265 IRTemp op2addr = newTemp(Ity_I64);
2266 IRTemp d2 = newTemp(Ity_I64);
2267
2268 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2269 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2270 mkU64(0)));
2271
2272 mnm = irgen(r1, r3, op2addr);
2273
sewardj7ee97522011-05-09 21:45:04 +00002274 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002275 s390_disasm(ENC4(MNM, GPR, UINT, SDXB), mnm, r1, r3, dh2, dl2, 0, b2);
2276}
2277
2278static void
florian55085f82012-11-21 00:36:55 +00002279s390_format_RSY_RDRM(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardjd7bde722011-04-05 13:19:33 +00002280 UChar r1, UChar m3, UChar b2, UShort dl2, UChar dh2,
2281 Int xmnm_kind)
2282{
2283 IRTemp op2addr = newTemp(Ity_I64);
2284 IRTemp d2 = newTemp(Ity_I64);
2285
florian6820ba52012-07-26 02:01:50 +00002286 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
2287
sewardjd7bde722011-04-05 13:19:33 +00002288 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2289 assign(op2addr, binop(Iop_Add64, mkexpr(d2), b2 != 0 ? get_gpr_dw0(b2) :
2290 mkU64(0)));
2291
2292 irgen(r1, op2addr);
florian6820ba52012-07-26 02:01:50 +00002293
2294 vassert(dis_res->whatNext == Dis_Continue);
sewardjd7bde722011-04-05 13:19:33 +00002295
sewardj7ee97522011-05-09 21:45:04 +00002296 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjd7bde722011-04-05 13:19:33 +00002297 s390_disasm(ENC3(XMNM, GPR, SDXB), xmnm_kind, m3, r1, dh2, dl2, 0, b2);
2298}
2299
2300static void
florian55085f82012-11-21 00:36:55 +00002301s390_format_RX(const HChar *(*irgen)(UChar r1, UChar x2, UChar b2, UShort d2,
sewardj2019a972011-03-07 16:04:07 +00002302 IRTemp op2addr),
2303 UChar r1, UChar x2, UChar b2, UShort d2)
2304{
2305 IRTemp op2addr = newTemp(Ity_I64);
2306
2307 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2308 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2309 mkU64(0)));
2310
2311 irgen(r1, x2, b2, d2, op2addr);
2312}
2313
2314static void
florian55085f82012-11-21 00:36:55 +00002315s390_format_RX_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002316 UChar r1, UChar x2, UChar b2, UShort d2)
2317{
florian55085f82012-11-21 00:36:55 +00002318 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002319 IRTemp op2addr = newTemp(Ity_I64);
2320
2321 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2322 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2323 mkU64(0)));
2324
2325 mnm = irgen(r1, op2addr);
2326
sewardj7ee97522011-05-09 21:45:04 +00002327 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002328 s390_disasm(ENC3(MNM, GPR, UDXB), mnm, r1, d2, x2, b2);
2329}
2330
2331static void
florian55085f82012-11-21 00:36:55 +00002332s390_format_RX_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002333 UChar r1, UChar x2, UChar b2, UShort d2)
2334{
florian55085f82012-11-21 00:36:55 +00002335 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002336 IRTemp op2addr = newTemp(Ity_I64);
2337
2338 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2339 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2340 mkU64(0)));
2341
2342 mnm = irgen(r1, op2addr);
2343
sewardj7ee97522011-05-09 21:45:04 +00002344 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002345 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2346}
2347
2348static void
florian55085f82012-11-21 00:36:55 +00002349s390_format_RXE_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002350 UChar r1, UChar x2, UChar b2, UShort d2)
2351{
florian55085f82012-11-21 00:36:55 +00002352 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002353 IRTemp op2addr = newTemp(Ity_I64);
2354
2355 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2356 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2357 mkU64(0)));
2358
2359 mnm = irgen(r1, op2addr);
2360
sewardj7ee97522011-05-09 21:45:04 +00002361 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002362 s390_disasm(ENC3(MNM, FPR, UDXB), mnm, r1, d2, x2, b2);
2363}
2364
2365static void
florian55085f82012-11-21 00:36:55 +00002366s390_format_RXF_FRRDF(const HChar *(*irgen)(UChar, IRTemp, UChar),
sewardj2019a972011-03-07 16:04:07 +00002367 UChar r3, UChar x2, UChar b2, UShort d2, UChar r1)
2368{
florian55085f82012-11-21 00:36:55 +00002369 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002370 IRTemp op2addr = newTemp(Ity_I64);
2371
2372 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkU64(d2),
2373 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2374 mkU64(0)));
2375
2376 mnm = irgen(r3, op2addr, r1);
2377
sewardj7ee97522011-05-09 21:45:04 +00002378 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002379 s390_disasm(ENC4(MNM, FPR, FPR, UDXB), mnm, r1, r3, d2, x2, b2);
2380}
2381
2382static void
florian55085f82012-11-21 00:36:55 +00002383s390_format_RXY_RRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002384 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2385{
florian55085f82012-11-21 00:36:55 +00002386 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002387 IRTemp op2addr = newTemp(Ity_I64);
2388 IRTemp d2 = newTemp(Ity_I64);
2389
2390 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2391 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2392 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2393 mkU64(0)));
2394
2395 mnm = irgen(r1, op2addr);
2396
sewardj7ee97522011-05-09 21:45:04 +00002397 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002398 s390_disasm(ENC3(MNM, GPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2399}
2400
2401static void
florian55085f82012-11-21 00:36:55 +00002402s390_format_RXY_FRRD(const HChar *(*irgen)(UChar r1, IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002403 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2404{
florian55085f82012-11-21 00:36:55 +00002405 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002406 IRTemp op2addr = newTemp(Ity_I64);
2407 IRTemp d2 = newTemp(Ity_I64);
2408
2409 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2410 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2411 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2412 mkU64(0)));
2413
2414 mnm = irgen(r1, op2addr);
2415
sewardj7ee97522011-05-09 21:45:04 +00002416 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002417 s390_disasm(ENC3(MNM, FPR, SDXB), mnm, r1, dh2, dl2, x2, b2);
2418}
2419
2420static void
florian55085f82012-11-21 00:36:55 +00002421s390_format_RXY_URRD(const HChar *(*irgen)(void),
sewardj2019a972011-03-07 16:04:07 +00002422 UChar r1, UChar x2, UChar b2, UShort dl2, UChar dh2)
2423{
florian55085f82012-11-21 00:36:55 +00002424 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002425 IRTemp op2addr = newTemp(Ity_I64);
2426 IRTemp d2 = newTemp(Ity_I64);
2427
2428 assign(d2, mkU64(((ULong)(Long)(Char)dh2 << 12) | ((ULong)dl2)));
2429 assign(op2addr, binop(Iop_Add64, binop(Iop_Add64, mkexpr(d2),
2430 b2 != 0 ? get_gpr_dw0(b2) : mkU64(0)), x2 != 0 ? get_gpr_dw0(x2) :
2431 mkU64(0)));
2432
2433 mnm = irgen();
2434
sewardj7ee97522011-05-09 21:45:04 +00002435 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002436 s390_disasm(ENC3(MNM, UINT, SDXB), mnm, r1, dh2, dl2, x2, b2);
2437}
2438
2439static void
florian55085f82012-11-21 00:36:55 +00002440s390_format_S_RD(const HChar *(*irgen)(IRTemp op2addr),
sewardj2019a972011-03-07 16:04:07 +00002441 UChar b2, UShort d2)
2442{
florian55085f82012-11-21 00:36:55 +00002443 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002444 IRTemp op2addr = newTemp(Ity_I64);
2445
2446 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2447 mkU64(0)));
2448
2449 mnm = irgen(op2addr);
2450
sewardj7ee97522011-05-09 21:45:04 +00002451 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002452 s390_disasm(ENC2(MNM, UDXB), mnm, d2, 0, b2);
2453}
2454
2455static void
florian55085f82012-11-21 00:36:55 +00002456s390_format_SI_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002457 UChar i2, UChar b1, UShort d1)
2458{
florian55085f82012-11-21 00:36:55 +00002459 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002460 IRTemp op1addr = newTemp(Ity_I64);
2461
2462 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2463 mkU64(0)));
2464
2465 mnm = irgen(i2, op1addr);
2466
sewardj7ee97522011-05-09 21:45:04 +00002467 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002468 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2469}
2470
2471static void
florian55085f82012-11-21 00:36:55 +00002472s390_format_SIY_URD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002473 UChar i2, UChar b1, UShort dl1, UChar dh1)
2474{
florian55085f82012-11-21 00:36:55 +00002475 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002476 IRTemp op1addr = newTemp(Ity_I64);
2477 IRTemp d1 = newTemp(Ity_I64);
2478
2479 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2480 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2481 mkU64(0)));
2482
2483 mnm = irgen(i2, op1addr);
2484
sewardj7ee97522011-05-09 21:45:04 +00002485 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002486 s390_disasm(ENC3(MNM, SDXB, UINT), mnm, dh1, dl1, 0, b1, i2);
2487}
2488
2489static void
florian55085f82012-11-21 00:36:55 +00002490s390_format_SIY_IRD(const HChar *(*irgen)(UChar i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002491 UChar i2, UChar b1, UShort dl1, UChar dh1)
2492{
florian55085f82012-11-21 00:36:55 +00002493 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002494 IRTemp op1addr = newTemp(Ity_I64);
2495 IRTemp d1 = newTemp(Ity_I64);
2496
2497 assign(d1, mkU64(((ULong)(Long)(Char)dh1 << 12) | ((ULong)dl1)));
2498 assign(op1addr, binop(Iop_Add64, mkexpr(d1), b1 != 0 ? get_gpr_dw0(b1) :
2499 mkU64(0)));
2500
2501 mnm = irgen(i2, op1addr);
2502
sewardj7ee97522011-05-09 21:45:04 +00002503 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002504 s390_disasm(ENC3(MNM, SDXB, INT), mnm, dh1, dl1, 0, b1, (Int)(Char)i2);
2505}
2506
2507static void
florian55085f82012-11-21 00:36:55 +00002508s390_format_SS_L0RDRD(const HChar *(*irgen)(UChar, IRTemp, IRTemp),
sewardj2019a972011-03-07 16:04:07 +00002509 UChar l, UChar b1, UShort d1, UChar b2, UShort d2)
2510{
florian55085f82012-11-21 00:36:55 +00002511 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002512 IRTemp op1addr = newTemp(Ity_I64);
2513 IRTemp op2addr = newTemp(Ity_I64);
2514
2515 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2516 mkU64(0)));
2517 assign(op2addr, binop(Iop_Add64, mkU64(d2), b2 != 0 ? get_gpr_dw0(b2) :
2518 mkU64(0)));
2519
2520 mnm = irgen(l, op1addr, op2addr);
2521
sewardj7ee97522011-05-09 21:45:04 +00002522 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002523 s390_disasm(ENC3(MNM, UDLB, UDXB), mnm, d1, l, b1, d2, 0, b2);
2524}
2525
2526static void
florian55085f82012-11-21 00:36:55 +00002527s390_format_SIL_RDI(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002528 UChar b1, UShort d1, UShort i2)
2529{
florian55085f82012-11-21 00:36:55 +00002530 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002531 IRTemp op1addr = newTemp(Ity_I64);
2532
2533 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2534 mkU64(0)));
2535
2536 mnm = irgen(i2, op1addr);
2537
sewardj7ee97522011-05-09 21:45:04 +00002538 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002539 s390_disasm(ENC3(MNM, UDXB, INT), mnm, d1, 0, b1, (Int)(Short)i2);
2540}
2541
2542static void
florian55085f82012-11-21 00:36:55 +00002543s390_format_SIL_RDU(const HChar *(*irgen)(UShort i2, IRTemp op1addr),
sewardj2019a972011-03-07 16:04:07 +00002544 UChar b1, UShort d1, UShort i2)
2545{
florian55085f82012-11-21 00:36:55 +00002546 const HChar *mnm;
sewardj2019a972011-03-07 16:04:07 +00002547 IRTemp op1addr = newTemp(Ity_I64);
2548
2549 assign(op1addr, binop(Iop_Add64, mkU64(d1), b1 != 0 ? get_gpr_dw0(b1) :
2550 mkU64(0)));
2551
2552 mnm = irgen(i2, op1addr);
2553
sewardj7ee97522011-05-09 21:45:04 +00002554 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00002555 s390_disasm(ENC3(MNM, UDXB, UINT), mnm, d1, 0, b1, i2);
2556}
2557
2558
2559
2560/*------------------------------------------------------------*/
2561/*--- Build IR for opcodes ---*/
2562/*------------------------------------------------------------*/
2563
florian55085f82012-11-21 00:36:55 +00002564static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002565s390_irgen_AR(UChar r1, UChar r2)
2566{
2567 IRTemp op1 = newTemp(Ity_I32);
2568 IRTemp op2 = newTemp(Ity_I32);
2569 IRTemp result = newTemp(Ity_I32);
2570
2571 assign(op1, get_gpr_w1(r1));
2572 assign(op2, get_gpr_w1(r2));
2573 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2574 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2575 put_gpr_w1(r1, mkexpr(result));
2576
2577 return "ar";
2578}
2579
florian55085f82012-11-21 00:36:55 +00002580static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002581s390_irgen_AGR(UChar r1, UChar r2)
2582{
2583 IRTemp op1 = newTemp(Ity_I64);
2584 IRTemp op2 = newTemp(Ity_I64);
2585 IRTemp result = newTemp(Ity_I64);
2586
2587 assign(op1, get_gpr_dw0(r1));
2588 assign(op2, get_gpr_dw0(r2));
2589 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2590 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2591 put_gpr_dw0(r1, mkexpr(result));
2592
2593 return "agr";
2594}
2595
florian55085f82012-11-21 00:36:55 +00002596static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002597s390_irgen_AGFR(UChar r1, UChar r2)
2598{
2599 IRTemp op1 = newTemp(Ity_I64);
2600 IRTemp op2 = newTemp(Ity_I64);
2601 IRTemp result = newTemp(Ity_I64);
2602
2603 assign(op1, get_gpr_dw0(r1));
2604 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
2605 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2606 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2607 put_gpr_dw0(r1, mkexpr(result));
2608
2609 return "agfr";
2610}
2611
florian55085f82012-11-21 00:36:55 +00002612static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002613s390_irgen_ARK(UChar r3, UChar r1, UChar r2)
2614{
2615 IRTemp op2 = newTemp(Ity_I32);
2616 IRTemp op3 = newTemp(Ity_I32);
2617 IRTemp result = newTemp(Ity_I32);
2618
2619 assign(op2, get_gpr_w1(r2));
2620 assign(op3, get_gpr_w1(r3));
2621 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2622 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2623 put_gpr_w1(r1, mkexpr(result));
2624
2625 return "ark";
2626}
2627
florian55085f82012-11-21 00:36:55 +00002628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002629s390_irgen_AGRK(UChar r3, UChar r1, UChar r2)
2630{
2631 IRTemp op2 = newTemp(Ity_I64);
2632 IRTemp op3 = newTemp(Ity_I64);
2633 IRTemp result = newTemp(Ity_I64);
2634
2635 assign(op2, get_gpr_dw0(r2));
2636 assign(op3, get_gpr_dw0(r3));
2637 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2638 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
2639 put_gpr_dw0(r1, mkexpr(result));
2640
2641 return "agrk";
2642}
2643
florian55085f82012-11-21 00:36:55 +00002644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002645s390_irgen_A(UChar r1, IRTemp op2addr)
2646{
2647 IRTemp op1 = newTemp(Ity_I32);
2648 IRTemp op2 = newTemp(Ity_I32);
2649 IRTemp result = newTemp(Ity_I32);
2650
2651 assign(op1, get_gpr_w1(r1));
2652 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2653 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2654 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2655 put_gpr_w1(r1, mkexpr(result));
2656
2657 return "a";
2658}
2659
florian55085f82012-11-21 00:36:55 +00002660static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002661s390_irgen_AY(UChar r1, IRTemp op2addr)
2662{
2663 IRTemp op1 = newTemp(Ity_I32);
2664 IRTemp op2 = newTemp(Ity_I32);
2665 IRTemp result = newTemp(Ity_I32);
2666
2667 assign(op1, get_gpr_w1(r1));
2668 assign(op2, load(Ity_I32, mkexpr(op2addr)));
2669 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2670 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2671 put_gpr_w1(r1, mkexpr(result));
2672
2673 return "ay";
2674}
2675
florian55085f82012-11-21 00:36:55 +00002676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002677s390_irgen_AG(UChar r1, IRTemp op2addr)
2678{
2679 IRTemp op1 = newTemp(Ity_I64);
2680 IRTemp op2 = newTemp(Ity_I64);
2681 IRTemp result = newTemp(Ity_I64);
2682
2683 assign(op1, get_gpr_dw0(r1));
2684 assign(op2, load(Ity_I64, mkexpr(op2addr)));
2685 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2686 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2687 put_gpr_dw0(r1, mkexpr(result));
2688
2689 return "ag";
2690}
2691
florian55085f82012-11-21 00:36:55 +00002692static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002693s390_irgen_AGF(UChar r1, IRTemp op2addr)
2694{
2695 IRTemp op1 = newTemp(Ity_I64);
2696 IRTemp op2 = newTemp(Ity_I64);
2697 IRTemp result = newTemp(Ity_I64);
2698
2699 assign(op1, get_gpr_dw0(r1));
2700 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
2701 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2702 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, op2);
2703 put_gpr_dw0(r1, mkexpr(result));
2704
2705 return "agf";
2706}
2707
florian55085f82012-11-21 00:36:55 +00002708static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002709s390_irgen_AFI(UChar r1, UInt i2)
2710{
2711 IRTemp op1 = newTemp(Ity_I32);
2712 Int op2;
2713 IRTemp result = newTemp(Ity_I32);
2714
2715 assign(op1, get_gpr_w1(r1));
2716 op2 = (Int)i2;
2717 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2718 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2719 mkU32((UInt)op2)));
2720 put_gpr_w1(r1, mkexpr(result));
2721
2722 return "afi";
2723}
2724
florian55085f82012-11-21 00:36:55 +00002725static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002726s390_irgen_AGFI(UChar r1, UInt i2)
2727{
2728 IRTemp op1 = newTemp(Ity_I64);
2729 Long op2;
2730 IRTemp result = newTemp(Ity_I64);
2731
2732 assign(op1, get_gpr_dw0(r1));
2733 op2 = (Long)(Int)i2;
2734 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2735 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2736 mkU64((ULong)op2)));
2737 put_gpr_dw0(r1, mkexpr(result));
2738
2739 return "agfi";
2740}
2741
florian55085f82012-11-21 00:36:55 +00002742static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002743s390_irgen_AHIK(UChar r1, UChar r3, UShort i2)
2744{
2745 Int op2;
2746 IRTemp op3 = newTemp(Ity_I32);
2747 IRTemp result = newTemp(Ity_I32);
2748
2749 op2 = (Int)(Short)i2;
2750 assign(op3, get_gpr_w1(r3));
2751 assign(result, binop(Iop_Add32, mkU32((UInt)op2), mkexpr(op3)));
2752 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, mktemp(Ity_I32, mkU32((UInt)
2753 op2)), op3);
2754 put_gpr_w1(r1, mkexpr(result));
2755
2756 return "ahik";
2757}
2758
florian55085f82012-11-21 00:36:55 +00002759static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002760s390_irgen_AGHIK(UChar r1, UChar r3, UShort i2)
2761{
2762 Long op2;
2763 IRTemp op3 = newTemp(Ity_I64);
2764 IRTemp result = newTemp(Ity_I64);
2765
2766 op2 = (Long)(Short)i2;
2767 assign(op3, get_gpr_dw0(r3));
2768 assign(result, binop(Iop_Add64, mkU64((ULong)op2), mkexpr(op3)));
2769 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, mktemp(Ity_I64, mkU64((ULong)
2770 op2)), op3);
2771 put_gpr_dw0(r1, mkexpr(result));
2772
2773 return "aghik";
2774}
2775
florian55085f82012-11-21 00:36:55 +00002776static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002777s390_irgen_ASI(UChar i2, IRTemp op1addr)
2778{
2779 IRTemp op1 = newTemp(Ity_I32);
2780 Int op2;
2781 IRTemp result = newTemp(Ity_I32);
2782
2783 assign(op1, load(Ity_I32, mkexpr(op1addr)));
2784 op2 = (Int)(Char)i2;
2785 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2786 store(mkexpr(op1addr), mkexpr(result));
2787 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2788 mkU32((UInt)op2)));
2789
2790 return "asi";
2791}
2792
florian55085f82012-11-21 00:36:55 +00002793static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002794s390_irgen_AGSI(UChar i2, IRTemp op1addr)
2795{
2796 IRTemp op1 = newTemp(Ity_I64);
2797 Long op2;
2798 IRTemp result = newTemp(Ity_I64);
2799
2800 assign(op1, load(Ity_I64, mkexpr(op1addr)));
2801 op2 = (Long)(Char)i2;
2802 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2803 store(mkexpr(op1addr), mkexpr(result));
2804 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2805 mkU64((ULong)op2)));
2806
2807 return "agsi";
2808}
2809
florian55085f82012-11-21 00:36:55 +00002810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002811s390_irgen_AH(UChar r1, IRTemp op2addr)
2812{
2813 IRTemp op1 = newTemp(Ity_I32);
2814 IRTemp op2 = newTemp(Ity_I32);
2815 IRTemp result = newTemp(Ity_I32);
2816
2817 assign(op1, get_gpr_w1(r1));
2818 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2819 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2820 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2821 put_gpr_w1(r1, mkexpr(result));
2822
2823 return "ah";
2824}
2825
florian55085f82012-11-21 00:36:55 +00002826static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002827s390_irgen_AHY(UChar r1, IRTemp op2addr)
2828{
2829 IRTemp op1 = newTemp(Ity_I32);
2830 IRTemp op2 = newTemp(Ity_I32);
2831 IRTemp result = newTemp(Ity_I32);
2832
2833 assign(op1, get_gpr_w1(r1));
2834 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
2835 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2836 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, op2);
2837 put_gpr_w1(r1, mkexpr(result));
2838
2839 return "ahy";
2840}
2841
florian55085f82012-11-21 00:36:55 +00002842static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002843s390_irgen_AHI(UChar r1, UShort i2)
2844{
2845 IRTemp op1 = newTemp(Ity_I32);
2846 Int op2;
2847 IRTemp result = newTemp(Ity_I32);
2848
2849 assign(op1, get_gpr_w1(r1));
2850 op2 = (Int)(Short)i2;
2851 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2852 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2853 mkU32((UInt)op2)));
2854 put_gpr_w1(r1, mkexpr(result));
2855
2856 return "ahi";
2857}
2858
florian55085f82012-11-21 00:36:55 +00002859static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002860s390_irgen_AGHI(UChar r1, UShort i2)
2861{
2862 IRTemp op1 = newTemp(Ity_I64);
2863 Long op2;
2864 IRTemp result = newTemp(Ity_I64);
2865
2866 assign(op1, get_gpr_dw0(r1));
2867 op2 = (Long)(Short)i2;
2868 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64((ULong)op2)));
2869 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op1, mktemp(Ity_I64,
2870 mkU64((ULong)op2)));
2871 put_gpr_dw0(r1, mkexpr(result));
2872
2873 return "aghi";
2874}
2875
florian55085f82012-11-21 00:36:55 +00002876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002877s390_irgen_AHHHR(UChar r3, UChar r1, UChar r2)
2878{
2879 IRTemp op2 = newTemp(Ity_I32);
2880 IRTemp op3 = newTemp(Ity_I32);
2881 IRTemp result = newTemp(Ity_I32);
2882
2883 assign(op2, get_gpr_w0(r2));
2884 assign(op3, get_gpr_w0(r3));
2885 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2886 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2887 put_gpr_w0(r1, mkexpr(result));
2888
2889 return "ahhhr";
2890}
2891
florian55085f82012-11-21 00:36:55 +00002892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002893s390_irgen_AHHLR(UChar r3, UChar r1, UChar r2)
2894{
2895 IRTemp op2 = newTemp(Ity_I32);
2896 IRTemp op3 = newTemp(Ity_I32);
2897 IRTemp result = newTemp(Ity_I32);
2898
2899 assign(op2, get_gpr_w0(r2));
2900 assign(op3, get_gpr_w1(r3));
2901 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2902 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
2903 put_gpr_w0(r1, mkexpr(result));
2904
2905 return "ahhlr";
2906}
2907
florian55085f82012-11-21 00:36:55 +00002908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002909s390_irgen_AIH(UChar r1, UInt i2)
2910{
2911 IRTemp op1 = newTemp(Ity_I32);
2912 Int op2;
2913 IRTemp result = newTemp(Ity_I32);
2914
2915 assign(op1, get_gpr_w0(r1));
2916 op2 = (Int)i2;
2917 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32((UInt)op2)));
2918 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op1, mktemp(Ity_I32,
2919 mkU32((UInt)op2)));
2920 put_gpr_w0(r1, mkexpr(result));
2921
2922 return "aih";
2923}
2924
florian55085f82012-11-21 00:36:55 +00002925static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002926s390_irgen_ALR(UChar r1, UChar r2)
2927{
2928 IRTemp op1 = newTemp(Ity_I32);
2929 IRTemp op2 = newTemp(Ity_I32);
2930 IRTemp result = newTemp(Ity_I32);
2931
2932 assign(op1, get_gpr_w1(r1));
2933 assign(op2, get_gpr_w1(r2));
2934 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
2935 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
2936 put_gpr_w1(r1, mkexpr(result));
2937
2938 return "alr";
2939}
2940
florian55085f82012-11-21 00:36:55 +00002941static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002942s390_irgen_ALGR(UChar r1, UChar r2)
2943{
2944 IRTemp op1 = newTemp(Ity_I64);
2945 IRTemp op2 = newTemp(Ity_I64);
2946 IRTemp result = newTemp(Ity_I64);
2947
2948 assign(op1, get_gpr_dw0(r1));
2949 assign(op2, get_gpr_dw0(r2));
2950 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2951 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2952 put_gpr_dw0(r1, mkexpr(result));
2953
2954 return "algr";
2955}
2956
florian55085f82012-11-21 00:36:55 +00002957static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002958s390_irgen_ALGFR(UChar r1, UChar r2)
2959{
2960 IRTemp op1 = newTemp(Ity_I64);
2961 IRTemp op2 = newTemp(Ity_I64);
2962 IRTemp result = newTemp(Ity_I64);
2963
2964 assign(op1, get_gpr_dw0(r1));
2965 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
2966 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
2967 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
2968 put_gpr_dw0(r1, mkexpr(result));
2969
2970 return "algfr";
2971}
2972
florian55085f82012-11-21 00:36:55 +00002973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002974s390_irgen_ALRK(UChar r3, UChar r1, UChar r2)
2975{
2976 IRTemp op2 = newTemp(Ity_I32);
2977 IRTemp op3 = newTemp(Ity_I32);
2978 IRTemp result = newTemp(Ity_I32);
2979
2980 assign(op2, get_gpr_w1(r2));
2981 assign(op3, get_gpr_w1(r3));
2982 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
2983 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
2984 put_gpr_w1(r1, mkexpr(result));
2985
2986 return "alrk";
2987}
2988
florian55085f82012-11-21 00:36:55 +00002989static const HChar *
sewardj2019a972011-03-07 16:04:07 +00002990s390_irgen_ALGRK(UChar r3, UChar r1, UChar r2)
2991{
2992 IRTemp op2 = newTemp(Ity_I64);
2993 IRTemp op3 = newTemp(Ity_I64);
2994 IRTemp result = newTemp(Ity_I64);
2995
2996 assign(op2, get_gpr_dw0(r2));
2997 assign(op3, get_gpr_dw0(r3));
2998 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
2999 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
3000 put_gpr_dw0(r1, mkexpr(result));
3001
3002 return "algrk";
3003}
3004
florian55085f82012-11-21 00:36:55 +00003005static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003006s390_irgen_AL(UChar r1, IRTemp op2addr)
3007{
3008 IRTemp op1 = newTemp(Ity_I32);
3009 IRTemp op2 = newTemp(Ity_I32);
3010 IRTemp result = newTemp(Ity_I32);
3011
3012 assign(op1, get_gpr_w1(r1));
3013 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3014 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3015 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3016 put_gpr_w1(r1, mkexpr(result));
3017
3018 return "al";
3019}
3020
florian55085f82012-11-21 00:36:55 +00003021static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003022s390_irgen_ALY(UChar r1, IRTemp op2addr)
3023{
3024 IRTemp op1 = newTemp(Ity_I32);
3025 IRTemp op2 = newTemp(Ity_I32);
3026 IRTemp result = newTemp(Ity_I32);
3027
3028 assign(op1, get_gpr_w1(r1));
3029 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3030 assign(result, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)));
3031 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, op2);
3032 put_gpr_w1(r1, mkexpr(result));
3033
3034 return "aly";
3035}
3036
florian55085f82012-11-21 00:36:55 +00003037static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003038s390_irgen_ALG(UChar r1, IRTemp op2addr)
3039{
3040 IRTemp op1 = newTemp(Ity_I64);
3041 IRTemp op2 = newTemp(Ity_I64);
3042 IRTemp result = newTemp(Ity_I64);
3043
3044 assign(op1, get_gpr_dw0(r1));
3045 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3046 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3047 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3048 put_gpr_dw0(r1, mkexpr(result));
3049
3050 return "alg";
3051}
3052
florian55085f82012-11-21 00:36:55 +00003053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003054s390_irgen_ALGF(UChar r1, IRTemp op2addr)
3055{
3056 IRTemp op1 = newTemp(Ity_I64);
3057 IRTemp op2 = newTemp(Ity_I64);
3058 IRTemp result = newTemp(Ity_I64);
3059
3060 assign(op1, get_gpr_dw0(r1));
3061 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
3062 assign(result, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)));
3063 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, op2);
3064 put_gpr_dw0(r1, mkexpr(result));
3065
3066 return "algf";
3067}
3068
florian55085f82012-11-21 00:36:55 +00003069static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003070s390_irgen_ALFI(UChar r1, UInt i2)
3071{
3072 IRTemp op1 = newTemp(Ity_I32);
3073 UInt op2;
3074 IRTemp result = newTemp(Ity_I32);
3075
3076 assign(op1, get_gpr_w1(r1));
3077 op2 = i2;
3078 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3079 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3080 mkU32(op2)));
3081 put_gpr_w1(r1, mkexpr(result));
3082
3083 return "alfi";
3084}
3085
florian55085f82012-11-21 00:36:55 +00003086static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003087s390_irgen_ALGFI(UChar r1, UInt i2)
3088{
3089 IRTemp op1 = newTemp(Ity_I64);
3090 ULong op2;
3091 IRTemp result = newTemp(Ity_I64);
3092
3093 assign(op1, get_gpr_dw0(r1));
3094 op2 = (ULong)i2;
3095 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3096 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3097 mkU64(op2)));
3098 put_gpr_dw0(r1, mkexpr(result));
3099
3100 return "algfi";
3101}
3102
florian55085f82012-11-21 00:36:55 +00003103static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003104s390_irgen_ALHHHR(UChar r3, UChar r1, UChar r2)
3105{
3106 IRTemp op2 = newTemp(Ity_I32);
3107 IRTemp op3 = newTemp(Ity_I32);
3108 IRTemp result = newTemp(Ity_I32);
3109
3110 assign(op2, get_gpr_w0(r2));
3111 assign(op3, get_gpr_w0(r3));
3112 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3113 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3114 put_gpr_w0(r1, mkexpr(result));
3115
3116 return "alhhhr";
3117}
3118
florian55085f82012-11-21 00:36:55 +00003119static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003120s390_irgen_ALHHLR(UChar r3, UChar r1, UChar r2)
3121{
3122 IRTemp op2 = newTemp(Ity_I32);
3123 IRTemp op3 = newTemp(Ity_I32);
3124 IRTemp result = newTemp(Ity_I32);
3125
3126 assign(op2, get_gpr_w0(r2));
3127 assign(op3, get_gpr_w1(r3));
3128 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
3129 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
3130 put_gpr_w0(r1, mkexpr(result));
3131
3132 return "alhhlr";
3133}
3134
florian55085f82012-11-21 00:36:55 +00003135static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003136s390_irgen_ALCR(UChar r1, UChar r2)
3137{
3138 IRTemp op1 = newTemp(Ity_I32);
3139 IRTemp op2 = newTemp(Ity_I32);
3140 IRTemp result = newTemp(Ity_I32);
3141 IRTemp carry_in = newTemp(Ity_I32);
3142
3143 assign(op1, get_gpr_w1(r1));
3144 assign(op2, get_gpr_w1(r2));
3145 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3146 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3147 mkexpr(carry_in)));
3148 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3149 put_gpr_w1(r1, mkexpr(result));
3150
3151 return "alcr";
3152}
3153
florian55085f82012-11-21 00:36:55 +00003154static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003155s390_irgen_ALCGR(UChar r1, UChar r2)
3156{
3157 IRTemp op1 = newTemp(Ity_I64);
3158 IRTemp op2 = newTemp(Ity_I64);
3159 IRTemp result = newTemp(Ity_I64);
3160 IRTemp carry_in = newTemp(Ity_I64);
3161
3162 assign(op1, get_gpr_dw0(r1));
3163 assign(op2, get_gpr_dw0(r2));
3164 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3165 mkU8(1))));
3166 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3167 mkexpr(carry_in)));
3168 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3169 put_gpr_dw0(r1, mkexpr(result));
3170
3171 return "alcgr";
3172}
3173
florian55085f82012-11-21 00:36:55 +00003174static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003175s390_irgen_ALC(UChar r1, IRTemp op2addr)
3176{
3177 IRTemp op1 = newTemp(Ity_I32);
3178 IRTemp op2 = newTemp(Ity_I32);
3179 IRTemp result = newTemp(Ity_I32);
3180 IRTemp carry_in = newTemp(Ity_I32);
3181
3182 assign(op1, get_gpr_w1(r1));
3183 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3184 assign(carry_in, binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)));
3185 assign(result, binop(Iop_Add32, binop(Iop_Add32, mkexpr(op1), mkexpr(op2)),
3186 mkexpr(carry_in)));
3187 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_32, op1, op2, carry_in);
3188 put_gpr_w1(r1, mkexpr(result));
3189
3190 return "alc";
3191}
3192
florian55085f82012-11-21 00:36:55 +00003193static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003194s390_irgen_ALCG(UChar r1, IRTemp op2addr)
3195{
3196 IRTemp op1 = newTemp(Ity_I64);
3197 IRTemp op2 = newTemp(Ity_I64);
3198 IRTemp result = newTemp(Ity_I64);
3199 IRTemp carry_in = newTemp(Ity_I64);
3200
3201 assign(op1, get_gpr_dw0(r1));
3202 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3203 assign(carry_in, unop(Iop_32Uto64, binop(Iop_Shr32, s390_call_calculate_cc(),
3204 mkU8(1))));
3205 assign(result, binop(Iop_Add64, binop(Iop_Add64, mkexpr(op1), mkexpr(op2)),
3206 mkexpr(carry_in)));
3207 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_ADDC_64, op1, op2, carry_in);
3208 put_gpr_dw0(r1, mkexpr(result));
3209
3210 return "alcg";
3211}
3212
florian55085f82012-11-21 00:36:55 +00003213static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003214s390_irgen_ALSI(UChar i2, IRTemp op1addr)
3215{
3216 IRTemp op1 = newTemp(Ity_I32);
3217 UInt op2;
3218 IRTemp result = newTemp(Ity_I32);
3219
3220 assign(op1, load(Ity_I32, mkexpr(op1addr)));
3221 op2 = (UInt)(Int)(Char)i2;
3222 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3223 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3224 mkU32(op2)));
3225 store(mkexpr(op1addr), mkexpr(result));
3226
3227 return "alsi";
3228}
3229
florian55085f82012-11-21 00:36:55 +00003230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003231s390_irgen_ALGSI(UChar i2, IRTemp op1addr)
3232{
3233 IRTemp op1 = newTemp(Ity_I64);
3234 ULong op2;
3235 IRTemp result = newTemp(Ity_I64);
3236
3237 assign(op1, load(Ity_I64, mkexpr(op1addr)));
3238 op2 = (ULong)(Long)(Char)i2;
3239 assign(result, binop(Iop_Add64, mkexpr(op1), mkU64(op2)));
3240 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op1, mktemp(Ity_I64,
3241 mkU64(op2)));
3242 store(mkexpr(op1addr), mkexpr(result));
3243
3244 return "algsi";
3245}
3246
florian55085f82012-11-21 00:36:55 +00003247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003248s390_irgen_ALHSIK(UChar r1, UChar r3, UShort i2)
3249{
3250 UInt op2;
3251 IRTemp op3 = newTemp(Ity_I32);
3252 IRTemp result = newTemp(Ity_I32);
3253
3254 op2 = (UInt)(Int)(Short)i2;
3255 assign(op3, get_gpr_w1(r3));
3256 assign(result, binop(Iop_Add32, mkU32(op2), mkexpr(op3)));
3257 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, mktemp(Ity_I32, mkU32(op2)),
3258 op3);
3259 put_gpr_w1(r1, mkexpr(result));
3260
3261 return "alhsik";
3262}
3263
florian55085f82012-11-21 00:36:55 +00003264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003265s390_irgen_ALGHSIK(UChar r1, UChar r3, UShort i2)
3266{
3267 ULong op2;
3268 IRTemp op3 = newTemp(Ity_I64);
3269 IRTemp result = newTemp(Ity_I64);
3270
3271 op2 = (ULong)(Long)(Short)i2;
3272 assign(op3, get_gpr_dw0(r3));
3273 assign(result, binop(Iop_Add64, mkU64(op2), mkexpr(op3)));
3274 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, mktemp(Ity_I64, mkU64(op2)),
3275 op3);
3276 put_gpr_dw0(r1, mkexpr(result));
3277
3278 return "alghsik";
3279}
3280
florian55085f82012-11-21 00:36:55 +00003281static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003282s390_irgen_ALSIH(UChar r1, UInt i2)
3283{
3284 IRTemp op1 = newTemp(Ity_I32);
3285 UInt op2;
3286 IRTemp result = newTemp(Ity_I32);
3287
3288 assign(op1, get_gpr_w0(r1));
3289 op2 = i2;
3290 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3291 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op1, mktemp(Ity_I32,
3292 mkU32(op2)));
3293 put_gpr_w0(r1, mkexpr(result));
3294
3295 return "alsih";
3296}
3297
florian55085f82012-11-21 00:36:55 +00003298static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003299s390_irgen_ALSIHN(UChar r1, UInt i2)
3300{
3301 IRTemp op1 = newTemp(Ity_I32);
3302 UInt op2;
3303 IRTemp result = newTemp(Ity_I32);
3304
3305 assign(op1, get_gpr_w0(r1));
3306 op2 = i2;
3307 assign(result, binop(Iop_Add32, mkexpr(op1), mkU32(op2)));
3308 put_gpr_w0(r1, mkexpr(result));
3309
3310 return "alsihn";
3311}
3312
florian55085f82012-11-21 00:36:55 +00003313static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003314s390_irgen_NR(UChar r1, UChar r2)
3315{
3316 IRTemp op1 = newTemp(Ity_I32);
3317 IRTemp op2 = newTemp(Ity_I32);
3318 IRTemp result = newTemp(Ity_I32);
3319
3320 assign(op1, get_gpr_w1(r1));
3321 assign(op2, get_gpr_w1(r2));
3322 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3323 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3324 put_gpr_w1(r1, mkexpr(result));
3325
3326 return "nr";
3327}
3328
florian55085f82012-11-21 00:36:55 +00003329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003330s390_irgen_NGR(UChar r1, UChar r2)
3331{
3332 IRTemp op1 = newTemp(Ity_I64);
3333 IRTemp op2 = newTemp(Ity_I64);
3334 IRTemp result = newTemp(Ity_I64);
3335
3336 assign(op1, get_gpr_dw0(r1));
3337 assign(op2, get_gpr_dw0(r2));
3338 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3339 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3340 put_gpr_dw0(r1, mkexpr(result));
3341
3342 return "ngr";
3343}
3344
florian55085f82012-11-21 00:36:55 +00003345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003346s390_irgen_NRK(UChar r3, UChar r1, UChar r2)
3347{
3348 IRTemp op2 = newTemp(Ity_I32);
3349 IRTemp op3 = newTemp(Ity_I32);
3350 IRTemp result = newTemp(Ity_I32);
3351
3352 assign(op2, get_gpr_w1(r2));
3353 assign(op3, get_gpr_w1(r3));
3354 assign(result, binop(Iop_And32, mkexpr(op2), mkexpr(op3)));
3355 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3356 put_gpr_w1(r1, mkexpr(result));
3357
3358 return "nrk";
3359}
3360
florian55085f82012-11-21 00:36:55 +00003361static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003362s390_irgen_NGRK(UChar r3, UChar r1, UChar r2)
3363{
3364 IRTemp op2 = newTemp(Ity_I64);
3365 IRTemp op3 = newTemp(Ity_I64);
3366 IRTemp result = newTemp(Ity_I64);
3367
3368 assign(op2, get_gpr_dw0(r2));
3369 assign(op3, get_gpr_dw0(r3));
3370 assign(result, binop(Iop_And64, mkexpr(op2), mkexpr(op3)));
3371 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3372 put_gpr_dw0(r1, mkexpr(result));
3373
3374 return "ngrk";
3375}
3376
florian55085f82012-11-21 00:36:55 +00003377static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003378s390_irgen_N(UChar r1, IRTemp op2addr)
3379{
3380 IRTemp op1 = newTemp(Ity_I32);
3381 IRTemp op2 = newTemp(Ity_I32);
3382 IRTemp result = newTemp(Ity_I32);
3383
3384 assign(op1, get_gpr_w1(r1));
3385 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3386 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3387 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3388 put_gpr_w1(r1, mkexpr(result));
3389
3390 return "n";
3391}
3392
florian55085f82012-11-21 00:36:55 +00003393static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003394s390_irgen_NY(UChar r1, IRTemp op2addr)
3395{
3396 IRTemp op1 = newTemp(Ity_I32);
3397 IRTemp op2 = newTemp(Ity_I32);
3398 IRTemp result = newTemp(Ity_I32);
3399
3400 assign(op1, get_gpr_w1(r1));
3401 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3402 assign(result, binop(Iop_And32, mkexpr(op1), mkexpr(op2)));
3403 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3404 put_gpr_w1(r1, mkexpr(result));
3405
3406 return "ny";
3407}
3408
florian55085f82012-11-21 00:36:55 +00003409static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003410s390_irgen_NG(UChar r1, IRTemp op2addr)
3411{
3412 IRTemp op1 = newTemp(Ity_I64);
3413 IRTemp op2 = newTemp(Ity_I64);
3414 IRTemp result = newTemp(Ity_I64);
3415
3416 assign(op1, get_gpr_dw0(r1));
3417 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3418 assign(result, binop(Iop_And64, mkexpr(op1), mkexpr(op2)));
3419 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3420 put_gpr_dw0(r1, mkexpr(result));
3421
3422 return "ng";
3423}
3424
florian55085f82012-11-21 00:36:55 +00003425static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003426s390_irgen_NI(UChar i2, IRTemp op1addr)
3427{
3428 IRTemp op1 = newTemp(Ity_I8);
3429 UChar op2;
3430 IRTemp result = newTemp(Ity_I8);
3431
3432 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3433 op2 = i2;
3434 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3435 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3436 store(mkexpr(op1addr), mkexpr(result));
3437
3438 return "ni";
3439}
3440
florian55085f82012-11-21 00:36:55 +00003441static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003442s390_irgen_NIY(UChar i2, IRTemp op1addr)
3443{
3444 IRTemp op1 = newTemp(Ity_I8);
3445 UChar op2;
3446 IRTemp result = newTemp(Ity_I8);
3447
3448 assign(op1, load(Ity_I8, mkexpr(op1addr)));
3449 op2 = i2;
3450 assign(result, binop(Iop_And8, mkexpr(op1), mkU8(op2)));
3451 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3452 store(mkexpr(op1addr), mkexpr(result));
3453
3454 return "niy";
3455}
3456
florian55085f82012-11-21 00:36:55 +00003457static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003458s390_irgen_NIHF(UChar r1, UInt i2)
3459{
3460 IRTemp op1 = newTemp(Ity_I32);
3461 UInt op2;
3462 IRTemp result = newTemp(Ity_I32);
3463
3464 assign(op1, get_gpr_w0(r1));
3465 op2 = i2;
3466 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3467 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3468 put_gpr_w0(r1, mkexpr(result));
3469
3470 return "nihf";
3471}
3472
florian55085f82012-11-21 00:36:55 +00003473static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003474s390_irgen_NIHH(UChar r1, UShort i2)
3475{
3476 IRTemp op1 = newTemp(Ity_I16);
3477 UShort op2;
3478 IRTemp result = newTemp(Ity_I16);
3479
3480 assign(op1, get_gpr_hw0(r1));
3481 op2 = i2;
3482 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3483 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3484 put_gpr_hw0(r1, mkexpr(result));
3485
3486 return "nihh";
3487}
3488
florian55085f82012-11-21 00:36:55 +00003489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003490s390_irgen_NIHL(UChar r1, UShort i2)
3491{
3492 IRTemp op1 = newTemp(Ity_I16);
3493 UShort op2;
3494 IRTemp result = newTemp(Ity_I16);
3495
3496 assign(op1, get_gpr_hw1(r1));
3497 op2 = i2;
3498 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3499 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3500 put_gpr_hw1(r1, mkexpr(result));
3501
3502 return "nihl";
3503}
3504
florian55085f82012-11-21 00:36:55 +00003505static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003506s390_irgen_NILF(UChar r1, UInt i2)
3507{
3508 IRTemp op1 = newTemp(Ity_I32);
3509 UInt op2;
3510 IRTemp result = newTemp(Ity_I32);
3511
3512 assign(op1, get_gpr_w1(r1));
3513 op2 = i2;
3514 assign(result, binop(Iop_And32, mkexpr(op1), mkU32(op2)));
3515 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3516 put_gpr_w1(r1, mkexpr(result));
3517
3518 return "nilf";
3519}
3520
florian55085f82012-11-21 00:36:55 +00003521static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003522s390_irgen_NILH(UChar r1, UShort i2)
3523{
3524 IRTemp op1 = newTemp(Ity_I16);
3525 UShort op2;
3526 IRTemp result = newTemp(Ity_I16);
3527
3528 assign(op1, get_gpr_hw2(r1));
3529 op2 = i2;
3530 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3531 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3532 put_gpr_hw2(r1, mkexpr(result));
3533
3534 return "nilh";
3535}
3536
florian55085f82012-11-21 00:36:55 +00003537static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003538s390_irgen_NILL(UChar r1, UShort i2)
3539{
3540 IRTemp op1 = newTemp(Ity_I16);
3541 UShort op2;
3542 IRTemp result = newTemp(Ity_I16);
3543
3544 assign(op1, get_gpr_hw3(r1));
3545 op2 = i2;
3546 assign(result, binop(Iop_And16, mkexpr(op1), mkU16(op2)));
3547 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
3548 put_gpr_hw3(r1, mkexpr(result));
3549
3550 return "nill";
3551}
3552
florian55085f82012-11-21 00:36:55 +00003553static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003554s390_irgen_BASR(UChar r1, UChar r2)
3555{
3556 IRTemp target = newTemp(Ity_I64);
3557
3558 if (r2 == 0) {
3559 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3560 } else {
3561 if (r1 != r2) {
3562 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3563 call_function(get_gpr_dw0(r2));
3564 } else {
3565 assign(target, get_gpr_dw0(r2));
3566 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 2ULL));
3567 call_function(mkexpr(target));
3568 }
3569 }
3570
3571 return "basr";
3572}
3573
florian55085f82012-11-21 00:36:55 +00003574static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003575s390_irgen_BAS(UChar r1, IRTemp op2addr)
3576{
3577 IRTemp target = newTemp(Ity_I64);
3578
3579 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
3580 assign(target, mkexpr(op2addr));
3581 call_function(mkexpr(target));
3582
3583 return "bas";
3584}
3585
florian55085f82012-11-21 00:36:55 +00003586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003587s390_irgen_BCR(UChar r1, UChar r2)
3588{
3589 IRTemp cond = newTemp(Ity_I32);
3590
sewardja52e37e2011-04-28 18:48:06 +00003591 if (r2 == 0 && (r1 >= 14)) { /* serialization */
3592 stmt(IRStmt_MBE(Imbe_Fence));
3593 }
3594
sewardj2019a972011-03-07 16:04:07 +00003595 if ((r2 == 0) || (r1 == 0)) {
3596 } else {
3597 if (r1 == 15) {
3598 return_from_function(get_gpr_dw0(r2));
3599 } else {
3600 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003601 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3602 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003603 }
3604 }
sewardj7ee97522011-05-09 21:45:04 +00003605 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003606 s390_disasm(ENC2(XMNM, GPR), S390_XMNM_BCR, r1, r2);
3607
3608 return "bcr";
3609}
3610
florian55085f82012-11-21 00:36:55 +00003611static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003612s390_irgen_BC(UChar r1, UChar x2, UChar b2, UShort d2, IRTemp op2addr)
3613{
3614 IRTemp cond = newTemp(Ity_I32);
3615
3616 if (r1 == 0) {
3617 } else {
3618 if (r1 == 15) {
3619 always_goto(mkexpr(op2addr));
3620 } else {
3621 assign(cond, s390_call_calculate_cond(r1));
florianf321da72012-07-21 20:32:57 +00003622 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3623 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003624 }
3625 }
sewardj7ee97522011-05-09 21:45:04 +00003626 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003627 s390_disasm(ENC2(XMNM, UDXB), S390_XMNM_BC, r1, d2, x2, b2);
3628
3629 return "bc";
3630}
3631
florian55085f82012-11-21 00:36:55 +00003632static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003633s390_irgen_BCTR(UChar r1, UChar r2)
3634{
3635 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3636 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003637 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3638 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003639 }
3640
3641 return "bctr";
3642}
3643
florian55085f82012-11-21 00:36:55 +00003644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003645s390_irgen_BCTGR(UChar r1, UChar r2)
3646{
3647 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3648 if (r2 != 0) {
florianf321da72012-07-21 20:32:57 +00003649 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3650 get_gpr_dw0(r2));
sewardj2019a972011-03-07 16:04:07 +00003651 }
3652
3653 return "bctgr";
3654}
3655
florian55085f82012-11-21 00:36:55 +00003656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003657s390_irgen_BCT(UChar r1, IRTemp op2addr)
3658{
3659 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
florianf321da72012-07-21 20:32:57 +00003660 if_condition_goto_computed(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3661 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003662
3663 return "bct";
3664}
3665
florian55085f82012-11-21 00:36:55 +00003666static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003667s390_irgen_BCTG(UChar r1, IRTemp op2addr)
3668{
3669 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
florianf321da72012-07-21 20:32:57 +00003670 if_condition_goto_computed(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3671 mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003672
3673 return "bctg";
3674}
3675
florian55085f82012-11-21 00:36:55 +00003676static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003677s390_irgen_BXH(UChar r1, UChar r3, IRTemp op2addr)
3678{
3679 IRTemp value = newTemp(Ity_I32);
3680
3681 assign(value, get_gpr_w1(r3 | 1));
3682 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003683 if_condition_goto_computed(binop(Iop_CmpLT32S, mkexpr(value),
3684 get_gpr_w1(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003685
3686 return "bxh";
3687}
3688
florian55085f82012-11-21 00:36:55 +00003689static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003690s390_irgen_BXHG(UChar r1, UChar r3, IRTemp op2addr)
3691{
3692 IRTemp value = newTemp(Ity_I64);
3693
3694 assign(value, get_gpr_dw0(r3 | 1));
3695 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003696 if_condition_goto_computed(binop(Iop_CmpLT64S, mkexpr(value),
3697 get_gpr_dw0(r1)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003698
3699 return "bxhg";
3700}
3701
florian55085f82012-11-21 00:36:55 +00003702static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003703s390_irgen_BXLE(UChar r1, UChar r3, IRTemp op2addr)
3704{
3705 IRTemp value = newTemp(Ity_I32);
3706
3707 assign(value, get_gpr_w1(r3 | 1));
3708 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
florianf321da72012-07-21 20:32:57 +00003709 if_condition_goto_computed(binop(Iop_CmpLE32S, get_gpr_w1(r1),
3710 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003711
3712 return "bxle";
3713}
3714
florian55085f82012-11-21 00:36:55 +00003715static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003716s390_irgen_BXLEG(UChar r1, UChar r3, IRTemp op2addr)
3717{
3718 IRTemp value = newTemp(Ity_I64);
3719
3720 assign(value, get_gpr_dw0(r3 | 1));
3721 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
florianf321da72012-07-21 20:32:57 +00003722 if_condition_goto_computed(binop(Iop_CmpLE64S, get_gpr_dw0(r1),
3723 mkexpr(value)), mkexpr(op2addr));
sewardj2019a972011-03-07 16:04:07 +00003724
3725 return "bxleg";
3726}
3727
florian55085f82012-11-21 00:36:55 +00003728static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003729s390_irgen_BRAS(UChar r1, UShort i2)
3730{
3731 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL));
floriana64c2432011-07-16 02:11:50 +00003732 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003733
3734 return "bras";
3735}
3736
florian55085f82012-11-21 00:36:55 +00003737static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003738s390_irgen_BRASL(UChar r1, UInt i2)
3739{
3740 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL));
floriana64c2432011-07-16 02:11:50 +00003741 call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003742
3743 return "brasl";
3744}
3745
florian55085f82012-11-21 00:36:55 +00003746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003747s390_irgen_BRC(UChar r1, UShort i2)
3748{
3749 IRTemp cond = newTemp(Ity_I32);
3750
3751 if (r1 == 0) {
3752 } else {
3753 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003754 always_goto_and_chase(
3755 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003756 } else {
3757 assign(cond, s390_call_calculate_cond(r1));
3758 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3759 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3760
3761 }
3762 }
sewardj7ee97522011-05-09 21:45:04 +00003763 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003764 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRC, r1, (Int)(Short)i2);
3765
3766 return "brc";
3767}
3768
florian55085f82012-11-21 00:36:55 +00003769static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003770s390_irgen_BRCL(UChar r1, UInt i2)
3771{
3772 IRTemp cond = newTemp(Ity_I32);
3773
3774 if (r1 == 0) {
3775 } else {
3776 if (r1 == 15) {
floriana64c2432011-07-16 02:11:50 +00003777 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
sewardj2019a972011-03-07 16:04:07 +00003778 } else {
3779 assign(cond, s390_call_calculate_cond(r1));
3780 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
3781 guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1));
3782 }
3783 }
sewardj7ee97522011-05-09 21:45:04 +00003784 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00003785 s390_disasm(ENC2(XMNM, PCREL), S390_XMNM_BRCL, r1, i2);
3786
3787 return "brcl";
3788}
3789
florian55085f82012-11-21 00:36:55 +00003790static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003791s390_irgen_BRCT(UChar r1, UShort i2)
3792{
3793 put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1)));
3794 if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)),
3795 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3796
3797 return "brct";
3798}
3799
florian55085f82012-11-21 00:36:55 +00003800static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003801s390_irgen_BRCTG(UChar r1, UShort i2)
3802{
3803 put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1)));
3804 if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)),
3805 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3806
3807 return "brctg";
3808}
3809
florian55085f82012-11-21 00:36:55 +00003810static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003811s390_irgen_BRXH(UChar r1, UChar r3, UShort i2)
3812{
3813 IRTemp value = newTemp(Ity_I32);
3814
3815 assign(value, get_gpr_w1(r3 | 1));
3816 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3817 if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)),
3818 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3819
3820 return "brxh";
3821}
3822
florian55085f82012-11-21 00:36:55 +00003823static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003824s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2)
3825{
3826 IRTemp value = newTemp(Ity_I64);
3827
3828 assign(value, get_gpr_dw0(r3 | 1));
3829 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3830 if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)),
3831 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3832
3833 return "brxhg";
3834}
3835
florian55085f82012-11-21 00:36:55 +00003836static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003837s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2)
3838{
3839 IRTemp value = newTemp(Ity_I32);
3840
3841 assign(value, get_gpr_w1(r3 | 1));
3842 put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3)));
3843 if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)),
3844 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3845
3846 return "brxle";
3847}
3848
florian55085f82012-11-21 00:36:55 +00003849static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003850s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2)
3851{
3852 IRTemp value = newTemp(Ity_I64);
3853
3854 assign(value, get_gpr_dw0(r3 | 1));
3855 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3)));
3856 if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)),
3857 guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1));
3858
3859 return "brxlg";
3860}
3861
florian55085f82012-11-21 00:36:55 +00003862static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003863s390_irgen_CR(UChar r1, UChar r2)
3864{
3865 IRTemp op1 = newTemp(Ity_I32);
3866 IRTemp op2 = newTemp(Ity_I32);
3867
3868 assign(op1, get_gpr_w1(r1));
3869 assign(op2, get_gpr_w1(r2));
3870 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3871
3872 return "cr";
3873}
3874
florian55085f82012-11-21 00:36:55 +00003875static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003876s390_irgen_CGR(UChar r1, UChar r2)
3877{
3878 IRTemp op1 = newTemp(Ity_I64);
3879 IRTemp op2 = newTemp(Ity_I64);
3880
3881 assign(op1, get_gpr_dw0(r1));
3882 assign(op2, get_gpr_dw0(r2));
3883 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3884
3885 return "cgr";
3886}
3887
florian55085f82012-11-21 00:36:55 +00003888static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003889s390_irgen_CGFR(UChar r1, UChar r2)
3890{
3891 IRTemp op1 = newTemp(Ity_I64);
3892 IRTemp op2 = newTemp(Ity_I64);
3893
3894 assign(op1, get_gpr_dw0(r1));
3895 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
3896 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3897
3898 return "cgfr";
3899}
3900
florian55085f82012-11-21 00:36:55 +00003901static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003902s390_irgen_C(UChar r1, IRTemp op2addr)
3903{
3904 IRTemp op1 = newTemp(Ity_I32);
3905 IRTemp op2 = newTemp(Ity_I32);
3906
3907 assign(op1, get_gpr_w1(r1));
3908 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3909 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3910
3911 return "c";
3912}
3913
florian55085f82012-11-21 00:36:55 +00003914static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003915s390_irgen_CY(UChar r1, IRTemp op2addr)
3916{
3917 IRTemp op1 = newTemp(Ity_I32);
3918 IRTemp op2 = newTemp(Ity_I32);
3919
3920 assign(op1, get_gpr_w1(r1));
3921 assign(op2, load(Ity_I32, mkexpr(op2addr)));
3922 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3923
3924 return "cy";
3925}
3926
florian55085f82012-11-21 00:36:55 +00003927static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003928s390_irgen_CG(UChar r1, IRTemp op2addr)
3929{
3930 IRTemp op1 = newTemp(Ity_I64);
3931 IRTemp op2 = newTemp(Ity_I64);
3932
3933 assign(op1, get_gpr_dw0(r1));
3934 assign(op2, load(Ity_I64, mkexpr(op2addr)));
3935 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3936
3937 return "cg";
3938}
3939
florian55085f82012-11-21 00:36:55 +00003940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003941s390_irgen_CGF(UChar r1, IRTemp op2addr)
3942{
3943 IRTemp op1 = newTemp(Ity_I64);
3944 IRTemp op2 = newTemp(Ity_I64);
3945
3946 assign(op1, get_gpr_dw0(r1));
3947 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
3948 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3949
3950 return "cgf";
3951}
3952
florian55085f82012-11-21 00:36:55 +00003953static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003954s390_irgen_CFI(UChar r1, UInt i2)
3955{
3956 IRTemp op1 = newTemp(Ity_I32);
3957 Int op2;
3958
3959 assign(op1, get_gpr_w1(r1));
3960 op2 = (Int)i2;
3961 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
3962 mkU32((UInt)op2)));
3963
3964 return "cfi";
3965}
3966
florian55085f82012-11-21 00:36:55 +00003967static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003968s390_irgen_CGFI(UChar r1, UInt i2)
3969{
3970 IRTemp op1 = newTemp(Ity_I64);
3971 Long op2;
3972
3973 assign(op1, get_gpr_dw0(r1));
3974 op2 = (Long)(Int)i2;
3975 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
3976 mkU64((ULong)op2)));
3977
3978 return "cgfi";
3979}
3980
florian55085f82012-11-21 00:36:55 +00003981static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003982s390_irgen_CRL(UChar r1, UInt i2)
3983{
3984 IRTemp op1 = newTemp(Ity_I32);
3985 IRTemp op2 = newTemp(Ity_I32);
3986
3987 assign(op1, get_gpr_w1(r1));
3988 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
3989 i2 << 1))));
3990 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
3991
3992 return "crl";
3993}
3994
florian55085f82012-11-21 00:36:55 +00003995static const HChar *
sewardj2019a972011-03-07 16:04:07 +00003996s390_irgen_CGRL(UChar r1, UInt i2)
3997{
3998 IRTemp op1 = newTemp(Ity_I64);
3999 IRTemp op2 = newTemp(Ity_I64);
4000
4001 assign(op1, get_gpr_dw0(r1));
4002 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4003 i2 << 1))));
4004 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4005
4006 return "cgrl";
4007}
4008
florian55085f82012-11-21 00:36:55 +00004009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004010s390_irgen_CGFRL(UChar r1, UInt i2)
4011{
4012 IRTemp op1 = newTemp(Ity_I64);
4013 IRTemp op2 = newTemp(Ity_I64);
4014
4015 assign(op1, get_gpr_dw0(r1));
4016 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4017 ((ULong)(Long)(Int)i2 << 1)))));
4018 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4019
4020 return "cgfrl";
4021}
4022
florian55085f82012-11-21 00:36:55 +00004023static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004024s390_irgen_CRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4025{
4026 IRTemp op1 = newTemp(Ity_I32);
4027 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004028 IRTemp cond = newTemp(Ity_I32);
4029
4030 if (m3 == 0) {
4031 } else {
4032 if (m3 == 14) {
4033 always_goto(mkexpr(op4addr));
4034 } else {
4035 assign(op1, get_gpr_w1(r1));
4036 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004037 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4038 op1, op2));
florianf321da72012-07-21 20:32:57 +00004039 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4040 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004041 }
4042 }
4043
4044 return "crb";
4045}
4046
florian55085f82012-11-21 00:36:55 +00004047static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004048s390_irgen_CGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4049{
4050 IRTemp op1 = newTemp(Ity_I64);
4051 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004052 IRTemp cond = newTemp(Ity_I32);
4053
4054 if (m3 == 0) {
4055 } else {
4056 if (m3 == 14) {
4057 always_goto(mkexpr(op4addr));
4058 } else {
4059 assign(op1, get_gpr_dw0(r1));
4060 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004061 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4062 op1, op2));
florianf321da72012-07-21 20:32:57 +00004063 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond),
4064 mkU32(0)), mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004065 }
4066 }
4067
4068 return "cgrb";
4069}
4070
florian55085f82012-11-21 00:36:55 +00004071static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004072s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4073{
4074 IRTemp op1 = newTemp(Ity_I32);
4075 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004076 IRTemp cond = newTemp(Ity_I32);
4077
4078 if (m3 == 0) {
4079 } else {
4080 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004081 always_goto_and_chase(
4082 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004083 } else {
4084 assign(op1, get_gpr_w1(r1));
4085 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004086 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4087 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004088 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4089 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4090
4091 }
4092 }
4093
4094 return "crj";
4095}
4096
florian55085f82012-11-21 00:36:55 +00004097static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004098s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4099{
4100 IRTemp op1 = newTemp(Ity_I64);
4101 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004102 IRTemp cond = newTemp(Ity_I32);
4103
4104 if (m3 == 0) {
4105 } else {
4106 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004107 always_goto_and_chase(
4108 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004109 } else {
4110 assign(op1, get_gpr_dw0(r1));
4111 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004112 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE,
4113 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004114 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4115 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4116
4117 }
4118 }
4119
4120 return "cgrj";
4121}
4122
florian55085f82012-11-21 00:36:55 +00004123static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004124s390_irgen_CIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4125{
4126 IRTemp op1 = newTemp(Ity_I32);
4127 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004128 IRTemp cond = newTemp(Ity_I32);
4129
4130 if (m3 == 0) {
4131 } else {
4132 if (m3 == 14) {
4133 always_goto(mkexpr(op4addr));
4134 } else {
4135 assign(op1, get_gpr_w1(r1));
4136 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004137 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4138 mktemp(Ity_I32, mkU32((UInt)op2))));
florianf321da72012-07-21 20:32:57 +00004139 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4140 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004141 }
4142 }
4143
4144 return "cib";
4145}
4146
florian55085f82012-11-21 00:36:55 +00004147static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004148s390_irgen_CGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4149{
4150 IRTemp op1 = newTemp(Ity_I64);
4151 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004152 IRTemp cond = newTemp(Ity_I32);
4153
4154 if (m3 == 0) {
4155 } else {
4156 if (m3 == 14) {
4157 always_goto(mkexpr(op4addr));
4158 } else {
4159 assign(op1, get_gpr_dw0(r1));
4160 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004161 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4162 mktemp(Ity_I64, mkU64((ULong)op2))));
florianf321da72012-07-21 20:32:57 +00004163 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4164 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004165 }
4166 }
4167
4168 return "cgib";
4169}
4170
florian55085f82012-11-21 00:36:55 +00004171static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004172s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4173{
4174 IRTemp op1 = newTemp(Ity_I32);
4175 Int op2;
sewardj2019a972011-03-07 16:04:07 +00004176 IRTemp cond = newTemp(Ity_I32);
4177
4178 if (m3 == 0) {
4179 } else {
4180 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004181 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004182 } else {
4183 assign(op1, get_gpr_w1(r1));
4184 op2 = (Int)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004185 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4186 mktemp(Ity_I32, mkU32((UInt)op2))));
sewardj2019a972011-03-07 16:04:07 +00004187 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4188 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4189
4190 }
4191 }
4192
4193 return "cij";
4194}
4195
florian55085f82012-11-21 00:36:55 +00004196static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004197s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4198{
4199 IRTemp op1 = newTemp(Ity_I64);
4200 Long op2;
sewardj2019a972011-03-07 16:04:07 +00004201 IRTemp cond = newTemp(Ity_I32);
4202
4203 if (m3 == 0) {
4204 } else {
4205 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004206 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004207 } else {
4208 assign(op1, get_gpr_dw0(r1));
4209 op2 = (Long)(Char)i2;
florianff9613f2012-05-12 15:26:44 +00004210 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1,
4211 mktemp(Ity_I64, mkU64((ULong)op2))));
sewardj2019a972011-03-07 16:04:07 +00004212 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4213 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4214
4215 }
4216 }
4217
4218 return "cgij";
4219}
4220
florian55085f82012-11-21 00:36:55 +00004221static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004222s390_irgen_CH(UChar r1, IRTemp op2addr)
4223{
4224 IRTemp op1 = newTemp(Ity_I32);
4225 IRTemp op2 = newTemp(Ity_I32);
4226
4227 assign(op1, get_gpr_w1(r1));
4228 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4229 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4230
4231 return "ch";
4232}
4233
florian55085f82012-11-21 00:36:55 +00004234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004235s390_irgen_CHY(UChar r1, IRTemp op2addr)
4236{
4237 IRTemp op1 = newTemp(Ity_I32);
4238 IRTemp op2 = newTemp(Ity_I32);
4239
4240 assign(op1, get_gpr_w1(r1));
4241 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
4242 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4243
4244 return "chy";
4245}
4246
florian55085f82012-11-21 00:36:55 +00004247static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004248s390_irgen_CGH(UChar r1, IRTemp op2addr)
4249{
4250 IRTemp op1 = newTemp(Ity_I64);
4251 IRTemp op2 = newTemp(Ity_I64);
4252
4253 assign(op1, get_gpr_dw0(r1));
4254 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
4255 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4256
4257 return "cgh";
4258}
4259
florian55085f82012-11-21 00:36:55 +00004260static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004261s390_irgen_CHI(UChar r1, UShort i2)
4262{
4263 IRTemp op1 = newTemp(Ity_I32);
4264 Int op2;
4265
4266 assign(op1, get_gpr_w1(r1));
4267 op2 = (Int)(Short)i2;
4268 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4269 mkU32((UInt)op2)));
4270
4271 return "chi";
4272}
4273
florian55085f82012-11-21 00:36:55 +00004274static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004275s390_irgen_CGHI(UChar r1, UShort i2)
4276{
4277 IRTemp op1 = newTemp(Ity_I64);
4278 Long op2;
4279
4280 assign(op1, get_gpr_dw0(r1));
4281 op2 = (Long)(Short)i2;
4282 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4283 mkU64((ULong)op2)));
4284
4285 return "cghi";
4286}
4287
florian55085f82012-11-21 00:36:55 +00004288static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004289s390_irgen_CHHSI(UShort i2, IRTemp op1addr)
4290{
4291 IRTemp op1 = newTemp(Ity_I16);
4292 Short op2;
4293
4294 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4295 op2 = (Short)i2;
4296 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I16,
4297 mkU16((UShort)op2)));
4298
4299 return "chhsi";
4300}
4301
florian55085f82012-11-21 00:36:55 +00004302static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004303s390_irgen_CHSI(UShort i2, IRTemp op1addr)
4304{
4305 IRTemp op1 = newTemp(Ity_I32);
4306 Int op2;
4307
4308 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4309 op2 = (Int)(Short)i2;
4310 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4311 mkU32((UInt)op2)));
4312
4313 return "chsi";
4314}
4315
florian55085f82012-11-21 00:36:55 +00004316static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004317s390_irgen_CGHSI(UShort i2, IRTemp op1addr)
4318{
4319 IRTemp op1 = newTemp(Ity_I64);
4320 Long op2;
4321
4322 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4323 op2 = (Long)(Short)i2;
4324 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I64,
4325 mkU64((ULong)op2)));
4326
4327 return "cghsi";
4328}
4329
florian55085f82012-11-21 00:36:55 +00004330static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004331s390_irgen_CHRL(UChar r1, UInt i2)
4332{
4333 IRTemp op1 = newTemp(Ity_I32);
4334 IRTemp op2 = newTemp(Ity_I32);
4335
4336 assign(op1, get_gpr_w1(r1));
4337 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4338 ((ULong)(Long)(Int)i2 << 1)))));
4339 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4340
4341 return "chrl";
4342}
4343
florian55085f82012-11-21 00:36:55 +00004344static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004345s390_irgen_CGHRL(UChar r1, UInt i2)
4346{
4347 IRTemp op1 = newTemp(Ity_I64);
4348 IRTemp op2 = newTemp(Ity_I64);
4349
4350 assign(op1, get_gpr_dw0(r1));
4351 assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4352 ((ULong)(Long)(Int)i2 << 1)))));
4353 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4354
4355 return "cghrl";
4356}
4357
florian55085f82012-11-21 00:36:55 +00004358static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004359s390_irgen_CHHR(UChar r1, UChar r2)
4360{
4361 IRTemp op1 = newTemp(Ity_I32);
4362 IRTemp op2 = newTemp(Ity_I32);
4363
4364 assign(op1, get_gpr_w0(r1));
4365 assign(op2, get_gpr_w0(r2));
4366 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4367
4368 return "chhr";
4369}
4370
florian55085f82012-11-21 00:36:55 +00004371static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004372s390_irgen_CHLR(UChar r1, UChar r2)
4373{
4374 IRTemp op1 = newTemp(Ity_I32);
4375 IRTemp op2 = newTemp(Ity_I32);
4376
4377 assign(op1, get_gpr_w0(r1));
4378 assign(op2, get_gpr_w1(r2));
4379 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4380
4381 return "chlr";
4382}
4383
florian55085f82012-11-21 00:36:55 +00004384static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004385s390_irgen_CHF(UChar r1, IRTemp op2addr)
4386{
4387 IRTemp op1 = newTemp(Ity_I32);
4388 IRTemp op2 = newTemp(Ity_I32);
4389
4390 assign(op1, get_gpr_w0(r1));
4391 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4392 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2);
4393
4394 return "chf";
4395}
4396
florian55085f82012-11-21 00:36:55 +00004397static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004398s390_irgen_CIH(UChar r1, UInt i2)
4399{
4400 IRTemp op1 = newTemp(Ity_I32);
4401 Int op2;
4402
4403 assign(op1, get_gpr_w0(r1));
4404 op2 = (Int)i2;
4405 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, mktemp(Ity_I32,
4406 mkU32((UInt)op2)));
4407
4408 return "cih";
4409}
4410
florian55085f82012-11-21 00:36:55 +00004411static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004412s390_irgen_CLR(UChar r1, UChar r2)
4413{
4414 IRTemp op1 = newTemp(Ity_I32);
4415 IRTemp op2 = newTemp(Ity_I32);
4416
4417 assign(op1, get_gpr_w1(r1));
4418 assign(op2, get_gpr_w1(r2));
4419 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4420
4421 return "clr";
4422}
4423
florian55085f82012-11-21 00:36:55 +00004424static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004425s390_irgen_CLGR(UChar r1, UChar r2)
4426{
4427 IRTemp op1 = newTemp(Ity_I64);
4428 IRTemp op2 = newTemp(Ity_I64);
4429
4430 assign(op1, get_gpr_dw0(r1));
4431 assign(op2, get_gpr_dw0(r2));
4432 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4433
4434 return "clgr";
4435}
4436
florian55085f82012-11-21 00:36:55 +00004437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004438s390_irgen_CLGFR(UChar r1, UChar r2)
4439{
4440 IRTemp op1 = newTemp(Ity_I64);
4441 IRTemp op2 = newTemp(Ity_I64);
4442
4443 assign(op1, get_gpr_dw0(r1));
4444 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
4445 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4446
4447 return "clgfr";
4448}
4449
florian55085f82012-11-21 00:36:55 +00004450static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004451s390_irgen_CL(UChar r1, IRTemp op2addr)
4452{
4453 IRTemp op1 = newTemp(Ity_I32);
4454 IRTemp op2 = newTemp(Ity_I32);
4455
4456 assign(op1, get_gpr_w1(r1));
4457 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4458 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4459
4460 return "cl";
4461}
4462
florian55085f82012-11-21 00:36:55 +00004463static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004464s390_irgen_CLY(UChar r1, IRTemp op2addr)
4465{
4466 IRTemp op1 = newTemp(Ity_I32);
4467 IRTemp op2 = newTemp(Ity_I32);
4468
4469 assign(op1, get_gpr_w1(r1));
4470 assign(op2, load(Ity_I32, mkexpr(op2addr)));
4471 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4472
4473 return "cly";
4474}
4475
florian55085f82012-11-21 00:36:55 +00004476static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004477s390_irgen_CLG(UChar r1, IRTemp op2addr)
4478{
4479 IRTemp op1 = newTemp(Ity_I64);
4480 IRTemp op2 = newTemp(Ity_I64);
4481
4482 assign(op1, get_gpr_dw0(r1));
4483 assign(op2, load(Ity_I64, mkexpr(op2addr)));
4484 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4485
4486 return "clg";
4487}
4488
florian55085f82012-11-21 00:36:55 +00004489static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004490s390_irgen_CLGF(UChar r1, IRTemp op2addr)
4491{
4492 IRTemp op1 = newTemp(Ity_I64);
4493 IRTemp op2 = newTemp(Ity_I64);
4494
4495 assign(op1, get_gpr_dw0(r1));
4496 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
4497 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4498
4499 return "clgf";
4500}
4501
florian55085f82012-11-21 00:36:55 +00004502static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004503s390_irgen_CLFI(UChar r1, UInt i2)
4504{
4505 IRTemp op1 = newTemp(Ity_I32);
4506 UInt op2;
4507
4508 assign(op1, get_gpr_w1(r1));
4509 op2 = i2;
4510 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4511 mkU32(op2)));
4512
4513 return "clfi";
4514}
4515
florian55085f82012-11-21 00:36:55 +00004516static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004517s390_irgen_CLGFI(UChar r1, UInt i2)
4518{
4519 IRTemp op1 = newTemp(Ity_I64);
4520 ULong op2;
4521
4522 assign(op1, get_gpr_dw0(r1));
4523 op2 = (ULong)i2;
4524 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4525 mkU64(op2)));
4526
4527 return "clgfi";
4528}
4529
florian55085f82012-11-21 00:36:55 +00004530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004531s390_irgen_CLI(UChar i2, IRTemp op1addr)
4532{
4533 IRTemp op1 = newTemp(Ity_I8);
4534 UChar op2;
4535
4536 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4537 op2 = i2;
4538 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4539 mkU8(op2)));
4540
4541 return "cli";
4542}
4543
florian55085f82012-11-21 00:36:55 +00004544static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004545s390_irgen_CLIY(UChar i2, IRTemp op1addr)
4546{
4547 IRTemp op1 = newTemp(Ity_I8);
4548 UChar op2;
4549
4550 assign(op1, load(Ity_I8, mkexpr(op1addr)));
4551 op2 = i2;
4552 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I8,
4553 mkU8(op2)));
4554
4555 return "cliy";
4556}
4557
florian55085f82012-11-21 00:36:55 +00004558static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004559s390_irgen_CLFHSI(UShort i2, IRTemp op1addr)
4560{
4561 IRTemp op1 = newTemp(Ity_I32);
4562 UInt op2;
4563
4564 assign(op1, load(Ity_I32, mkexpr(op1addr)));
4565 op2 = (UInt)i2;
4566 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
4567 mkU32(op2)));
4568
4569 return "clfhsi";
4570}
4571
florian55085f82012-11-21 00:36:55 +00004572static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004573s390_irgen_CLGHSI(UShort i2, IRTemp op1addr)
4574{
4575 IRTemp op1 = newTemp(Ity_I64);
4576 ULong op2;
4577
4578 assign(op1, load(Ity_I64, mkexpr(op1addr)));
4579 op2 = (ULong)i2;
4580 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I64,
4581 mkU64(op2)));
4582
4583 return "clghsi";
4584}
4585
florian55085f82012-11-21 00:36:55 +00004586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004587s390_irgen_CLHHSI(UShort i2, IRTemp op1addr)
4588{
4589 IRTemp op1 = newTemp(Ity_I16);
4590 UShort op2;
4591
4592 assign(op1, load(Ity_I16, mkexpr(op1addr)));
4593 op2 = i2;
4594 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I16,
4595 mkU16(op2)));
4596
4597 return "clhhsi";
4598}
4599
florian55085f82012-11-21 00:36:55 +00004600static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004601s390_irgen_CLRL(UChar r1, UInt i2)
4602{
4603 IRTemp op1 = newTemp(Ity_I32);
4604 IRTemp op2 = newTemp(Ity_I32);
4605
4606 assign(op1, get_gpr_w1(r1));
4607 assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4608 i2 << 1))));
4609 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4610
4611 return "clrl";
4612}
4613
florian55085f82012-11-21 00:36:55 +00004614static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004615s390_irgen_CLGRL(UChar r1, UInt i2)
4616{
4617 IRTemp op1 = newTemp(Ity_I64);
4618 IRTemp op2 = newTemp(Ity_I64);
4619
4620 assign(op1, get_gpr_dw0(r1));
4621 assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
4622 i2 << 1))));
4623 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4624
4625 return "clgrl";
4626}
4627
florian55085f82012-11-21 00:36:55 +00004628static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004629s390_irgen_CLGFRL(UChar r1, UInt i2)
4630{
4631 IRTemp op1 = newTemp(Ity_I64);
4632 IRTemp op2 = newTemp(Ity_I64);
4633
4634 assign(op1, get_gpr_dw0(r1));
4635 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
4636 ((ULong)(Long)(Int)i2 << 1)))));
4637 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4638
4639 return "clgfrl";
4640}
4641
florian55085f82012-11-21 00:36:55 +00004642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004643s390_irgen_CLHRL(UChar r1, UInt i2)
4644{
4645 IRTemp op1 = newTemp(Ity_I32);
4646 IRTemp op2 = newTemp(Ity_I32);
4647
4648 assign(op1, get_gpr_w1(r1));
4649 assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
4650 ((ULong)(Long)(Int)i2 << 1)))));
4651 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4652
4653 return "clhrl";
4654}
4655
florian55085f82012-11-21 00:36:55 +00004656static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004657s390_irgen_CLGHRL(UChar r1, UInt i2)
4658{
4659 IRTemp op1 = newTemp(Ity_I64);
4660 IRTemp op2 = newTemp(Ity_I64);
4661
4662 assign(op1, get_gpr_dw0(r1));
4663 assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
4664 ((ULong)(Long)(Int)i2 << 1)))));
4665 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4666
4667 return "clghrl";
4668}
4669
florian55085f82012-11-21 00:36:55 +00004670static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004671s390_irgen_CLRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4672{
4673 IRTemp op1 = newTemp(Ity_I32);
4674 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004675 IRTemp cond = newTemp(Ity_I32);
4676
4677 if (m3 == 0) {
4678 } else {
4679 if (m3 == 14) {
4680 always_goto(mkexpr(op4addr));
4681 } else {
4682 assign(op1, get_gpr_w1(r1));
4683 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004684 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4685 op1, op2));
florianf321da72012-07-21 20:32:57 +00004686 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4687 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004688 }
4689 }
4690
4691 return "clrb";
4692}
4693
florian55085f82012-11-21 00:36:55 +00004694static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004695s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr)
4696{
4697 IRTemp op1 = newTemp(Ity_I64);
4698 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004699 IRTemp cond = newTemp(Ity_I32);
4700
4701 if (m3 == 0) {
4702 } else {
4703 if (m3 == 14) {
4704 always_goto(mkexpr(op4addr));
4705 } else {
4706 assign(op1, get_gpr_dw0(r1));
4707 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004708 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4709 op1, op2));
florianf321da72012-07-21 20:32:57 +00004710 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4711 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004712 }
4713 }
4714
4715 return "clgrb";
4716}
4717
florian55085f82012-11-21 00:36:55 +00004718static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004719s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4720{
4721 IRTemp op1 = newTemp(Ity_I32);
4722 IRTemp op2 = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00004723 IRTemp cond = newTemp(Ity_I32);
4724
4725 if (m3 == 0) {
4726 } else {
4727 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004728 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004729 } else {
4730 assign(op1, get_gpr_w1(r1));
4731 assign(op2, get_gpr_w1(r2));
florianff9613f2012-05-12 15:26:44 +00004732 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4733 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004734 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4735 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4736
4737 }
4738 }
4739
4740 return "clrj";
4741}
4742
florian55085f82012-11-21 00:36:55 +00004743static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004744s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3)
4745{
4746 IRTemp op1 = newTemp(Ity_I64);
4747 IRTemp op2 = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +00004748 IRTemp cond = newTemp(Ity_I32);
4749
4750 if (m3 == 0) {
4751 } else {
4752 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004753 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004754 } else {
4755 assign(op1, get_gpr_dw0(r1));
4756 assign(op2, get_gpr_dw0(r2));
florianff9613f2012-05-12 15:26:44 +00004757 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE,
4758 op1, op2));
sewardj2019a972011-03-07 16:04:07 +00004759 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4760 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4761
4762 }
4763 }
4764
4765 return "clgrj";
4766}
4767
florian55085f82012-11-21 00:36:55 +00004768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004769s390_irgen_CLIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4770{
4771 IRTemp op1 = newTemp(Ity_I32);
4772 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004773 IRTemp cond = newTemp(Ity_I32);
4774
4775 if (m3 == 0) {
4776 } else {
4777 if (m3 == 14) {
4778 always_goto(mkexpr(op4addr));
4779 } else {
4780 assign(op1, get_gpr_w1(r1));
4781 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004782 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4783 mktemp(Ity_I32, mkU32(op2))));
florianf321da72012-07-21 20:32:57 +00004784 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4785 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004786 }
4787 }
4788
4789 return "clib";
4790}
4791
florian55085f82012-11-21 00:36:55 +00004792static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004793s390_irgen_CLGIB(UChar r1, UChar m3, UChar i2, IRTemp op4addr)
4794{
4795 IRTemp op1 = newTemp(Ity_I64);
4796 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004797 IRTemp cond = newTemp(Ity_I32);
4798
4799 if (m3 == 0) {
4800 } else {
4801 if (m3 == 14) {
4802 always_goto(mkexpr(op4addr));
4803 } else {
4804 assign(op1, get_gpr_dw0(r1));
4805 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004806 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4807 mktemp(Ity_I64, mkU64(op2))));
florianf321da72012-07-21 20:32:57 +00004808 if_condition_goto_computed(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4809 mkexpr(op4addr));
sewardj2019a972011-03-07 16:04:07 +00004810 }
4811 }
4812
4813 return "clgib";
4814}
4815
florian55085f82012-11-21 00:36:55 +00004816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004817s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4818{
4819 IRTemp op1 = newTemp(Ity_I32);
4820 UInt op2;
sewardj2019a972011-03-07 16:04:07 +00004821 IRTemp cond = newTemp(Ity_I32);
4822
4823 if (m3 == 0) {
4824 } else {
4825 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004826 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004827 } else {
4828 assign(op1, get_gpr_w1(r1));
4829 op2 = (UInt)i2;
florianff9613f2012-05-12 15:26:44 +00004830 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4831 mktemp(Ity_I32, mkU32(op2))));
sewardj2019a972011-03-07 16:04:07 +00004832 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4833 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4834
4835 }
4836 }
4837
4838 return "clij";
4839}
4840
florian55085f82012-11-21 00:36:55 +00004841static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004842s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2)
4843{
4844 IRTemp op1 = newTemp(Ity_I64);
4845 ULong op2;
sewardj2019a972011-03-07 16:04:07 +00004846 IRTemp cond = newTemp(Ity_I32);
4847
4848 if (m3 == 0) {
4849 } else {
4850 if (m3 == 14) {
floriana64c2432011-07-16 02:11:50 +00004851 always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
sewardj2019a972011-03-07 16:04:07 +00004852 } else {
4853 assign(op1, get_gpr_dw0(r1));
4854 op2 = (ULong)i2;
florianff9613f2012-05-12 15:26:44 +00004855 assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1,
4856 mktemp(Ity_I64, mkU64(op2))));
sewardj2019a972011-03-07 16:04:07 +00004857 if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)),
4858 guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1));
4859
4860 }
4861 }
4862
4863 return "clgij";
4864}
4865
florian55085f82012-11-21 00:36:55 +00004866static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004867s390_irgen_CLM(UChar r1, UChar r3, IRTemp op2addr)
4868{
4869 IRTemp op1 = newTemp(Ity_I32);
4870 IRTemp op2 = newTemp(Ity_I32);
4871 IRTemp b0 = newTemp(Ity_I32);
4872 IRTemp b1 = newTemp(Ity_I32);
4873 IRTemp b2 = newTemp(Ity_I32);
4874 IRTemp b3 = newTemp(Ity_I32);
4875 IRTemp c0 = newTemp(Ity_I32);
4876 IRTemp c1 = newTemp(Ity_I32);
4877 IRTemp c2 = newTemp(Ity_I32);
4878 IRTemp c3 = newTemp(Ity_I32);
4879 UChar n;
4880
4881 n = 0;
4882 if ((r3 & 8) != 0) {
4883 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4884 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4885 n = n + 1;
4886 } else {
4887 assign(b0, mkU32(0));
4888 assign(c0, mkU32(0));
4889 }
4890 if ((r3 & 4) != 0) {
4891 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4892 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4893 mkU64(n)))));
4894 n = n + 1;
4895 } else {
4896 assign(b1, mkU32(0));
4897 assign(c1, mkU32(0));
4898 }
4899 if ((r3 & 2) != 0) {
4900 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4901 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4902 mkU64(n)))));
4903 n = n + 1;
4904 } else {
4905 assign(b2, mkU32(0));
4906 assign(c2, mkU32(0));
4907 }
4908 if ((r3 & 1) != 0) {
4909 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4910 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4911 mkU64(n)))));
4912 n = n + 1;
4913 } else {
4914 assign(b3, mkU32(0));
4915 assign(c3, mkU32(0));
4916 }
4917 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4918 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4919 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4920 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4921 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4922 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4923 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4924
4925 return "clm";
4926}
4927
florian55085f82012-11-21 00:36:55 +00004928static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004929s390_irgen_CLMY(UChar r1, UChar r3, IRTemp op2addr)
4930{
4931 IRTemp op1 = newTemp(Ity_I32);
4932 IRTemp op2 = newTemp(Ity_I32);
4933 IRTemp b0 = newTemp(Ity_I32);
4934 IRTemp b1 = newTemp(Ity_I32);
4935 IRTemp b2 = newTemp(Ity_I32);
4936 IRTemp b3 = newTemp(Ity_I32);
4937 IRTemp c0 = newTemp(Ity_I32);
4938 IRTemp c1 = newTemp(Ity_I32);
4939 IRTemp c2 = newTemp(Ity_I32);
4940 IRTemp c3 = newTemp(Ity_I32);
4941 UChar n;
4942
4943 n = 0;
4944 if ((r3 & 8) != 0) {
4945 assign(b0, unop(Iop_8Uto32, get_gpr_b4(r1)));
4946 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
4947 n = n + 1;
4948 } else {
4949 assign(b0, mkU32(0));
4950 assign(c0, mkU32(0));
4951 }
4952 if ((r3 & 4) != 0) {
4953 assign(b1, unop(Iop_8Uto32, get_gpr_b5(r1)));
4954 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4955 mkU64(n)))));
4956 n = n + 1;
4957 } else {
4958 assign(b1, mkU32(0));
4959 assign(c1, mkU32(0));
4960 }
4961 if ((r3 & 2) != 0) {
4962 assign(b2, unop(Iop_8Uto32, get_gpr_b6(r1)));
4963 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4964 mkU64(n)))));
4965 n = n + 1;
4966 } else {
4967 assign(b2, mkU32(0));
4968 assign(c2, mkU32(0));
4969 }
4970 if ((r3 & 1) != 0) {
4971 assign(b3, unop(Iop_8Uto32, get_gpr_b7(r1)));
4972 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
4973 mkU64(n)))));
4974 n = n + 1;
4975 } else {
4976 assign(b3, mkU32(0));
4977 assign(c3, mkU32(0));
4978 }
4979 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4980 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
4981 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
4982 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
4983 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
4984 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
4985 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
4986
4987 return "clmy";
4988}
4989
florian55085f82012-11-21 00:36:55 +00004990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00004991s390_irgen_CLMH(UChar r1, UChar r3, IRTemp op2addr)
4992{
4993 IRTemp op1 = newTemp(Ity_I32);
4994 IRTemp op2 = newTemp(Ity_I32);
4995 IRTemp b0 = newTemp(Ity_I32);
4996 IRTemp b1 = newTemp(Ity_I32);
4997 IRTemp b2 = newTemp(Ity_I32);
4998 IRTemp b3 = newTemp(Ity_I32);
4999 IRTemp c0 = newTemp(Ity_I32);
5000 IRTemp c1 = newTemp(Ity_I32);
5001 IRTemp c2 = newTemp(Ity_I32);
5002 IRTemp c3 = newTemp(Ity_I32);
5003 UChar n;
5004
5005 n = 0;
5006 if ((r3 & 8) != 0) {
5007 assign(b0, unop(Iop_8Uto32, get_gpr_b0(r1)));
5008 assign(c0, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
5009 n = n + 1;
5010 } else {
5011 assign(b0, mkU32(0));
5012 assign(c0, mkU32(0));
5013 }
5014 if ((r3 & 4) != 0) {
5015 assign(b1, unop(Iop_8Uto32, get_gpr_b1(r1)));
5016 assign(c1, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5017 mkU64(n)))));
5018 n = n + 1;
5019 } else {
5020 assign(b1, mkU32(0));
5021 assign(c1, mkU32(0));
5022 }
5023 if ((r3 & 2) != 0) {
5024 assign(b2, unop(Iop_8Uto32, get_gpr_b2(r1)));
5025 assign(c2, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5026 mkU64(n)))));
5027 n = n + 1;
5028 } else {
5029 assign(b2, mkU32(0));
5030 assign(c2, mkU32(0));
5031 }
5032 if ((r3 & 1) != 0) {
5033 assign(b3, unop(Iop_8Uto32, get_gpr_b3(r1)));
5034 assign(c3, unop(Iop_8Uto32, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr),
5035 mkU64(n)))));
5036 n = n + 1;
5037 } else {
5038 assign(b3, mkU32(0));
5039 assign(c3, mkU32(0));
5040 }
5041 assign(op1, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5042 mkexpr(b0), mkU8(24)), binop(Iop_Shl32, mkexpr(b1), mkU8(16))),
5043 binop(Iop_Shl32, mkexpr(b2), mkU8(8))), mkexpr(b3)));
5044 assign(op2, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Or32, binop(Iop_Shl32,
5045 mkexpr(c0), mkU8(24)), binop(Iop_Shl32, mkexpr(c1), mkU8(16))),
5046 binop(Iop_Shl32, mkexpr(c2), mkU8(8))), mkexpr(c3)));
5047 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5048
5049 return "clmh";
5050}
5051
florian55085f82012-11-21 00:36:55 +00005052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005053s390_irgen_CLHHR(UChar r1, UChar r2)
5054{
5055 IRTemp op1 = newTemp(Ity_I32);
5056 IRTemp op2 = newTemp(Ity_I32);
5057
5058 assign(op1, get_gpr_w0(r1));
5059 assign(op2, get_gpr_w0(r2));
5060 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5061
5062 return "clhhr";
5063}
5064
florian55085f82012-11-21 00:36:55 +00005065static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005066s390_irgen_CLHLR(UChar r1, UChar r2)
5067{
5068 IRTemp op1 = newTemp(Ity_I32);
5069 IRTemp op2 = newTemp(Ity_I32);
5070
5071 assign(op1, get_gpr_w0(r1));
5072 assign(op2, get_gpr_w1(r2));
5073 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5074
5075 return "clhlr";
5076}
5077
florian55085f82012-11-21 00:36:55 +00005078static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005079s390_irgen_CLHF(UChar r1, IRTemp op2addr)
5080{
5081 IRTemp op1 = newTemp(Ity_I32);
5082 IRTemp op2 = newTemp(Ity_I32);
5083
5084 assign(op1, get_gpr_w0(r1));
5085 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5086 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2);
5087
5088 return "clhf";
5089}
5090
florian55085f82012-11-21 00:36:55 +00005091static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005092s390_irgen_CLIH(UChar r1, UInt i2)
5093{
5094 IRTemp op1 = newTemp(Ity_I32);
5095 UInt op2;
5096
5097 assign(op1, get_gpr_w0(r1));
5098 op2 = i2;
5099 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, mktemp(Ity_I32,
5100 mkU32(op2)));
5101
5102 return "clih";
5103}
5104
florian55085f82012-11-21 00:36:55 +00005105static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005106s390_irgen_CPYA(UChar r1, UChar r2)
5107{
5108 put_ar_w0(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005109 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005110 s390_disasm(ENC3(MNM, AR, AR), "cpya", r1, r2);
5111
5112 return "cpya";
5113}
5114
florian55085f82012-11-21 00:36:55 +00005115static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005116s390_irgen_XR(UChar r1, UChar r2)
5117{
5118 IRTemp op1 = newTemp(Ity_I32);
5119 IRTemp op2 = newTemp(Ity_I32);
5120 IRTemp result = newTemp(Ity_I32);
5121
5122 if (r1 == r2) {
5123 assign(result, mkU32(0));
5124 } else {
5125 assign(op1, get_gpr_w1(r1));
5126 assign(op2, get_gpr_w1(r2));
5127 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5128 }
5129 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5130 put_gpr_w1(r1, mkexpr(result));
5131
5132 return "xr";
5133}
5134
florian55085f82012-11-21 00:36:55 +00005135static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005136s390_irgen_XGR(UChar r1, UChar r2)
5137{
5138 IRTemp op1 = newTemp(Ity_I64);
5139 IRTemp op2 = newTemp(Ity_I64);
5140 IRTemp result = newTemp(Ity_I64);
5141
5142 if (r1 == r2) {
5143 assign(result, mkU64(0));
5144 } else {
5145 assign(op1, get_gpr_dw0(r1));
5146 assign(op2, get_gpr_dw0(r2));
5147 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5148 }
5149 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5150 put_gpr_dw0(r1, mkexpr(result));
5151
5152 return "xgr";
5153}
5154
florian55085f82012-11-21 00:36:55 +00005155static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005156s390_irgen_XRK(UChar r3, UChar r1, UChar r2)
5157{
5158 IRTemp op2 = newTemp(Ity_I32);
5159 IRTemp op3 = newTemp(Ity_I32);
5160 IRTemp result = newTemp(Ity_I32);
5161
5162 assign(op2, get_gpr_w1(r2));
5163 assign(op3, get_gpr_w1(r3));
5164 assign(result, binop(Iop_Xor32, mkexpr(op2), mkexpr(op3)));
5165 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5166 put_gpr_w1(r1, mkexpr(result));
5167
5168 return "xrk";
5169}
5170
florian55085f82012-11-21 00:36:55 +00005171static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005172s390_irgen_XGRK(UChar r3, UChar r1, UChar r2)
5173{
5174 IRTemp op2 = newTemp(Ity_I64);
5175 IRTemp op3 = newTemp(Ity_I64);
5176 IRTemp result = newTemp(Ity_I64);
5177
5178 assign(op2, get_gpr_dw0(r2));
5179 assign(op3, get_gpr_dw0(r3));
5180 assign(result, binop(Iop_Xor64, mkexpr(op2), mkexpr(op3)));
5181 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5182 put_gpr_dw0(r1, mkexpr(result));
5183
5184 return "xgrk";
5185}
5186
florian55085f82012-11-21 00:36:55 +00005187static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005188s390_irgen_X(UChar r1, IRTemp op2addr)
5189{
5190 IRTemp op1 = newTemp(Ity_I32);
5191 IRTemp op2 = newTemp(Ity_I32);
5192 IRTemp result = newTemp(Ity_I32);
5193
5194 assign(op1, get_gpr_w1(r1));
5195 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5196 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5197 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5198 put_gpr_w1(r1, mkexpr(result));
5199
5200 return "x";
5201}
5202
florian55085f82012-11-21 00:36:55 +00005203static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005204s390_irgen_XY(UChar r1, IRTemp op2addr)
5205{
5206 IRTemp op1 = newTemp(Ity_I32);
5207 IRTemp op2 = newTemp(Ity_I32);
5208 IRTemp result = newTemp(Ity_I32);
5209
5210 assign(op1, get_gpr_w1(r1));
5211 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5212 assign(result, binop(Iop_Xor32, mkexpr(op1), mkexpr(op2)));
5213 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5214 put_gpr_w1(r1, mkexpr(result));
5215
5216 return "xy";
5217}
5218
florian55085f82012-11-21 00:36:55 +00005219static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005220s390_irgen_XG(UChar r1, IRTemp op2addr)
5221{
5222 IRTemp op1 = newTemp(Ity_I64);
5223 IRTemp op2 = newTemp(Ity_I64);
5224 IRTemp result = newTemp(Ity_I64);
5225
5226 assign(op1, get_gpr_dw0(r1));
5227 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5228 assign(result, binop(Iop_Xor64, mkexpr(op1), mkexpr(op2)));
5229 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5230 put_gpr_dw0(r1, mkexpr(result));
5231
5232 return "xg";
5233}
5234
florian55085f82012-11-21 00:36:55 +00005235static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005236s390_irgen_XI(UChar i2, IRTemp op1addr)
5237{
5238 IRTemp op1 = newTemp(Ity_I8);
5239 UChar op2;
5240 IRTemp result = newTemp(Ity_I8);
5241
5242 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5243 op2 = i2;
5244 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5245 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5246 store(mkexpr(op1addr), mkexpr(result));
5247
5248 return "xi";
5249}
5250
florian55085f82012-11-21 00:36:55 +00005251static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005252s390_irgen_XIY(UChar i2, IRTemp op1addr)
5253{
5254 IRTemp op1 = newTemp(Ity_I8);
5255 UChar op2;
5256 IRTemp result = newTemp(Ity_I8);
5257
5258 assign(op1, load(Ity_I8, mkexpr(op1addr)));
5259 op2 = i2;
5260 assign(result, binop(Iop_Xor8, mkexpr(op1), mkU8(op2)));
5261 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5262 store(mkexpr(op1addr), mkexpr(result));
5263
5264 return "xiy";
5265}
5266
florian55085f82012-11-21 00:36:55 +00005267static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005268s390_irgen_XIHF(UChar r1, UInt i2)
5269{
5270 IRTemp op1 = newTemp(Ity_I32);
5271 UInt op2;
5272 IRTemp result = newTemp(Ity_I32);
5273
5274 assign(op1, get_gpr_w0(r1));
5275 op2 = i2;
5276 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5277 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5278 put_gpr_w0(r1, mkexpr(result));
5279
5280 return "xihf";
5281}
5282
florian55085f82012-11-21 00:36:55 +00005283static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005284s390_irgen_XILF(UChar r1, UInt i2)
5285{
5286 IRTemp op1 = newTemp(Ity_I32);
5287 UInt op2;
5288 IRTemp result = newTemp(Ity_I32);
5289
5290 assign(op1, get_gpr_w1(r1));
5291 op2 = i2;
5292 assign(result, binop(Iop_Xor32, mkexpr(op1), mkU32(op2)));
5293 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5294 put_gpr_w1(r1, mkexpr(result));
5295
5296 return "xilf";
5297}
5298
florian55085f82012-11-21 00:36:55 +00005299static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005300s390_irgen_EAR(UChar r1, UChar r2)
5301{
5302 put_gpr_w1(r1, get_ar_w0(r2));
sewardj7ee97522011-05-09 21:45:04 +00005303 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00005304 s390_disasm(ENC3(MNM, GPR, AR), "ear", r1, r2);
5305
5306 return "ear";
5307}
5308
florian55085f82012-11-21 00:36:55 +00005309static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005310s390_irgen_IC(UChar r1, IRTemp op2addr)
5311{
5312 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5313
5314 return "ic";
5315}
5316
florian55085f82012-11-21 00:36:55 +00005317static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005318s390_irgen_ICY(UChar r1, IRTemp op2addr)
5319{
5320 put_gpr_b7(r1, load(Ity_I8, mkexpr(op2addr)));
5321
5322 return "icy";
5323}
5324
florian55085f82012-11-21 00:36:55 +00005325static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005326s390_irgen_ICM(UChar r1, UChar r3, IRTemp op2addr)
5327{
5328 UChar n;
5329 IRTemp result = newTemp(Ity_I32);
5330 UInt mask;
5331
5332 n = 0;
5333 mask = (UInt)r3;
5334 if ((mask & 8) != 0) {
5335 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5336 n = n + 1;
5337 }
5338 if ((mask & 4) != 0) {
5339 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5340
5341 n = n + 1;
5342 }
5343 if ((mask & 2) != 0) {
5344 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5345
5346 n = n + 1;
5347 }
5348 if ((mask & 1) != 0) {
5349 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5350
5351 n = n + 1;
5352 }
5353 assign(result, get_gpr_w1(r1));
5354 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5355 mkU32(mask)));
5356
5357 return "icm";
5358}
5359
florian55085f82012-11-21 00:36:55 +00005360static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005361s390_irgen_ICMY(UChar r1, UChar r3, IRTemp op2addr)
5362{
5363 UChar n;
5364 IRTemp result = newTemp(Ity_I32);
5365 UInt mask;
5366
5367 n = 0;
5368 mask = (UInt)r3;
5369 if ((mask & 8) != 0) {
5370 put_gpr_b4(r1, load(Ity_I8, mkexpr(op2addr)));
5371 n = n + 1;
5372 }
5373 if ((mask & 4) != 0) {
5374 put_gpr_b5(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5375
5376 n = n + 1;
5377 }
5378 if ((mask & 2) != 0) {
5379 put_gpr_b6(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5380
5381 n = n + 1;
5382 }
5383 if ((mask & 1) != 0) {
5384 put_gpr_b7(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5385
5386 n = n + 1;
5387 }
5388 assign(result, get_gpr_w1(r1));
5389 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5390 mkU32(mask)));
5391
5392 return "icmy";
5393}
5394
florian55085f82012-11-21 00:36:55 +00005395static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005396s390_irgen_ICMH(UChar r1, UChar r3, IRTemp op2addr)
5397{
5398 UChar n;
5399 IRTemp result = newTemp(Ity_I32);
5400 UInt mask;
5401
5402 n = 0;
5403 mask = (UInt)r3;
5404 if ((mask & 8) != 0) {
5405 put_gpr_b0(r1, load(Ity_I8, mkexpr(op2addr)));
5406 n = n + 1;
5407 }
5408 if ((mask & 4) != 0) {
5409 put_gpr_b1(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5410
5411 n = n + 1;
5412 }
5413 if ((mask & 2) != 0) {
5414 put_gpr_b2(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5415
5416 n = n + 1;
5417 }
5418 if ((mask & 1) != 0) {
5419 put_gpr_b3(r1, load(Ity_I8, binop(Iop_Add64, mkexpr(op2addr), mkU64(n))));
5420
5421 n = n + 1;
5422 }
5423 assign(result, get_gpr_w0(r1));
5424 s390_cc_thunk_putZZ(S390_CC_OP_INSERT_CHAR_MASK_32, result, mktemp(Ity_I32,
5425 mkU32(mask)));
5426
5427 return "icmh";
5428}
5429
florian55085f82012-11-21 00:36:55 +00005430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005431s390_irgen_IIHF(UChar r1, UInt i2)
5432{
5433 put_gpr_w0(r1, mkU32(i2));
5434
5435 return "iihf";
5436}
5437
florian55085f82012-11-21 00:36:55 +00005438static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005439s390_irgen_IIHH(UChar r1, UShort i2)
5440{
5441 put_gpr_hw0(r1, mkU16(i2));
5442
5443 return "iihh";
5444}
5445
florian55085f82012-11-21 00:36:55 +00005446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005447s390_irgen_IIHL(UChar r1, UShort i2)
5448{
5449 put_gpr_hw1(r1, mkU16(i2));
5450
5451 return "iihl";
5452}
5453
florian55085f82012-11-21 00:36:55 +00005454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005455s390_irgen_IILF(UChar r1, UInt i2)
5456{
5457 put_gpr_w1(r1, mkU32(i2));
5458
5459 return "iilf";
5460}
5461
florian55085f82012-11-21 00:36:55 +00005462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005463s390_irgen_IILH(UChar r1, UShort i2)
5464{
5465 put_gpr_hw2(r1, mkU16(i2));
5466
5467 return "iilh";
5468}
5469
florian55085f82012-11-21 00:36:55 +00005470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005471s390_irgen_IILL(UChar r1, UShort i2)
5472{
5473 put_gpr_hw3(r1, mkU16(i2));
5474
5475 return "iill";
5476}
5477
florian55085f82012-11-21 00:36:55 +00005478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005479s390_irgen_LR(UChar r1, UChar r2)
5480{
5481 put_gpr_w1(r1, get_gpr_w1(r2));
5482
5483 return "lr";
5484}
5485
florian55085f82012-11-21 00:36:55 +00005486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005487s390_irgen_LGR(UChar r1, UChar r2)
5488{
5489 put_gpr_dw0(r1, get_gpr_dw0(r2));
5490
5491 return "lgr";
5492}
5493
florian55085f82012-11-21 00:36:55 +00005494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005495s390_irgen_LGFR(UChar r1, UChar r2)
5496{
5497 put_gpr_dw0(r1, unop(Iop_32Sto64, get_gpr_w1(r2)));
5498
5499 return "lgfr";
5500}
5501
florian55085f82012-11-21 00:36:55 +00005502static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005503s390_irgen_L(UChar r1, IRTemp op2addr)
5504{
5505 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5506
5507 return "l";
5508}
5509
florian55085f82012-11-21 00:36:55 +00005510static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005511s390_irgen_LY(UChar r1, IRTemp op2addr)
5512{
5513 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
5514
5515 return "ly";
5516}
5517
florian55085f82012-11-21 00:36:55 +00005518static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005519s390_irgen_LG(UChar r1, IRTemp op2addr)
5520{
5521 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
5522
5523 return "lg";
5524}
5525
florian55085f82012-11-21 00:36:55 +00005526static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005527s390_irgen_LGF(UChar r1, IRTemp op2addr)
5528{
5529 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5530
5531 return "lgf";
5532}
5533
florian55085f82012-11-21 00:36:55 +00005534static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005535s390_irgen_LGFI(UChar r1, UInt i2)
5536{
5537 put_gpr_dw0(r1, mkU64((ULong)(Long)(Int)i2));
5538
5539 return "lgfi";
5540}
5541
florian55085f82012-11-21 00:36:55 +00005542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005543s390_irgen_LRL(UChar r1, UInt i2)
5544{
5545 put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5546 i2 << 1))));
5547
5548 return "lrl";
5549}
5550
florian55085f82012-11-21 00:36:55 +00005551static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005552s390_irgen_LGRL(UChar r1, UInt i2)
5553{
5554 put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)
5555 i2 << 1))));
5556
5557 return "lgrl";
5558}
5559
florian55085f82012-11-21 00:36:55 +00005560static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005561s390_irgen_LGFRL(UChar r1, UInt i2)
5562{
5563 put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
5564 ((ULong)(Long)(Int)i2 << 1)))));
5565
5566 return "lgfrl";
5567}
5568
florian55085f82012-11-21 00:36:55 +00005569static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005570s390_irgen_LA(UChar r1, IRTemp op2addr)
5571{
5572 put_gpr_dw0(r1, mkexpr(op2addr));
5573
5574 return "la";
5575}
5576
florian55085f82012-11-21 00:36:55 +00005577static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005578s390_irgen_LAY(UChar r1, IRTemp op2addr)
5579{
5580 put_gpr_dw0(r1, mkexpr(op2addr));
5581
5582 return "lay";
5583}
5584
florian55085f82012-11-21 00:36:55 +00005585static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005586s390_irgen_LAE(UChar r1, IRTemp op2addr)
5587{
5588 put_gpr_dw0(r1, mkexpr(op2addr));
5589
5590 return "lae";
5591}
5592
florian55085f82012-11-21 00:36:55 +00005593static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005594s390_irgen_LAEY(UChar r1, IRTemp op2addr)
5595{
5596 put_gpr_dw0(r1, mkexpr(op2addr));
5597
5598 return "laey";
5599}
5600
florian55085f82012-11-21 00:36:55 +00005601static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005602s390_irgen_LARL(UChar r1, UInt i2)
5603{
5604 put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)));
5605
5606 return "larl";
5607}
5608
floriana265ee72012-12-02 20:58:17 +00005609/* The IR representation of LAA and friends is an approximation of what
5610 happens natively. Essentially a loop containing a compare-and-swap is
5611 constructed which will iterate until the CAS succeeds. As a consequence,
5612 instrumenters may see more memory accesses than happen natively. See also
5613 discussion here: https://bugs.kde.org/show_bug.cgi?id=306035 */
florianffc94012012-12-02 21:31:15 +00005614static void
5615s390_irgen_load_and_add32(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
sewardj2019a972011-03-07 16:04:07 +00005616{
floriana265ee72012-12-02 20:58:17 +00005617 IRCAS *cas;
5618 IRTemp old_mem = newTemp(Ity_I32);
sewardj2019a972011-03-07 16:04:07 +00005619 IRTemp op2 = newTemp(Ity_I32);
5620 IRTemp op3 = newTemp(Ity_I32);
5621 IRTemp result = newTemp(Ity_I32);
5622
5623 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5624 assign(op3, get_gpr_w1(r3));
5625 assign(result, binop(Iop_Add32, mkexpr(op2), mkexpr(op3)));
floriana265ee72012-12-02 20:58:17 +00005626
5627 /* Place the addition of second operand and third operand at the
5628 second-operand location everytime */
5629 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5630 Iend_BE, mkexpr(op2addr),
5631 NULL, mkexpr(op2), /* expected value */
5632 NULL, mkexpr(result) /* new value */);
5633 stmt(IRStmt_CAS(cas));
5634
florianffc94012012-12-02 21:31:15 +00005635 /* Set CC according to 32-bit addition */
5636 if (is_signed) {
5637 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_32, op2, op3);
5638 } else {
5639 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_32, op2, op3);
5640 }
floriana265ee72012-12-02 20:58:17 +00005641
5642 /* If old_mem contains the expected value, then the CAS succeeded.
5643 Otherwise, it did not */
5644 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5645 put_gpr_w1(r1, mkexpr(old_mem));
florianffc94012012-12-02 21:31:15 +00005646}
5647
5648static void
5649s390_irgen_load_and_add64(UChar r1, UChar r3, IRTemp op2addr, Bool is_signed)
5650{
5651 IRCAS *cas;
5652 IRTemp old_mem = newTemp(Ity_I64);
5653 IRTemp op2 = newTemp(Ity_I64);
5654 IRTemp op3 = newTemp(Ity_I64);
5655 IRTemp result = newTemp(Ity_I64);
5656
5657 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5658 assign(op3, get_gpr_dw0(r3));
5659 assign(result, binop(Iop_Add64, mkexpr(op2), mkexpr(op3)));
5660
5661 /* Place the addition of second operand and third operand at the
5662 second-operand location everytime */
5663 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5664 Iend_BE, mkexpr(op2addr),
5665 NULL, mkexpr(op2), /* expected value */
5666 NULL, mkexpr(result) /* new value */);
5667 stmt(IRStmt_CAS(cas));
5668
5669 /* Set CC according to 64-bit addition */
5670 if (is_signed) {
5671 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_ADD_64, op2, op3);
5672 } else {
5673 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_ADD_64, op2, op3);
5674 }
5675
5676 /* If old_mem contains the expected value, then the CAS succeeded.
5677 Otherwise, it did not */
5678 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5679 put_gpr_dw0(r1, mkexpr(old_mem));
5680}
5681
5682static void
5683s390_irgen_load_and_bitwise32(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5684{
5685 IRCAS *cas;
5686 IRTemp old_mem = newTemp(Ity_I32);
5687 IRTemp op2 = newTemp(Ity_I32);
5688 IRTemp op3 = newTemp(Ity_I32);
5689 IRTemp result = newTemp(Ity_I32);
5690
5691 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5692 assign(op3, get_gpr_w1(r3));
5693 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5694
5695 /* Place the addition of second operand and third operand at the
5696 second-operand location everytime */
5697 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5698 Iend_BE, mkexpr(op2addr),
5699 NULL, mkexpr(op2), /* expected value */
5700 NULL, mkexpr(result) /* new value */);
5701 stmt(IRStmt_CAS(cas));
5702
5703 /* Set CC according to bitwise operation */
5704 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5705
5706 /* If old_mem contains the expected value, then the CAS succeeded.
5707 Otherwise, it did not */
5708 yield_if(binop(Iop_CmpNE32, mkexpr(old_mem), mkexpr(op2)));
5709 put_gpr_w1(r1, mkexpr(old_mem));
5710}
5711
5712static void
5713s390_irgen_load_and_bitwise64(UChar r1, UChar r3, IRTemp op2addr, IROp op)
5714{
5715 IRCAS *cas;
5716 IRTemp old_mem = newTemp(Ity_I64);
5717 IRTemp op2 = newTemp(Ity_I64);
5718 IRTemp op3 = newTemp(Ity_I64);
5719 IRTemp result = newTemp(Ity_I64);
5720
5721 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5722 assign(op3, get_gpr_dw0(r3));
5723 assign(result, binop(op, mkexpr(op2), mkexpr(op3)));
5724
5725 /* Place the addition of second operand and third operand at the
5726 second-operand location everytime */
5727 cas = mkIRCAS(IRTemp_INVALID, old_mem,
5728 Iend_BE, mkexpr(op2addr),
5729 NULL, mkexpr(op2), /* expected value */
5730 NULL, mkexpr(result) /* new value */);
5731 stmt(IRStmt_CAS(cas));
5732
5733 /* Set CC according to bitwise operation */
5734 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
5735
5736 /* If old_mem contains the expected value, then the CAS succeeded.
5737 Otherwise, it did not */
5738 yield_if(binop(Iop_CmpNE64, mkexpr(old_mem), mkexpr(op2)));
5739 put_gpr_dw0(r1, mkexpr(old_mem));
5740}
5741
5742static const HChar *
5743s390_irgen_LAA(UChar r1, UChar r3, IRTemp op2addr)
5744{
5745 s390_irgen_load_and_add32(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005746
5747 return "laa";
5748}
5749
florian55085f82012-11-21 00:36:55 +00005750static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005751s390_irgen_LAAG(UChar r1, UChar r3, IRTemp op2addr)
5752{
florianffc94012012-12-02 21:31:15 +00005753 s390_irgen_load_and_add64(r1, r3, op2addr, True /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005754
5755 return "laag";
5756}
5757
florian55085f82012-11-21 00:36:55 +00005758static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005759s390_irgen_LAAL(UChar r1, UChar r3, IRTemp op2addr)
5760{
florianffc94012012-12-02 21:31:15 +00005761 s390_irgen_load_and_add32(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005762
5763 return "laal";
5764}
5765
florian55085f82012-11-21 00:36:55 +00005766static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005767s390_irgen_LAALG(UChar r1, UChar r3, IRTemp op2addr)
5768{
florianffc94012012-12-02 21:31:15 +00005769 s390_irgen_load_and_add64(r1, r3, op2addr, False /* is_signed */);
sewardj2019a972011-03-07 16:04:07 +00005770
5771 return "laalg";
5772}
5773
florian55085f82012-11-21 00:36:55 +00005774static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005775s390_irgen_LAN(UChar r1, UChar r3, IRTemp op2addr)
5776{
florianffc94012012-12-02 21:31:15 +00005777 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_And32);
sewardj2019a972011-03-07 16:04:07 +00005778
5779 return "lan";
5780}
5781
florian55085f82012-11-21 00:36:55 +00005782static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005783s390_irgen_LANG(UChar r1, UChar r3, IRTemp op2addr)
5784{
florianffc94012012-12-02 21:31:15 +00005785 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_And64);
sewardj2019a972011-03-07 16:04:07 +00005786
5787 return "lang";
5788}
5789
florian55085f82012-11-21 00:36:55 +00005790static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005791s390_irgen_LAX(UChar r1, UChar r3, IRTemp op2addr)
5792{
florianffc94012012-12-02 21:31:15 +00005793 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Xor32);
sewardj2019a972011-03-07 16:04:07 +00005794
5795 return "lax";
5796}
5797
florian55085f82012-11-21 00:36:55 +00005798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005799s390_irgen_LAXG(UChar r1, UChar r3, IRTemp op2addr)
5800{
florianffc94012012-12-02 21:31:15 +00005801 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Xor64);
sewardj2019a972011-03-07 16:04:07 +00005802
5803 return "laxg";
5804}
5805
florian55085f82012-11-21 00:36:55 +00005806static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005807s390_irgen_LAO(UChar r1, UChar r3, IRTemp op2addr)
5808{
florianffc94012012-12-02 21:31:15 +00005809 s390_irgen_load_and_bitwise32(r1, r3, op2addr, Iop_Or32);
sewardj2019a972011-03-07 16:04:07 +00005810
5811 return "lao";
5812}
5813
florian55085f82012-11-21 00:36:55 +00005814static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005815s390_irgen_LAOG(UChar r1, UChar r3, IRTemp op2addr)
5816{
florianffc94012012-12-02 21:31:15 +00005817 s390_irgen_load_and_bitwise64(r1, r3, op2addr, Iop_Or64);
sewardj2019a972011-03-07 16:04:07 +00005818
5819 return "laog";
5820}
5821
florian55085f82012-11-21 00:36:55 +00005822static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005823s390_irgen_LTR(UChar r1, UChar r2)
5824{
5825 IRTemp op2 = newTemp(Ity_I32);
5826
5827 assign(op2, get_gpr_w1(r2));
5828 put_gpr_w1(r1, mkexpr(op2));
5829 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5830
5831 return "ltr";
5832}
5833
florian55085f82012-11-21 00:36:55 +00005834static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005835s390_irgen_LTGR(UChar r1, UChar r2)
5836{
5837 IRTemp op2 = newTemp(Ity_I64);
5838
5839 assign(op2, get_gpr_dw0(r2));
5840 put_gpr_dw0(r1, mkexpr(op2));
5841 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5842
5843 return "ltgr";
5844}
5845
florian55085f82012-11-21 00:36:55 +00005846static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005847s390_irgen_LTGFR(UChar r1, UChar r2)
5848{
5849 IRTemp op2 = newTemp(Ity_I64);
5850
5851 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5852 put_gpr_dw0(r1, mkexpr(op2));
5853 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5854
5855 return "ltgfr";
5856}
5857
florian55085f82012-11-21 00:36:55 +00005858static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005859s390_irgen_LT(UChar r1, IRTemp op2addr)
5860{
5861 IRTemp op2 = newTemp(Ity_I32);
5862
5863 assign(op2, load(Ity_I32, mkexpr(op2addr)));
5864 put_gpr_w1(r1, mkexpr(op2));
5865 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5866
5867 return "lt";
5868}
5869
florian55085f82012-11-21 00:36:55 +00005870static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005871s390_irgen_LTG(UChar r1, IRTemp op2addr)
5872{
5873 IRTemp op2 = newTemp(Ity_I64);
5874
5875 assign(op2, load(Ity_I64, mkexpr(op2addr)));
5876 put_gpr_dw0(r1, mkexpr(op2));
5877 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5878
5879 return "ltg";
5880}
5881
florian55085f82012-11-21 00:36:55 +00005882static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005883s390_irgen_LTGF(UChar r1, IRTemp op2addr)
5884{
5885 IRTemp op2 = newTemp(Ity_I64);
5886
5887 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
5888 put_gpr_dw0(r1, mkexpr(op2));
5889 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
5890
5891 return "ltgf";
5892}
5893
florian55085f82012-11-21 00:36:55 +00005894static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005895s390_irgen_LBR(UChar r1, UChar r2)
5896{
5897 put_gpr_w1(r1, unop(Iop_8Sto32, get_gpr_b7(r2)));
5898
5899 return "lbr";
5900}
5901
florian55085f82012-11-21 00:36:55 +00005902static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005903s390_irgen_LGBR(UChar r1, UChar r2)
5904{
5905 put_gpr_dw0(r1, unop(Iop_8Sto64, get_gpr_b7(r2)));
5906
5907 return "lgbr";
5908}
5909
florian55085f82012-11-21 00:36:55 +00005910static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005911s390_irgen_LB(UChar r1, IRTemp op2addr)
5912{
5913 put_gpr_w1(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5914
5915 return "lb";
5916}
5917
florian55085f82012-11-21 00:36:55 +00005918static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005919s390_irgen_LGB(UChar r1, IRTemp op2addr)
5920{
5921 put_gpr_dw0(r1, unop(Iop_8Sto64, load(Ity_I8, mkexpr(op2addr))));
5922
5923 return "lgb";
5924}
5925
florian55085f82012-11-21 00:36:55 +00005926static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005927s390_irgen_LBH(UChar r1, IRTemp op2addr)
5928{
5929 put_gpr_w0(r1, unop(Iop_8Sto32, load(Ity_I8, mkexpr(op2addr))));
5930
5931 return "lbh";
5932}
5933
florian55085f82012-11-21 00:36:55 +00005934static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005935s390_irgen_LCR(UChar r1, UChar r2)
5936{
5937 Int op1;
5938 IRTemp op2 = newTemp(Ity_I32);
5939 IRTemp result = newTemp(Ity_I32);
5940
5941 op1 = 0;
5942 assign(op2, get_gpr_w1(r2));
5943 assign(result, binop(Iop_Sub32, mkU32((UInt)op1), mkexpr(op2)));
5944 put_gpr_w1(r1, mkexpr(result));
5945 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, mktemp(Ity_I32, mkU32((UInt)
5946 op1)), op2);
5947
5948 return "lcr";
5949}
5950
florian55085f82012-11-21 00:36:55 +00005951static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005952s390_irgen_LCGR(UChar r1, UChar r2)
5953{
5954 Long op1;
5955 IRTemp op2 = newTemp(Ity_I64);
5956 IRTemp result = newTemp(Ity_I64);
5957
5958 op1 = 0ULL;
5959 assign(op2, get_gpr_dw0(r2));
5960 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5961 put_gpr_dw0(r1, mkexpr(result));
5962 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5963 op1)), op2);
5964
5965 return "lcgr";
5966}
5967
florian55085f82012-11-21 00:36:55 +00005968static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005969s390_irgen_LCGFR(UChar r1, UChar r2)
5970{
5971 Long op1;
5972 IRTemp op2 = newTemp(Ity_I64);
5973 IRTemp result = newTemp(Ity_I64);
5974
5975 op1 = 0ULL;
5976 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
5977 assign(result, binop(Iop_Sub64, mkU64((ULong)op1), mkexpr(op2)));
5978 put_gpr_dw0(r1, mkexpr(result));
5979 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, mktemp(Ity_I64, mkU64((ULong)
5980 op1)), op2);
5981
5982 return "lcgfr";
5983}
5984
florian55085f82012-11-21 00:36:55 +00005985static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005986s390_irgen_LHR(UChar r1, UChar r2)
5987{
5988 put_gpr_w1(r1, unop(Iop_16Sto32, get_gpr_hw3(r2)));
5989
5990 return "lhr";
5991}
5992
florian55085f82012-11-21 00:36:55 +00005993static const HChar *
sewardj2019a972011-03-07 16:04:07 +00005994s390_irgen_LGHR(UChar r1, UChar r2)
5995{
5996 put_gpr_dw0(r1, unop(Iop_16Sto64, get_gpr_hw3(r2)));
5997
5998 return "lghr";
5999}
6000
florian55085f82012-11-21 00:36:55 +00006001static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006002s390_irgen_LH(UChar r1, IRTemp op2addr)
6003{
6004 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6005
6006 return "lh";
6007}
6008
florian55085f82012-11-21 00:36:55 +00006009static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006010s390_irgen_LHY(UChar r1, IRTemp op2addr)
6011{
6012 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6013
6014 return "lhy";
6015}
6016
florian55085f82012-11-21 00:36:55 +00006017static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006018s390_irgen_LGH(UChar r1, IRTemp op2addr)
6019{
6020 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkexpr(op2addr))));
6021
6022 return "lgh";
6023}
6024
florian55085f82012-11-21 00:36:55 +00006025static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006026s390_irgen_LHI(UChar r1, UShort i2)
6027{
6028 put_gpr_w1(r1, mkU32((UInt)(Int)(Short)i2));
6029
6030 return "lhi";
6031}
6032
florian55085f82012-11-21 00:36:55 +00006033static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006034s390_irgen_LGHI(UChar r1, UShort i2)
6035{
6036 put_gpr_dw0(r1, mkU64((ULong)(Long)(Short)i2));
6037
6038 return "lghi";
6039}
6040
florian55085f82012-11-21 00:36:55 +00006041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006042s390_irgen_LHRL(UChar r1, UInt i2)
6043{
6044 put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6045 ((ULong)(Long)(Int)i2 << 1)))));
6046
6047 return "lhrl";
6048}
6049
florian55085f82012-11-21 00:36:55 +00006050static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006051s390_irgen_LGHRL(UChar r1, UInt i2)
6052{
6053 put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6054 ((ULong)(Long)(Int)i2 << 1)))));
6055
6056 return "lghrl";
6057}
6058
florian55085f82012-11-21 00:36:55 +00006059static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006060s390_irgen_LHH(UChar r1, IRTemp op2addr)
6061{
6062 put_gpr_w0(r1, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
6063
6064 return "lhh";
6065}
6066
florian55085f82012-11-21 00:36:55 +00006067static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006068s390_irgen_LFH(UChar r1, IRTemp op2addr)
6069{
6070 put_gpr_w0(r1, load(Ity_I32, mkexpr(op2addr)));
6071
6072 return "lfh";
6073}
6074
florian55085f82012-11-21 00:36:55 +00006075static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006076s390_irgen_LLGFR(UChar r1, UChar r2)
6077{
6078 put_gpr_dw0(r1, unop(Iop_32Uto64, get_gpr_w1(r2)));
6079
6080 return "llgfr";
6081}
6082
florian55085f82012-11-21 00:36:55 +00006083static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006084s390_irgen_LLGF(UChar r1, IRTemp op2addr)
6085{
6086 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
6087
6088 return "llgf";
6089}
6090
florian55085f82012-11-21 00:36:55 +00006091static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006092s390_irgen_LLGFRL(UChar r1, UInt i2)
6093{
6094 put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr +
6095 ((ULong)(Long)(Int)i2 << 1)))));
6096
6097 return "llgfrl";
6098}
6099
florian55085f82012-11-21 00:36:55 +00006100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006101s390_irgen_LLCR(UChar r1, UChar r2)
6102{
6103 put_gpr_w1(r1, unop(Iop_8Uto32, get_gpr_b7(r2)));
6104
6105 return "llcr";
6106}
6107
florian55085f82012-11-21 00:36:55 +00006108static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006109s390_irgen_LLGCR(UChar r1, UChar r2)
6110{
6111 put_gpr_dw0(r1, unop(Iop_8Uto64, get_gpr_b7(r2)));
6112
6113 return "llgcr";
6114}
6115
florian55085f82012-11-21 00:36:55 +00006116static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006117s390_irgen_LLC(UChar r1, IRTemp op2addr)
6118{
6119 put_gpr_w1(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6120
6121 return "llc";
6122}
6123
florian55085f82012-11-21 00:36:55 +00006124static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006125s390_irgen_LLGC(UChar r1, IRTemp op2addr)
6126{
6127 put_gpr_dw0(r1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(op2addr))));
6128
6129 return "llgc";
6130}
6131
florian55085f82012-11-21 00:36:55 +00006132static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006133s390_irgen_LLCH(UChar r1, IRTemp op2addr)
6134{
6135 put_gpr_w0(r1, unop(Iop_8Uto32, load(Ity_I8, mkexpr(op2addr))));
6136
6137 return "llch";
6138}
6139
florian55085f82012-11-21 00:36:55 +00006140static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006141s390_irgen_LLHR(UChar r1, UChar r2)
6142{
6143 put_gpr_w1(r1, unop(Iop_16Uto32, get_gpr_hw3(r2)));
6144
6145 return "llhr";
6146}
6147
florian55085f82012-11-21 00:36:55 +00006148static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006149s390_irgen_LLGHR(UChar r1, UChar r2)
6150{
6151 put_gpr_dw0(r1, unop(Iop_16Uto64, get_gpr_hw3(r2)));
6152
6153 return "llghr";
6154}
6155
florian55085f82012-11-21 00:36:55 +00006156static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006157s390_irgen_LLH(UChar r1, IRTemp op2addr)
6158{
6159 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6160
6161 return "llh";
6162}
6163
florian55085f82012-11-21 00:36:55 +00006164static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006165s390_irgen_LLGH(UChar r1, IRTemp op2addr)
6166{
6167 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkexpr(op2addr))));
6168
6169 return "llgh";
6170}
6171
florian55085f82012-11-21 00:36:55 +00006172static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006173s390_irgen_LLHRL(UChar r1, UInt i2)
6174{
6175 put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr +
6176 ((ULong)(Long)(Int)i2 << 1)))));
6177
6178 return "llhrl";
6179}
6180
florian55085f82012-11-21 00:36:55 +00006181static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006182s390_irgen_LLGHRL(UChar r1, UInt i2)
6183{
6184 put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr +
6185 ((ULong)(Long)(Int)i2 << 1)))));
6186
6187 return "llghrl";
6188}
6189
florian55085f82012-11-21 00:36:55 +00006190static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006191s390_irgen_LLHH(UChar r1, IRTemp op2addr)
6192{
6193 put_gpr_w0(r1, unop(Iop_16Uto32, load(Ity_I16, mkexpr(op2addr))));
6194
6195 return "llhh";
6196}
6197
florian55085f82012-11-21 00:36:55 +00006198static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006199s390_irgen_LLIHF(UChar r1, UInt i2)
6200{
6201 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6202
6203 return "llihf";
6204}
6205
florian55085f82012-11-21 00:36:55 +00006206static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006207s390_irgen_LLIHH(UChar r1, UShort i2)
6208{
6209 put_gpr_dw0(r1, mkU64(((ULong)i2) << 48));
6210
6211 return "llihh";
6212}
6213
florian55085f82012-11-21 00:36:55 +00006214static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006215s390_irgen_LLIHL(UChar r1, UShort i2)
6216{
6217 put_gpr_dw0(r1, mkU64(((ULong)i2) << 32));
6218
6219 return "llihl";
6220}
6221
florian55085f82012-11-21 00:36:55 +00006222static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006223s390_irgen_LLILF(UChar r1, UInt i2)
6224{
6225 put_gpr_dw0(r1, mkU64(i2));
6226
6227 return "llilf";
6228}
6229
florian55085f82012-11-21 00:36:55 +00006230static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006231s390_irgen_LLILH(UChar r1, UShort i2)
6232{
6233 put_gpr_dw0(r1, mkU64(((ULong)i2) << 16));
6234
6235 return "llilh";
6236}
6237
florian55085f82012-11-21 00:36:55 +00006238static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006239s390_irgen_LLILL(UChar r1, UShort i2)
6240{
6241 put_gpr_dw0(r1, mkU64(i2));
6242
6243 return "llill";
6244}
6245
florian55085f82012-11-21 00:36:55 +00006246static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006247s390_irgen_LLGTR(UChar r1, UChar r2)
6248{
6249 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, get_gpr_w1(r2),
6250 mkU32(2147483647))));
6251
6252 return "llgtr";
6253}
6254
florian55085f82012-11-21 00:36:55 +00006255static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006256s390_irgen_LLGT(UChar r1, IRTemp op2addr)
6257{
6258 put_gpr_dw0(r1, unop(Iop_32Uto64, binop(Iop_And32, load(Ity_I32,
6259 mkexpr(op2addr)), mkU32(2147483647))));
6260
6261 return "llgt";
6262}
6263
florian55085f82012-11-21 00:36:55 +00006264static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006265s390_irgen_LNR(UChar r1, UChar r2)
6266{
6267 IRTemp op2 = newTemp(Ity_I32);
6268 IRTemp result = newTemp(Ity_I32);
6269
6270 assign(op2, get_gpr_w1(r2));
6271 assign(result, mkite(binop(Iop_CmpLE32S, mkexpr(op2), mkU32(0)), mkexpr(op2),
6272 binop(Iop_Sub32, mkU32(0), mkexpr(op2))));
6273 put_gpr_w1(r1, mkexpr(result));
6274 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6275
6276 return "lnr";
6277}
6278
florian55085f82012-11-21 00:36:55 +00006279static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006280s390_irgen_LNGR(UChar r1, UChar r2)
6281{
6282 IRTemp op2 = newTemp(Ity_I64);
6283 IRTemp result = newTemp(Ity_I64);
6284
6285 assign(op2, get_gpr_dw0(r2));
6286 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6287 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6288 put_gpr_dw0(r1, mkexpr(result));
6289 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6290
6291 return "lngr";
6292}
6293
florian55085f82012-11-21 00:36:55 +00006294static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006295s390_irgen_LNGFR(UChar r1, UChar r2 __attribute__((unused)))
6296{
6297 IRTemp op2 = newTemp(Ity_I64);
6298 IRTemp result = newTemp(Ity_I64);
6299
6300 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r1)));
6301 assign(result, mkite(binop(Iop_CmpLE64S, mkexpr(op2), mkU64(0)), mkexpr(op2),
6302 binop(Iop_Sub64, mkU64(0), mkexpr(op2))));
6303 put_gpr_dw0(r1, mkexpr(result));
6304 s390_cc_thunk_putS(S390_CC_OP_BITWISE, result);
6305
6306 return "lngfr";
6307}
6308
florian55085f82012-11-21 00:36:55 +00006309static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006310s390_irgen_LOCR(UChar m3, UChar r1, UChar r2)
6311{
florian6820ba52012-07-26 02:01:50 +00006312 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006313 put_gpr_w1(r1, get_gpr_w1(r2));
6314
6315 return "locr";
6316}
6317
florian55085f82012-11-21 00:36:55 +00006318static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006319s390_irgen_LOCGR(UChar m3, UChar r1, UChar r2)
6320{
florian6820ba52012-07-26 02:01:50 +00006321 next_insn_if(binop(Iop_CmpEQ32, s390_call_calculate_cond(m3), mkU32(0)));
sewardjd7bde722011-04-05 13:19:33 +00006322 put_gpr_dw0(r1, get_gpr_dw0(r2));
6323
6324 return "locgr";
6325}
6326
florian55085f82012-11-21 00:36:55 +00006327static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006328s390_irgen_LOC(UChar r1, IRTemp op2addr)
6329{
6330 /* condition is checked in format handler */
6331 put_gpr_w1(r1, load(Ity_I32, mkexpr(op2addr)));
6332
6333 return "loc";
6334}
6335
florian55085f82012-11-21 00:36:55 +00006336static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00006337s390_irgen_LOCG(UChar r1, IRTemp op2addr)
6338{
6339 /* condition is checked in format handler */
6340 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6341
6342 return "locg";
6343}
6344
florian55085f82012-11-21 00:36:55 +00006345static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006346s390_irgen_LPQ(UChar r1, IRTemp op2addr)
6347{
6348 put_gpr_dw0(r1, load(Ity_I64, mkexpr(op2addr)));
6349 put_gpr_dw0(r1 + 1, load(Ity_I64, binop(Iop_Add64, mkexpr(op2addr), mkU64(8))
6350 ));
6351
6352 return "lpq";
6353}
6354
florian55085f82012-11-21 00:36:55 +00006355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006356s390_irgen_LPR(UChar r1, UChar r2)
6357{
6358 IRTemp op2 = newTemp(Ity_I32);
6359 IRTemp result = newTemp(Ity_I32);
6360
6361 assign(op2, get_gpr_w1(r2));
6362 assign(result, mkite(binop(Iop_CmpLT32S, mkexpr(op2), mkU32(0)),
6363 binop(Iop_Sub32, mkU32(0), mkexpr(op2)), mkexpr(op2)));
6364 put_gpr_w1(r1, mkexpr(result));
6365 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_32, op2);
6366
6367 return "lpr";
6368}
6369
florian55085f82012-11-21 00:36:55 +00006370static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006371s390_irgen_LPGR(UChar r1, UChar r2)
6372{
6373 IRTemp op2 = newTemp(Ity_I64);
6374 IRTemp result = newTemp(Ity_I64);
6375
6376 assign(op2, get_gpr_dw0(r2));
6377 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6378 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6379 put_gpr_dw0(r1, mkexpr(result));
6380 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6381
6382 return "lpgr";
6383}
6384
florian55085f82012-11-21 00:36:55 +00006385static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006386s390_irgen_LPGFR(UChar r1, UChar r2)
6387{
6388 IRTemp op2 = newTemp(Ity_I64);
6389 IRTemp result = newTemp(Ity_I64);
6390
6391 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
6392 assign(result, mkite(binop(Iop_CmpLT64S, mkexpr(op2), mkU64(0)),
6393 binop(Iop_Sub64, mkU64(0), mkexpr(op2)), mkexpr(op2)));
6394 put_gpr_dw0(r1, mkexpr(result));
6395 s390_cc_thunk_putS(S390_CC_OP_LOAD_POSITIVE_64, op2);
6396
6397 return "lpgfr";
6398}
6399
florian55085f82012-11-21 00:36:55 +00006400static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006401s390_irgen_LRVR(UChar r1, UChar r2)
6402{
6403 IRTemp b0 = newTemp(Ity_I8);
6404 IRTemp b1 = newTemp(Ity_I8);
6405 IRTemp b2 = newTemp(Ity_I8);
6406 IRTemp b3 = newTemp(Ity_I8);
6407
6408 assign(b3, get_gpr_b7(r2));
6409 assign(b2, get_gpr_b6(r2));
6410 assign(b1, get_gpr_b5(r2));
6411 assign(b0, get_gpr_b4(r2));
6412 put_gpr_b4(r1, mkexpr(b3));
6413 put_gpr_b5(r1, mkexpr(b2));
6414 put_gpr_b6(r1, mkexpr(b1));
6415 put_gpr_b7(r1, mkexpr(b0));
6416
6417 return "lrvr";
6418}
6419
florian55085f82012-11-21 00:36:55 +00006420static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006421s390_irgen_LRVGR(UChar r1, UChar r2)
6422{
6423 IRTemp b0 = newTemp(Ity_I8);
6424 IRTemp b1 = newTemp(Ity_I8);
6425 IRTemp b2 = newTemp(Ity_I8);
6426 IRTemp b3 = newTemp(Ity_I8);
6427 IRTemp b4 = newTemp(Ity_I8);
6428 IRTemp b5 = newTemp(Ity_I8);
6429 IRTemp b6 = newTemp(Ity_I8);
6430 IRTemp b7 = newTemp(Ity_I8);
6431
6432 assign(b7, get_gpr_b7(r2));
6433 assign(b6, get_gpr_b6(r2));
6434 assign(b5, get_gpr_b5(r2));
6435 assign(b4, get_gpr_b4(r2));
6436 assign(b3, get_gpr_b3(r2));
6437 assign(b2, get_gpr_b2(r2));
6438 assign(b1, get_gpr_b1(r2));
6439 assign(b0, get_gpr_b0(r2));
6440 put_gpr_b0(r1, mkexpr(b7));
6441 put_gpr_b1(r1, mkexpr(b6));
6442 put_gpr_b2(r1, mkexpr(b5));
6443 put_gpr_b3(r1, mkexpr(b4));
6444 put_gpr_b4(r1, mkexpr(b3));
6445 put_gpr_b5(r1, mkexpr(b2));
6446 put_gpr_b6(r1, mkexpr(b1));
6447 put_gpr_b7(r1, mkexpr(b0));
6448
6449 return "lrvgr";
6450}
6451
florian55085f82012-11-21 00:36:55 +00006452static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006453s390_irgen_LRVH(UChar r1, IRTemp op2addr)
6454{
6455 IRTemp op2 = newTemp(Ity_I16);
6456
6457 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6458 put_gpr_b6(r1, unop(Iop_16to8, mkexpr(op2)));
6459 put_gpr_b7(r1, unop(Iop_16HIto8, mkexpr(op2)));
6460
6461 return "lrvh";
6462}
6463
florian55085f82012-11-21 00:36:55 +00006464static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006465s390_irgen_LRV(UChar r1, IRTemp op2addr)
6466{
6467 IRTemp op2 = newTemp(Ity_I32);
6468
6469 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6470 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_And32, mkexpr(op2), mkU32(255))));
6471 put_gpr_b5(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6472 mkU8(8)), mkU32(255))));
6473 put_gpr_b6(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6474 mkU8(16)), mkU32(255))));
6475 put_gpr_b7(r1, unop(Iop_32to8, binop(Iop_And32, binop(Iop_Shr32, mkexpr(op2),
6476 mkU8(24)), mkU32(255))));
6477
6478 return "lrv";
6479}
6480
florian55085f82012-11-21 00:36:55 +00006481static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006482s390_irgen_LRVG(UChar r1, IRTemp op2addr)
6483{
6484 IRTemp op2 = newTemp(Ity_I64);
6485
6486 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6487 put_gpr_b0(r1, unop(Iop_64to8, binop(Iop_And64, mkexpr(op2), mkU64(255))));
6488 put_gpr_b1(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6489 mkU8(8)), mkU64(255))));
6490 put_gpr_b2(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6491 mkU8(16)), mkU64(255))));
6492 put_gpr_b3(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6493 mkU8(24)), mkU64(255))));
6494 put_gpr_b4(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6495 mkU8(32)), mkU64(255))));
6496 put_gpr_b5(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6497 mkU8(40)), mkU64(255))));
6498 put_gpr_b6(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6499 mkU8(48)), mkU64(255))));
6500 put_gpr_b7(r1, unop(Iop_64to8, binop(Iop_And64, binop(Iop_Shr64, mkexpr(op2),
6501 mkU8(56)), mkU64(255))));
6502
6503 return "lrvg";
6504}
6505
florian55085f82012-11-21 00:36:55 +00006506static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006507s390_irgen_MVHHI(UShort i2, IRTemp op1addr)
6508{
6509 store(mkexpr(op1addr), mkU16(i2));
6510
6511 return "mvhhi";
6512}
6513
florian55085f82012-11-21 00:36:55 +00006514static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006515s390_irgen_MVHI(UShort i2, IRTemp op1addr)
6516{
6517 store(mkexpr(op1addr), mkU32((UInt)(Int)(Short)i2));
6518
6519 return "mvhi";
6520}
6521
florian55085f82012-11-21 00:36:55 +00006522static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006523s390_irgen_MVGHI(UShort i2, IRTemp op1addr)
6524{
6525 store(mkexpr(op1addr), mkU64((ULong)(Long)(Short)i2));
6526
6527 return "mvghi";
6528}
6529
florian55085f82012-11-21 00:36:55 +00006530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006531s390_irgen_MVI(UChar i2, IRTemp op1addr)
6532{
6533 store(mkexpr(op1addr), mkU8(i2));
6534
6535 return "mvi";
6536}
6537
florian55085f82012-11-21 00:36:55 +00006538static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006539s390_irgen_MVIY(UChar i2, IRTemp op1addr)
6540{
6541 store(mkexpr(op1addr), mkU8(i2));
6542
6543 return "mviy";
6544}
6545
florian55085f82012-11-21 00:36:55 +00006546static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006547s390_irgen_MR(UChar r1, UChar r2)
6548{
6549 IRTemp op1 = newTemp(Ity_I32);
6550 IRTemp op2 = newTemp(Ity_I32);
6551 IRTemp result = newTemp(Ity_I64);
6552
6553 assign(op1, get_gpr_w1(r1 + 1));
6554 assign(op2, get_gpr_w1(r2));
6555 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6556 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6557 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6558
6559 return "mr";
6560}
6561
florian55085f82012-11-21 00:36:55 +00006562static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006563s390_irgen_M(UChar r1, IRTemp op2addr)
6564{
6565 IRTemp op1 = newTemp(Ity_I32);
6566 IRTemp op2 = newTemp(Ity_I32);
6567 IRTemp result = newTemp(Ity_I64);
6568
6569 assign(op1, get_gpr_w1(r1 + 1));
6570 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6571 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6572 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6573 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6574
6575 return "m";
6576}
6577
florian55085f82012-11-21 00:36:55 +00006578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006579s390_irgen_MFY(UChar r1, IRTemp op2addr)
6580{
6581 IRTemp op1 = newTemp(Ity_I32);
6582 IRTemp op2 = newTemp(Ity_I32);
6583 IRTemp result = newTemp(Ity_I64);
6584
6585 assign(op1, get_gpr_w1(r1 + 1));
6586 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6587 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6588 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6589 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6590
6591 return "mfy";
6592}
6593
florian55085f82012-11-21 00:36:55 +00006594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006595s390_irgen_MH(UChar r1, IRTemp op2addr)
6596{
6597 IRTemp op1 = newTemp(Ity_I32);
6598 IRTemp op2 = newTemp(Ity_I16);
6599 IRTemp result = newTemp(Ity_I64);
6600
6601 assign(op1, get_gpr_w1(r1));
6602 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6603 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6604 ));
6605 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6606
6607 return "mh";
6608}
6609
florian55085f82012-11-21 00:36:55 +00006610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006611s390_irgen_MHY(UChar r1, IRTemp op2addr)
6612{
6613 IRTemp op1 = newTemp(Ity_I32);
6614 IRTemp op2 = newTemp(Ity_I16);
6615 IRTemp result = newTemp(Ity_I64);
6616
6617 assign(op1, get_gpr_w1(r1));
6618 assign(op2, load(Ity_I16, mkexpr(op2addr)));
6619 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32, mkexpr(op2))
6620 ));
6621 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6622
6623 return "mhy";
6624}
6625
florian55085f82012-11-21 00:36:55 +00006626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006627s390_irgen_MHI(UChar r1, UShort i2)
6628{
6629 IRTemp op1 = newTemp(Ity_I32);
6630 Short op2;
6631 IRTemp result = newTemp(Ity_I64);
6632
6633 assign(op1, get_gpr_w1(r1));
6634 op2 = (Short)i2;
6635 assign(result, binop(Iop_MullS32, mkexpr(op1), unop(Iop_16Sto32,
6636 mkU16((UShort)op2))));
6637 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6638
6639 return "mhi";
6640}
6641
florian55085f82012-11-21 00:36:55 +00006642static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006643s390_irgen_MGHI(UChar r1, UShort i2)
6644{
6645 IRTemp op1 = newTemp(Ity_I64);
6646 Short op2;
6647 IRTemp result = newTemp(Ity_I128);
6648
6649 assign(op1, get_gpr_dw0(r1));
6650 op2 = (Short)i2;
6651 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_16Sto64,
6652 mkU16((UShort)op2))));
6653 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6654
6655 return "mghi";
6656}
6657
florian55085f82012-11-21 00:36:55 +00006658static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006659s390_irgen_MLR(UChar r1, UChar r2)
6660{
6661 IRTemp op1 = newTemp(Ity_I32);
6662 IRTemp op2 = newTemp(Ity_I32);
6663 IRTemp result = newTemp(Ity_I64);
6664
6665 assign(op1, get_gpr_w1(r1 + 1));
6666 assign(op2, get_gpr_w1(r2));
6667 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6668 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6669 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6670
6671 return "mlr";
6672}
6673
florian55085f82012-11-21 00:36:55 +00006674static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006675s390_irgen_MLGR(UChar r1, UChar r2)
6676{
6677 IRTemp op1 = newTemp(Ity_I64);
6678 IRTemp op2 = newTemp(Ity_I64);
6679 IRTemp result = newTemp(Ity_I128);
6680
6681 assign(op1, get_gpr_dw0(r1 + 1));
6682 assign(op2, get_gpr_dw0(r2));
6683 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6684 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6685 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6686
6687 return "mlgr";
6688}
6689
florian55085f82012-11-21 00:36:55 +00006690static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006691s390_irgen_ML(UChar r1, IRTemp op2addr)
6692{
6693 IRTemp op1 = newTemp(Ity_I32);
6694 IRTemp op2 = newTemp(Ity_I32);
6695 IRTemp result = newTemp(Ity_I64);
6696
6697 assign(op1, get_gpr_w1(r1 + 1));
6698 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6699 assign(result, binop(Iop_MullU32, mkexpr(op1), mkexpr(op2)));
6700 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
6701 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
6702
6703 return "ml";
6704}
6705
florian55085f82012-11-21 00:36:55 +00006706static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006707s390_irgen_MLG(UChar r1, IRTemp op2addr)
6708{
6709 IRTemp op1 = newTemp(Ity_I64);
6710 IRTemp op2 = newTemp(Ity_I64);
6711 IRTemp result = newTemp(Ity_I128);
6712
6713 assign(op1, get_gpr_dw0(r1 + 1));
6714 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6715 assign(result, binop(Iop_MullU64, mkexpr(op1), mkexpr(op2)));
6716 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result)));
6717 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result)));
6718
6719 return "mlg";
6720}
6721
florian55085f82012-11-21 00:36:55 +00006722static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006723s390_irgen_MSR(UChar r1, UChar r2)
6724{
6725 IRTemp op1 = newTemp(Ity_I32);
6726 IRTemp op2 = newTemp(Ity_I32);
6727 IRTemp result = newTemp(Ity_I64);
6728
6729 assign(op1, get_gpr_w1(r1));
6730 assign(op2, get_gpr_w1(r2));
6731 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6732 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6733
6734 return "msr";
6735}
6736
florian55085f82012-11-21 00:36:55 +00006737static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006738s390_irgen_MSGR(UChar r1, UChar r2)
6739{
6740 IRTemp op1 = newTemp(Ity_I64);
6741 IRTemp op2 = newTemp(Ity_I64);
6742 IRTemp result = newTemp(Ity_I128);
6743
6744 assign(op1, get_gpr_dw0(r1));
6745 assign(op2, get_gpr_dw0(r2));
6746 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6747 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6748
6749 return "msgr";
6750}
6751
florian55085f82012-11-21 00:36:55 +00006752static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006753s390_irgen_MSGFR(UChar r1, UChar r2)
6754{
6755 IRTemp op1 = newTemp(Ity_I64);
6756 IRTemp op2 = newTemp(Ity_I32);
6757 IRTemp result = newTemp(Ity_I128);
6758
6759 assign(op1, get_gpr_dw0(r1));
6760 assign(op2, get_gpr_w1(r2));
6761 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6762 ));
6763 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6764
6765 return "msgfr";
6766}
6767
florian55085f82012-11-21 00:36:55 +00006768static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006769s390_irgen_MS(UChar r1, IRTemp op2addr)
6770{
6771 IRTemp op1 = newTemp(Ity_I32);
6772 IRTemp op2 = newTemp(Ity_I32);
6773 IRTemp result = newTemp(Ity_I64);
6774
6775 assign(op1, get_gpr_w1(r1));
6776 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6777 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6778 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6779
6780 return "ms";
6781}
6782
florian55085f82012-11-21 00:36:55 +00006783static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006784s390_irgen_MSY(UChar r1, IRTemp op2addr)
6785{
6786 IRTemp op1 = newTemp(Ity_I32);
6787 IRTemp op2 = newTemp(Ity_I32);
6788 IRTemp result = newTemp(Ity_I64);
6789
6790 assign(op1, get_gpr_w1(r1));
6791 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6792 assign(result, binop(Iop_MullS32, mkexpr(op1), mkexpr(op2)));
6793 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6794
6795 return "msy";
6796}
6797
florian55085f82012-11-21 00:36:55 +00006798static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006799s390_irgen_MSG(UChar r1, IRTemp op2addr)
6800{
6801 IRTemp op1 = newTemp(Ity_I64);
6802 IRTemp op2 = newTemp(Ity_I64);
6803 IRTemp result = newTemp(Ity_I128);
6804
6805 assign(op1, get_gpr_dw0(r1));
6806 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6807 assign(result, binop(Iop_MullS64, mkexpr(op1), mkexpr(op2)));
6808 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6809
6810 return "msg";
6811}
6812
florian55085f82012-11-21 00:36:55 +00006813static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006814s390_irgen_MSGF(UChar r1, IRTemp op2addr)
6815{
6816 IRTemp op1 = newTemp(Ity_I64);
6817 IRTemp op2 = newTemp(Ity_I32);
6818 IRTemp result = newTemp(Ity_I128);
6819
6820 assign(op1, get_gpr_dw0(r1));
6821 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6822 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkexpr(op2))
6823 ));
6824 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6825
6826 return "msgf";
6827}
6828
florian55085f82012-11-21 00:36:55 +00006829static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006830s390_irgen_MSFI(UChar r1, UInt i2)
6831{
6832 IRTemp op1 = newTemp(Ity_I32);
6833 Int op2;
6834 IRTemp result = newTemp(Ity_I64);
6835
6836 assign(op1, get_gpr_w1(r1));
6837 op2 = (Int)i2;
6838 assign(result, binop(Iop_MullS32, mkexpr(op1), mkU32((UInt)op2)));
6839 put_gpr_w1(r1, unop(Iop_64to32, mkexpr(result)));
6840
6841 return "msfi";
6842}
6843
florian55085f82012-11-21 00:36:55 +00006844static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006845s390_irgen_MSGFI(UChar r1, UInt i2)
6846{
6847 IRTemp op1 = newTemp(Ity_I64);
6848 Int op2;
6849 IRTemp result = newTemp(Ity_I128);
6850
6851 assign(op1, get_gpr_dw0(r1));
6852 op2 = (Int)i2;
6853 assign(result, binop(Iop_MullS64, mkexpr(op1), unop(Iop_32Sto64, mkU32((UInt)
6854 op2))));
6855 put_gpr_dw0(r1, unop(Iop_128to64, mkexpr(result)));
6856
6857 return "msgfi";
6858}
6859
florian55085f82012-11-21 00:36:55 +00006860static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006861s390_irgen_OR(UChar r1, UChar r2)
6862{
6863 IRTemp op1 = newTemp(Ity_I32);
6864 IRTemp op2 = newTemp(Ity_I32);
6865 IRTemp result = newTemp(Ity_I32);
6866
6867 assign(op1, get_gpr_w1(r1));
6868 assign(op2, get_gpr_w1(r2));
6869 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6870 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6871 put_gpr_w1(r1, mkexpr(result));
6872
6873 return "or";
6874}
6875
florian55085f82012-11-21 00:36:55 +00006876static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006877s390_irgen_OGR(UChar r1, UChar r2)
6878{
6879 IRTemp op1 = newTemp(Ity_I64);
6880 IRTemp op2 = newTemp(Ity_I64);
6881 IRTemp result = newTemp(Ity_I64);
6882
6883 assign(op1, get_gpr_dw0(r1));
6884 assign(op2, get_gpr_dw0(r2));
6885 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6886 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6887 put_gpr_dw0(r1, mkexpr(result));
6888
6889 return "ogr";
6890}
6891
florian55085f82012-11-21 00:36:55 +00006892static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006893s390_irgen_ORK(UChar r3, UChar r1, UChar r2)
6894{
6895 IRTemp op2 = newTemp(Ity_I32);
6896 IRTemp op3 = newTemp(Ity_I32);
6897 IRTemp result = newTemp(Ity_I32);
6898
6899 assign(op2, get_gpr_w1(r2));
6900 assign(op3, get_gpr_w1(r3));
6901 assign(result, binop(Iop_Or32, mkexpr(op2), mkexpr(op3)));
6902 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6903 put_gpr_w1(r1, mkexpr(result));
6904
6905 return "ork";
6906}
6907
florian55085f82012-11-21 00:36:55 +00006908static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006909s390_irgen_OGRK(UChar r3, UChar r1, UChar r2)
6910{
6911 IRTemp op2 = newTemp(Ity_I64);
6912 IRTemp op3 = newTemp(Ity_I64);
6913 IRTemp result = newTemp(Ity_I64);
6914
6915 assign(op2, get_gpr_dw0(r2));
6916 assign(op3, get_gpr_dw0(r3));
6917 assign(result, binop(Iop_Or64, mkexpr(op2), mkexpr(op3)));
6918 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6919 put_gpr_dw0(r1, mkexpr(result));
6920
6921 return "ogrk";
6922}
6923
florian55085f82012-11-21 00:36:55 +00006924static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006925s390_irgen_O(UChar r1, IRTemp op2addr)
6926{
6927 IRTemp op1 = newTemp(Ity_I32);
6928 IRTemp op2 = newTemp(Ity_I32);
6929 IRTemp result = newTemp(Ity_I32);
6930
6931 assign(op1, get_gpr_w1(r1));
6932 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6933 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6934 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6935 put_gpr_w1(r1, mkexpr(result));
6936
6937 return "o";
6938}
6939
florian55085f82012-11-21 00:36:55 +00006940static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006941s390_irgen_OY(UChar r1, IRTemp op2addr)
6942{
6943 IRTemp op1 = newTemp(Ity_I32);
6944 IRTemp op2 = newTemp(Ity_I32);
6945 IRTemp result = newTemp(Ity_I32);
6946
6947 assign(op1, get_gpr_w1(r1));
6948 assign(op2, load(Ity_I32, mkexpr(op2addr)));
6949 assign(result, binop(Iop_Or32, mkexpr(op1), mkexpr(op2)));
6950 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6951 put_gpr_w1(r1, mkexpr(result));
6952
6953 return "oy";
6954}
6955
florian55085f82012-11-21 00:36:55 +00006956static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006957s390_irgen_OG(UChar r1, IRTemp op2addr)
6958{
6959 IRTemp op1 = newTemp(Ity_I64);
6960 IRTemp op2 = newTemp(Ity_I64);
6961 IRTemp result = newTemp(Ity_I64);
6962
6963 assign(op1, get_gpr_dw0(r1));
6964 assign(op2, load(Ity_I64, mkexpr(op2addr)));
6965 assign(result, binop(Iop_Or64, mkexpr(op1), mkexpr(op2)));
6966 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6967 put_gpr_dw0(r1, mkexpr(result));
6968
6969 return "og";
6970}
6971
florian55085f82012-11-21 00:36:55 +00006972static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006973s390_irgen_OI(UChar i2, IRTemp op1addr)
6974{
6975 IRTemp op1 = newTemp(Ity_I8);
6976 UChar op2;
6977 IRTemp result = newTemp(Ity_I8);
6978
6979 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6980 op2 = i2;
6981 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6982 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6983 store(mkexpr(op1addr), mkexpr(result));
6984
6985 return "oi";
6986}
6987
florian55085f82012-11-21 00:36:55 +00006988static const HChar *
sewardj2019a972011-03-07 16:04:07 +00006989s390_irgen_OIY(UChar i2, IRTemp op1addr)
6990{
6991 IRTemp op1 = newTemp(Ity_I8);
6992 UChar op2;
6993 IRTemp result = newTemp(Ity_I8);
6994
6995 assign(op1, load(Ity_I8, mkexpr(op1addr)));
6996 op2 = i2;
6997 assign(result, binop(Iop_Or8, mkexpr(op1), mkU8(op2)));
6998 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
6999 store(mkexpr(op1addr), mkexpr(result));
7000
7001 return "oiy";
7002}
7003
florian55085f82012-11-21 00:36:55 +00007004static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007005s390_irgen_OIHF(UChar r1, UInt i2)
7006{
7007 IRTemp op1 = newTemp(Ity_I32);
7008 UInt op2;
7009 IRTemp result = newTemp(Ity_I32);
7010
7011 assign(op1, get_gpr_w0(r1));
7012 op2 = i2;
7013 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7014 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7015 put_gpr_w0(r1, mkexpr(result));
7016
7017 return "oihf";
7018}
7019
florian55085f82012-11-21 00:36:55 +00007020static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007021s390_irgen_OIHH(UChar r1, UShort i2)
7022{
7023 IRTemp op1 = newTemp(Ity_I16);
7024 UShort op2;
7025 IRTemp result = newTemp(Ity_I16);
7026
7027 assign(op1, get_gpr_hw0(r1));
7028 op2 = i2;
7029 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7030 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7031 put_gpr_hw0(r1, mkexpr(result));
7032
7033 return "oihh";
7034}
7035
florian55085f82012-11-21 00:36:55 +00007036static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007037s390_irgen_OIHL(UChar r1, UShort i2)
7038{
7039 IRTemp op1 = newTemp(Ity_I16);
7040 UShort op2;
7041 IRTemp result = newTemp(Ity_I16);
7042
7043 assign(op1, get_gpr_hw1(r1));
7044 op2 = i2;
7045 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7046 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7047 put_gpr_hw1(r1, mkexpr(result));
7048
7049 return "oihl";
7050}
7051
florian55085f82012-11-21 00:36:55 +00007052static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007053s390_irgen_OILF(UChar r1, UInt i2)
7054{
7055 IRTemp op1 = newTemp(Ity_I32);
7056 UInt op2;
7057 IRTemp result = newTemp(Ity_I32);
7058
7059 assign(op1, get_gpr_w1(r1));
7060 op2 = i2;
7061 assign(result, binop(Iop_Or32, mkexpr(op1), mkU32(op2)));
7062 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7063 put_gpr_w1(r1, mkexpr(result));
7064
7065 return "oilf";
7066}
7067
florian55085f82012-11-21 00:36:55 +00007068static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007069s390_irgen_OILH(UChar r1, UShort i2)
7070{
7071 IRTemp op1 = newTemp(Ity_I16);
7072 UShort op2;
7073 IRTemp result = newTemp(Ity_I16);
7074
7075 assign(op1, get_gpr_hw2(r1));
7076 op2 = i2;
7077 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7078 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7079 put_gpr_hw2(r1, mkexpr(result));
7080
7081 return "oilh";
7082}
7083
florian55085f82012-11-21 00:36:55 +00007084static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007085s390_irgen_OILL(UChar r1, UShort i2)
7086{
7087 IRTemp op1 = newTemp(Ity_I16);
7088 UShort op2;
7089 IRTemp result = newTemp(Ity_I16);
7090
7091 assign(op1, get_gpr_hw3(r1));
7092 op2 = i2;
7093 assign(result, binop(Iop_Or16, mkexpr(op1), mkU16(op2)));
7094 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7095 put_gpr_hw3(r1, mkexpr(result));
7096
7097 return "oill";
7098}
7099
florian55085f82012-11-21 00:36:55 +00007100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007101s390_irgen_PFD(void)
7102{
7103
7104 return "pfd";
7105}
7106
florian55085f82012-11-21 00:36:55 +00007107static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007108s390_irgen_PFDRL(void)
7109{
7110
7111 return "pfdrl";
7112}
7113
florian55085f82012-11-21 00:36:55 +00007114static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007115s390_irgen_RLL(UChar r1, UChar r3, IRTemp op2addr)
7116{
7117 IRTemp amount = newTemp(Ity_I64);
7118 IRTemp op = newTemp(Ity_I32);
7119
7120 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(31)));
7121 assign(op, get_gpr_w1(r3));
7122 put_gpr_w1(r1, binop(Iop_Or32, binop(Iop_Shl32, mkexpr(op), unop(Iop_64to8,
7123 mkexpr(amount))), binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8,
7124 binop(Iop_Sub64, mkU64(32), mkexpr(amount))))));
7125
7126 return "rll";
7127}
7128
florian55085f82012-11-21 00:36:55 +00007129static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007130s390_irgen_RLLG(UChar r1, UChar r3, IRTemp op2addr)
7131{
7132 IRTemp amount = newTemp(Ity_I64);
7133 IRTemp op = newTemp(Ity_I64);
7134
7135 assign(amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7136 assign(op, get_gpr_dw0(r3));
7137 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(op), unop(Iop_64to8,
7138 mkexpr(amount))), binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8,
7139 binop(Iop_Sub64, mkU64(64), mkexpr(amount))))));
7140
7141 return "rllg";
7142}
7143
florian55085f82012-11-21 00:36:55 +00007144static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007145s390_irgen_RNSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7146{
7147 UChar from;
7148 UChar to;
7149 UChar rot;
7150 UChar t_bit;
7151 ULong mask;
7152 ULong maskc;
7153 IRTemp result = newTemp(Ity_I64);
7154 IRTemp op2 = newTemp(Ity_I64);
7155
7156 from = i3 & 63;
7157 to = i4 & 63;
7158 rot = i5 & 63;
7159 t_bit = i3 & 128;
7160 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7161 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7162 mkU8(64 - rot))));
7163 if (from <= to) {
7164 mask = ~0ULL;
7165 mask = (mask >> from) & (mask << (63 - to));
7166 maskc = ~mask;
7167 } else {
7168 maskc = ~0ULL;
7169 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7170 mask = ~maskc;
7171 }
7172 assign(result, binop(Iop_And64, binop(Iop_And64, get_gpr_dw0(r1), mkexpr(op2)
7173 ), mkU64(mask)));
7174 if (t_bit == 0) {
7175 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7176 mkU64(maskc)), mkexpr(result)));
7177 }
7178 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7179
7180 return "rnsbg";
7181}
7182
florian55085f82012-11-21 00:36:55 +00007183static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007184s390_irgen_RXSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7185{
7186 UChar from;
7187 UChar to;
7188 UChar rot;
7189 UChar t_bit;
7190 ULong mask;
7191 ULong maskc;
7192 IRTemp result = newTemp(Ity_I64);
7193 IRTemp op2 = newTemp(Ity_I64);
7194
7195 from = i3 & 63;
7196 to = i4 & 63;
7197 rot = i5 & 63;
7198 t_bit = i3 & 128;
7199 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7200 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7201 mkU8(64 - rot))));
7202 if (from <= to) {
7203 mask = ~0ULL;
7204 mask = (mask >> from) & (mask << (63 - to));
7205 maskc = ~mask;
7206 } else {
7207 maskc = ~0ULL;
7208 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7209 mask = ~maskc;
7210 }
7211 assign(result, binop(Iop_And64, binop(Iop_Xor64, get_gpr_dw0(r1), mkexpr(op2)
7212 ), mkU64(mask)));
7213 if (t_bit == 0) {
7214 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7215 mkU64(maskc)), mkexpr(result)));
7216 }
7217 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7218
7219 return "rxsbg";
7220}
7221
florian55085f82012-11-21 00:36:55 +00007222static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007223s390_irgen_ROSBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7224{
7225 UChar from;
7226 UChar to;
7227 UChar rot;
7228 UChar t_bit;
7229 ULong mask;
7230 ULong maskc;
7231 IRTemp result = newTemp(Ity_I64);
7232 IRTemp op2 = newTemp(Ity_I64);
7233
7234 from = i3 & 63;
7235 to = i4 & 63;
7236 rot = i5 & 63;
7237 t_bit = i3 & 128;
7238 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7239 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7240 mkU8(64 - rot))));
7241 if (from <= to) {
7242 mask = ~0ULL;
7243 mask = (mask >> from) & (mask << (63 - to));
7244 maskc = ~mask;
7245 } else {
7246 maskc = ~0ULL;
7247 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7248 mask = ~maskc;
7249 }
7250 assign(result, binop(Iop_And64, binop(Iop_Or64, get_gpr_dw0(r1), mkexpr(op2)
7251 ), mkU64(mask)));
7252 if (t_bit == 0) {
7253 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7254 mkU64(maskc)), mkexpr(result)));
7255 }
7256 s390_cc_thunk_putZ(S390_CC_OP_BITWISE, result);
7257
7258 return "rosbg";
7259}
7260
florian55085f82012-11-21 00:36:55 +00007261static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007262s390_irgen_RISBG(UChar r1, UChar r2, UChar i3, UChar i4, UChar i5)
7263{
7264 UChar from;
7265 UChar to;
7266 UChar rot;
7267 UChar z_bit;
7268 ULong mask;
7269 ULong maskc;
7270 IRTemp op2 = newTemp(Ity_I64);
7271 IRTemp result = newTemp(Ity_I64);
7272
7273 from = i3 & 63;
7274 to = i4 & 63;
7275 rot = i5 & 63;
7276 z_bit = i4 & 128;
7277 assign(op2, rot == 0 ? get_gpr_dw0(r2) : binop(Iop_Or64, binop(Iop_Shl64,
7278 get_gpr_dw0(r2), mkU8(rot)), binop(Iop_Shr64, get_gpr_dw0(r2),
7279 mkU8(64 - rot))));
7280 if (from <= to) {
7281 mask = ~0ULL;
7282 mask = (mask >> from) & (mask << (63 - to));
7283 maskc = ~mask;
7284 } else {
7285 maskc = ~0ULL;
7286 maskc = (maskc >> (to + 1)) & (maskc << (64 - from));
7287 mask = ~maskc;
7288 }
7289 if (z_bit == 0) {
7290 put_gpr_dw0(r1, binop(Iop_Or64, binop(Iop_And64, get_gpr_dw0(r1),
7291 mkU64(maskc)), binop(Iop_And64, mkexpr(op2), mkU64(mask))));
7292 } else {
7293 put_gpr_dw0(r1, binop(Iop_And64, mkexpr(op2), mkU64(mask)));
7294 }
7295 assign(result, get_gpr_dw0(r1));
7296 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, op2);
7297
7298 return "risbg";
7299}
7300
florian55085f82012-11-21 00:36:55 +00007301static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007302s390_irgen_SAR(UChar r1, UChar r2)
7303{
7304 put_ar_w0(r1, get_gpr_w1(r2));
sewardj7ee97522011-05-09 21:45:04 +00007305 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +00007306 s390_disasm(ENC3(MNM, AR, GPR), "sar", r1, r2);
7307
7308 return "sar";
7309}
7310
florian55085f82012-11-21 00:36:55 +00007311static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007312s390_irgen_SLDA(UChar r1, IRTemp op2addr)
7313{
7314 IRTemp p1 = newTemp(Ity_I64);
7315 IRTemp p2 = newTemp(Ity_I64);
7316 IRTemp op = newTemp(Ity_I64);
7317 IRTemp result = newTemp(Ity_I64);
florian417b22d2012-07-13 13:41:41 +00007318 ULong sign_mask;
sewardj2019a972011-03-07 16:04:07 +00007319 IRTemp shift_amount = newTemp(Ity_I64);
7320
7321 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7322 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7323 assign(op, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1), mkU8(32)), mkexpr(p2)
7324 ));
7325 sign_mask = 1ULL << 63;
7326 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7327 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(op),
florian417b22d2012-07-13 13:41:41 +00007328 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7329 binop(Iop_And64, mkexpr(op), mkU64(sign_mask))));
sewardj2019a972011-03-07 16:04:07 +00007330 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7331 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7332 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7333
7334 return "slda";
7335}
7336
florian55085f82012-11-21 00:36:55 +00007337static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007338s390_irgen_SLDL(UChar r1, IRTemp op2addr)
7339{
7340 IRTemp p1 = newTemp(Ity_I64);
7341 IRTemp p2 = newTemp(Ity_I64);
7342 IRTemp result = newTemp(Ity_I64);
7343
7344 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7345 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7346 assign(result, binop(Iop_Shl64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7347 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7348 mkexpr(op2addr), mkU64(63)))));
7349 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7350 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7351
7352 return "sldl";
7353}
7354
florian55085f82012-11-21 00:36:55 +00007355static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007356s390_irgen_SLA(UChar r1, IRTemp op2addr)
7357{
7358 IRTemp uop = newTemp(Ity_I32);
7359 IRTemp result = newTemp(Ity_I32);
7360 UInt sign_mask;
7361 IRTemp shift_amount = newTemp(Ity_I64);
7362 IRTemp op = newTemp(Ity_I32);
7363
7364 assign(op, get_gpr_w1(r1));
7365 assign(uop, get_gpr_w1(r1));
7366 sign_mask = 2147483648U;
7367 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7368 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7369 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7370 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7371 put_gpr_w1(r1, mkexpr(result));
7372 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7373
7374 return "sla";
7375}
7376
florian55085f82012-11-21 00:36:55 +00007377static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007378s390_irgen_SLAK(UChar r1, UChar r3, IRTemp op2addr)
7379{
7380 IRTemp uop = newTemp(Ity_I32);
7381 IRTemp result = newTemp(Ity_I32);
7382 UInt sign_mask;
7383 IRTemp shift_amount = newTemp(Ity_I64);
7384 IRTemp op = newTemp(Ity_I32);
7385
7386 assign(op, get_gpr_w1(r3));
7387 assign(uop, get_gpr_w1(r3));
7388 sign_mask = 2147483648U;
7389 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7390 assign(result, binop(Iop_Or32, binop(Iop_And32, binop(Iop_Shl32, mkexpr(uop),
7391 unop(Iop_64to8, mkexpr(shift_amount))), mkU32(~sign_mask)),
7392 binop(Iop_And32, mkexpr(uop), mkU32(sign_mask))));
7393 put_gpr_w1(r1, mkexpr(result));
7394 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_32, op, shift_amount);
7395
7396 return "slak";
7397}
7398
florian55085f82012-11-21 00:36:55 +00007399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007400s390_irgen_SLAG(UChar r1, UChar r3, IRTemp op2addr)
7401{
7402 IRTemp uop = newTemp(Ity_I64);
7403 IRTemp result = newTemp(Ity_I64);
7404 ULong sign_mask;
7405 IRTemp shift_amount = newTemp(Ity_I64);
7406 IRTemp op = newTemp(Ity_I64);
7407
7408 assign(op, get_gpr_dw0(r3));
7409 assign(uop, get_gpr_dw0(r3));
7410 sign_mask = 9223372036854775808ULL;
7411 assign(shift_amount, binop(Iop_And64, mkexpr(op2addr), mkU64(63)));
7412 assign(result, binop(Iop_Or64, binop(Iop_And64, binop(Iop_Shl64, mkexpr(uop),
7413 unop(Iop_64to8, mkexpr(shift_amount))), mkU64(~sign_mask)),
7414 binop(Iop_And64, mkexpr(uop), mkU64(sign_mask))));
7415 put_gpr_dw0(r1, mkexpr(result));
7416 s390_cc_thunk_putZZ(S390_CC_OP_SHIFT_LEFT_64, op, shift_amount);
7417
7418 return "slag";
7419}
7420
florian55085f82012-11-21 00:36:55 +00007421static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007422s390_irgen_SLL(UChar r1, IRTemp op2addr)
7423{
7424 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r1), unop(Iop_64to8,
7425 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7426
7427 return "sll";
7428}
7429
florian55085f82012-11-21 00:36:55 +00007430static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007431s390_irgen_SLLK(UChar r1, UChar r3, IRTemp op2addr)
7432{
7433 put_gpr_w1(r1, binop(Iop_Shl32, get_gpr_w1(r3), unop(Iop_64to8,
7434 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7435
7436 return "sllk";
7437}
7438
florian55085f82012-11-21 00:36:55 +00007439static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007440s390_irgen_SLLG(UChar r1, UChar r3, IRTemp op2addr)
7441{
7442 put_gpr_dw0(r1, binop(Iop_Shl64, get_gpr_dw0(r3), unop(Iop_64to8,
7443 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
7444
7445 return "sllg";
7446}
7447
florian55085f82012-11-21 00:36:55 +00007448static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007449s390_irgen_SRDA(UChar r1, IRTemp op2addr)
7450{
7451 IRTemp p1 = newTemp(Ity_I64);
7452 IRTemp p2 = newTemp(Ity_I64);
7453 IRTemp result = newTemp(Ity_I64);
7454
7455 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7456 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7457 assign(result, binop(Iop_Sar64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7458 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7459 mkexpr(op2addr), mkU64(63)))));
7460 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7461 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7462 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7463
7464 return "srda";
7465}
7466
florian55085f82012-11-21 00:36:55 +00007467static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007468s390_irgen_SRDL(UChar r1, IRTemp op2addr)
7469{
7470 IRTemp p1 = newTemp(Ity_I64);
7471 IRTemp p2 = newTemp(Ity_I64);
7472 IRTemp result = newTemp(Ity_I64);
7473
7474 assign(p1, unop(Iop_32Uto64, get_gpr_w1(r1)));
7475 assign(p2, unop(Iop_32Uto64, get_gpr_w1(r1 + 1)));
7476 assign(result, binop(Iop_Shr64, binop(Iop_Or64, binop(Iop_Shl64, mkexpr(p1),
7477 mkU8(32)), mkexpr(p2)), unop(Iop_64to8, binop(Iop_And64,
7478 mkexpr(op2addr), mkU64(63)))));
7479 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result)));
7480 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result)));
7481
7482 return "srdl";
7483}
7484
florian55085f82012-11-21 00:36:55 +00007485static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007486s390_irgen_SRA(UChar r1, IRTemp op2addr)
7487{
7488 IRTemp result = newTemp(Ity_I32);
7489 IRTemp op = newTemp(Ity_I32);
7490
7491 assign(op, get_gpr_w1(r1));
7492 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7493 mkexpr(op2addr), mkU64(63)))));
7494 put_gpr_w1(r1, mkexpr(result));
7495 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7496
7497 return "sra";
7498}
7499
florian55085f82012-11-21 00:36:55 +00007500static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007501s390_irgen_SRAK(UChar r1, UChar r3, IRTemp op2addr)
7502{
7503 IRTemp result = newTemp(Ity_I32);
7504 IRTemp op = newTemp(Ity_I32);
7505
7506 assign(op, get_gpr_w1(r3));
7507 assign(result, binop(Iop_Sar32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7508 mkexpr(op2addr), mkU64(63)))));
7509 put_gpr_w1(r1, mkexpr(result));
7510 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7511
7512 return "srak";
7513}
7514
florian55085f82012-11-21 00:36:55 +00007515static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007516s390_irgen_SRAG(UChar r1, UChar r3, IRTemp op2addr)
7517{
7518 IRTemp result = newTemp(Ity_I64);
7519 IRTemp op = newTemp(Ity_I64);
7520
7521 assign(op, get_gpr_dw0(r3));
7522 assign(result, binop(Iop_Sar64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7523 mkexpr(op2addr), mkU64(63)))));
7524 put_gpr_dw0(r1, mkexpr(result));
7525 s390_cc_thunk_putS(S390_CC_OP_LOAD_AND_TEST, result);
7526
7527 return "srag";
7528}
7529
florian55085f82012-11-21 00:36:55 +00007530static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007531s390_irgen_SRL(UChar r1, IRTemp op2addr)
7532{
7533 IRTemp op = newTemp(Ity_I32);
7534
7535 assign(op, get_gpr_w1(r1));
7536 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7537 mkexpr(op2addr), mkU64(63)))));
7538
7539 return "srl";
7540}
7541
florian55085f82012-11-21 00:36:55 +00007542static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007543s390_irgen_SRLK(UChar r1, UChar r3, IRTemp op2addr)
7544{
7545 IRTemp op = newTemp(Ity_I32);
7546
7547 assign(op, get_gpr_w1(r3));
7548 put_gpr_w1(r1, binop(Iop_Shr32, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7549 mkexpr(op2addr), mkU64(63)))));
7550
7551 return "srlk";
7552}
7553
florian55085f82012-11-21 00:36:55 +00007554static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007555s390_irgen_SRLG(UChar r1, UChar r3, IRTemp op2addr)
7556{
7557 IRTemp op = newTemp(Ity_I64);
7558
7559 assign(op, get_gpr_dw0(r3));
7560 put_gpr_dw0(r1, binop(Iop_Shr64, mkexpr(op), unop(Iop_64to8, binop(Iop_And64,
7561 mkexpr(op2addr), mkU64(63)))));
7562
7563 return "srlg";
7564}
7565
florian55085f82012-11-21 00:36:55 +00007566static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007567s390_irgen_ST(UChar r1, IRTemp op2addr)
7568{
7569 store(mkexpr(op2addr), get_gpr_w1(r1));
7570
7571 return "st";
7572}
7573
florian55085f82012-11-21 00:36:55 +00007574static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007575s390_irgen_STY(UChar r1, IRTemp op2addr)
7576{
7577 store(mkexpr(op2addr), get_gpr_w1(r1));
7578
7579 return "sty";
7580}
7581
florian55085f82012-11-21 00:36:55 +00007582static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007583s390_irgen_STG(UChar r1, IRTemp op2addr)
7584{
7585 store(mkexpr(op2addr), get_gpr_dw0(r1));
7586
7587 return "stg";
7588}
7589
florian55085f82012-11-21 00:36:55 +00007590static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007591s390_irgen_STRL(UChar r1, UInt i2)
7592{
7593 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7594 get_gpr_w1(r1));
7595
7596 return "strl";
7597}
7598
florian55085f82012-11-21 00:36:55 +00007599static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007600s390_irgen_STGRL(UChar r1, UInt i2)
7601{
7602 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7603 get_gpr_dw0(r1));
7604
7605 return "stgrl";
7606}
7607
florian55085f82012-11-21 00:36:55 +00007608static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007609s390_irgen_STC(UChar r1, IRTemp op2addr)
7610{
7611 store(mkexpr(op2addr), get_gpr_b7(r1));
7612
7613 return "stc";
7614}
7615
florian55085f82012-11-21 00:36:55 +00007616static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007617s390_irgen_STCY(UChar r1, IRTemp op2addr)
7618{
7619 store(mkexpr(op2addr), get_gpr_b7(r1));
7620
7621 return "stcy";
7622}
7623
florian55085f82012-11-21 00:36:55 +00007624static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007625s390_irgen_STCH(UChar r1, IRTemp op2addr)
7626{
7627 store(mkexpr(op2addr), get_gpr_b3(r1));
7628
7629 return "stch";
7630}
7631
florian55085f82012-11-21 00:36:55 +00007632static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007633s390_irgen_STCM(UChar r1, UChar r3, IRTemp op2addr)
7634{
7635 UChar mask;
7636 UChar n;
7637
7638 mask = (UChar)r3;
7639 n = 0;
7640 if ((mask & 8) != 0) {
7641 store(mkexpr(op2addr), get_gpr_b4(r1));
7642 n = n + 1;
7643 }
7644 if ((mask & 4) != 0) {
7645 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7646 n = n + 1;
7647 }
7648 if ((mask & 2) != 0) {
7649 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7650 n = n + 1;
7651 }
7652 if ((mask & 1) != 0) {
7653 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7654 }
7655
7656 return "stcm";
7657}
7658
florian55085f82012-11-21 00:36:55 +00007659static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007660s390_irgen_STCMY(UChar r1, UChar r3, IRTemp op2addr)
7661{
7662 UChar mask;
7663 UChar n;
7664
7665 mask = (UChar)r3;
7666 n = 0;
7667 if ((mask & 8) != 0) {
7668 store(mkexpr(op2addr), get_gpr_b4(r1));
7669 n = n + 1;
7670 }
7671 if ((mask & 4) != 0) {
7672 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b5(r1));
7673 n = n + 1;
7674 }
7675 if ((mask & 2) != 0) {
7676 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b6(r1));
7677 n = n + 1;
7678 }
7679 if ((mask & 1) != 0) {
7680 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b7(r1));
7681 }
7682
7683 return "stcmy";
7684}
7685
florian55085f82012-11-21 00:36:55 +00007686static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007687s390_irgen_STCMH(UChar r1, UChar r3, IRTemp op2addr)
7688{
7689 UChar mask;
7690 UChar n;
7691
7692 mask = (UChar)r3;
7693 n = 0;
7694 if ((mask & 8) != 0) {
7695 store(mkexpr(op2addr), get_gpr_b0(r1));
7696 n = n + 1;
7697 }
7698 if ((mask & 4) != 0) {
7699 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b1(r1));
7700 n = n + 1;
7701 }
7702 if ((mask & 2) != 0) {
7703 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b2(r1));
7704 n = n + 1;
7705 }
7706 if ((mask & 1) != 0) {
7707 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(n)), get_gpr_b3(r1));
7708 }
7709
7710 return "stcmh";
7711}
7712
florian55085f82012-11-21 00:36:55 +00007713static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007714s390_irgen_STH(UChar r1, IRTemp op2addr)
7715{
7716 store(mkexpr(op2addr), get_gpr_hw3(r1));
7717
7718 return "sth";
7719}
7720
florian55085f82012-11-21 00:36:55 +00007721static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007722s390_irgen_STHY(UChar r1, IRTemp op2addr)
7723{
7724 store(mkexpr(op2addr), get_gpr_hw3(r1));
7725
7726 return "sthy";
7727}
7728
florian55085f82012-11-21 00:36:55 +00007729static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007730s390_irgen_STHRL(UChar r1, UInt i2)
7731{
7732 store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)),
7733 get_gpr_hw3(r1));
7734
7735 return "sthrl";
7736}
7737
florian55085f82012-11-21 00:36:55 +00007738static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007739s390_irgen_STHH(UChar r1, IRTemp op2addr)
7740{
7741 store(mkexpr(op2addr), get_gpr_hw1(r1));
7742
7743 return "sthh";
7744}
7745
florian55085f82012-11-21 00:36:55 +00007746static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007747s390_irgen_STFH(UChar r1, IRTemp op2addr)
7748{
7749 store(mkexpr(op2addr), get_gpr_w0(r1));
7750
7751 return "stfh";
7752}
7753
florian55085f82012-11-21 00:36:55 +00007754static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007755s390_irgen_STOC(UChar r1, IRTemp op2addr)
7756{
7757 /* condition is checked in format handler */
7758 store(mkexpr(op2addr), get_gpr_w1(r1));
7759
7760 return "stoc";
7761}
7762
florian55085f82012-11-21 00:36:55 +00007763static const HChar *
sewardjd7bde722011-04-05 13:19:33 +00007764s390_irgen_STOCG(UChar r1, IRTemp op2addr)
7765{
7766 /* condition is checked in format handler */
7767 store(mkexpr(op2addr), get_gpr_dw0(r1));
7768
7769 return "stocg";
7770}
7771
florian55085f82012-11-21 00:36:55 +00007772static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007773s390_irgen_STPQ(UChar r1, IRTemp op2addr)
7774{
7775 store(mkexpr(op2addr), get_gpr_dw0(r1));
7776 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(8)), get_gpr_dw0(r1 + 1));
7777
7778 return "stpq";
7779}
7780
florian55085f82012-11-21 00:36:55 +00007781static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007782s390_irgen_STRVH(UChar r1, IRTemp op2addr)
7783{
7784 store(mkexpr(op2addr), get_gpr_b7(r1));
7785 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7786
7787 return "strvh";
7788}
7789
florian55085f82012-11-21 00:36:55 +00007790static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007791s390_irgen_STRV(UChar r1, IRTemp op2addr)
7792{
7793 store(mkexpr(op2addr), get_gpr_b7(r1));
7794 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7795 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7796 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7797
7798 return "strv";
7799}
7800
florian55085f82012-11-21 00:36:55 +00007801static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007802s390_irgen_STRVG(UChar r1, IRTemp op2addr)
7803{
7804 store(mkexpr(op2addr), get_gpr_b7(r1));
7805 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(1)), get_gpr_b6(r1));
7806 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(2)), get_gpr_b5(r1));
7807 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(3)), get_gpr_b4(r1));
7808 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(4)), get_gpr_b3(r1));
7809 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(5)), get_gpr_b2(r1));
7810 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(6)), get_gpr_b1(r1));
7811 store(binop(Iop_Add64, mkexpr(op2addr), mkU64(7)), get_gpr_b0(r1));
7812
7813 return "strvg";
7814}
7815
florian55085f82012-11-21 00:36:55 +00007816static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007817s390_irgen_SR(UChar r1, UChar r2)
7818{
7819 IRTemp op1 = newTemp(Ity_I32);
7820 IRTemp op2 = newTemp(Ity_I32);
7821 IRTemp result = newTemp(Ity_I32);
7822
7823 assign(op1, get_gpr_w1(r1));
7824 assign(op2, get_gpr_w1(r2));
7825 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7826 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7827 put_gpr_w1(r1, mkexpr(result));
7828
7829 return "sr";
7830}
7831
florian55085f82012-11-21 00:36:55 +00007832static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007833s390_irgen_SGR(UChar r1, UChar r2)
7834{
7835 IRTemp op1 = newTemp(Ity_I64);
7836 IRTemp op2 = newTemp(Ity_I64);
7837 IRTemp result = newTemp(Ity_I64);
7838
7839 assign(op1, get_gpr_dw0(r1));
7840 assign(op2, get_gpr_dw0(r2));
7841 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7842 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7843 put_gpr_dw0(r1, mkexpr(result));
7844
7845 return "sgr";
7846}
7847
florian55085f82012-11-21 00:36:55 +00007848static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007849s390_irgen_SGFR(UChar r1, UChar r2)
7850{
7851 IRTemp op1 = newTemp(Ity_I64);
7852 IRTemp op2 = newTemp(Ity_I64);
7853 IRTemp result = newTemp(Ity_I64);
7854
7855 assign(op1, get_gpr_dw0(r1));
7856 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
7857 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7858 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7859 put_gpr_dw0(r1, mkexpr(result));
7860
7861 return "sgfr";
7862}
7863
florian55085f82012-11-21 00:36:55 +00007864static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007865s390_irgen_SRK(UChar r3, UChar r1, UChar r2)
7866{
7867 IRTemp op2 = newTemp(Ity_I32);
7868 IRTemp op3 = newTemp(Ity_I32);
7869 IRTemp result = newTemp(Ity_I32);
7870
7871 assign(op2, get_gpr_w1(r2));
7872 assign(op3, get_gpr_w1(r3));
7873 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
7874 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
7875 put_gpr_w1(r1, mkexpr(result));
7876
7877 return "srk";
7878}
7879
florian55085f82012-11-21 00:36:55 +00007880static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007881s390_irgen_SGRK(UChar r3, UChar r1, UChar r2)
7882{
7883 IRTemp op2 = newTemp(Ity_I64);
7884 IRTemp op3 = newTemp(Ity_I64);
7885 IRTemp result = newTemp(Ity_I64);
7886
7887 assign(op2, get_gpr_dw0(r2));
7888 assign(op3, get_gpr_dw0(r3));
7889 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
7890 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op2, op3);
7891 put_gpr_dw0(r1, mkexpr(result));
7892
7893 return "sgrk";
7894}
7895
florian55085f82012-11-21 00:36:55 +00007896static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007897s390_irgen_S(UChar r1, IRTemp op2addr)
7898{
7899 IRTemp op1 = newTemp(Ity_I32);
7900 IRTemp op2 = newTemp(Ity_I32);
7901 IRTemp result = newTemp(Ity_I32);
7902
7903 assign(op1, get_gpr_w1(r1));
7904 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7905 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7906 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7907 put_gpr_w1(r1, mkexpr(result));
7908
7909 return "s";
7910}
7911
florian55085f82012-11-21 00:36:55 +00007912static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007913s390_irgen_SY(UChar r1, IRTemp op2addr)
7914{
7915 IRTemp op1 = newTemp(Ity_I32);
7916 IRTemp op2 = newTemp(Ity_I32);
7917 IRTemp result = newTemp(Ity_I32);
7918
7919 assign(op1, get_gpr_w1(r1));
7920 assign(op2, load(Ity_I32, mkexpr(op2addr)));
7921 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7922 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7923 put_gpr_w1(r1, mkexpr(result));
7924
7925 return "sy";
7926}
7927
florian55085f82012-11-21 00:36:55 +00007928static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007929s390_irgen_SG(UChar r1, IRTemp op2addr)
7930{
7931 IRTemp op1 = newTemp(Ity_I64);
7932 IRTemp op2 = newTemp(Ity_I64);
7933 IRTemp result = newTemp(Ity_I64);
7934
7935 assign(op1, get_gpr_dw0(r1));
7936 assign(op2, load(Ity_I64, mkexpr(op2addr)));
7937 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7938 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7939 put_gpr_dw0(r1, mkexpr(result));
7940
7941 return "sg";
7942}
7943
florian55085f82012-11-21 00:36:55 +00007944static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007945s390_irgen_SGF(UChar r1, IRTemp op2addr)
7946{
7947 IRTemp op1 = newTemp(Ity_I64);
7948 IRTemp op2 = newTemp(Ity_I64);
7949 IRTemp result = newTemp(Ity_I64);
7950
7951 assign(op1, get_gpr_dw0(r1));
7952 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
7953 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
7954 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_64, op1, op2);
7955 put_gpr_dw0(r1, mkexpr(result));
7956
7957 return "sgf";
7958}
7959
florian55085f82012-11-21 00:36:55 +00007960static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007961s390_irgen_SH(UChar r1, IRTemp op2addr)
7962{
7963 IRTemp op1 = newTemp(Ity_I32);
7964 IRTemp op2 = newTemp(Ity_I32);
7965 IRTemp result = newTemp(Ity_I32);
7966
7967 assign(op1, get_gpr_w1(r1));
7968 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7969 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7970 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7971 put_gpr_w1(r1, mkexpr(result));
7972
7973 return "sh";
7974}
7975
florian55085f82012-11-21 00:36:55 +00007976static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007977s390_irgen_SHY(UChar r1, IRTemp op2addr)
7978{
7979 IRTemp op1 = newTemp(Ity_I32);
7980 IRTemp op2 = newTemp(Ity_I32);
7981 IRTemp result = newTemp(Ity_I32);
7982
7983 assign(op1, get_gpr_w1(r1));
7984 assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkexpr(op2addr))));
7985 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
7986 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op1, op2);
7987 put_gpr_w1(r1, mkexpr(result));
7988
7989 return "shy";
7990}
7991
florian55085f82012-11-21 00:36:55 +00007992static const HChar *
sewardj2019a972011-03-07 16:04:07 +00007993s390_irgen_SHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
7994{
7995 IRTemp op2 = newTemp(Ity_I32);
7996 IRTemp op3 = newTemp(Ity_I32);
7997 IRTemp result = newTemp(Ity_I32);
7998
7999 assign(op2, get_gpr_w0(r1));
8000 assign(op3, get_gpr_w0(r2));
8001 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8002 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8003 put_gpr_w0(r1, mkexpr(result));
8004
8005 return "shhhr";
8006}
8007
florian55085f82012-11-21 00:36:55 +00008008static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008009s390_irgen_SHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8010{
8011 IRTemp op2 = newTemp(Ity_I32);
8012 IRTemp op3 = newTemp(Ity_I32);
8013 IRTemp result = newTemp(Ity_I32);
8014
8015 assign(op2, get_gpr_w0(r1));
8016 assign(op3, get_gpr_w1(r2));
8017 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8018 s390_cc_thunk_putSS(S390_CC_OP_SIGNED_SUB_32, op2, op3);
8019 put_gpr_w0(r1, mkexpr(result));
8020
8021 return "shhlr";
8022}
8023
florian55085f82012-11-21 00:36:55 +00008024static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008025s390_irgen_SLR(UChar r1, UChar r2)
8026{
8027 IRTemp op1 = newTemp(Ity_I32);
8028 IRTemp op2 = newTemp(Ity_I32);
8029 IRTemp result = newTemp(Ity_I32);
8030
8031 assign(op1, get_gpr_w1(r1));
8032 assign(op2, get_gpr_w1(r2));
8033 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8034 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8035 put_gpr_w1(r1, mkexpr(result));
8036
8037 return "slr";
8038}
8039
florian55085f82012-11-21 00:36:55 +00008040static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008041s390_irgen_SLGR(UChar r1, UChar r2)
8042{
8043 IRTemp op1 = newTemp(Ity_I64);
8044 IRTemp op2 = newTemp(Ity_I64);
8045 IRTemp result = newTemp(Ity_I64);
8046
8047 assign(op1, get_gpr_dw0(r1));
8048 assign(op2, get_gpr_dw0(r2));
8049 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8050 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8051 put_gpr_dw0(r1, mkexpr(result));
8052
8053 return "slgr";
8054}
8055
florian55085f82012-11-21 00:36:55 +00008056static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008057s390_irgen_SLGFR(UChar r1, UChar r2)
8058{
8059 IRTemp op1 = newTemp(Ity_I64);
8060 IRTemp op2 = newTemp(Ity_I64);
8061 IRTemp result = newTemp(Ity_I64);
8062
8063 assign(op1, get_gpr_dw0(r1));
8064 assign(op2, unop(Iop_32Uto64, get_gpr_w1(r2)));
8065 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8066 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8067 put_gpr_dw0(r1, mkexpr(result));
8068
8069 return "slgfr";
8070}
8071
florian55085f82012-11-21 00:36:55 +00008072static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008073s390_irgen_SLRK(UChar r3, UChar r1, UChar r2)
8074{
8075 IRTemp op2 = newTemp(Ity_I32);
8076 IRTemp op3 = newTemp(Ity_I32);
8077 IRTemp result = newTemp(Ity_I32);
8078
8079 assign(op2, get_gpr_w1(r2));
8080 assign(op3, get_gpr_w1(r3));
8081 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8082 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8083 put_gpr_w1(r1, mkexpr(result));
8084
8085 return "slrk";
8086}
8087
florian55085f82012-11-21 00:36:55 +00008088static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008089s390_irgen_SLGRK(UChar r3, UChar r1, UChar r2)
8090{
8091 IRTemp op2 = newTemp(Ity_I64);
8092 IRTemp op3 = newTemp(Ity_I64);
8093 IRTemp result = newTemp(Ity_I64);
8094
8095 assign(op2, get_gpr_dw0(r2));
8096 assign(op3, get_gpr_dw0(r3));
8097 assign(result, binop(Iop_Sub64, mkexpr(op2), mkexpr(op3)));
8098 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op2, op3);
8099 put_gpr_dw0(r1, mkexpr(result));
8100
8101 return "slgrk";
8102}
8103
florian55085f82012-11-21 00:36:55 +00008104static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008105s390_irgen_SL(UChar r1, IRTemp op2addr)
8106{
8107 IRTemp op1 = newTemp(Ity_I32);
8108 IRTemp op2 = newTemp(Ity_I32);
8109 IRTemp result = newTemp(Ity_I32);
8110
8111 assign(op1, get_gpr_w1(r1));
8112 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8113 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8114 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8115 put_gpr_w1(r1, mkexpr(result));
8116
8117 return "sl";
8118}
8119
florian55085f82012-11-21 00:36:55 +00008120static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008121s390_irgen_SLY(UChar r1, IRTemp op2addr)
8122{
8123 IRTemp op1 = newTemp(Ity_I32);
8124 IRTemp op2 = newTemp(Ity_I32);
8125 IRTemp result = newTemp(Ity_I32);
8126
8127 assign(op1, get_gpr_w1(r1));
8128 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8129 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)));
8130 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, op2);
8131 put_gpr_w1(r1, mkexpr(result));
8132
8133 return "sly";
8134}
8135
florian55085f82012-11-21 00:36:55 +00008136static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008137s390_irgen_SLG(UChar r1, IRTemp op2addr)
8138{
8139 IRTemp op1 = newTemp(Ity_I64);
8140 IRTemp op2 = newTemp(Ity_I64);
8141 IRTemp result = newTemp(Ity_I64);
8142
8143 assign(op1, get_gpr_dw0(r1));
8144 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8145 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8146 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8147 put_gpr_dw0(r1, mkexpr(result));
8148
8149 return "slg";
8150}
8151
florian55085f82012-11-21 00:36:55 +00008152static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008153s390_irgen_SLGF(UChar r1, IRTemp op2addr)
8154{
8155 IRTemp op1 = newTemp(Ity_I64);
8156 IRTemp op2 = newTemp(Ity_I64);
8157 IRTemp result = newTemp(Ity_I64);
8158
8159 assign(op1, get_gpr_dw0(r1));
8160 assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))));
8161 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)));
8162 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, op2);
8163 put_gpr_dw0(r1, mkexpr(result));
8164
8165 return "slgf";
8166}
8167
florian55085f82012-11-21 00:36:55 +00008168static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008169s390_irgen_SLFI(UChar r1, UInt i2)
8170{
8171 IRTemp op1 = newTemp(Ity_I32);
8172 UInt op2;
8173 IRTemp result = newTemp(Ity_I32);
8174
8175 assign(op1, get_gpr_w1(r1));
8176 op2 = i2;
8177 assign(result, binop(Iop_Sub32, mkexpr(op1), mkU32(op2)));
8178 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op1, mktemp(Ity_I32,
8179 mkU32(op2)));
8180 put_gpr_w1(r1, mkexpr(result));
8181
8182 return "slfi";
8183}
8184
florian55085f82012-11-21 00:36:55 +00008185static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008186s390_irgen_SLGFI(UChar r1, UInt i2)
8187{
8188 IRTemp op1 = newTemp(Ity_I64);
8189 ULong op2;
8190 IRTemp result = newTemp(Ity_I64);
8191
8192 assign(op1, get_gpr_dw0(r1));
8193 op2 = (ULong)i2;
8194 assign(result, binop(Iop_Sub64, mkexpr(op1), mkU64(op2)));
8195 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_64, op1, mktemp(Ity_I64,
8196 mkU64(op2)));
8197 put_gpr_dw0(r1, mkexpr(result));
8198
8199 return "slgfi";
8200}
8201
florian55085f82012-11-21 00:36:55 +00008202static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008203s390_irgen_SLHHHR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8204{
8205 IRTemp op2 = newTemp(Ity_I32);
8206 IRTemp op3 = newTemp(Ity_I32);
8207 IRTemp result = newTemp(Ity_I32);
8208
8209 assign(op2, get_gpr_w0(r1));
8210 assign(op3, get_gpr_w0(r2));
8211 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8212 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8213 put_gpr_w0(r1, mkexpr(result));
8214
8215 return "slhhhr";
8216}
8217
florian55085f82012-11-21 00:36:55 +00008218static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008219s390_irgen_SLHHLR(UChar r3 __attribute__((unused)), UChar r1, UChar r2)
8220{
8221 IRTemp op2 = newTemp(Ity_I32);
8222 IRTemp op3 = newTemp(Ity_I32);
8223 IRTemp result = newTemp(Ity_I32);
8224
8225 assign(op2, get_gpr_w0(r1));
8226 assign(op3, get_gpr_w1(r2));
8227 assign(result, binop(Iop_Sub32, mkexpr(op2), mkexpr(op3)));
8228 s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_SUB_32, op2, op3);
8229 put_gpr_w0(r1, mkexpr(result));
8230
8231 return "slhhlr";
8232}
8233
florian55085f82012-11-21 00:36:55 +00008234static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008235s390_irgen_SLBR(UChar r1, UChar r2)
8236{
8237 IRTemp op1 = newTemp(Ity_I32);
8238 IRTemp op2 = newTemp(Ity_I32);
8239 IRTemp result = newTemp(Ity_I32);
8240 IRTemp borrow_in = newTemp(Ity_I32);
8241
8242 assign(op1, get_gpr_w1(r1));
8243 assign(op2, get_gpr_w1(r2));
8244 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8245 s390_call_calculate_cc(), mkU8(1))));
8246 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8247 mkexpr(borrow_in)));
8248 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8249 put_gpr_w1(r1, mkexpr(result));
8250
8251 return "slbr";
8252}
8253
florian55085f82012-11-21 00:36:55 +00008254static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008255s390_irgen_SLBGR(UChar r1, UChar r2)
8256{
8257 IRTemp op1 = newTemp(Ity_I64);
8258 IRTemp op2 = newTemp(Ity_I64);
8259 IRTemp result = newTemp(Ity_I64);
8260 IRTemp borrow_in = newTemp(Ity_I64);
8261
8262 assign(op1, get_gpr_dw0(r1));
8263 assign(op2, get_gpr_dw0(r2));
8264 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8265 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8266 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8267 mkexpr(borrow_in)));
8268 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8269 put_gpr_dw0(r1, mkexpr(result));
8270
8271 return "slbgr";
8272}
8273
florian55085f82012-11-21 00:36:55 +00008274static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008275s390_irgen_SLB(UChar r1, IRTemp op2addr)
8276{
8277 IRTemp op1 = newTemp(Ity_I32);
8278 IRTemp op2 = newTemp(Ity_I32);
8279 IRTemp result = newTemp(Ity_I32);
8280 IRTemp borrow_in = newTemp(Ity_I32);
8281
8282 assign(op1, get_gpr_w1(r1));
8283 assign(op2, load(Ity_I32, mkexpr(op2addr)));
8284 assign(borrow_in, binop(Iop_Sub32, mkU32(1), binop(Iop_Shr32,
8285 s390_call_calculate_cc(), mkU8(1))));
8286 assign(result, binop(Iop_Sub32, binop(Iop_Sub32, mkexpr(op1), mkexpr(op2)),
8287 mkexpr(borrow_in)));
8288 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_32, op1, op2, borrow_in);
8289 put_gpr_w1(r1, mkexpr(result));
8290
8291 return "slb";
8292}
8293
florian55085f82012-11-21 00:36:55 +00008294static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008295s390_irgen_SLBG(UChar r1, IRTemp op2addr)
8296{
8297 IRTemp op1 = newTemp(Ity_I64);
8298 IRTemp op2 = newTemp(Ity_I64);
8299 IRTemp result = newTemp(Ity_I64);
8300 IRTemp borrow_in = newTemp(Ity_I64);
8301
8302 assign(op1, get_gpr_dw0(r1));
8303 assign(op2, load(Ity_I64, mkexpr(op2addr)));
8304 assign(borrow_in, unop(Iop_32Uto64, binop(Iop_Sub32, mkU32(1),
8305 binop(Iop_Shr32, s390_call_calculate_cc(), mkU8(1)))));
8306 assign(result, binop(Iop_Sub64, binop(Iop_Sub64, mkexpr(op1), mkexpr(op2)),
8307 mkexpr(borrow_in)));
8308 s390_cc_thunk_putZZZ(S390_CC_OP_UNSIGNED_SUBB_64, op1, op2, borrow_in);
8309 put_gpr_dw0(r1, mkexpr(result));
8310
8311 return "slbg";
8312}
8313
florian55085f82012-11-21 00:36:55 +00008314static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008315s390_irgen_SVC(UChar i)
8316{
8317 IRTemp sysno = newTemp(Ity_I64);
8318
8319 if (i != 0) {
8320 assign(sysno, mkU64(i));
8321 } else {
8322 assign(sysno, unop(Iop_32Uto64, get_gpr_w1(1)));
8323 }
8324 system_call(mkexpr(sysno));
8325
8326 return "svc";
8327}
8328
florian55085f82012-11-21 00:36:55 +00008329static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008330s390_irgen_TM(UChar i2, IRTemp op1addr)
8331{
8332 UChar mask;
8333 IRTemp value = newTemp(Ity_I8);
8334
8335 mask = i2;
8336 assign(value, load(Ity_I8, mkexpr(op1addr)));
8337 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8338 mkU8(mask)));
8339
8340 return "tm";
8341}
8342
florian55085f82012-11-21 00:36:55 +00008343static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008344s390_irgen_TMY(UChar i2, IRTemp op1addr)
8345{
8346 UChar mask;
8347 IRTemp value = newTemp(Ity_I8);
8348
8349 mask = i2;
8350 assign(value, load(Ity_I8, mkexpr(op1addr)));
8351 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_8, value, mktemp(Ity_I8,
8352 mkU8(mask)));
8353
8354 return "tmy";
8355}
8356
florian55085f82012-11-21 00:36:55 +00008357static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008358s390_irgen_TMHH(UChar r1, UShort i2)
8359{
8360 UShort mask;
8361 IRTemp value = newTemp(Ity_I16);
8362
8363 mask = i2;
8364 assign(value, get_gpr_hw0(r1));
8365 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8366 mkU16(mask)));
8367
8368 return "tmhh";
8369}
8370
florian55085f82012-11-21 00:36:55 +00008371static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008372s390_irgen_TMHL(UChar r1, UShort i2)
8373{
8374 UShort mask;
8375 IRTemp value = newTemp(Ity_I16);
8376
8377 mask = i2;
8378 assign(value, get_gpr_hw1(r1));
8379 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8380 mkU16(mask)));
8381
8382 return "tmhl";
8383}
8384
florian55085f82012-11-21 00:36:55 +00008385static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008386s390_irgen_TMLH(UChar r1, UShort i2)
8387{
8388 UShort mask;
8389 IRTemp value = newTemp(Ity_I16);
8390
8391 mask = i2;
8392 assign(value, get_gpr_hw2(r1));
8393 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8394 mkU16(mask)));
8395
8396 return "tmlh";
8397}
8398
florian55085f82012-11-21 00:36:55 +00008399static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008400s390_irgen_TMLL(UChar r1, UShort i2)
8401{
8402 UShort mask;
8403 IRTemp value = newTemp(Ity_I16);
8404
8405 mask = i2;
8406 assign(value, get_gpr_hw3(r1));
8407 s390_cc_thunk_putZZ(S390_CC_OP_TEST_UNDER_MASK_16, value, mktemp(Ity_I16,
8408 mkU16(mask)));
8409
8410 return "tmll";
8411}
8412
florian55085f82012-11-21 00:36:55 +00008413static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008414s390_irgen_EFPC(UChar r1)
8415{
8416 put_gpr_w1(r1, get_fpc_w0());
8417
8418 return "efpc";
8419}
8420
florian55085f82012-11-21 00:36:55 +00008421static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008422s390_irgen_LER(UChar r1, UChar r2)
8423{
8424 put_fpr_w0(r1, get_fpr_w0(r2));
8425
8426 return "ler";
8427}
8428
florian55085f82012-11-21 00:36:55 +00008429static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008430s390_irgen_LDR(UChar r1, UChar r2)
8431{
8432 put_fpr_dw0(r1, get_fpr_dw0(r2));
8433
8434 return "ldr";
8435}
8436
florian55085f82012-11-21 00:36:55 +00008437static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008438s390_irgen_LXR(UChar r1, UChar r2)
8439{
8440 put_fpr_dw0(r1, get_fpr_dw0(r2));
8441 put_fpr_dw0(r1 + 2, get_fpr_dw0(r2 + 2));
8442
8443 return "lxr";
8444}
8445
florian55085f82012-11-21 00:36:55 +00008446static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008447s390_irgen_LE(UChar r1, IRTemp op2addr)
8448{
8449 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8450
8451 return "le";
8452}
8453
florian55085f82012-11-21 00:36:55 +00008454static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008455s390_irgen_LD(UChar r1, IRTemp op2addr)
8456{
8457 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8458
8459 return "ld";
8460}
8461
florian55085f82012-11-21 00:36:55 +00008462static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008463s390_irgen_LEY(UChar r1, IRTemp op2addr)
8464{
8465 put_fpr_w0(r1, load(Ity_F32, mkexpr(op2addr)));
8466
8467 return "ley";
8468}
8469
florian55085f82012-11-21 00:36:55 +00008470static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008471s390_irgen_LDY(UChar r1, IRTemp op2addr)
8472{
8473 put_fpr_dw0(r1, load(Ity_F64, mkexpr(op2addr)));
8474
8475 return "ldy";
8476}
8477
florian55085f82012-11-21 00:36:55 +00008478static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008479s390_irgen_LFPC(IRTemp op2addr)
8480{
8481 put_fpc_w0(load(Ity_I32, mkexpr(op2addr)));
8482
8483 return "lfpc";
8484}
8485
florian55085f82012-11-21 00:36:55 +00008486static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008487s390_irgen_LZER(UChar r1)
8488{
8489 put_fpr_w0(r1, mkF32i(0x0));
8490
8491 return "lzer";
8492}
8493
florian55085f82012-11-21 00:36:55 +00008494static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008495s390_irgen_LZDR(UChar r1)
8496{
8497 put_fpr_dw0(r1, mkF64i(0x0));
8498
8499 return "lzdr";
8500}
8501
florian55085f82012-11-21 00:36:55 +00008502static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008503s390_irgen_LZXR(UChar r1)
8504{
8505 put_fpr_dw0(r1, mkF64i(0x0));
8506 put_fpr_dw0(r1 + 2, mkF64i(0x0));
8507
8508 return "lzxr";
8509}
8510
florian55085f82012-11-21 00:36:55 +00008511static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008512s390_irgen_SRNM(IRTemp op2addr)
8513{
florianf0fa1be2012-09-18 20:24:38 +00008514 UInt input_mask, fpc_mask;
sewardj2019a972011-03-07 16:04:07 +00008515
florianf0fa1be2012-09-18 20:24:38 +00008516 input_mask = 3;
8517 fpc_mask = s390_host_has_fpext ? 7 : 3;
sewardj2019a972011-03-07 16:04:07 +00008518
florianf0fa1be2012-09-18 20:24:38 +00008519 put_fpc_w0(binop(Iop_Or32,
8520 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8521 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8522 mkU32(input_mask))));
sewardj2019a972011-03-07 16:04:07 +00008523 return "srnm";
8524}
8525
florian55085f82012-11-21 00:36:55 +00008526static const HChar *
florianf0fa1be2012-09-18 20:24:38 +00008527s390_irgen_SRNMB(IRTemp op2addr)
8528{
8529 UInt input_mask, fpc_mask;
8530
8531 input_mask = 7;
8532 fpc_mask = 7;
8533
8534 put_fpc_w0(binop(Iop_Or32,
8535 binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8536 binop(Iop_And32, unop(Iop_64to32, mkexpr(op2addr)),
8537 mkU32(input_mask))));
8538 return "srnmb";
8539}
8540
florian81a4bfe2012-09-20 01:25:28 +00008541static void
florianf0fa1be2012-09-18 20:24:38 +00008542s390_irgen_srnmb_wrapper(UChar b2, UShort d2)
8543{
8544 if (b2 == 0) { /* This is the typical case */
8545 if (d2 > 3) {
8546 if (s390_host_has_fpext && d2 == 7) {
8547 /* ok */
8548 } else {
8549 emulation_warning(EmWarn_S390X_invalid_rounding);
florian125e20d2012-10-07 15:42:37 +00008550 d2 = S390_FPC_BFP_ROUND_NEAREST_EVEN;
florianf0fa1be2012-09-18 20:24:38 +00008551 }
8552 }
8553 }
8554
8555 s390_format_S_RD(s390_irgen_SRNMB, b2, d2);
8556}
8557
florian82cdba62013-03-12 01:31:24 +00008558/* Wrapper to validate the parameter as in SRNMB is not required, as all
8559 the 8 values in op2addr[61:63] correspond to a valid DFP rounding mode */
8560static const HChar *
8561s390_irgen_SRNMT(IRTemp op2addr)
8562{
8563 UInt input_mask, fpc_mask;
8564
8565 input_mask = 7;
8566 fpc_mask = 0x70;
8567
8568 /* fpc[25:27] <- op2addr[61:63]
8569 fpc = (fpc & ~(0x70)) | ((op2addr & 7) << 4) */
8570 put_fpc_w0(binop(Iop_Or32, binop(Iop_And32, get_fpc_w0(), mkU32(~fpc_mask)),
8571 binop(Iop_Shl32, binop(Iop_And32,
8572 unop(Iop_64to32, mkexpr(op2addr)),
8573 mkU32(input_mask)), mkU8(4))));
8574 return "srnmt";
8575}
8576
florianf0fa1be2012-09-18 20:24:38 +00008577
florian55085f82012-11-21 00:36:55 +00008578static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008579s390_irgen_SFPC(UChar r1)
8580{
8581 put_fpc_w0(get_gpr_w1(r1));
8582
8583 return "sfpc";
8584}
8585
florian55085f82012-11-21 00:36:55 +00008586static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008587s390_irgen_STE(UChar r1, IRTemp op2addr)
8588{
8589 store(mkexpr(op2addr), get_fpr_w0(r1));
8590
8591 return "ste";
8592}
8593
florian55085f82012-11-21 00:36:55 +00008594static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008595s390_irgen_STD(UChar r1, IRTemp op2addr)
8596{
8597 store(mkexpr(op2addr), get_fpr_dw0(r1));
8598
8599 return "std";
8600}
8601
florian55085f82012-11-21 00:36:55 +00008602static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008603s390_irgen_STEY(UChar r1, IRTemp op2addr)
8604{
8605 store(mkexpr(op2addr), get_fpr_w0(r1));
8606
8607 return "stey";
8608}
8609
florian55085f82012-11-21 00:36:55 +00008610static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008611s390_irgen_STDY(UChar r1, IRTemp op2addr)
8612{
8613 store(mkexpr(op2addr), get_fpr_dw0(r1));
8614
8615 return "stdy";
8616}
8617
florian55085f82012-11-21 00:36:55 +00008618static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008619s390_irgen_STFPC(IRTemp op2addr)
8620{
8621 store(mkexpr(op2addr), get_fpc_w0());
8622
8623 return "stfpc";
8624}
8625
florian55085f82012-11-21 00:36:55 +00008626static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008627s390_irgen_AEBR(UChar r1, UChar r2)
8628{
8629 IRTemp op1 = newTemp(Ity_F32);
8630 IRTemp op2 = newTemp(Ity_F32);
8631 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008632 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008633
8634 assign(op1, get_fpr_w0(r1));
8635 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008636 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008637 mkexpr(op2)));
8638 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8639 put_fpr_w0(r1, mkexpr(result));
8640
8641 return "aebr";
8642}
8643
florian55085f82012-11-21 00:36:55 +00008644static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008645s390_irgen_ADBR(UChar r1, UChar r2)
8646{
8647 IRTemp op1 = newTemp(Ity_F64);
8648 IRTemp op2 = newTemp(Ity_F64);
8649 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008650 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008651
8652 assign(op1, get_fpr_dw0(r1));
8653 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008654 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008655 mkexpr(op2)));
8656 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8657 put_fpr_dw0(r1, mkexpr(result));
8658
8659 return "adbr";
8660}
8661
florian55085f82012-11-21 00:36:55 +00008662static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008663s390_irgen_AEB(UChar r1, IRTemp op2addr)
8664{
8665 IRTemp op1 = newTemp(Ity_F32);
8666 IRTemp op2 = newTemp(Ity_F32);
8667 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008668 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008669
8670 assign(op1, get_fpr_w0(r1));
8671 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008672 assign(result, triop(Iop_AddF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008673 mkexpr(op2)));
8674 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
8675 put_fpr_w0(r1, mkexpr(result));
8676
8677 return "aeb";
8678}
8679
florian55085f82012-11-21 00:36:55 +00008680static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008681s390_irgen_ADB(UChar r1, IRTemp op2addr)
8682{
8683 IRTemp op1 = newTemp(Ity_F64);
8684 IRTemp op2 = newTemp(Ity_F64);
8685 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008686 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008687
8688 assign(op1, get_fpr_dw0(r1));
8689 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00008690 assign(result, triop(Iop_AddF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008691 mkexpr(op2)));
8692 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
8693 put_fpr_dw0(r1, mkexpr(result));
8694
8695 return "adb";
8696}
8697
florian55085f82012-11-21 00:36:55 +00008698static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008699s390_irgen_CEFBR(UChar m3, UChar m4 __attribute__((unused)),
8700 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008701{
florian125e20d2012-10-07 15:42:37 +00008702 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008703 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008704 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008705 }
sewardj2019a972011-03-07 16:04:07 +00008706 IRTemp op2 = newTemp(Ity_I32);
8707
8708 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008709 put_fpr_w0(r1, binop(Iop_I32StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008710 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008711
8712 return "cefbr";
8713}
8714
florian55085f82012-11-21 00:36:55 +00008715static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008716s390_irgen_CDFBR(UChar m3 __attribute__((unused)),
8717 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008718{
8719 IRTemp op2 = newTemp(Ity_I32);
8720
8721 assign(op2, get_gpr_w1(r2));
8722 put_fpr_dw0(r1, unop(Iop_I32StoF64, mkexpr(op2)));
8723
8724 return "cdfbr";
8725}
8726
florian55085f82012-11-21 00:36:55 +00008727static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008728s390_irgen_CEGBR(UChar m3, UChar m4 __attribute__((unused)),
8729 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008730{
florian125e20d2012-10-07 15:42:37 +00008731 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008732 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008733 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008734 }
sewardj2019a972011-03-07 16:04:07 +00008735 IRTemp op2 = newTemp(Ity_I64);
8736
8737 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008738 put_fpr_w0(r1, binop(Iop_I64StoF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008739 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008740
8741 return "cegbr";
8742}
8743
florian55085f82012-11-21 00:36:55 +00008744static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008745s390_irgen_CDGBR(UChar m3, UChar m4 __attribute__((unused)),
8746 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008747{
florian125e20d2012-10-07 15:42:37 +00008748 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian4b8efad2012-09-02 18:07:08 +00008749 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00008750 m3 = S390_BFP_ROUND_PER_FPC;
florian4b8efad2012-09-02 18:07:08 +00008751 }
sewardj2019a972011-03-07 16:04:07 +00008752 IRTemp op2 = newTemp(Ity_I64);
8753
8754 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008755 put_fpr_dw0(r1, binop(Iop_I64StoF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00008756 mkexpr(op2)));
sewardj2019a972011-03-07 16:04:07 +00008757
8758 return "cdgbr";
8759}
8760
florian55085f82012-11-21 00:36:55 +00008761static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008762s390_irgen_CELFBR(UChar m3, UChar m4 __attribute__((unused)),
8763 UChar r1, UChar r2)
8764{
floriane75dafa2012-09-01 17:54:09 +00008765 if (! s390_host_has_fpext) {
8766 emulation_failure(EmFail_S390X_fpext);
8767 } else {
8768 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008769
floriane75dafa2012-09-01 17:54:09 +00008770 assign(op2, get_gpr_w1(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008771 put_fpr_w0(r1, binop(Iop_I32UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008772 mkexpr(op2)));
8773 }
florian1c8f7ff2012-09-01 00:12:11 +00008774 return "celfbr";
8775}
8776
florian55085f82012-11-21 00:36:55 +00008777static const HChar *
floriand2129202012-09-01 20:01:39 +00008778s390_irgen_CDLFBR(UChar m3 __attribute__((unused)),
8779 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +00008780{
floriane75dafa2012-09-01 17:54:09 +00008781 if (! s390_host_has_fpext) {
8782 emulation_failure(EmFail_S390X_fpext);
8783 } else {
8784 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +00008785
floriane75dafa2012-09-01 17:54:09 +00008786 assign(op2, get_gpr_w1(r2));
8787 put_fpr_dw0(r1, unop(Iop_I32UtoF64, mkexpr(op2)));
8788 }
florian1c8f7ff2012-09-01 00:12:11 +00008789 return "cdlfbr";
8790}
8791
florian55085f82012-11-21 00:36:55 +00008792static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008793s390_irgen_CELGBR(UChar m3, UChar m4 __attribute__((unused)),
8794 UChar r1, UChar r2)
8795{
floriane75dafa2012-09-01 17:54:09 +00008796 if (! s390_host_has_fpext) {
8797 emulation_failure(EmFail_S390X_fpext);
8798 } else {
8799 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008800
floriane75dafa2012-09-01 17:54:09 +00008801 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008802 put_fpr_w0(r1, binop(Iop_I64UtoF32, mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008803 mkexpr(op2)));
8804 }
florian1c8f7ff2012-09-01 00:12:11 +00008805 return "celgbr";
8806}
8807
florian55085f82012-11-21 00:36:55 +00008808static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008809s390_irgen_CDLGBR(UChar m3, UChar m4 __attribute__((unused)),
8810 UChar r1, UChar r2)
8811{
floriane75dafa2012-09-01 17:54:09 +00008812 if (! s390_host_has_fpext) {
8813 emulation_failure(EmFail_S390X_fpext);
8814 } else {
8815 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +00008816
floriane75dafa2012-09-01 17:54:09 +00008817 assign(op2, get_gpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008818 put_fpr_dw0(r1, binop(Iop_I64UtoF64,
8819 mkexpr(encode_bfp_rounding_mode(m3)),
floriane75dafa2012-09-01 17:54:09 +00008820 mkexpr(op2)));
8821 }
florian1c8f7ff2012-09-01 00:12:11 +00008822 return "cdlgbr";
8823}
8824
florian55085f82012-11-21 00:36:55 +00008825static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008826s390_irgen_CLFEBR(UChar m3, UChar m4 __attribute__((unused)),
8827 UChar r1, UChar r2)
8828{
floriane75dafa2012-09-01 17:54:09 +00008829 if (! s390_host_has_fpext) {
8830 emulation_failure(EmFail_S390X_fpext);
8831 } else {
8832 IRTemp op = newTemp(Ity_F32);
8833 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008834 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008835
floriane75dafa2012-09-01 17:54:09 +00008836 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008837 assign(result, binop(Iop_F32toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008838 mkexpr(op)));
8839 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008840 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008841 }
florian1c8f7ff2012-09-01 00:12:11 +00008842 return "clfebr";
8843}
8844
florian55085f82012-11-21 00:36:55 +00008845static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008846s390_irgen_CLFDBR(UChar m3, UChar m4 __attribute__((unused)),
8847 UChar r1, UChar r2)
8848{
floriane75dafa2012-09-01 17:54:09 +00008849 if (! s390_host_has_fpext) {
8850 emulation_failure(EmFail_S390X_fpext);
8851 } else {
8852 IRTemp op = newTemp(Ity_F64);
8853 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008854 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008855
floriane75dafa2012-09-01 17:54:09 +00008856 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008857 assign(result, binop(Iop_F64toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008858 mkexpr(op)));
8859 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008860 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008861 }
florian1c8f7ff2012-09-01 00:12:11 +00008862 return "clfdbr";
8863}
8864
florian55085f82012-11-21 00:36:55 +00008865static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008866s390_irgen_CLGEBR(UChar m3, UChar m4 __attribute__((unused)),
8867 UChar r1, UChar r2)
8868{
floriane75dafa2012-09-01 17:54:09 +00008869 if (! s390_host_has_fpext) {
8870 emulation_failure(EmFail_S390X_fpext);
8871 } else {
8872 IRTemp op = newTemp(Ity_F32);
8873 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008874 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008875
floriane75dafa2012-09-01 17:54:09 +00008876 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008877 assign(result, binop(Iop_F32toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008878 mkexpr(op)));
8879 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008880 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008881 }
florian1c8f7ff2012-09-01 00:12:11 +00008882 return "clgebr";
8883}
8884
florian55085f82012-11-21 00:36:55 +00008885static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +00008886s390_irgen_CLGDBR(UChar m3, UChar m4 __attribute__((unused)),
8887 UChar r1, UChar r2)
8888{
floriane75dafa2012-09-01 17:54:09 +00008889 if (! s390_host_has_fpext) {
8890 emulation_failure(EmFail_S390X_fpext);
8891 } else {
8892 IRTemp op = newTemp(Ity_F64);
8893 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008894 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +00008895
floriane75dafa2012-09-01 17:54:09 +00008896 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008897 assign(result, binop(Iop_F64toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +00008898 mkexpr(op)));
8899 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008900 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_UINT_64, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +00008901 }
florian1c8f7ff2012-09-01 00:12:11 +00008902 return "clgdbr";
8903}
8904
florian55085f82012-11-21 00:36:55 +00008905static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008906s390_irgen_CFEBR(UChar m3, UChar m4 __attribute__((unused)),
8907 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008908{
8909 IRTemp op = newTemp(Ity_F32);
8910 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008911 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008912
8913 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008914 assign(result, binop(Iop_F32toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008915 mkexpr(op)));
8916 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008917 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008918
8919 return "cfebr";
8920}
8921
florian55085f82012-11-21 00:36:55 +00008922static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008923s390_irgen_CFDBR(UChar m3, UChar m4 __attribute__((unused)),
8924 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008925{
8926 IRTemp op = newTemp(Ity_F64);
8927 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +00008928 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008929
8930 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008931 assign(result, binop(Iop_F64toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008932 mkexpr(op)));
8933 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008934 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008935
8936 return "cfdbr";
8937}
8938
florian55085f82012-11-21 00:36:55 +00008939static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008940s390_irgen_CGEBR(UChar m3, UChar m4 __attribute__((unused)),
8941 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008942{
8943 IRTemp op = newTemp(Ity_F32);
8944 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008945 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008946
8947 assign(op, get_fpr_w0(r2));
florian19e00772012-09-06 03:13:22 +00008948 assign(result, binop(Iop_F32toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008949 mkexpr(op)));
8950 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008951 s390_cc_thunk_putFZ(S390_CC_OP_BFP_32_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008952
8953 return "cgebr";
8954}
8955
florian55085f82012-11-21 00:36:55 +00008956static const HChar *
florian4b8efad2012-09-02 18:07:08 +00008957s390_irgen_CGDBR(UChar m3, UChar m4 __attribute__((unused)),
8958 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00008959{
8960 IRTemp op = newTemp(Ity_F64);
8961 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +00008962 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +00008963
8964 assign(op, get_fpr_dw0(r2));
florian19e00772012-09-06 03:13:22 +00008965 assign(result, binop(Iop_F64toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +00008966 mkexpr(op)));
8967 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +00008968 s390_cc_thunk_putFZ(S390_CC_OP_BFP_64_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +00008969
8970 return "cgdbr";
8971}
8972
florian55085f82012-11-21 00:36:55 +00008973static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008974s390_irgen_DEBR(UChar r1, UChar r2)
8975{
8976 IRTemp op1 = newTemp(Ity_F32);
8977 IRTemp op2 = newTemp(Ity_F32);
8978 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00008979 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008980
8981 assign(op1, get_fpr_w0(r1));
8982 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00008983 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00008984 mkexpr(op2)));
8985 put_fpr_w0(r1, mkexpr(result));
8986
8987 return "debr";
8988}
8989
florian55085f82012-11-21 00:36:55 +00008990static const HChar *
sewardj2019a972011-03-07 16:04:07 +00008991s390_irgen_DDBR(UChar r1, UChar r2)
8992{
8993 IRTemp op1 = newTemp(Ity_F64);
8994 IRTemp op2 = newTemp(Ity_F64);
8995 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00008996 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00008997
8998 assign(op1, get_fpr_dw0(r1));
8999 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009000 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009001 mkexpr(op2)));
9002 put_fpr_dw0(r1, mkexpr(result));
9003
9004 return "ddbr";
9005}
9006
florian55085f82012-11-21 00:36:55 +00009007static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009008s390_irgen_DEB(UChar r1, IRTemp op2addr)
9009{
9010 IRTemp op1 = newTemp(Ity_F32);
9011 IRTemp op2 = newTemp(Ity_F32);
9012 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009013 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009014
9015 assign(op1, get_fpr_w0(r1));
9016 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009017 assign(result, triop(Iop_DivF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009018 mkexpr(op2)));
9019 put_fpr_w0(r1, mkexpr(result));
9020
9021 return "deb";
9022}
9023
florian55085f82012-11-21 00:36:55 +00009024static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009025s390_irgen_DDB(UChar r1, IRTemp op2addr)
9026{
9027 IRTemp op1 = newTemp(Ity_F64);
9028 IRTemp op2 = newTemp(Ity_F64);
9029 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009030 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009031
9032 assign(op1, get_fpr_dw0(r1));
9033 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009034 assign(result, triop(Iop_DivF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009035 mkexpr(op2)));
9036 put_fpr_dw0(r1, mkexpr(result));
9037
9038 return "ddb";
9039}
9040
florian55085f82012-11-21 00:36:55 +00009041static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009042s390_irgen_LTEBR(UChar r1, UChar r2)
9043{
9044 IRTemp result = newTemp(Ity_F32);
9045
9046 assign(result, get_fpr_w0(r2));
9047 put_fpr_w0(r1, mkexpr(result));
9048 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9049
9050 return "ltebr";
9051}
9052
florian55085f82012-11-21 00:36:55 +00009053static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009054s390_irgen_LTDBR(UChar r1, UChar r2)
9055{
9056 IRTemp result = newTemp(Ity_F64);
9057
9058 assign(result, get_fpr_dw0(r2));
9059 put_fpr_dw0(r1, mkexpr(result));
9060 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9061
9062 return "ltdbr";
9063}
9064
florian55085f82012-11-21 00:36:55 +00009065static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009066s390_irgen_LCEBR(UChar r1, UChar r2)
9067{
9068 IRTemp result = newTemp(Ity_F32);
9069
9070 assign(result, unop(Iop_NegF32, get_fpr_w0(r2)));
9071 put_fpr_w0(r1, mkexpr(result));
9072 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9073
9074 return "lcebr";
9075}
9076
florian55085f82012-11-21 00:36:55 +00009077static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009078s390_irgen_LCDBR(UChar r1, UChar r2)
9079{
9080 IRTemp result = newTemp(Ity_F64);
9081
9082 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
9083 put_fpr_dw0(r1, mkexpr(result));
9084 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9085
9086 return "lcdbr";
9087}
9088
florian55085f82012-11-21 00:36:55 +00009089static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009090s390_irgen_LDEBR(UChar r1, UChar r2)
9091{
9092 IRTemp op = newTemp(Ity_F32);
9093
9094 assign(op, get_fpr_w0(r2));
9095 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9096
9097 return "ldebr";
9098}
9099
florian55085f82012-11-21 00:36:55 +00009100static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009101s390_irgen_LDEB(UChar r1, IRTemp op2addr)
9102{
9103 IRTemp op = newTemp(Ity_F32);
9104
9105 assign(op, load(Ity_F32, mkexpr(op2addr)));
9106 put_fpr_dw0(r1, unop(Iop_F32toF64, mkexpr(op)));
9107
9108 return "ldeb";
9109}
9110
florian55085f82012-11-21 00:36:55 +00009111static const HChar *
florian4b8efad2012-09-02 18:07:08 +00009112s390_irgen_LEDBR(UChar m3, UChar m4 __attribute__((unused)),
9113 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +00009114{
florian125e20d2012-10-07 15:42:37 +00009115 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +00009116 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +00009117 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +00009118 }
sewardj2019a972011-03-07 16:04:07 +00009119 IRTemp op = newTemp(Ity_F64);
9120
9121 assign(op, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009122 put_fpr_w0(r1, binop(Iop_F64toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +00009123 mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +00009124
9125 return "ledbr";
9126}
9127
florian55085f82012-11-21 00:36:55 +00009128static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009129s390_irgen_MEEBR(UChar r1, UChar r2)
9130{
9131 IRTemp op1 = newTemp(Ity_F32);
9132 IRTemp op2 = newTemp(Ity_F32);
9133 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009134 IRRoundingMode rounding_mode =
9135 encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009136
9137 assign(op1, get_fpr_w0(r1));
9138 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009139 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009140 mkexpr(op2)));
9141 put_fpr_w0(r1, mkexpr(result));
9142
9143 return "meebr";
9144}
9145
florian55085f82012-11-21 00:36:55 +00009146static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009147s390_irgen_MDBR(UChar r1, UChar r2)
9148{
9149 IRTemp op1 = newTemp(Ity_F64);
9150 IRTemp op2 = newTemp(Ity_F64);
9151 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009152 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009153
9154 assign(op1, get_fpr_dw0(r1));
9155 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009156 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009157 mkexpr(op2)));
9158 put_fpr_dw0(r1, mkexpr(result));
9159
9160 return "mdbr";
9161}
9162
florian55085f82012-11-21 00:36:55 +00009163static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009164s390_irgen_MEEB(UChar r1, IRTemp op2addr)
9165{
9166 IRTemp op1 = newTemp(Ity_F32);
9167 IRTemp op2 = newTemp(Ity_F32);
9168 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009169 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009170
9171 assign(op1, get_fpr_w0(r1));
9172 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009173 assign(result, triop(Iop_MulF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009174 mkexpr(op2)));
9175 put_fpr_w0(r1, mkexpr(result));
9176
9177 return "meeb";
9178}
9179
florian55085f82012-11-21 00:36:55 +00009180static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009181s390_irgen_MDB(UChar r1, IRTemp op2addr)
9182{
9183 IRTemp op1 = newTemp(Ity_F64);
9184 IRTemp op2 = newTemp(Ity_F64);
9185 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009186 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009187
9188 assign(op1, get_fpr_dw0(r1));
9189 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009190 assign(result, triop(Iop_MulF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009191 mkexpr(op2)));
9192 put_fpr_dw0(r1, mkexpr(result));
9193
9194 return "mdb";
9195}
9196
florian55085f82012-11-21 00:36:55 +00009197static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009198s390_irgen_SEBR(UChar r1, UChar r2)
9199{
9200 IRTemp op1 = newTemp(Ity_F32);
9201 IRTemp op2 = newTemp(Ity_F32);
9202 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009203 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009204
9205 assign(op1, get_fpr_w0(r1));
9206 assign(op2, get_fpr_w0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009207 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009208 mkexpr(op2)));
9209 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9210 put_fpr_w0(r1, mkexpr(result));
9211
9212 return "sebr";
9213}
9214
florian55085f82012-11-21 00:36:55 +00009215static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009216s390_irgen_SDBR(UChar r1, UChar r2)
9217{
9218 IRTemp op1 = newTemp(Ity_F64);
9219 IRTemp op2 = newTemp(Ity_F64);
9220 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009221 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009222
9223 assign(op1, get_fpr_dw0(r1));
9224 assign(op2, get_fpr_dw0(r2));
floriandb4fcaa2012-09-05 19:54:08 +00009225 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009226 mkexpr(op2)));
9227 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9228 put_fpr_dw0(r1, mkexpr(result));
9229
9230 return "sdbr";
9231}
9232
florian55085f82012-11-21 00:36:55 +00009233static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009234s390_irgen_SEB(UChar r1, IRTemp op2addr)
9235{
9236 IRTemp op1 = newTemp(Ity_F32);
9237 IRTemp op2 = newTemp(Ity_F32);
9238 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +00009239 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009240
9241 assign(op1, get_fpr_w0(r1));
9242 assign(op2, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009243 assign(result, triop(Iop_SubF32, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009244 mkexpr(op2)));
9245 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_32, result);
9246 put_fpr_w0(r1, mkexpr(result));
9247
9248 return "seb";
9249}
9250
florian55085f82012-11-21 00:36:55 +00009251static const HChar *
sewardj2019a972011-03-07 16:04:07 +00009252s390_irgen_SDB(UChar r1, IRTemp op2addr)
9253{
9254 IRTemp op1 = newTemp(Ity_F64);
9255 IRTemp op2 = newTemp(Ity_F64);
9256 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +00009257 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +00009258
9259 assign(op1, get_fpr_dw0(r1));
9260 assign(op2, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +00009261 assign(result, triop(Iop_SubF64, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +00009262 mkexpr(op2)));
9263 s390_cc_thunk_putF(S390_CC_OP_BFP_RESULT_64, result);
9264 put_fpr_dw0(r1, mkexpr(result));
9265
9266 return "sdb";
9267}
9268
florian55085f82012-11-21 00:36:55 +00009269static const HChar *
florian12390202012-11-10 22:34:14 +00009270s390_irgen_ADTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9271{
9272 IRTemp op1 = newTemp(Ity_D64);
9273 IRTemp op2 = newTemp(Ity_D64);
9274 IRTemp result = newTemp(Ity_D64);
9275 IRTemp rounding_mode;
9276
9277 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009278
9279 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9280 emulation_warning(EmWarn_S390X_fpext_rounding);
9281 m4 = S390_DFP_ROUND_PER_FPC_0;
9282 }
9283
florian12390202012-11-10 22:34:14 +00009284 rounding_mode = encode_dfp_rounding_mode(m4);
9285 assign(op1, get_dpr_dw0(r2));
9286 assign(op2, get_dpr_dw0(r3));
9287 assign(result, triop(Iop_AddD64, mkexpr(rounding_mode), mkexpr(op1),
9288 mkexpr(op2)));
9289 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9290 put_dpr_dw0(r1, mkexpr(result));
9291
9292 return (m4 == 0) ? "adtr" : "adtra";
9293}
9294
florian55085f82012-11-21 00:36:55 +00009295static const HChar *
floriane38f6412012-12-21 17:32:12 +00009296s390_irgen_AXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9297{
9298 IRTemp op1 = newTemp(Ity_D128);
9299 IRTemp op2 = newTemp(Ity_D128);
9300 IRTemp result = newTemp(Ity_D128);
9301 IRTemp rounding_mode;
9302
9303 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009304
9305 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9306 emulation_warning(EmWarn_S390X_fpext_rounding);
9307 m4 = S390_DFP_ROUND_PER_FPC_0;
9308 }
9309
floriane38f6412012-12-21 17:32:12 +00009310 rounding_mode = encode_dfp_rounding_mode(m4);
9311 assign(op1, get_dpr_pair(r2));
9312 assign(op2, get_dpr_pair(r3));
9313 assign(result, triop(Iop_AddD128, mkexpr(rounding_mode), mkexpr(op1),
9314 mkexpr(op2)));
9315 put_dpr_pair(r1, mkexpr(result));
9316
9317 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9318
9319 return (m4 == 0) ? "axtr" : "axtra";
9320}
9321
9322static const HChar *
9323s390_irgen_CDTR(UChar r1, UChar r2)
9324{
9325 IRTemp op1 = newTemp(Ity_D64);
9326 IRTemp op2 = newTemp(Ity_D64);
9327 IRTemp cc_vex = newTemp(Ity_I32);
9328 IRTemp cc_s390 = newTemp(Ity_I32);
9329
9330 assign(op1, get_dpr_dw0(r1));
9331 assign(op2, get_dpr_dw0(r2));
9332 assign(cc_vex, binop(Iop_CmpD64, mkexpr(op1), mkexpr(op2)));
9333
florian2d3d87f2012-12-21 21:05:17 +00009334 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009335 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9336
9337 return "cdtr";
9338}
9339
9340static const HChar *
9341s390_irgen_CXTR(UChar r1, UChar r2)
9342{
9343 IRTemp op1 = newTemp(Ity_D128);
9344 IRTemp op2 = newTemp(Ity_D128);
9345 IRTemp cc_vex = newTemp(Ity_I32);
9346 IRTemp cc_s390 = newTemp(Ity_I32);
9347
9348 assign(op1, get_dpr_pair(r1));
9349 assign(op2, get_dpr_pair(r2));
9350 assign(cc_vex, binop(Iop_CmpD128, mkexpr(op1), mkexpr(op2)));
9351
florian2d3d87f2012-12-21 21:05:17 +00009352 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
floriane38f6412012-12-21 17:32:12 +00009353 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9354
9355 return "cxtr";
9356}
9357
9358static const HChar *
florian5f034622013-01-13 02:29:05 +00009359s390_irgen_CDFTR(UChar m3 __attribute__((unused)),
9360 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9361{
9362 vassert(s390_host_has_dfp);
9363
9364 if (! s390_host_has_fpext) {
9365 emulation_failure(EmFail_S390X_fpext);
9366 } else {
9367 IRTemp op2 = newTemp(Ity_I32);
9368
9369 assign(op2, get_gpr_w1(r2));
9370 put_dpr_dw0(r1, unop(Iop_I32StoD64, mkexpr(op2)));
9371 }
9372 return "cdftr";
9373}
9374
9375static const HChar *
9376s390_irgen_CXFTR(UChar m3 __attribute__((unused)),
9377 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9378{
9379 vassert(s390_host_has_dfp);
9380
9381 if (! s390_host_has_fpext) {
9382 emulation_failure(EmFail_S390X_fpext);
9383 } else {
9384 IRTemp op2 = newTemp(Ity_I32);
9385
9386 assign(op2, get_gpr_w1(r2));
9387 put_dpr_pair(r1, unop(Iop_I32StoD128, mkexpr(op2)));
9388 }
9389 return "cxftr";
9390}
9391
9392static const HChar *
floriana887acd2013-02-08 23:32:54 +00009393s390_irgen_CDGTRA(UChar m3, UChar m4 __attribute__((unused)),
9394 UChar r1, UChar r2)
9395{
9396 IRTemp op2 = newTemp(Ity_I64);
9397
9398 vassert(s390_host_has_dfp);
9399 if (! s390_host_has_fpext && m3 != S390_DFP_ROUND_PER_FPC_0) {
9400 emulation_warning(EmWarn_S390X_fpext_rounding);
9401 m3 = S390_DFP_ROUND_PER_FPC_0;
9402 }
9403
9404 assign(op2, get_gpr_dw0(r2));
9405 put_dpr_dw0(r1, binop(Iop_I64StoD64, mkexpr(encode_dfp_rounding_mode(m3)),
9406 mkexpr(op2)));
9407
9408 return (m3 == 0) ? "cdgtr" : "cdgtra";
9409}
9410
9411static const HChar *
9412s390_irgen_CXGTR(UChar m3 __attribute__((unused)),
9413 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9414{
9415 IRTemp op2 = newTemp(Ity_I64);
9416
9417 vassert(s390_host_has_dfp);
9418
florian1bb7f6f2013-02-11 00:03:27 +00009419 /* No emulation warning here about an non-zero m3 on hosts without
9420 floating point extension facility. No rounding is performed */
9421
floriana887acd2013-02-08 23:32:54 +00009422 assign(op2, get_gpr_dw0(r2));
9423 put_dpr_pair(r1, unop(Iop_I64StoD128, mkexpr(op2)));
9424
9425 return "cxgtr";
9426}
9427
9428static const HChar *
florian5f034622013-01-13 02:29:05 +00009429s390_irgen_CDLFTR(UChar m3 __attribute__((unused)),
9430 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9431{
9432 vassert(s390_host_has_dfp);
9433
9434 if (! s390_host_has_fpext) {
9435 emulation_failure(EmFail_S390X_fpext);
9436 } else {
9437 IRTemp op2 = newTemp(Ity_I32);
9438
9439 assign(op2, get_gpr_w1(r2));
9440 put_dpr_dw0(r1, unop(Iop_I32UtoD64, mkexpr(op2)));
9441 }
9442 return "cdlftr";
9443}
9444
9445static const HChar *
9446s390_irgen_CXLFTR(UChar m3 __attribute__((unused)),
9447 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9448{
9449 vassert(s390_host_has_dfp);
9450
9451 if (! s390_host_has_fpext) {
9452 emulation_failure(EmFail_S390X_fpext);
9453 } else {
9454 IRTemp op2 = newTemp(Ity_I32);
9455
9456 assign(op2, get_gpr_w1(r2));
9457 put_dpr_pair(r1, unop(Iop_I32UtoD128, mkexpr(op2)));
9458 }
9459 return "cxlftr";
9460}
9461
9462static const HChar *
9463s390_irgen_CDLGTR(UChar m3, UChar m4 __attribute__((unused)),
9464 UChar r1, UChar r2)
9465{
9466 vassert(s390_host_has_dfp);
9467
9468 if (! s390_host_has_fpext) {
9469 emulation_failure(EmFail_S390X_fpext);
9470 } else {
9471 IRTemp op2 = newTemp(Ity_I64);
9472
9473 assign(op2, get_gpr_dw0(r2));
9474 put_dpr_dw0(r1, binop(Iop_I64UtoD64,
9475 mkexpr(encode_dfp_rounding_mode(m3)),
9476 mkexpr(op2)));
9477 }
9478 return "cdlgtr";
9479}
9480
9481static const HChar *
9482s390_irgen_CXLGTR(UChar m3 __attribute__((unused)),
9483 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9484{
9485 vassert(s390_host_has_dfp);
9486
9487 if (! s390_host_has_fpext) {
9488 emulation_failure(EmFail_S390X_fpext);
9489 } else {
9490 IRTemp op2 = newTemp(Ity_I64);
9491
9492 assign(op2, get_gpr_dw0(r2));
9493 put_dpr_pair(r1, unop(Iop_I64UtoD128, mkexpr(op2)));
9494 }
9495 return "cxlgtr";
9496}
9497
9498static const HChar *
9499s390_irgen_CFDTR(UChar m3, UChar m4 __attribute__((unused)),
9500 UChar r1, UChar r2)
9501{
9502 vassert(s390_host_has_dfp);
9503
9504 if (! s390_host_has_fpext) {
9505 emulation_failure(EmFail_S390X_fpext);
9506 } else {
9507 IRTemp op = newTemp(Ity_D64);
9508 IRTemp result = newTemp(Ity_I32);
9509 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9510
9511 assign(op, get_dpr_dw0(r2));
9512 assign(result, binop(Iop_D64toI32S, mkexpr(rounding_mode),
9513 mkexpr(op)));
9514 put_gpr_w1(r1, mkexpr(result));
9515 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_32, op, rounding_mode);
9516 }
9517 return "cfdtr";
9518}
9519
9520static const HChar *
9521s390_irgen_CFXTR(UChar m3, UChar m4 __attribute__((unused)),
9522 UChar r1, UChar r2)
9523{
9524 vassert(s390_host_has_dfp);
9525
9526 if (! s390_host_has_fpext) {
9527 emulation_failure(EmFail_S390X_fpext);
9528 } else {
9529 IRTemp op = newTemp(Ity_D128);
9530 IRTemp result = newTemp(Ity_I32);
9531 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9532
9533 assign(op, get_dpr_pair(r2));
9534 assign(result, binop(Iop_D128toI32S, mkexpr(rounding_mode),
9535 mkexpr(op)));
9536 put_gpr_w1(r1, mkexpr(result));
9537 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_32, op, rounding_mode);
9538 }
9539 return "cfxtr";
9540}
9541
9542static const HChar *
floriana887acd2013-02-08 23:32:54 +00009543s390_irgen_CGDTR(UChar m3, UChar m4 __attribute__((unused)),
9544 UChar r1, UChar r2)
9545{
9546 IRTemp op = newTemp(Ity_D64);
9547 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9548
9549 vassert(s390_host_has_dfp);
9550
9551 /* If fpext is not installed and m3 is in 1:7,
9552 rounding mode performed is unpredictable */
9553 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9554 emulation_warning(EmWarn_S390X_fpext_rounding);
9555 m3 = S390_DFP_ROUND_PER_FPC_0;
9556 }
9557
9558 assign(op, get_dpr_dw0(r2));
9559 put_gpr_dw0(r1, binop(Iop_D64toI64S, mkexpr(rounding_mode), mkexpr(op)));
9560 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_INT_64, op, rounding_mode);
9561
9562 return "cgdtr";
9563}
9564
9565static const HChar *
9566s390_irgen_CGXTR(UChar m3, UChar m4 __attribute__((unused)),
9567 UChar r1, UChar r2)
9568{
9569 IRTemp op = newTemp(Ity_D128);
9570 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9571
9572 vassert(s390_host_has_dfp);
9573
9574 /* If fpext is not installed and m3 is in 1:7,
9575 rounding mode performed is unpredictable */
9576 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
9577 emulation_warning(EmWarn_S390X_fpext_rounding);
9578 m3 = S390_DFP_ROUND_PER_FPC_0;
9579 }
9580 assign(op, get_dpr_pair(r2));
9581 put_gpr_dw0(r1, binop(Iop_D128toI64S, mkexpr(rounding_mode), mkexpr(op)));
9582 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_INT_64, op, rounding_mode);
9583
9584 return "cgxtr";
9585}
9586
9587static const HChar *
florian20c6bca2012-12-26 17:47:19 +00009588s390_irgen_CEDTR(UChar r1, UChar r2)
9589{
9590 IRTemp op1 = newTemp(Ity_D64);
9591 IRTemp op2 = newTemp(Ity_D64);
9592 IRTemp cc_vex = newTemp(Ity_I32);
9593 IRTemp cc_s390 = newTemp(Ity_I32);
9594
9595 vassert(s390_host_has_dfp);
9596 assign(op1, get_dpr_dw0(r1));
9597 assign(op2, get_dpr_dw0(r2));
9598 assign(cc_vex, binop(Iop_CmpExpD64, mkexpr(op1), mkexpr(op2)));
9599
9600 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9601 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9602
9603 return "cedtr";
9604}
9605
9606static const HChar *
9607s390_irgen_CEXTR(UChar r1, UChar r2)
9608{
9609 IRTemp op1 = newTemp(Ity_D128);
9610 IRTemp op2 = newTemp(Ity_D128);
9611 IRTemp cc_vex = newTemp(Ity_I32);
9612 IRTemp cc_s390 = newTemp(Ity_I32);
9613
9614 vassert(s390_host_has_dfp);
9615 assign(op1, get_dpr_pair(r1));
9616 assign(op2, get_dpr_pair(r2));
9617 assign(cc_vex, binop(Iop_CmpExpD128, mkexpr(op1), mkexpr(op2)));
9618
9619 assign(cc_s390, convert_vex_dfpcc_to_s390(cc_vex));
9620 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
9621
9622 return "cextr";
9623}
9624
9625static const HChar *
florian5f034622013-01-13 02:29:05 +00009626s390_irgen_CLFDTR(UChar m3, UChar m4 __attribute__((unused)),
9627 UChar r1, UChar r2)
9628{
9629 vassert(s390_host_has_dfp);
9630
9631 if (! s390_host_has_fpext) {
9632 emulation_failure(EmFail_S390X_fpext);
9633 } else {
9634 IRTemp op = newTemp(Ity_D64);
9635 IRTemp result = newTemp(Ity_I32);
9636 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9637
9638 assign(op, get_dpr_dw0(r2));
9639 assign(result, binop(Iop_D64toI32U, mkexpr(rounding_mode),
9640 mkexpr(op)));
9641 put_gpr_w1(r1, mkexpr(result));
9642 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_32, op, rounding_mode);
9643 }
9644 return "clfdtr";
9645}
9646
9647static const HChar *
9648s390_irgen_CLFXTR(UChar m3, UChar m4 __attribute__((unused)),
9649 UChar r1, UChar r2)
9650{
9651 vassert(s390_host_has_dfp);
9652
9653 if (! s390_host_has_fpext) {
9654 emulation_failure(EmFail_S390X_fpext);
9655 } else {
9656 IRTemp op = newTemp(Ity_D128);
9657 IRTemp result = newTemp(Ity_I32);
9658 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9659
9660 assign(op, get_dpr_pair(r2));
9661 assign(result, binop(Iop_D128toI32U, mkexpr(rounding_mode),
9662 mkexpr(op)));
9663 put_gpr_w1(r1, mkexpr(result));
9664 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_32, op, rounding_mode);
9665 }
9666 return "clfxtr";
9667}
9668
9669static const HChar *
9670s390_irgen_CLGDTR(UChar m3, UChar m4 __attribute__((unused)),
9671 UChar r1, UChar r2)
9672{
9673 vassert(s390_host_has_dfp);
9674
9675 if (! s390_host_has_fpext) {
9676 emulation_failure(EmFail_S390X_fpext);
9677 } else {
9678 IRTemp op = newTemp(Ity_D64);
9679 IRTemp result = newTemp(Ity_I64);
9680 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9681
9682 assign(op, get_dpr_dw0(r2));
9683 assign(result, binop(Iop_D64toI64U, mkexpr(rounding_mode),
9684 mkexpr(op)));
9685 put_gpr_dw0(r1, mkexpr(result));
9686 s390_cc_thunk_putFZ(S390_CC_OP_DFP_64_TO_UINT_64, op, rounding_mode);
9687 }
9688 return "clgdtr";
9689}
9690
9691static const HChar *
9692s390_irgen_CLGXTR(UChar m3, UChar m4 __attribute__((unused)),
9693 UChar r1, UChar r2)
9694{
9695 vassert(s390_host_has_dfp);
9696
9697 if (! s390_host_has_fpext) {
9698 emulation_failure(EmFail_S390X_fpext);
9699 } else {
9700 IRTemp op = newTemp(Ity_D128);
9701 IRTemp result = newTemp(Ity_I64);
9702 IRTemp rounding_mode = encode_dfp_rounding_mode(m3);
9703
9704 assign(op, get_dpr_pair(r2));
9705 assign(result, binop(Iop_D128toI64U, mkexpr(rounding_mode),
9706 mkexpr(op)));
9707 put_gpr_dw0(r1, mkexpr(result));
9708 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_128_TO_UINT_64, op,
9709 rounding_mode);
9710 }
9711 return "clgxtr";
9712}
9713
9714static const HChar *
florian12390202012-11-10 22:34:14 +00009715s390_irgen_DDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9716{
9717 IRTemp op1 = newTemp(Ity_D64);
9718 IRTemp op2 = newTemp(Ity_D64);
9719 IRTemp result = newTemp(Ity_D64);
9720 IRTemp rounding_mode;
9721
9722 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009723
9724 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9725 emulation_warning(EmWarn_S390X_fpext_rounding);
9726 m4 = S390_DFP_ROUND_PER_FPC_0;
9727 }
9728
florian12390202012-11-10 22:34:14 +00009729 rounding_mode = encode_dfp_rounding_mode(m4);
9730 assign(op1, get_dpr_dw0(r2));
9731 assign(op2, get_dpr_dw0(r3));
9732 assign(result, triop(Iop_DivD64, mkexpr(rounding_mode), mkexpr(op1),
9733 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009734 put_dpr_dw0(r1, mkexpr(result));
9735
9736 return (m4 == 0) ? "ddtr" : "ddtra";
9737}
9738
florian55085f82012-11-21 00:36:55 +00009739static const HChar *
floriane38f6412012-12-21 17:32:12 +00009740s390_irgen_DXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9741{
9742 IRTemp op1 = newTemp(Ity_D128);
9743 IRTemp op2 = newTemp(Ity_D128);
9744 IRTemp result = newTemp(Ity_D128);
9745 IRTemp rounding_mode;
9746
9747 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009748
9749 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9750 emulation_warning(EmWarn_S390X_fpext_rounding);
9751 m4 = S390_DFP_ROUND_PER_FPC_0;
9752 }
9753
floriane38f6412012-12-21 17:32:12 +00009754 rounding_mode = encode_dfp_rounding_mode(m4);
9755 assign(op1, get_dpr_pair(r2));
9756 assign(op2, get_dpr_pair(r3));
9757 assign(result, triop(Iop_DivD128, mkexpr(rounding_mode), mkexpr(op1),
9758 mkexpr(op2)));
9759 put_dpr_pair(r1, mkexpr(result));
9760
9761 return (m4 == 0) ? "dxtr" : "dxtra";
9762}
9763
9764static const HChar *
florian5c539732013-02-14 14:27:12 +00009765s390_irgen_EEDTR(UChar r1, UChar r2)
9766{
9767 vassert(s390_host_has_dfp);
9768
9769 put_gpr_dw0(r1, unop(Iop_ExtractExpD64, get_dpr_dw0(r2)));
9770 return "eedtr";
9771}
9772
9773static const HChar *
9774s390_irgen_EEXTR(UChar r1, UChar r2)
9775{
9776 vassert(s390_host_has_dfp);
9777
9778 put_gpr_dw0(r1, unop(Iop_ExtractExpD128, get_dpr_pair(r2)));
9779 return "eextr";
9780}
9781
9782static const HChar *
floriance9e3db2012-12-27 20:14:03 +00009783s390_irgen_ESDTR(UChar r1, UChar r2)
9784{
9785 vassert(s390_host_has_dfp);
9786 put_gpr_dw0(r1, unop(Iop_ExtractSigD64, get_dpr_dw0(r2)));
9787 return "esdtr";
9788}
9789
9790static const HChar *
9791s390_irgen_ESXTR(UChar r1, UChar r2)
9792{
9793 vassert(s390_host_has_dfp);
9794 put_gpr_dw0(r1, unop(Iop_ExtractSigD128, get_dpr_pair(r2)));
9795 return "esxtr";
9796}
9797
9798static const HChar *
florian5c539732013-02-14 14:27:12 +00009799s390_irgen_IEDTR(UChar r3, UChar r1, UChar r2)
9800{
9801 IRTemp op1 = newTemp(Ity_I64);
9802 IRTemp op2 = newTemp(Ity_D64);
9803 IRTemp result = newTemp(Ity_D64);
9804
9805 vassert(s390_host_has_dfp);
9806
9807 assign(op1, get_gpr_dw0(r2));
9808 assign(op2, get_dpr_dw0(r3));
9809 assign(result, binop(Iop_InsertExpD64, mkexpr(op1), mkexpr(op2)));
9810 put_dpr_dw0(r1, mkexpr(result));
9811
9812 return "iedtr";
9813}
9814
9815static const HChar *
9816s390_irgen_IEXTR(UChar r3, UChar r1, UChar r2)
9817{
9818 IRTemp op1 = newTemp(Ity_I64);
9819 IRTemp op2 = newTemp(Ity_D128);
9820 IRTemp result = newTemp(Ity_D128);
9821
9822 vassert(s390_host_has_dfp);
9823
9824 assign(op1, get_gpr_dw0(r2));
9825 assign(op2, get_dpr_pair(r3));
9826 assign(result, binop(Iop_InsertExpD128, mkexpr(op1), mkexpr(op2)));
9827 put_dpr_pair(r1, mkexpr(result));
9828
9829 return "iextr";
9830}
9831
9832static const HChar *
floriane38f6412012-12-21 17:32:12 +00009833s390_irgen_LDETR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9834{
9835 IRTemp op = newTemp(Ity_D32);
9836
9837 vassert(s390_host_has_dfp);
9838
9839 assign(op, get_dpr_w0(r2));
9840 put_dpr_dw0(r1, unop(Iop_D32toD64, mkexpr(op)));
9841
9842 return "ldetr";
9843}
9844
9845static const HChar *
9846s390_irgen_LXDTR(UChar m4 __attribute__((unused)), UChar r1, UChar r2)
9847{
9848 IRTemp op = newTemp(Ity_D64);
9849
9850 assign(op, get_dpr_dw0(r2));
9851 put_dpr_pair(r1, unop(Iop_D64toD128, mkexpr(op)));
9852
9853 return "lxdtr";
9854}
9855
9856static const HChar *
9857s390_irgen_LDXTR(UChar m3, UChar m4 __attribute__((unused)),
9858 UChar r1, UChar r2)
9859{
9860 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009861
9862 /* If fpext is not installed and m3 is in 1:7,
9863 rounding mode performed is unpredictable */
9864 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +00009865 emulation_warning(EmWarn_S390X_fpext_rounding);
9866 m3 = S390_DFP_ROUND_PER_FPC_0;
9867 }
9868 IRTemp result = newTemp(Ity_D64);
9869
9870 assign(result, binop(Iop_D128toD64, mkexpr(encode_dfp_rounding_mode(m3)),
9871 get_dpr_pair(r2)));
9872 put_dpr_dw0(r1, mkexpr(result));
9873
9874 return "ldxtr";
9875}
9876
9877static const HChar *
9878s390_irgen_LEDTR(UChar m3, UChar m4 __attribute__((unused)),
9879 UChar r1, UChar r2)
9880{
9881 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009882
9883 /* If fpext is not installed and m3 is in 1:7,
9884 rounding mode performed is unpredictable */
9885 if (! s390_host_has_fpext && m3 > 0 && m3 < 8) {
floriane38f6412012-12-21 17:32:12 +00009886 emulation_warning(EmWarn_S390X_fpext_rounding);
9887 m3 = S390_DFP_ROUND_PER_FPC_0;
9888 }
9889 IRTemp op = newTemp(Ity_D64);
9890
9891 assign(op, get_dpr_dw0(r2));
9892 put_dpr_w0(r1, binop(Iop_D64toD32, mkexpr(encode_dfp_rounding_mode(m3)),
9893 mkexpr(op)));
9894
9895 return "ledtr";
9896}
9897
9898static const HChar *
9899s390_irgen_LTDTR(UChar r1, UChar r2)
9900{
9901 IRTemp result = newTemp(Ity_D64);
9902
9903 assign(result, get_dpr_dw0(r2));
9904 put_dpr_dw0(r1, mkexpr(result));
9905 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
9906
9907 return "ltdtr";
9908}
9909
9910static const HChar *
9911s390_irgen_LTXTR(UChar r1, UChar r2)
9912{
9913 IRTemp result = newTemp(Ity_D128);
9914
9915 assign(result, get_dpr_pair(r2));
9916 put_dpr_pair(r1, mkexpr(result));
9917 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
9918
9919 return "ltxtr";
9920}
9921
9922static const HChar *
florian12390202012-11-10 22:34:14 +00009923s390_irgen_MDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9924{
9925 IRTemp op1 = newTemp(Ity_D64);
9926 IRTemp op2 = newTemp(Ity_D64);
9927 IRTemp result = newTemp(Ity_D64);
9928 IRTemp rounding_mode;
9929
9930 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009931
9932 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9933 emulation_warning(EmWarn_S390X_fpext_rounding);
9934 m4 = S390_DFP_ROUND_PER_FPC_0;
9935 }
9936
florian12390202012-11-10 22:34:14 +00009937 rounding_mode = encode_dfp_rounding_mode(m4);
9938 assign(op1, get_dpr_dw0(r2));
9939 assign(op2, get_dpr_dw0(r3));
9940 assign(result, triop(Iop_MulD64, mkexpr(rounding_mode), mkexpr(op1),
9941 mkexpr(op2)));
florian12390202012-11-10 22:34:14 +00009942 put_dpr_dw0(r1, mkexpr(result));
9943
9944 return (m4 == 0) ? "mdtr" : "mdtra";
9945}
9946
florian55085f82012-11-21 00:36:55 +00009947static const HChar *
floriane38f6412012-12-21 17:32:12 +00009948s390_irgen_MXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
9949{
9950 IRTemp op1 = newTemp(Ity_D128);
9951 IRTemp op2 = newTemp(Ity_D128);
9952 IRTemp result = newTemp(Ity_D128);
9953 IRTemp rounding_mode;
9954
9955 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +00009956
9957 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
9958 emulation_warning(EmWarn_S390X_fpext_rounding);
9959 m4 = S390_DFP_ROUND_PER_FPC_0;
9960 }
9961
floriane38f6412012-12-21 17:32:12 +00009962 rounding_mode = encode_dfp_rounding_mode(m4);
9963 assign(op1, get_dpr_pair(r2));
9964 assign(op2, get_dpr_pair(r3));
9965 assign(result, triop(Iop_MulD128, mkexpr(rounding_mode), mkexpr(op1),
9966 mkexpr(op2)));
9967 put_dpr_pair(r1, mkexpr(result));
9968
9969 return (m4 == 0) ? "mxtr" : "mxtra";
9970}
9971
9972static const HChar *
florian5c539732013-02-14 14:27:12 +00009973s390_irgen_QADTR(UChar r3, UChar m4, UChar r1, UChar r2)
9974{
9975 IRTemp op1 = newTemp(Ity_D64);
9976 IRTemp op2 = newTemp(Ity_D64);
9977 IRTemp result = newTemp(Ity_D64);
9978 IRTemp rounding_mode;
9979
9980 vassert(s390_host_has_dfp);
9981 /* If fpext is not installed and m4 is in 1:7,
9982 rounding mode performed is unpredictable */
9983 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
9984 emulation_warning(EmWarn_S390X_fpext_rounding);
9985 m4 = S390_DFP_ROUND_PER_FPC_0;
9986 }
9987
9988 rounding_mode = encode_dfp_rounding_mode(m4);
9989 assign(op1, get_dpr_dw0(r2));
9990 assign(op2, get_dpr_dw0(r3));
9991 assign(result, triop(Iop_QuantizeD64, mkexpr(rounding_mode), mkexpr(op1),
9992 mkexpr(op2)));
9993 put_dpr_dw0(r1, mkexpr(result));
9994
9995 return "qadtr";
9996}
9997
9998static const HChar *
9999s390_irgen_QAXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10000{
10001 IRTemp op1 = newTemp(Ity_D128);
10002 IRTemp op2 = newTemp(Ity_D128);
10003 IRTemp result = newTemp(Ity_D128);
10004 IRTemp rounding_mode;
10005
10006 vassert(s390_host_has_dfp);
10007 /* If fpext is not installed and m4 is in 1:7,
10008 rounding mode performed is unpredictable */
10009 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10010 emulation_warning(EmWarn_S390X_fpext_rounding);
10011 m4 = S390_DFP_ROUND_PER_FPC_0;
10012 }
10013
10014 rounding_mode = encode_dfp_rounding_mode(m4);
10015 assign(op1, get_dpr_pair(r2));
10016 assign(op2, get_dpr_pair(r3));
10017 assign(result, triop(Iop_QuantizeD128, mkexpr(rounding_mode), mkexpr(op1),
10018 mkexpr(op2)));
10019 put_dpr_pair(r1, mkexpr(result));
10020
10021 return "qaxtr";
10022}
10023
10024static const HChar *
10025s390_irgen_RRDTR(UChar r3, UChar m4, UChar r1, UChar r2)
10026{
10027 IRTemp op1 = newTemp(Ity_I8);
10028 IRTemp op2 = newTemp(Ity_D64);
10029 IRTemp result = newTemp(Ity_D64);
10030 IRTemp rounding_mode;
10031
10032 vassert(s390_host_has_dfp);
10033 /* If fpext is not installed and m4 is in 1:7,
10034 rounding mode performed is unpredictable */
10035 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10036 emulation_warning(EmWarn_S390X_fpext_rounding);
10037 m4 = S390_DFP_ROUND_PER_FPC_0;
10038 }
10039
10040 rounding_mode = encode_dfp_rounding_mode(m4);
10041 assign(op1, get_gpr_b7(r2));
10042 assign(op2, get_dpr_dw0(r3));
10043 assign(result, triop(Iop_SignificanceRoundD64, mkexpr(rounding_mode),
10044 mkexpr(op1), mkexpr(op2)));
10045 put_dpr_dw0(r1, mkexpr(result));
10046
10047 return "rrdtr";
10048}
10049
10050static const HChar *
10051s390_irgen_RRXTR(UChar r3, UChar m4, UChar r1, UChar r2)
10052{
10053 IRTemp op1 = newTemp(Ity_I8);
10054 IRTemp op2 = newTemp(Ity_D128);
10055 IRTemp result = newTemp(Ity_D128);
10056 IRTemp rounding_mode;
10057
10058 vassert(s390_host_has_dfp);
10059 /* If fpext is not installed and m4 is in 1:7,
10060 rounding mode performed is unpredictable */
10061 if (! s390_host_has_fpext && m4 > 0 && m4 < 8) {
10062 emulation_warning(EmWarn_S390X_fpext_rounding);
10063 m4 = S390_DFP_ROUND_PER_FPC_0;
10064 }
10065
10066 rounding_mode = encode_dfp_rounding_mode(m4);
10067 assign(op1, get_gpr_b7(r2));
10068 assign(op2, get_dpr_pair(r3));
10069 assign(result, triop(Iop_SignificanceRoundD128, mkexpr(rounding_mode),
10070 mkexpr(op1), mkexpr(op2)));
10071 put_dpr_pair(r1, mkexpr(result));
10072
10073 return "rrxtr";
10074}
10075
10076static const HChar *
florian12390202012-11-10 22:34:14 +000010077s390_irgen_SDTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10078{
10079 IRTemp op1 = newTemp(Ity_D64);
10080 IRTemp op2 = newTemp(Ity_D64);
10081 IRTemp result = newTemp(Ity_D64);
10082 IRTemp rounding_mode;
10083
10084 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010085
10086 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10087 emulation_warning(EmWarn_S390X_fpext_rounding);
10088 m4 = S390_DFP_ROUND_PER_FPC_0;
10089 }
10090
florian12390202012-11-10 22:34:14 +000010091 rounding_mode = encode_dfp_rounding_mode(m4);
10092 assign(op1, get_dpr_dw0(r2));
10093 assign(op2, get_dpr_dw0(r3));
10094 assign(result, triop(Iop_SubD64, mkexpr(rounding_mode), mkexpr(op1),
10095 mkexpr(op2)));
10096 s390_cc_thunk_putF(S390_CC_OP_DFP_RESULT_64, result);
10097 put_dpr_dw0(r1, mkexpr(result));
10098
10099 return (m4 == 0) ? "sdtr" : "sdtra";
10100}
10101
floriane38f6412012-12-21 17:32:12 +000010102static const HChar *
10103s390_irgen_SXTRA(UChar r3, UChar m4, UChar r1, UChar r2)
10104{
10105 IRTemp op1 = newTemp(Ity_D128);
10106 IRTemp op2 = newTemp(Ity_D128);
10107 IRTemp result = newTemp(Ity_D128);
10108 IRTemp rounding_mode;
10109
10110 vassert(s390_host_has_dfp);
florian1bb7f6f2013-02-11 00:03:27 +000010111
10112 if (! s390_host_has_fpext && m4 != S390_DFP_ROUND_PER_FPC_0) {
10113 emulation_warning(EmWarn_S390X_fpext_rounding);
10114 m4 = S390_DFP_ROUND_PER_FPC_0;
10115 }
10116
floriane38f6412012-12-21 17:32:12 +000010117 rounding_mode = encode_dfp_rounding_mode(m4);
10118 assign(op1, get_dpr_pair(r2));
10119 assign(op2, get_dpr_pair(r3));
10120 assign(result, triop(Iop_SubD128, mkexpr(rounding_mode), mkexpr(op1),
10121 mkexpr(op2)));
10122 put_dpr_pair(r1, mkexpr(result));
10123
10124 s390_cc_thunk_put1d128(S390_CC_OP_DFP_RESULT_128, result);
10125
10126 return (m4 == 0) ? "sxtr" : "sxtra";
10127}
sewardj2019a972011-03-07 16:04:07 +000010128
florian55085f82012-11-21 00:36:55 +000010129static const HChar *
florian1b901d42013-01-01 22:19:24 +000010130s390_irgen_SLDT(UChar r3, IRTemp op2addr, UChar r1)
10131{
10132 IRTemp op = newTemp(Ity_D64);
10133
10134 vassert(s390_host_has_dfp);
10135
10136 assign(op, get_dpr_dw0(r3));
10137 put_dpr_dw0(r1, binop(Iop_ShlD64, mkexpr(op), unop(Iop_64to8,
10138 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10139
10140 return "sldt";
10141}
10142
10143static const HChar *
10144s390_irgen_SLXT(UChar r3, IRTemp op2addr, UChar r1)
10145{
10146 IRTemp op = newTemp(Ity_D128);
10147
10148 vassert(s390_host_has_dfp);
10149
10150 assign(op, get_dpr_pair(r3));
10151 put_dpr_pair(r1, binop(Iop_ShlD128, mkexpr(op), unop(Iop_64to8,
10152 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10153
10154 return "slxt";
10155}
10156
10157static const HChar *
10158s390_irgen_SRDT(UChar r3, IRTemp op2addr, UChar r1)
10159{
10160 IRTemp op = newTemp(Ity_D64);
10161
10162 vassert(s390_host_has_dfp);
10163
10164 assign(op, get_dpr_dw0(r3));
10165 put_dpr_dw0(r1, binop(Iop_ShrD64, mkexpr(op), unop(Iop_64to8,
10166 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10167
10168 return "srdt";
10169}
10170
10171static const HChar *
10172s390_irgen_SRXT(UChar r3, IRTemp op2addr, UChar r1)
10173{
10174 IRTemp op = newTemp(Ity_D128);
10175
10176 vassert(s390_host_has_dfp);
10177
10178 assign(op, get_dpr_pair(r3));
10179 put_dpr_pair(r1, binop(Iop_ShrD128, mkexpr(op), unop(Iop_64to8,
10180 binop(Iop_And64, mkexpr(op2addr), mkU64(63)))));
10181
10182 return "srxt";
10183}
10184
10185static const HChar *
floriance9e3db2012-12-27 20:14:03 +000010186s390_irgen_TDCET(UChar r1, IRTemp op2addr)
10187{
10188 IRTemp value = newTemp(Ity_D32);
10189
10190 vassert(s390_host_has_dfp);
10191 assign(value, get_dpr_w0(r1));
10192
10193 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_32, value, op2addr);
10194
10195 return "tdcet";
10196}
10197
10198static const HChar *
10199s390_irgen_TDCDT(UChar r1, IRTemp op2addr)
10200{
10201 IRTemp value = newTemp(Ity_D64);
10202
10203 vassert(s390_host_has_dfp);
10204 assign(value, get_dpr_dw0(r1));
10205
10206 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDC_64, value, op2addr);
10207
10208 return "tdcdt";
10209}
10210
10211static const HChar *
10212s390_irgen_TDCXT(UChar r1, IRTemp op2addr)
10213{
10214 IRTemp value = newTemp(Ity_D128);
10215
10216 vassert(s390_host_has_dfp);
10217 assign(value, get_dpr_pair(r1));
10218
10219 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDC_128, value, op2addr);
10220
10221 return "tdcxt";
10222}
10223
10224static const HChar *
10225s390_irgen_TDGET(UChar r1, IRTemp op2addr)
10226{
10227 IRTemp value = newTemp(Ity_D32);
10228
10229 vassert(s390_host_has_dfp);
10230 assign(value, get_dpr_w0(r1));
10231
10232 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_32, value, op2addr);
10233
10234 return "tdget";
10235}
10236
10237static const HChar *
10238s390_irgen_TDGDT(UChar r1, IRTemp op2addr)
10239{
10240 IRTemp value = newTemp(Ity_D64);
10241
10242 vassert(s390_host_has_dfp);
10243 assign(value, get_dpr_dw0(r1));
10244
10245 s390_cc_thunk_putFZ(S390_CC_OP_DFP_TDG_64, value, op2addr);
10246
10247 return "tdgdt";
10248}
10249
10250static const HChar *
10251s390_irgen_TDGXT(UChar r1, IRTemp op2addr)
10252{
10253 IRTemp value = newTemp(Ity_D128);
10254
10255 vassert(s390_host_has_dfp);
10256 assign(value, get_dpr_pair(r1));
10257
10258 s390_cc_thunk_put1d128Z(S390_CC_OP_DFP_TDG_128, value, op2addr);
10259
10260 return "tdgxt";
10261}
10262
10263static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010264s390_irgen_CLC(UChar length, IRTemp start1, IRTemp start2)
10265{
florian79e839e2012-05-05 02:20:30 +000010266 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000010267
florian79e839e2012-05-05 02:20:30 +000010268 assign(len, mkU64(length));
10269 s390_irgen_CLC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010270
10271 return "clc";
10272}
10273
florian55085f82012-11-21 00:36:55 +000010274static const HChar *
florianb0c9a132011-09-08 15:37:39 +000010275s390_irgen_CLCL(UChar r1, UChar r2)
10276{
10277 IRTemp addr1 = newTemp(Ity_I64);
10278 IRTemp addr2 = newTemp(Ity_I64);
10279 IRTemp addr1_load = newTemp(Ity_I64);
10280 IRTemp addr2_load = newTemp(Ity_I64);
10281 IRTemp len1 = newTemp(Ity_I32);
10282 IRTemp len2 = newTemp(Ity_I32);
10283 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
10284 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
10285 IRTemp single1 = newTemp(Ity_I8);
10286 IRTemp single2 = newTemp(Ity_I8);
10287 IRTemp pad = newTemp(Ity_I8);
10288
10289 assign(addr1, get_gpr_dw0(r1));
10290 assign(r1p1, get_gpr_w1(r1 + 1));
10291 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
10292 assign(addr2, get_gpr_dw0(r2));
10293 assign(r2p1, get_gpr_w1(r2 + 1));
10294 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
10295 assign(pad, get_gpr_b4(r2 + 1));
10296
10297 /* len1 == 0 and len2 == 0? Exit */
10298 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010299 next_insn_if(binop(Iop_CmpEQ32, binop(Iop_Or32, mkexpr(len1),
10300 mkexpr(len2)), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000010301
10302 /* Because mkite evaluates both the then-clause and the else-clause
10303 we cannot load directly from addr1 here. If len1 is 0, then adddr1
10304 may be NULL and loading from there would segfault. So we provide a
10305 valid dummy address in that case. Loading from there does no harm and
10306 the value will be discarded at runtime. */
10307 assign(addr1_load,
10308 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10309 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
10310 assign(single1,
10311 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10312 mkexpr(pad), load(Ity_I8, mkexpr(addr1_load))));
10313
10314 assign(addr2_load,
10315 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10316 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
10317 assign(single2,
10318 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10319 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
10320
10321 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single2, False);
10322 /* Fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010323 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single2)));
florianb0c9a132011-09-08 15:37:39 +000010324
10325 /* Update len1 and addr1, unless len1 == 0. */
10326 put_gpr_dw0(r1,
10327 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10328 mkexpr(addr1),
10329 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
10330
10331 /* When updating len1 we must not modify bits (r1+1)[0:39] */
10332 put_gpr_w1(r1 + 1,
10333 mkite(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)),
10334 binop(Iop_And32, mkexpr(r1p1), mkU32(0xFF000000u)),
10335 binop(Iop_Sub32, mkexpr(r1p1), mkU32(1))));
10336
10337 /* Update len2 and addr2, unless len2 == 0. */
10338 put_gpr_dw0(r2,
10339 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10340 mkexpr(addr2),
10341 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
10342
10343 /* When updating len2 we must not modify bits (r2+1)[0:39] */
10344 put_gpr_w1(r2 + 1,
10345 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
10346 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
10347 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
10348
florian6820ba52012-07-26 02:01:50 +000010349 iterate();
florianb0c9a132011-09-08 15:37:39 +000010350
10351 return "clcl";
10352}
10353
florian55085f82012-11-21 00:36:55 +000010354static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010355s390_irgen_CLCLE(UChar r1, UChar r3, IRTemp pad2)
10356{
10357 IRTemp addr1, addr3, addr1_load, addr3_load, len1, len3, single1, single3;
10358
10359 addr1 = newTemp(Ity_I64);
10360 addr3 = newTemp(Ity_I64);
10361 addr1_load = newTemp(Ity_I64);
10362 addr3_load = newTemp(Ity_I64);
10363 len1 = newTemp(Ity_I64);
10364 len3 = newTemp(Ity_I64);
10365 single1 = newTemp(Ity_I8);
10366 single3 = newTemp(Ity_I8);
10367
10368 assign(addr1, get_gpr_dw0(r1));
10369 assign(len1, get_gpr_dw0(r1 + 1));
10370 assign(addr3, get_gpr_dw0(r3));
10371 assign(len3, get_gpr_dw0(r3 + 1));
10372
10373 /* len1 == 0 and len3 == 0? Exit */
10374 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000010375 next_insn_if(binop(Iop_CmpEQ64,binop(Iop_Or64, mkexpr(len1),
10376 mkexpr(len3)), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000010377
10378 /* A mux requires both ways to be possible. This is a way to prevent clcle
10379 from reading from addr1 if it should read from the pad. Since the pad
10380 has no address, just read from the instruction, we discard that anyway */
10381 assign(addr1_load,
florian6ad49522011-09-09 02:38:55 +000010382 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10383 mkU64(guest_IA_curr_instr), mkexpr(addr1)));
sewardj2019a972011-03-07 16:04:07 +000010384
10385 /* same for addr3 */
10386 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000010387 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10388 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000010389
10390 assign(single1,
florian6ad49522011-09-09 02:38:55 +000010391 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10392 unop(Iop_64to8, mkexpr(pad2)),
10393 load(Ity_I8, mkexpr(addr1_load))));
sewardj2019a972011-03-07 16:04:07 +000010394
10395 assign(single3,
florian6ad49522011-09-09 02:38:55 +000010396 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10397 unop(Iop_64to8, mkexpr(pad2)),
10398 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000010399
10400 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, single1, single3, False);
10401 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010402 next_insn_if(binop(Iop_CmpNE8, mkexpr(single1), mkexpr(single3)));
sewardj2019a972011-03-07 16:04:07 +000010403
10404 /* If a length in 0 we must not change this length and the address */
10405 put_gpr_dw0(r1,
florian6ad49522011-09-09 02:38:55 +000010406 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10407 mkexpr(addr1),
10408 binop(Iop_Add64, mkexpr(addr1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010409
10410 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000010411 mkite(binop(Iop_CmpEQ64, mkexpr(len1), mkU64(0)),
10412 mkU64(0), binop(Iop_Sub64, mkexpr(len1), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010413
10414 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000010415 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10416 mkexpr(addr3),
10417 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010418
10419 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000010420 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
10421 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000010422
florian6820ba52012-07-26 02:01:50 +000010423 iterate();
sewardj2019a972011-03-07 16:04:07 +000010424
10425 return "clcle";
10426}
floriana64c2432011-07-16 02:11:50 +000010427
florianb0bf6602012-05-05 00:01:16 +000010428
sewardj2019a972011-03-07 16:04:07 +000010429static void
10430s390_irgen_XC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10431{
florianb0bf6602012-05-05 00:01:16 +000010432 s390_irgen_xonc(Iop_Xor8, length, start1, start2);
10433}
sewardj2019a972011-03-07 16:04:07 +000010434
sewardj2019a972011-03-07 16:04:07 +000010435
florianb0bf6602012-05-05 00:01:16 +000010436static void
10437s390_irgen_NC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10438{
10439 s390_irgen_xonc(Iop_And8, length, start1, start2);
10440}
sewardj2019a972011-03-07 16:04:07 +000010441
sewardj2019a972011-03-07 16:04:07 +000010442
florianb0bf6602012-05-05 00:01:16 +000010443static void
10444s390_irgen_OC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10445{
10446 s390_irgen_xonc(Iop_Or8, length, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010447}
10448
10449
10450static void
10451s390_irgen_CLC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10452{
10453 IRTemp current1 = newTemp(Ity_I8);
10454 IRTemp current2 = newTemp(Ity_I8);
10455 IRTemp counter = newTemp(Ity_I64);
10456
10457 assign(counter, get_counter_dw0());
10458 put_counter_dw0(mkU64(0));
10459
10460 assign(current1, load(Ity_I8, binop(Iop_Add64, mkexpr(start1),
10461 mkexpr(counter))));
10462 assign(current2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10463 mkexpr(counter))));
10464 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, current1, current2,
10465 False);
10466
10467 /* Both fields differ ? */
florian6820ba52012-07-26 02:01:50 +000010468 next_insn_if(binop(Iop_CmpNE8, mkexpr(current1), mkexpr(current2)));
sewardj2019a972011-03-07 16:04:07 +000010469
10470 /* Check for end of field */
10471 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010472 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010473 put_counter_dw0(mkU64(0));
10474}
10475
10476static void
10477s390_irgen_MVC_EX(IRTemp length, IRTemp start1, IRTemp start2)
10478{
10479 IRTemp counter = newTemp(Ity_I64);
10480
10481 assign(counter, get_counter_dw0());
10482
10483 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)),
10484 load(Ity_I8, binop(Iop_Add64, mkexpr(start2), mkexpr(counter))));
10485
10486 /* Check for end of field */
10487 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010488 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010489 put_counter_dw0(mkU64(0));
10490}
10491
florianf87d4fb2012-05-05 02:55:24 +000010492static void
10493s390_irgen_TR_EX(IRTemp length, IRTemp start1, IRTemp start2)
10494{
10495 IRTemp op = newTemp(Ity_I8);
10496 IRTemp op1 = newTemp(Ity_I8);
10497 IRTemp result = newTemp(Ity_I64);
10498 IRTemp counter = newTemp(Ity_I64);
10499
10500 assign(counter, get_counter_dw0());
10501
10502 assign(op, load(Ity_I8, binop(Iop_Add64, mkexpr(start1), mkexpr(counter))));
10503
10504 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)), mkexpr(start2)));
10505
10506 assign(op1, load(Ity_I8, mkexpr(result)));
10507 store(binop(Iop_Add64, mkexpr(start1), mkexpr(counter)), mkexpr(op1));
10508
10509 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000010510 iterate_if(binop(Iop_CmpNE64, mkexpr(counter), mkexpr(length)));
florianf87d4fb2012-05-05 02:55:24 +000010511 put_counter_dw0(mkU64(0));
10512}
sewardj2019a972011-03-07 16:04:07 +000010513
10514
10515static void
10516s390_irgen_EX_SS(UChar r, IRTemp addr2,
florian6820ba52012-07-26 02:01:50 +000010517 void (*irgen)(IRTemp length, IRTemp start1, IRTemp start2),
florianffbd84d2012-12-09 02:06:29 +000010518 UInt lensize)
sewardj2019a972011-03-07 16:04:07 +000010519{
10520 struct SS {
10521 unsigned int op : 8;
10522 unsigned int l : 8;
10523 unsigned int b1 : 4;
10524 unsigned int d1 : 12;
10525 unsigned int b2 : 4;
10526 unsigned int d2 : 12;
10527 };
10528 union {
10529 struct SS dec;
10530 unsigned long bytes;
10531 } ss;
10532 IRTemp cond;
10533 IRDirty *d;
10534 IRTemp torun;
10535
10536 IRTemp start1 = newTemp(Ity_I64);
10537 IRTemp start2 = newTemp(Ity_I64);
10538 IRTemp len = newTemp(lensize == 64 ? Ity_I64 : Ity_I32);
10539 cond = newTemp(Ity_I1);
10540 torun = newTemp(Ity_I64);
10541
10542 assign(torun, load(Ity_I64, mkexpr(addr2)));
10543 /* Start with a check that the saved code is still correct */
10544 assign(cond, binop(Iop_CmpNE64, mkexpr(torun), mkU64(last_execute_target)));
10545 /* If not, save the new value */
10546 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10547 mkIRExprVec_1(mkexpr(torun)));
10548 d->guard = mkexpr(cond);
10549 stmt(IRStmt_Dirty(d));
10550
10551 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010552 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10553 mkU64(guest_IA_curr_instr)));
10554 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010555 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010556
10557 ss.bytes = last_execute_target;
10558 assign(start1, binop(Iop_Add64, mkU64(ss.dec.d1),
10559 ss.dec.b1 != 0 ? get_gpr_dw0(ss.dec.b1) : mkU64(0)));
10560 assign(start2, binop(Iop_Add64, mkU64(ss.dec.d2),
10561 ss.dec.b2 != 0 ? get_gpr_dw0(ss.dec.b2) : mkU64(0)));
10562 assign(len, unop(lensize == 64 ? Iop_8Uto64 : Iop_8Uto32, binop(Iop_Or8,
10563 r != 0 ? get_gpr_b7(r): mkU8(0), mkU8(ss.dec.l))));
10564 irgen(len, start1, start2);
florian8844a632012-04-13 04:04:06 +000010565
sewardj2019a972011-03-07 16:04:07 +000010566 last_execute_target = 0;
10567}
10568
florian55085f82012-11-21 00:36:55 +000010569static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010570s390_irgen_EX(UChar r1, IRTemp addr2)
10571{
10572 switch(last_execute_target & 0xff00000000000000ULL) {
10573 case 0:
10574 {
10575 /* no code information yet */
10576 IRDirty *d;
10577
10578 /* so safe the code... */
10579 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10580 mkIRExprVec_1(load(Ity_I64, mkexpr(addr2))));
10581 stmt(IRStmt_Dirty(d));
10582 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010583 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
10584 mkU64(guest_IA_curr_instr)));
10585 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010586 restart_if(IRExpr_Const(IRConst_U1(True)));
10587
sewardj2019a972011-03-07 16:04:07 +000010588 /* we know that this will be invalidated */
florianf9e1ed72012-04-17 02:41:56 +000010589 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000010590 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000010591 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000010592 break;
10593 }
10594
10595 case 0xd200000000000000ULL:
10596 /* special case MVC */
10597 s390_irgen_EX_SS(r1, addr2, s390_irgen_MVC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010598 return "ex@mvc";
sewardj2019a972011-03-07 16:04:07 +000010599
10600 case 0xd500000000000000ULL:
10601 /* special case CLC */
10602 s390_irgen_EX_SS(r1, addr2, s390_irgen_CLC_EX, 64);
florianeca33542012-12-16 22:49:05 +000010603 return "ex@clc";
sewardj2019a972011-03-07 16:04:07 +000010604
10605 case 0xd700000000000000ULL:
10606 /* special case XC */
10607 s390_irgen_EX_SS(r1, addr2, s390_irgen_XC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010608 return "ex@xc";
sewardj2019a972011-03-07 16:04:07 +000010609
florianb0bf6602012-05-05 00:01:16 +000010610 case 0xd600000000000000ULL:
10611 /* special case OC */
10612 s390_irgen_EX_SS(r1, addr2, s390_irgen_OC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010613 return "ex@oc";
florianb0bf6602012-05-05 00:01:16 +000010614
10615 case 0xd400000000000000ULL:
10616 /* special case NC */
10617 s390_irgen_EX_SS(r1, addr2, s390_irgen_NC_EX, 32);
florianeca33542012-12-16 22:49:05 +000010618 return "ex@nc";
sewardj2019a972011-03-07 16:04:07 +000010619
florianf87d4fb2012-05-05 02:55:24 +000010620 case 0xdc00000000000000ULL:
10621 /* special case TR */
10622 s390_irgen_EX_SS(r1, addr2, s390_irgen_TR_EX, 64);
florianeca33542012-12-16 22:49:05 +000010623 return "ex@tr";
florianf87d4fb2012-05-05 02:55:24 +000010624
sewardj2019a972011-03-07 16:04:07 +000010625 default:
10626 {
10627 /* everything else will get a self checking prefix that also checks the
10628 register content */
10629 IRDirty *d;
10630 UChar *bytes;
10631 IRTemp cond;
10632 IRTemp orperand;
10633 IRTemp torun;
10634
10635 cond = newTemp(Ity_I1);
10636 orperand = newTemp(Ity_I64);
10637 torun = newTemp(Ity_I64);
10638
10639 if (r1 == 0)
10640 assign(orperand, mkU64(0));
10641 else
10642 assign(orperand, unop(Iop_8Uto64,get_gpr_b7(r1)));
10643 /* This code is going to be translated */
10644 assign(torun, binop(Iop_Or64, load(Ity_I64, mkexpr(addr2)),
10645 binop(Iop_Shl64, mkexpr(orperand), mkU8(48))));
10646
10647 /* Start with a check that saved code is still correct */
10648 assign(cond, binop(Iop_CmpNE64, mkexpr(torun),
10649 mkU64(last_execute_target)));
10650 /* If not, save the new value */
10651 d = unsafeIRDirty_0_N (0, "s390x_dirtyhelper_EX", &s390x_dirtyhelper_EX,
10652 mkIRExprVec_1(mkexpr(torun)));
10653 d->guard = mkexpr(cond);
10654 stmt(IRStmt_Dirty(d));
10655
10656 /* and restart */
florian428dfdd2012-03-27 03:09:49 +000010657 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART), mkU64(guest_IA_curr_instr)));
10658 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN), mkU64(4)));
florian6820ba52012-07-26 02:01:50 +000010659 restart_if(mkexpr(cond));
sewardj2019a972011-03-07 16:04:07 +000010660
10661 /* Now comes the actual translation */
10662 bytes = (UChar *) &last_execute_target;
10663 s390_decode_and_irgen(bytes, ((((bytes[0] >> 6) + 1) >> 1) + 1) << 1,
10664 dis_res);
sewardj7ee97522011-05-09 21:45:04 +000010665 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardj2019a972011-03-07 16:04:07 +000010666 vex_printf(" which was executed by\n");
10667 /* dont make useless translations in the next execute */
10668 last_execute_target = 0;
10669 }
10670 }
10671 return "ex";
10672}
10673
florian55085f82012-11-21 00:36:55 +000010674static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010675s390_irgen_EXRL(UChar r1, UInt offset)
10676{
10677 IRTemp addr = newTemp(Ity_I64);
10678 /* we might save one round trip because we know the target */
10679 if (!last_execute_target)
10680 last_execute_target = *(ULong *)(HWord)
10681 (guest_IA_curr_instr + offset * 2UL);
10682 assign(addr, mkU64(guest_IA_curr_instr + offset * 2UL));
10683 s390_irgen_EX(r1, addr);
10684 return "exrl";
10685}
10686
florian55085f82012-11-21 00:36:55 +000010687static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010688s390_irgen_IPM(UChar r1)
10689{
10690 // As long as we dont support SPM, lets just assume 0 as program mask
10691 put_gpr_b4(r1, unop(Iop_32to8, binop(Iop_Or32, mkU32(0 /* program mask */),
10692 binop(Iop_Shl32, s390_call_calculate_cc(), mkU8(4)))));
10693
10694 return "ipm";
10695}
10696
10697
florian55085f82012-11-21 00:36:55 +000010698static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010699s390_irgen_SRST(UChar r1, UChar r2)
10700{
10701 IRTemp address = newTemp(Ity_I64);
10702 IRTemp next = newTemp(Ity_I64);
10703 IRTemp delim = newTemp(Ity_I8);
10704 IRTemp counter = newTemp(Ity_I64);
10705 IRTemp byte = newTemp(Ity_I8);
10706
10707 assign(address, get_gpr_dw0(r2));
10708 assign(next, get_gpr_dw0(r1));
10709
10710 assign(counter, get_counter_dw0());
10711 put_counter_dw0(mkU64(0));
10712
10713 // start = next? CC=2 and out r1 and r2 unchanged
10714 s390_cc_set(2);
10715 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010716 next_insn_if(binop(Iop_CmpEQ64, mkexpr(address), mkexpr(next)));
sewardj2019a972011-03-07 16:04:07 +000010717
10718 assign(byte, load(Ity_I8, mkexpr(address)));
10719 assign(delim, get_gpr_b7(0));
10720
10721 // byte = delim? CC=1, R1=address
10722 s390_cc_set(1);
10723 put_gpr_dw0(r1, mkexpr(address));
florian6820ba52012-07-26 02:01:50 +000010724 next_insn_if(binop(Iop_CmpEQ8, mkexpr(delim), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000010725
10726 // else: all equal, no end yet, loop
10727 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10728 put_gpr_dw0(r1, mkexpr(next));
10729 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(address), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010730
florian6820ba52012-07-26 02:01:50 +000010731 iterate();
sewardj2019a972011-03-07 16:04:07 +000010732
10733 return "srst";
10734}
10735
florian55085f82012-11-21 00:36:55 +000010736static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010737s390_irgen_CLST(UChar r1, UChar r2)
10738{
10739 IRTemp address1 = newTemp(Ity_I64);
10740 IRTemp address2 = newTemp(Ity_I64);
10741 IRTemp end = newTemp(Ity_I8);
10742 IRTemp counter = newTemp(Ity_I64);
10743 IRTemp byte1 = newTemp(Ity_I8);
10744 IRTemp byte2 = newTemp(Ity_I8);
10745
10746 assign(address1, get_gpr_dw0(r1));
10747 assign(address2, get_gpr_dw0(r2));
10748 assign(end, get_gpr_b7(0));
10749 assign(counter, get_counter_dw0());
10750 put_counter_dw0(mkU64(0));
10751 assign(byte1, load(Ity_I8, mkexpr(address1)));
10752 assign(byte2, load(Ity_I8, mkexpr(address2)));
10753
10754 // end in both? all equal, reset r1 and r2 to start values
10755 s390_cc_set(0);
10756 put_gpr_dw0(r1, binop(Iop_Sub64, mkexpr(address1), mkexpr(counter)));
10757 put_gpr_dw0(r2, binop(Iop_Sub64, mkexpr(address2), mkexpr(counter)));
florian6820ba52012-07-26 02:01:50 +000010758 next_insn_if(binop(Iop_CmpEQ8, mkU8(0),
10759 binop(Iop_Or8,
10760 binop(Iop_Xor8, mkexpr(byte1), mkexpr(end)),
10761 binop(Iop_Xor8, mkexpr(byte2), mkexpr(end)))));
sewardj2019a972011-03-07 16:04:07 +000010762
10763 put_gpr_dw0(r1, mkexpr(address1));
10764 put_gpr_dw0(r2, mkexpr(address2));
10765
10766 // End found in string1
10767 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010768 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte1)));
sewardj2019a972011-03-07 16:04:07 +000010769
10770 // End found in string2
10771 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010772 next_insn_if(binop(Iop_CmpEQ8, mkexpr(end), mkexpr(byte2)));
sewardj2019a972011-03-07 16:04:07 +000010773
10774 // string1 < string2
10775 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000010776 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte1)),
10777 unop(Iop_8Uto32, mkexpr(byte2))));
sewardj2019a972011-03-07 16:04:07 +000010778
10779 // string2 < string1
10780 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000010781 next_insn_if(binop(Iop_CmpLT32U, unop(Iop_8Uto32, mkexpr(byte2)),
10782 unop(Iop_8Uto32, mkexpr(byte1))));
sewardj2019a972011-03-07 16:04:07 +000010783
10784 // else: all equal, no end yet, loop
10785 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
10786 put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), mkU64(1)));
10787 put_gpr_dw0(r2, binop(Iop_Add64, get_gpr_dw0(r2), mkU64(1)));
floriancf87c942012-07-25 00:52:21 +000010788
florian6820ba52012-07-26 02:01:50 +000010789 iterate();
sewardj2019a972011-03-07 16:04:07 +000010790
10791 return "clst";
10792}
10793
10794static void
10795s390_irgen_load_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10796{
10797 UChar reg;
10798 IRTemp addr = newTemp(Ity_I64);
10799
10800 assign(addr, mkexpr(op2addr));
10801 reg = r1;
10802 do {
10803 IRTemp old = addr;
10804
10805 reg %= 16;
10806 put_gpr_w1(reg, load(Ity_I32, mkexpr(addr)));
10807 addr = newTemp(Ity_I64);
10808 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10809 reg++;
10810 } while (reg != (r3 + 1));
10811}
10812
florian55085f82012-11-21 00:36:55 +000010813static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010814s390_irgen_LM(UChar r1, UChar r3, IRTemp op2addr)
10815{
10816 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10817
10818 return "lm";
10819}
10820
florian55085f82012-11-21 00:36:55 +000010821static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010822s390_irgen_LMY(UChar r1, UChar r3, IRTemp op2addr)
10823{
10824 s390_irgen_load_multiple_32bit(r1, r3, op2addr);
10825
10826 return "lmy";
10827}
10828
florian55085f82012-11-21 00:36:55 +000010829static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010830s390_irgen_LMH(UChar r1, UChar r3, IRTemp op2addr)
10831{
10832 UChar reg;
10833 IRTemp addr = newTemp(Ity_I64);
10834
10835 assign(addr, mkexpr(op2addr));
10836 reg = r1;
10837 do {
10838 IRTemp old = addr;
10839
10840 reg %= 16;
10841 put_gpr_w0(reg, load(Ity_I32, mkexpr(addr)));
10842 addr = newTemp(Ity_I64);
10843 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10844 reg++;
10845 } while (reg != (r3 + 1));
10846
10847 return "lmh";
10848}
10849
florian55085f82012-11-21 00:36:55 +000010850static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010851s390_irgen_LMG(UChar r1, UChar r3, IRTemp op2addr)
10852{
10853 UChar reg;
10854 IRTemp addr = newTemp(Ity_I64);
10855
10856 assign(addr, mkexpr(op2addr));
10857 reg = r1;
10858 do {
10859 IRTemp old = addr;
10860
10861 reg %= 16;
10862 put_gpr_dw0(reg, load(Ity_I64, mkexpr(addr)));
10863 addr = newTemp(Ity_I64);
10864 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10865 reg++;
10866 } while (reg != (r3 + 1));
10867
10868 return "lmg";
10869}
10870
10871static void
10872s390_irgen_store_multiple_32bit(UChar r1, UChar r3, IRTemp op2addr)
10873{
10874 UChar reg;
10875 IRTemp addr = newTemp(Ity_I64);
10876
10877 assign(addr, mkexpr(op2addr));
10878 reg = r1;
10879 do {
10880 IRTemp old = addr;
10881
10882 reg %= 16;
10883 store(mkexpr(addr), get_gpr_w1(reg));
10884 addr = newTemp(Ity_I64);
10885 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10886 reg++;
10887 } while( reg != (r3 + 1));
10888}
10889
florian55085f82012-11-21 00:36:55 +000010890static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010891s390_irgen_STM(UChar r1, UChar r3, IRTemp op2addr)
10892{
10893 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10894
10895 return "stm";
10896}
10897
florian55085f82012-11-21 00:36:55 +000010898static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010899s390_irgen_STMY(UChar r1, UChar r3, IRTemp op2addr)
10900{
10901 s390_irgen_store_multiple_32bit(r1, r3, op2addr);
10902
10903 return "stmy";
10904}
10905
florian55085f82012-11-21 00:36:55 +000010906static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010907s390_irgen_STMH(UChar r1, UChar r3, IRTemp op2addr)
10908{
10909 UChar reg;
10910 IRTemp addr = newTemp(Ity_I64);
10911
10912 assign(addr, mkexpr(op2addr));
10913 reg = r1;
10914 do {
10915 IRTemp old = addr;
10916
10917 reg %= 16;
10918 store(mkexpr(addr), get_gpr_w0(reg));
10919 addr = newTemp(Ity_I64);
10920 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
10921 reg++;
10922 } while( reg != (r3 + 1));
10923
10924 return "stmh";
10925}
10926
florian55085f82012-11-21 00:36:55 +000010927static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010928s390_irgen_STMG(UChar r1, UChar r3, IRTemp op2addr)
10929{
10930 UChar reg;
10931 IRTemp addr = newTemp(Ity_I64);
10932
10933 assign(addr, mkexpr(op2addr));
10934 reg = r1;
10935 do {
10936 IRTemp old = addr;
10937
10938 reg %= 16;
10939 store(mkexpr(addr), get_gpr_dw0(reg));
10940 addr = newTemp(Ity_I64);
10941 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(8)));
10942 reg++;
10943 } while( reg != (r3 + 1));
10944
10945 return "stmg";
10946}
10947
10948static void
florianb0bf6602012-05-05 00:01:16 +000010949s390_irgen_xonc(IROp op, IRTemp length, IRTemp start1, IRTemp start2)
sewardj2019a972011-03-07 16:04:07 +000010950{
10951 IRTemp old1 = newTemp(Ity_I8);
10952 IRTemp old2 = newTemp(Ity_I8);
10953 IRTemp new1 = newTemp(Ity_I8);
10954 IRTemp counter = newTemp(Ity_I32);
10955 IRTemp addr1 = newTemp(Ity_I64);
10956
10957 assign(counter, get_counter_w0());
10958
10959 assign(addr1, binop(Iop_Add64, mkexpr(start1),
10960 unop(Iop_32Uto64, mkexpr(counter))));
10961
10962 assign(old1, load(Ity_I8, mkexpr(addr1)));
10963 assign(old2, load(Ity_I8, binop(Iop_Add64, mkexpr(start2),
10964 unop(Iop_32Uto64,mkexpr(counter)))));
10965 assign(new1, binop(op, mkexpr(old1), mkexpr(old2)));
10966
10967 /* Special case: xc is used to zero memory */
sewardj2019a972011-03-07 16:04:07 +000010968 if (op == Iop_Xor8) {
10969 store(mkexpr(addr1),
florian6ad49522011-09-09 02:38:55 +000010970 mkite(binop(Iop_CmpEQ64, mkexpr(start1), mkexpr(start2)),
10971 mkU8(0), mkexpr(new1)));
sewardj2019a972011-03-07 16:04:07 +000010972 } else
10973 store(mkexpr(addr1), mkexpr(new1));
10974 put_counter_w1(binop(Iop_Or32, unop(Iop_8Uto32, mkexpr(new1)),
10975 get_counter_w1()));
10976
10977 /* Check for end of field */
10978 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000010979 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkexpr(length)));
sewardj2019a972011-03-07 16:04:07 +000010980 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, get_counter_w1()),
10981 False);
10982 put_counter_dw0(mkU64(0));
10983}
10984
florian55085f82012-11-21 00:36:55 +000010985static const HChar *
sewardj2019a972011-03-07 16:04:07 +000010986s390_irgen_XC(UChar length, IRTemp start1, IRTemp start2)
10987{
florianb0bf6602012-05-05 00:01:16 +000010988 IRTemp len = newTemp(Ity_I32);
10989
10990 assign(len, mkU32(length));
10991 s390_irgen_xonc(Iop_Xor8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000010992
10993 return "xc";
10994}
10995
sewardjb63967e2011-03-24 08:50:04 +000010996static void
10997s390_irgen_XC_sameloc(UChar length, UChar b, UShort d)
10998{
10999 IRTemp counter = newTemp(Ity_I32);
11000 IRTemp start = newTemp(Ity_I64);
11001 IRTemp addr = newTemp(Ity_I64);
11002
11003 assign(start,
11004 binop(Iop_Add64, mkU64(d), b != 0 ? get_gpr_dw0(b) : mkU64(0)));
11005
11006 if (length < 8) {
11007 UInt i;
11008
11009 for (i = 0; i <= length; ++i) {
11010 store(binop(Iop_Add64, mkexpr(start), mkU64(i)), mkU8(0));
11011 }
11012 } else {
11013 assign(counter, get_counter_w0());
11014
11015 assign(addr, binop(Iop_Add64, mkexpr(start),
11016 unop(Iop_32Uto64, mkexpr(counter))));
11017
11018 store(mkexpr(addr), mkU8(0));
11019
11020 /* Check for end of field */
11021 put_counter_w0(binop(Iop_Add32, mkexpr(counter), mkU32(1)));
florian6820ba52012-07-26 02:01:50 +000011022 iterate_if(binop(Iop_CmpNE32, mkexpr(counter), mkU32(length)));
sewardjb63967e2011-03-24 08:50:04 +000011023
11024 /* Reset counter */
11025 put_counter_dw0(mkU64(0));
11026 }
11027
11028 s390_cc_thunk_put1(S390_CC_OP_BITWISE, mktemp(Ity_I32, mkU32(0)), False);
11029
sewardj7ee97522011-05-09 21:45:04 +000011030 if (UNLIKELY(vex_traceflags & VEX_TRACE_FE))
sewardjb63967e2011-03-24 08:50:04 +000011031 s390_disasm(ENC3(MNM, UDLB, UDXB), "xc", d, length, b, d, 0, b);
11032}
11033
florian55085f82012-11-21 00:36:55 +000011034static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011035s390_irgen_NC(UChar length, IRTemp start1, IRTemp start2)
11036{
florianb0bf6602012-05-05 00:01:16 +000011037 IRTemp len = newTemp(Ity_I32);
11038
11039 assign(len, mkU32(length));
11040 s390_irgen_xonc(Iop_And8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011041
11042 return "nc";
11043}
11044
florian55085f82012-11-21 00:36:55 +000011045static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011046s390_irgen_OC(UChar length, IRTemp start1, IRTemp start2)
11047{
florianb0bf6602012-05-05 00:01:16 +000011048 IRTemp len = newTemp(Ity_I32);
11049
11050 assign(len, mkU32(length));
11051 s390_irgen_xonc(Iop_Or8, len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011052
11053 return "oc";
11054}
11055
11056
florian55085f82012-11-21 00:36:55 +000011057static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011058s390_irgen_MVC(UChar length, IRTemp start1, IRTemp start2)
11059{
florian79e839e2012-05-05 02:20:30 +000011060 IRTemp len = newTemp(Ity_I64);
sewardj2019a972011-03-07 16:04:07 +000011061
florian79e839e2012-05-05 02:20:30 +000011062 assign(len, mkU64(length));
11063 s390_irgen_MVC_EX(len, start1, start2);
sewardj2019a972011-03-07 16:04:07 +000011064
11065 return "mvc";
11066}
11067
florian55085f82012-11-21 00:36:55 +000011068static const HChar *
florianb0c9a132011-09-08 15:37:39 +000011069s390_irgen_MVCL(UChar r1, UChar r2)
11070{
11071 IRTemp addr1 = newTemp(Ity_I64);
11072 IRTemp addr2 = newTemp(Ity_I64);
11073 IRTemp addr2_load = newTemp(Ity_I64);
11074 IRTemp r1p1 = newTemp(Ity_I32); /* contents of r1 + 1 */
11075 IRTemp r2p1 = newTemp(Ity_I32); /* contents of r2 + 1 */
11076 IRTemp len1 = newTemp(Ity_I32);
11077 IRTemp len2 = newTemp(Ity_I32);
11078 IRTemp pad = newTemp(Ity_I8);
11079 IRTemp single = newTemp(Ity_I8);
11080
11081 assign(addr1, get_gpr_dw0(r1));
11082 assign(r1p1, get_gpr_w1(r1 + 1));
11083 assign(len1, binop(Iop_And32, mkexpr(r1p1), mkU32(0x00ffffff)));
11084 assign(addr2, get_gpr_dw0(r2));
11085 assign(r2p1, get_gpr_w1(r2 + 1));
11086 assign(len2, binop(Iop_And32, mkexpr(r2p1), mkU32(0x00ffffff)));
11087 assign(pad, get_gpr_b4(r2 + 1));
11088
11089 /* len1 == 0 ? */
11090 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011091 next_insn_if(binop(Iop_CmpEQ32, mkexpr(len1), mkU32(0)));
florianb0c9a132011-09-08 15:37:39 +000011092
11093 /* Check for destructive overlap:
11094 addr1 > addr2 && addr2 + len1 > addr1 && (addr2 + len2) > addr1 */
11095 s390_cc_set(3);
11096 IRTemp cond1 = newTemp(Ity_I32);
11097 assign(cond1, unop(Iop_1Uto32,
11098 binop(Iop_CmpLT64U, mkexpr(addr2), mkexpr(addr1))));
11099 IRTemp cond2 = newTemp(Ity_I32);
11100 assign(cond2, unop(Iop_1Uto32,
11101 binop(Iop_CmpLT64U, mkexpr(addr1),
11102 binop(Iop_Add64, mkexpr(addr2),
11103 unop(Iop_32Uto64, mkexpr(len1))))));
11104 IRTemp cond3 = newTemp(Ity_I32);
11105 assign(cond3, unop(Iop_1Uto32,
11106 binop(Iop_CmpLT64U,
11107 mkexpr(addr1),
11108 binop(Iop_Add64, mkexpr(addr2),
11109 unop(Iop_32Uto64, mkexpr(len2))))));
11110
florian6820ba52012-07-26 02:01:50 +000011111 next_insn_if(binop(Iop_CmpEQ32,
11112 binop(Iop_And32,
11113 binop(Iop_And32, mkexpr(cond1), mkexpr(cond2)),
11114 mkexpr(cond3)),
11115 mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011116
11117 /* See s390_irgen_CLCL for explanation why we cannot load directly
11118 and need two steps. */
11119 assign(addr2_load,
11120 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11121 mkU64(guest_IA_curr_instr), mkexpr(addr2)));
11122 assign(single,
11123 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11124 mkexpr(pad), load(Ity_I8, mkexpr(addr2_load))));
11125
11126 store(mkexpr(addr1), mkexpr(single));
11127
11128 /* Update addr1 and len1 */
11129 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11130 put_gpr_w1(r1 + 1, binop(Iop_Sub32, mkexpr(r1p1), mkU32(1)));
11131
11132 /* Update addr2 and len2 */
11133 put_gpr_dw0(r2,
11134 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11135 mkexpr(addr2),
11136 binop(Iop_Add64, mkexpr(addr2), mkU64(1))));
11137
11138 /* When updating len2 we must not modify bits (r2+1)[0:39] */
11139 put_gpr_w1(r2 + 1,
11140 mkite(binop(Iop_CmpEQ32, mkexpr(len2), mkU32(0)),
11141 binop(Iop_And32, mkexpr(r2p1), mkU32(0xFF000000u)),
11142 binop(Iop_Sub32, mkexpr(r2p1), mkU32(1))));
11143
11144 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len2, False);
florian6820ba52012-07-26 02:01:50 +000011145 iterate_if(binop(Iop_CmpNE32, mkexpr(len1), mkU32(1)));
florianb0c9a132011-09-08 15:37:39 +000011146
11147 return "mvcl";
11148}
11149
11150
florian55085f82012-11-21 00:36:55 +000011151static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011152s390_irgen_MVCLE(UChar r1, UChar r3, IRTemp pad2)
11153{
11154 IRTemp addr1, addr3, addr3_load, len1, len3, single;
11155
11156 addr1 = newTemp(Ity_I64);
11157 addr3 = newTemp(Ity_I64);
11158 addr3_load = newTemp(Ity_I64);
11159 len1 = newTemp(Ity_I64);
11160 len3 = newTemp(Ity_I64);
11161 single = newTemp(Ity_I8);
11162
11163 assign(addr1, get_gpr_dw0(r1));
11164 assign(len1, get_gpr_dw0(r1 + 1));
11165 assign(addr3, get_gpr_dw0(r3));
11166 assign(len3, get_gpr_dw0(r3 + 1));
11167
11168 // len1 == 0 ?
11169 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011170 next_insn_if(binop(Iop_CmpEQ64,mkexpr(len1), mkU64(0)));
sewardj2019a972011-03-07 16:04:07 +000011171
11172 /* This is a hack to prevent mvcle from reading from addr3 if it
11173 should read from the pad. Since the pad has no address, just
11174 read from the instruction, we discard that anyway */
11175 assign(addr3_load,
florian6ad49522011-09-09 02:38:55 +000011176 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11177 mkU64(guest_IA_curr_instr), mkexpr(addr3)));
sewardj2019a972011-03-07 16:04:07 +000011178
11179 assign(single,
florian6ad49522011-09-09 02:38:55 +000011180 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11181 unop(Iop_64to8, mkexpr(pad2)),
11182 load(Ity_I8, mkexpr(addr3_load))));
sewardj2019a972011-03-07 16:04:07 +000011183 store(mkexpr(addr1), mkexpr(single));
11184
11185 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(1)));
11186
11187 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(1)));
11188
11189 put_gpr_dw0(r3,
florian6ad49522011-09-09 02:38:55 +000011190 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11191 mkexpr(addr3),
11192 binop(Iop_Add64, mkexpr(addr3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011193
11194 put_gpr_dw0(r3 + 1,
florian6ad49522011-09-09 02:38:55 +000011195 mkite(binop(Iop_CmpEQ64, mkexpr(len3), mkU64(0)),
11196 mkU64(0), binop(Iop_Sub64, mkexpr(len3), mkU64(1))));
sewardj2019a972011-03-07 16:04:07 +000011197
sewardj2019a972011-03-07 16:04:07 +000011198 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, len1, len3, False);
florian6820ba52012-07-26 02:01:50 +000011199 iterate_if(binop(Iop_CmpNE64, mkexpr(len1), mkU64(1)));
sewardj2019a972011-03-07 16:04:07 +000011200
11201 return "mvcle";
11202}
11203
florian55085f82012-11-21 00:36:55 +000011204static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011205s390_irgen_MVST(UChar r1, UChar r2)
11206{
11207 IRTemp addr1 = newTemp(Ity_I64);
11208 IRTemp addr2 = newTemp(Ity_I64);
11209 IRTemp end = newTemp(Ity_I8);
11210 IRTemp byte = newTemp(Ity_I8);
11211 IRTemp counter = newTemp(Ity_I64);
11212
11213 assign(addr1, get_gpr_dw0(r1));
11214 assign(addr2, get_gpr_dw0(r2));
11215 assign(counter, get_counter_dw0());
11216 assign(end, get_gpr_b7(0));
11217 assign(byte, load(Ity_I8, binop(Iop_Add64, mkexpr(addr2),mkexpr(counter))));
11218 store(binop(Iop_Add64,mkexpr(addr1),mkexpr(counter)), mkexpr(byte));
11219
11220 // We use unlimited as cpu-determined number
11221 put_counter_dw0(binop(Iop_Add64, mkexpr(counter), mkU64(1)));
florian6820ba52012-07-26 02:01:50 +000011222 iterate_if(binop(Iop_CmpNE8, mkexpr(end), mkexpr(byte)));
sewardj2019a972011-03-07 16:04:07 +000011223
11224 // and always set cc=1 at the end + update r1
11225 s390_cc_set(1);
11226 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(counter)));
11227 put_counter_dw0(mkU64(0));
11228
11229 return "mvst";
11230}
11231
11232static void
11233s390_irgen_divide_64to32(IROp op, UChar r1, IRTemp op2)
11234{
11235 IRTemp op1 = newTemp(Ity_I64);
11236 IRTemp result = newTemp(Ity_I64);
11237
11238 assign(op1, binop(Iop_32HLto64,
11239 get_gpr_w1(r1), // high 32 bits
11240 get_gpr_w1(r1 + 1))); // low 32 bits
11241 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11242 put_gpr_w1(r1, unop(Iop_64HIto32, mkexpr(result))); // remainder
11243 put_gpr_w1(r1 + 1, unop(Iop_64to32, mkexpr(result))); // quotient
11244}
11245
11246static void
11247s390_irgen_divide_128to64(IROp op, UChar r1, IRTemp op2)
11248{
11249 IRTemp op1 = newTemp(Ity_I128);
11250 IRTemp result = newTemp(Ity_I128);
11251
11252 assign(op1, binop(Iop_64HLto128,
11253 get_gpr_dw0(r1), // high 64 bits
11254 get_gpr_dw0(r1 + 1))); // low 64 bits
11255 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11256 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11257 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11258}
11259
11260static void
11261s390_irgen_divide_64to64(IROp op, UChar r1, IRTemp op2)
11262{
11263 IRTemp op1 = newTemp(Ity_I64);
11264 IRTemp result = newTemp(Ity_I128);
11265
11266 assign(op1, get_gpr_dw0(r1 + 1));
11267 assign(result, binop(op, mkexpr(op1), mkexpr(op2)));
11268 put_gpr_dw0(r1, unop(Iop_128HIto64, mkexpr(result))); // remainder
11269 put_gpr_dw0(r1 + 1, unop(Iop_128to64, mkexpr(result))); // quotient
11270}
11271
florian55085f82012-11-21 00:36:55 +000011272static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011273s390_irgen_DR(UChar r1, UChar r2)
11274{
11275 IRTemp op2 = newTemp(Ity_I32);
11276
11277 assign(op2, get_gpr_w1(r2));
11278
11279 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11280
11281 return "dr";
11282}
11283
florian55085f82012-11-21 00:36:55 +000011284static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011285s390_irgen_D(UChar r1, IRTemp op2addr)
11286{
11287 IRTemp op2 = newTemp(Ity_I32);
11288
11289 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11290
11291 s390_irgen_divide_64to32(Iop_DivModS64to32, r1, op2);
11292
11293 return "d";
11294}
11295
florian55085f82012-11-21 00:36:55 +000011296static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011297s390_irgen_DLR(UChar r1, UChar r2)
11298{
11299 IRTemp op2 = newTemp(Ity_I32);
11300
11301 assign(op2, get_gpr_w1(r2));
11302
11303 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11304
florian7cd1cde2012-08-16 23:57:43 +000011305 return "dlr";
sewardj2019a972011-03-07 16:04:07 +000011306}
11307
florian55085f82012-11-21 00:36:55 +000011308static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011309s390_irgen_DL(UChar r1, IRTemp op2addr)
11310{
11311 IRTemp op2 = newTemp(Ity_I32);
11312
11313 assign(op2, load(Ity_I32, mkexpr(op2addr)));
11314
11315 s390_irgen_divide_64to32(Iop_DivModU64to32, r1, op2);
11316
11317 return "dl";
11318}
11319
florian55085f82012-11-21 00:36:55 +000011320static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011321s390_irgen_DLG(UChar r1, IRTemp op2addr)
11322{
11323 IRTemp op2 = newTemp(Ity_I64);
11324
11325 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11326
11327 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11328
11329 return "dlg";
11330}
11331
florian55085f82012-11-21 00:36:55 +000011332static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011333s390_irgen_DLGR(UChar r1, UChar r2)
11334{
11335 IRTemp op2 = newTemp(Ity_I64);
11336
11337 assign(op2, get_gpr_dw0(r2));
11338
11339 s390_irgen_divide_128to64(Iop_DivModU128to64, r1, op2);
11340
11341 return "dlgr";
11342}
11343
florian55085f82012-11-21 00:36:55 +000011344static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011345s390_irgen_DSGR(UChar r1, UChar r2)
11346{
11347 IRTemp op2 = newTemp(Ity_I64);
11348
11349 assign(op2, get_gpr_dw0(r2));
11350
11351 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11352
11353 return "dsgr";
11354}
11355
florian55085f82012-11-21 00:36:55 +000011356static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011357s390_irgen_DSG(UChar r1, IRTemp op2addr)
11358{
11359 IRTemp op2 = newTemp(Ity_I64);
11360
11361 assign(op2, load(Ity_I64, mkexpr(op2addr)));
11362
11363 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11364
11365 return "dsg";
11366}
11367
florian55085f82012-11-21 00:36:55 +000011368static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011369s390_irgen_DSGFR(UChar r1, UChar r2)
11370{
11371 IRTemp op2 = newTemp(Ity_I64);
11372
11373 assign(op2, unop(Iop_32Sto64, get_gpr_w1(r2)));
11374
11375 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11376
11377 return "dsgfr";
11378}
11379
florian55085f82012-11-21 00:36:55 +000011380static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011381s390_irgen_DSGF(UChar r1, IRTemp op2addr)
11382{
11383 IRTemp op2 = newTemp(Ity_I64);
11384
11385 assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkexpr(op2addr))));
11386
11387 s390_irgen_divide_64to64(Iop_DivModS64to64, r1, op2);
11388
11389 return "dsgf";
11390}
11391
11392static void
11393s390_irgen_load_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11394{
11395 UChar reg;
11396 IRTemp addr = newTemp(Ity_I64);
11397
11398 assign(addr, mkexpr(op2addr));
11399 reg = r1;
11400 do {
11401 IRTemp old = addr;
11402
11403 reg %= 16;
11404 put_ar_w0(reg, load(Ity_I32, mkexpr(addr)));
11405 addr = newTemp(Ity_I64);
11406 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11407 reg++;
11408 } while (reg != (r3 + 1));
11409}
11410
florian55085f82012-11-21 00:36:55 +000011411static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011412s390_irgen_LAM(UChar r1, UChar r3, IRTemp op2addr)
11413{
11414 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11415
11416 return "lam";
11417}
11418
florian55085f82012-11-21 00:36:55 +000011419static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011420s390_irgen_LAMY(UChar r1, UChar r3, IRTemp op2addr)
11421{
11422 s390_irgen_load_ar_multiple(r1, r3, op2addr);
11423
11424 return "lamy";
11425}
11426
11427static void
11428s390_irgen_store_ar_multiple(UChar r1, UChar r3, IRTemp op2addr)
11429{
11430 UChar reg;
11431 IRTemp addr = newTemp(Ity_I64);
11432
11433 assign(addr, mkexpr(op2addr));
11434 reg = r1;
11435 do {
11436 IRTemp old = addr;
11437
11438 reg %= 16;
11439 store(mkexpr(addr), get_ar_w0(reg));
11440 addr = newTemp(Ity_I64);
11441 assign(addr, binop(Iop_Add64, mkexpr(old), mkU64(4)));
11442 reg++;
11443 } while (reg != (r3 + 1));
11444}
11445
florian55085f82012-11-21 00:36:55 +000011446static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011447s390_irgen_STAM(UChar r1, UChar r3, IRTemp op2addr)
11448{
11449 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11450
11451 return "stam";
11452}
11453
florian55085f82012-11-21 00:36:55 +000011454static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011455s390_irgen_STAMY(UChar r1, UChar r3, IRTemp op2addr)
11456{
11457 s390_irgen_store_ar_multiple(r1, r3, op2addr);
11458
11459 return "stamy";
11460}
11461
11462
11463/* Implementation for 32-bit compare-and-swap */
11464static void
11465s390_irgen_cas_32(UChar r1, UChar r3, IRTemp op2addr)
11466{
11467 IRCAS *cas;
11468 IRTemp op1 = newTemp(Ity_I32);
11469 IRTemp old_mem = newTemp(Ity_I32);
11470 IRTemp op3 = newTemp(Ity_I32);
11471 IRTemp result = newTemp(Ity_I32);
11472 IRTemp nequal = newTemp(Ity_I1);
11473
11474 assign(op1, get_gpr_w1(r1));
11475 assign(op3, get_gpr_w1(r3));
11476
11477 /* The first and second operands are compared. If they are equal,
11478 the third operand is stored at the second- operand location. */
11479 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11480 Iend_BE, mkexpr(op2addr),
11481 NULL, mkexpr(op1), /* expected value */
11482 NULL, mkexpr(op3) /* new value */);
11483 stmt(IRStmt_CAS(cas));
11484
11485 /* Set CC. Operands compared equal -> 0, else 1. */
11486 assign(result, binop(Iop_Sub32, mkexpr(op1), mkexpr(old_mem)));
11487 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11488
11489 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11490 Otherwise, store the old_value from memory in r1 and yield. */
11491 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11492 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011493 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011494}
11495
florian55085f82012-11-21 00:36:55 +000011496static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011497s390_irgen_CS(UChar r1, UChar r3, IRTemp op2addr)
11498{
11499 s390_irgen_cas_32(r1, r3, op2addr);
11500
11501 return "cs";
11502}
11503
florian55085f82012-11-21 00:36:55 +000011504static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011505s390_irgen_CSY(UChar r1, UChar r3, IRTemp op2addr)
11506{
11507 s390_irgen_cas_32(r1, r3, op2addr);
11508
11509 return "csy";
11510}
11511
florian55085f82012-11-21 00:36:55 +000011512static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011513s390_irgen_CSG(UChar r1, UChar r3, IRTemp op2addr)
11514{
11515 IRCAS *cas;
11516 IRTemp op1 = newTemp(Ity_I64);
11517 IRTemp old_mem = newTemp(Ity_I64);
11518 IRTemp op3 = newTemp(Ity_I64);
11519 IRTemp result = newTemp(Ity_I64);
11520 IRTemp nequal = newTemp(Ity_I1);
11521
11522 assign(op1, get_gpr_dw0(r1));
11523 assign(op3, get_gpr_dw0(r3));
11524
11525 /* The first and second operands are compared. If they are equal,
11526 the third operand is stored at the second- operand location. */
11527 cas = mkIRCAS(IRTemp_INVALID, old_mem,
11528 Iend_BE, mkexpr(op2addr),
11529 NULL, mkexpr(op1), /* expected value */
11530 NULL, mkexpr(op3) /* new value */);
11531 stmt(IRStmt_CAS(cas));
11532
11533 /* Set CC. Operands compared equal -> 0, else 1. */
11534 assign(result, binop(Iop_Sub64, mkexpr(op1), mkexpr(old_mem)));
11535 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11536
11537 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11538 Otherwise, store the old_value from memory in r1 and yield. */
11539 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11540 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem), mkexpr(op1)));
florian6820ba52012-07-26 02:01:50 +000011541 yield_if(mkexpr(nequal));
sewardj2019a972011-03-07 16:04:07 +000011542
11543 return "csg";
11544}
11545
florian448cbba2012-06-06 02:26:01 +000011546/* Implementation for 32-bit compare-double-and-swap */
11547static void
11548s390_irgen_cdas_32(UChar r1, UChar r3, IRTemp op2addr)
11549{
11550 IRCAS *cas;
11551 IRTemp op1_high = newTemp(Ity_I32);
11552 IRTemp op1_low = newTemp(Ity_I32);
11553 IRTemp old_mem_high = newTemp(Ity_I32);
11554 IRTemp old_mem_low = newTemp(Ity_I32);
11555 IRTemp op3_high = newTemp(Ity_I32);
11556 IRTemp op3_low = newTemp(Ity_I32);
11557 IRTemp result = newTemp(Ity_I32);
11558 IRTemp nequal = newTemp(Ity_I1);
11559
11560 assign(op1_high, get_gpr_w1(r1));
11561 assign(op1_low, get_gpr_w1(r1+1));
11562 assign(op3_high, get_gpr_w1(r3));
11563 assign(op3_low, get_gpr_w1(r3+1));
11564
11565 /* The first and second operands are compared. If they are equal,
11566 the third operand is stored at the second-operand location. */
11567 cas = mkIRCAS(old_mem_high, old_mem_low,
11568 Iend_BE, mkexpr(op2addr),
11569 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11570 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11571 stmt(IRStmt_CAS(cas));
11572
11573 /* Set CC. Operands compared equal -> 0, else 1. */
11574 assign(result, unop(Iop_1Uto32,
11575 binop(Iop_CmpNE32,
11576 binop(Iop_Or32,
11577 binop(Iop_Xor32, mkexpr(op1_high), mkexpr(old_mem_high)),
11578 binop(Iop_Xor32, mkexpr(op1_low), mkexpr(old_mem_low))),
11579 mkU32(0))));
11580
11581 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11582
11583 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11584 Otherwise, store the old_value from memory in r1 and yield. */
11585 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11586 put_gpr_w1(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11587 put_gpr_w1(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011588 yield_if(mkexpr(nequal));
florian448cbba2012-06-06 02:26:01 +000011589}
11590
florian55085f82012-11-21 00:36:55 +000011591static const HChar *
florian448cbba2012-06-06 02:26:01 +000011592s390_irgen_CDS(UChar r1, UChar r3, IRTemp op2addr)
11593{
11594 s390_irgen_cdas_32(r1, r3, op2addr);
11595
11596 return "cds";
11597}
11598
florian55085f82012-11-21 00:36:55 +000011599static const HChar *
florian448cbba2012-06-06 02:26:01 +000011600s390_irgen_CDSY(UChar r1, UChar r3, IRTemp op2addr)
11601{
11602 s390_irgen_cdas_32(r1, r3, op2addr);
11603
11604 return "cdsy";
11605}
11606
florian55085f82012-11-21 00:36:55 +000011607static const HChar *
florian448cbba2012-06-06 02:26:01 +000011608s390_irgen_CDSG(UChar r1, UChar r3, IRTemp op2addr)
11609{
11610 IRCAS *cas;
11611 IRTemp op1_high = newTemp(Ity_I64);
11612 IRTemp op1_low = newTemp(Ity_I64);
11613 IRTemp old_mem_high = newTemp(Ity_I64);
11614 IRTemp old_mem_low = newTemp(Ity_I64);
11615 IRTemp op3_high = newTemp(Ity_I64);
11616 IRTemp op3_low = newTemp(Ity_I64);
11617 IRTemp result = newTemp(Ity_I64);
11618 IRTemp nequal = newTemp(Ity_I1);
11619
11620 assign(op1_high, get_gpr_dw0(r1));
11621 assign(op1_low, get_gpr_dw0(r1+1));
11622 assign(op3_high, get_gpr_dw0(r3));
11623 assign(op3_low, get_gpr_dw0(r3+1));
11624
11625 /* The first and second operands are compared. If they are equal,
11626 the third operand is stored at the second-operand location. */
11627 cas = mkIRCAS(old_mem_high, old_mem_low,
11628 Iend_BE, mkexpr(op2addr),
11629 mkexpr(op1_high), mkexpr(op1_low), /* expected value */
11630 mkexpr(op3_high), mkexpr(op3_low) /* new value */);
11631 stmt(IRStmt_CAS(cas));
11632
11633 /* Set CC. Operands compared equal -> 0, else 1. */
11634 assign(result, unop(Iop_1Uto64,
11635 binop(Iop_CmpNE64,
11636 binop(Iop_Or64,
11637 binop(Iop_Xor64, mkexpr(op1_high), mkexpr(old_mem_high)),
11638 binop(Iop_Xor64, mkexpr(op1_low), mkexpr(old_mem_low))),
11639 mkU64(0))));
11640
11641 s390_cc_thunk_put1(S390_CC_OP_BITWISE, result, False);
11642
11643 /* If operands were equal (cc == 0) just store the old value op1 in r1.
11644 Otherwise, store the old_value from memory in r1 and yield. */
11645 assign(nequal, binop(Iop_CmpNE32, s390_call_calculate_cc(), mkU32(0)));
11646 put_gpr_dw0(r1, mkite(mkexpr(nequal), mkexpr(old_mem_high), mkexpr(op1_high)));
11647 put_gpr_dw0(r1+1, mkite(mkexpr(nequal), mkexpr(old_mem_low), mkexpr(op1_low)));
florian6820ba52012-07-26 02:01:50 +000011648 yield_if(mkexpr(nequal));
11649
florian448cbba2012-06-06 02:26:01 +000011650 return "cdsg";
11651}
11652
sewardj2019a972011-03-07 16:04:07 +000011653
11654/* Binary floating point */
11655
florian55085f82012-11-21 00:36:55 +000011656static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011657s390_irgen_AXBR(UChar r1, UChar r2)
11658{
11659 IRTemp op1 = newTemp(Ity_F128);
11660 IRTemp op2 = newTemp(Ity_F128);
11661 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011662 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011663
11664 assign(op1, get_fpr_pair(r1));
11665 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011666 assign(result, triop(Iop_AddF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011667 mkexpr(op2)));
11668 put_fpr_pair(r1, mkexpr(result));
11669
11670 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11671
11672 return "axbr";
11673}
11674
florian55085f82012-11-21 00:36:55 +000011675static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011676s390_irgen_CEBR(UChar r1, UChar r2)
11677{
11678 IRTemp op1 = newTemp(Ity_F32);
11679 IRTemp op2 = newTemp(Ity_F32);
11680 IRTemp cc_vex = newTemp(Ity_I32);
11681 IRTemp cc_s390 = newTemp(Ity_I32);
11682
11683 assign(op1, get_fpr_w0(r1));
11684 assign(op2, get_fpr_w0(r2));
11685 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11686
florian2d3d87f2012-12-21 21:05:17 +000011687 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011688 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11689
11690 return "cebr";
11691}
11692
florian55085f82012-11-21 00:36:55 +000011693static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011694s390_irgen_CDBR(UChar r1, UChar r2)
11695{
11696 IRTemp op1 = newTemp(Ity_F64);
11697 IRTemp op2 = newTemp(Ity_F64);
11698 IRTemp cc_vex = newTemp(Ity_I32);
11699 IRTemp cc_s390 = newTemp(Ity_I32);
11700
11701 assign(op1, get_fpr_dw0(r1));
11702 assign(op2, get_fpr_dw0(r2));
11703 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11704
florian2d3d87f2012-12-21 21:05:17 +000011705 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011706 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11707
11708 return "cdbr";
11709}
11710
florian55085f82012-11-21 00:36:55 +000011711static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011712s390_irgen_CXBR(UChar r1, UChar r2)
11713{
11714 IRTemp op1 = newTemp(Ity_F128);
11715 IRTemp op2 = newTemp(Ity_F128);
11716 IRTemp cc_vex = newTemp(Ity_I32);
11717 IRTemp cc_s390 = newTemp(Ity_I32);
11718
11719 assign(op1, get_fpr_pair(r1));
11720 assign(op2, get_fpr_pair(r2));
11721 assign(cc_vex, binop(Iop_CmpF128, mkexpr(op1), mkexpr(op2)));
11722
florian2d3d87f2012-12-21 21:05:17 +000011723 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011724 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11725
11726 return "cxbr";
11727}
11728
florian55085f82012-11-21 00:36:55 +000011729static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011730s390_irgen_CEB(UChar r1, IRTemp op2addr)
11731{
11732 IRTemp op1 = newTemp(Ity_F32);
11733 IRTemp op2 = newTemp(Ity_F32);
11734 IRTemp cc_vex = newTemp(Ity_I32);
11735 IRTemp cc_s390 = newTemp(Ity_I32);
11736
11737 assign(op1, get_fpr_w0(r1));
11738 assign(op2, load(Ity_F32, mkexpr(op2addr)));
11739 assign(cc_vex, binop(Iop_CmpF32, mkexpr(op1), mkexpr(op2)));
11740
florian2d3d87f2012-12-21 21:05:17 +000011741 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011742 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11743
11744 return "ceb";
11745}
11746
florian55085f82012-11-21 00:36:55 +000011747static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011748s390_irgen_CDB(UChar r1, IRTemp op2addr)
11749{
11750 IRTemp op1 = newTemp(Ity_F64);
11751 IRTemp op2 = newTemp(Ity_F64);
11752 IRTemp cc_vex = newTemp(Ity_I32);
11753 IRTemp cc_s390 = newTemp(Ity_I32);
11754
11755 assign(op1, get_fpr_dw0(r1));
11756 assign(op2, load(Ity_F64, mkexpr(op2addr)));
11757 assign(cc_vex, binop(Iop_CmpF64, mkexpr(op1), mkexpr(op2)));
11758
florian2d3d87f2012-12-21 21:05:17 +000011759 assign(cc_s390, convert_vex_bfpcc_to_s390(cc_vex));
sewardj2019a972011-03-07 16:04:07 +000011760 s390_cc_thunk_put1(S390_CC_OP_SET, cc_s390, False);
11761
11762 return "cdb";
11763}
11764
florian55085f82012-11-21 00:36:55 +000011765static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011766s390_irgen_CXFBR(UChar m3 __attribute__((unused)),
11767 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011768{
11769 IRTemp op2 = newTemp(Ity_I32);
11770
11771 assign(op2, get_gpr_w1(r2));
11772 put_fpr_pair(r1, unop(Iop_I32StoF128, mkexpr(op2)));
11773
11774 return "cxfbr";
11775}
11776
florian55085f82012-11-21 00:36:55 +000011777static const HChar *
floriand2129202012-09-01 20:01:39 +000011778s390_irgen_CXLFBR(UChar m3 __attribute__((unused)),
11779 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011780{
floriane75dafa2012-09-01 17:54:09 +000011781 if (! s390_host_has_fpext) {
11782 emulation_failure(EmFail_S390X_fpext);
11783 } else {
11784 IRTemp op2 = newTemp(Ity_I32);
florian1c8f7ff2012-09-01 00:12:11 +000011785
floriane75dafa2012-09-01 17:54:09 +000011786 assign(op2, get_gpr_w1(r2));
11787 put_fpr_pair(r1, unop(Iop_I32UtoF128, mkexpr(op2)));
11788 }
florian1c8f7ff2012-09-01 00:12:11 +000011789 return "cxlfbr";
11790}
11791
11792
florian55085f82012-11-21 00:36:55 +000011793static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011794s390_irgen_CXGBR(UChar m3 __attribute__((unused)),
11795 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011796{
11797 IRTemp op2 = newTemp(Ity_I64);
11798
11799 assign(op2, get_gpr_dw0(r2));
11800 put_fpr_pair(r1, unop(Iop_I64StoF128, mkexpr(op2)));
11801
11802 return "cxgbr";
11803}
11804
florian55085f82012-11-21 00:36:55 +000011805static const HChar *
floriand2129202012-09-01 20:01:39 +000011806s390_irgen_CXLGBR(UChar m3 __attribute__((unused)),
11807 UChar m4 __attribute__((unused)), UChar r1, UChar r2)
florian1c8f7ff2012-09-01 00:12:11 +000011808{
floriane75dafa2012-09-01 17:54:09 +000011809 if (! s390_host_has_fpext) {
11810 emulation_failure(EmFail_S390X_fpext);
11811 } else {
11812 IRTemp op2 = newTemp(Ity_I64);
florian1c8f7ff2012-09-01 00:12:11 +000011813
floriane75dafa2012-09-01 17:54:09 +000011814 assign(op2, get_gpr_dw0(r2));
11815 put_fpr_pair(r1, unop(Iop_I64UtoF128, mkexpr(op2)));
11816 }
florian1c8f7ff2012-09-01 00:12:11 +000011817 return "cxlgbr";
11818}
11819
florian55085f82012-11-21 00:36:55 +000011820static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011821s390_irgen_CFXBR(UChar m3, UChar m4 __attribute__((unused)),
11822 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011823{
11824 IRTemp op = newTemp(Ity_F128);
11825 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011826 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011827
11828 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011829 assign(result, binop(Iop_F128toI32S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011830 mkexpr(op)));
11831 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011832 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_32, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011833
11834 return "cfxbr";
11835}
11836
florian55085f82012-11-21 00:36:55 +000011837static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011838s390_irgen_CLFXBR(UChar m3, UChar m4 __attribute__((unused)),
11839 UChar r1, UChar r2)
11840{
floriane75dafa2012-09-01 17:54:09 +000011841 if (! s390_host_has_fpext) {
11842 emulation_failure(EmFail_S390X_fpext);
11843 } else {
11844 IRTemp op = newTemp(Ity_F128);
11845 IRTemp result = newTemp(Ity_I32);
florian19e00772012-09-06 03:13:22 +000011846 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011847
floriane75dafa2012-09-01 17:54:09 +000011848 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011849 assign(result, binop(Iop_F128toI32U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011850 mkexpr(op)));
11851 put_gpr_w1(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011852 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_32, op, rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011853 }
florian1c8f7ff2012-09-01 00:12:11 +000011854 return "clfxbr";
11855}
11856
11857
florian55085f82012-11-21 00:36:55 +000011858static const HChar *
florian4b8efad2012-09-02 18:07:08 +000011859s390_irgen_CGXBR(UChar m3, UChar m4 __attribute__((unused)),
11860 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000011861{
11862 IRTemp op = newTemp(Ity_F128);
11863 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011864 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
sewardj2019a972011-03-07 16:04:07 +000011865
11866 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011867 assign(result, binop(Iop_F128toI64S, mkexpr(rounding_mode),
sewardj2019a972011-03-07 16:04:07 +000011868 mkexpr(op)));
11869 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011870 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_INT_64, op, rounding_mode);
sewardj2019a972011-03-07 16:04:07 +000011871
11872 return "cgxbr";
11873}
11874
florian55085f82012-11-21 00:36:55 +000011875static const HChar *
florian1c8f7ff2012-09-01 00:12:11 +000011876s390_irgen_CLGXBR(UChar m3, UChar m4 __attribute__((unused)),
11877 UChar r1, UChar r2)
11878{
floriane75dafa2012-09-01 17:54:09 +000011879 if (! s390_host_has_fpext) {
11880 emulation_failure(EmFail_S390X_fpext);
11881 } else {
11882 IRTemp op = newTemp(Ity_F128);
11883 IRTemp result = newTemp(Ity_I64);
florian19e00772012-09-06 03:13:22 +000011884 IRTemp rounding_mode = encode_bfp_rounding_mode(m3);
florian1c8f7ff2012-09-01 00:12:11 +000011885
floriane75dafa2012-09-01 17:54:09 +000011886 assign(op, get_fpr_pair(r2));
florian19e00772012-09-06 03:13:22 +000011887 assign(result, binop(Iop_F128toI64U, mkexpr(rounding_mode),
floriane75dafa2012-09-01 17:54:09 +000011888 mkexpr(op)));
11889 put_gpr_dw0(r1, mkexpr(result));
florian19e00772012-09-06 03:13:22 +000011890 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_128_TO_UINT_64, op,
11891 rounding_mode);
floriane75dafa2012-09-01 17:54:09 +000011892 }
florian1c8f7ff2012-09-01 00:12:11 +000011893 return "clgxbr";
11894}
11895
florian55085f82012-11-21 00:36:55 +000011896static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011897s390_irgen_DXBR(UChar r1, UChar r2)
11898{
11899 IRTemp op1 = newTemp(Ity_F128);
11900 IRTemp op2 = newTemp(Ity_F128);
11901 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000011902 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000011903
11904 assign(op1, get_fpr_pair(r1));
11905 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000011906 assign(result, triop(Iop_DivF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000011907 mkexpr(op2)));
11908 put_fpr_pair(r1, mkexpr(result));
11909
11910 return "dxbr";
11911}
11912
florian55085f82012-11-21 00:36:55 +000011913static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011914s390_irgen_LTXBR(UChar r1, UChar r2)
11915{
11916 IRTemp result = newTemp(Ity_F128);
11917
11918 assign(result, get_fpr_pair(r2));
11919 put_fpr_pair(r1, mkexpr(result));
11920 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11921
11922 return "ltxbr";
11923}
11924
florian55085f82012-11-21 00:36:55 +000011925static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011926s390_irgen_LCXBR(UChar r1, UChar r2)
11927{
11928 IRTemp result = newTemp(Ity_F128);
11929
11930 assign(result, unop(Iop_NegF128, get_fpr_pair(r2)));
11931 put_fpr_pair(r1, mkexpr(result));
11932 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
11933
11934 return "lcxbr";
11935}
11936
florian55085f82012-11-21 00:36:55 +000011937static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011938s390_irgen_LXDBR(UChar r1, UChar r2)
11939{
11940 IRTemp op = newTemp(Ity_F64);
11941
11942 assign(op, get_fpr_dw0(r2));
11943 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11944
11945 return "lxdbr";
11946}
11947
florian55085f82012-11-21 00:36:55 +000011948static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011949s390_irgen_LXEBR(UChar r1, UChar r2)
11950{
11951 IRTemp op = newTemp(Ity_F32);
11952
11953 assign(op, get_fpr_w0(r2));
11954 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11955
11956 return "lxebr";
11957}
11958
florian55085f82012-11-21 00:36:55 +000011959static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011960s390_irgen_LXDB(UChar r1, IRTemp op2addr)
11961{
11962 IRTemp op = newTemp(Ity_F64);
11963
11964 assign(op, load(Ity_F64, mkexpr(op2addr)));
11965 put_fpr_pair(r1, unop(Iop_F64toF128, mkexpr(op)));
11966
11967 return "lxdb";
11968}
11969
florian55085f82012-11-21 00:36:55 +000011970static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011971s390_irgen_LXEB(UChar r1, IRTemp op2addr)
11972{
11973 IRTemp op = newTemp(Ity_F32);
11974
11975 assign(op, load(Ity_F32, mkexpr(op2addr)));
11976 put_fpr_pair(r1, unop(Iop_F32toF128, mkexpr(op)));
11977
11978 return "lxeb";
11979}
11980
florian55085f82012-11-21 00:36:55 +000011981static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011982s390_irgen_LNEBR(UChar r1, UChar r2)
11983{
11984 IRTemp result = newTemp(Ity_F32);
11985
11986 assign(result, unop(Iop_NegF32, unop(Iop_AbsF32, get_fpr_w0(r2))));
11987 put_fpr_w0(r1, mkexpr(result));
11988 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
11989
11990 return "lnebr";
11991}
11992
florian55085f82012-11-21 00:36:55 +000011993static const HChar *
sewardj2019a972011-03-07 16:04:07 +000011994s390_irgen_LNDBR(UChar r1, UChar r2)
11995{
11996 IRTemp result = newTemp(Ity_F64);
11997
11998 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
11999 put_fpr_dw0(r1, mkexpr(result));
12000 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12001
12002 return "lndbr";
12003}
12004
florian55085f82012-11-21 00:36:55 +000012005static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012006s390_irgen_LNXBR(UChar r1, UChar r2)
12007{
12008 IRTemp result = newTemp(Ity_F128);
12009
12010 assign(result, unop(Iop_NegF128, unop(Iop_AbsF128, get_fpr_pair(r2))));
12011 put_fpr_pair(r1, mkexpr(result));
12012 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12013
12014 return "lnxbr";
12015}
12016
florian55085f82012-11-21 00:36:55 +000012017static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012018s390_irgen_LPEBR(UChar r1, UChar r2)
12019{
12020 IRTemp result = newTemp(Ity_F32);
12021
12022 assign(result, unop(Iop_AbsF32, get_fpr_w0(r2)));
12023 put_fpr_w0(r1, mkexpr(result));
12024 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_32, result);
12025
12026 return "lpebr";
12027}
12028
florian55085f82012-11-21 00:36:55 +000012029static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012030s390_irgen_LPDBR(UChar r1, UChar r2)
12031{
12032 IRTemp result = newTemp(Ity_F64);
12033
12034 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12035 put_fpr_dw0(r1, mkexpr(result));
12036 s390_cc_thunk_put1f(S390_CC_OP_BFP_RESULT_64, result);
12037
12038 return "lpdbr";
12039}
12040
florian55085f82012-11-21 00:36:55 +000012041static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012042s390_irgen_LPXBR(UChar r1, UChar r2)
12043{
12044 IRTemp result = newTemp(Ity_F128);
12045
12046 assign(result, unop(Iop_AbsF128, get_fpr_pair(r2)));
12047 put_fpr_pair(r1, mkexpr(result));
12048 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12049
12050 return "lpxbr";
12051}
12052
florian55085f82012-11-21 00:36:55 +000012053static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012054s390_irgen_LDXBR(UChar m3, UChar m4 __attribute__((unused)),
12055 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012056{
florian125e20d2012-10-07 15:42:37 +000012057 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012058 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012059 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012060 }
sewardj2019a972011-03-07 16:04:07 +000012061 IRTemp result = newTemp(Ity_F64);
12062
floriandb4fcaa2012-09-05 19:54:08 +000012063 assign(result, binop(Iop_F128toF64, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012064 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012065 put_fpr_dw0(r1, mkexpr(result));
12066
12067 return "ldxbr";
12068}
12069
florian55085f82012-11-21 00:36:55 +000012070static const HChar *
florian4b8efad2012-09-02 18:07:08 +000012071s390_irgen_LEXBR(UChar m3, UChar m4 __attribute__((unused)),
12072 UChar r1, UChar r2)
sewardj2019a972011-03-07 16:04:07 +000012073{
florian125e20d2012-10-07 15:42:37 +000012074 if (! s390_host_has_fpext && m3 != S390_BFP_ROUND_PER_FPC) {
florian12b0bca2012-09-05 20:05:20 +000012075 emulation_warning(EmWarn_S390X_fpext_rounding);
florian125e20d2012-10-07 15:42:37 +000012076 m3 = S390_BFP_ROUND_PER_FPC;
florian12b0bca2012-09-05 20:05:20 +000012077 }
sewardj2019a972011-03-07 16:04:07 +000012078 IRTemp result = newTemp(Ity_F32);
12079
floriandb4fcaa2012-09-05 19:54:08 +000012080 assign(result, binop(Iop_F128toF32, mkexpr(encode_bfp_rounding_mode(m3)),
florian4b8efad2012-09-02 18:07:08 +000012081 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012082 put_fpr_w0(r1, mkexpr(result));
12083
12084 return "lexbr";
12085}
12086
florian55085f82012-11-21 00:36:55 +000012087static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012088s390_irgen_MXBR(UChar r1, UChar r2)
12089{
12090 IRTemp op1 = newTemp(Ity_F128);
12091 IRTemp op2 = newTemp(Ity_F128);
12092 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012093 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012094
12095 assign(op1, get_fpr_pair(r1));
12096 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012097 assign(result, triop(Iop_MulF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012098 mkexpr(op2)));
12099 put_fpr_pair(r1, mkexpr(result));
12100
12101 return "mxbr";
12102}
12103
florian55085f82012-11-21 00:36:55 +000012104static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012105s390_irgen_MAEBR(UChar r1, UChar r3, UChar r2)
12106{
florian125e20d2012-10-07 15:42:37 +000012107 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012108
floriandb4fcaa2012-09-05 19:54:08 +000012109 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012110 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012111
12112 return "maebr";
12113}
12114
florian55085f82012-11-21 00:36:55 +000012115static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012116s390_irgen_MADBR(UChar r1, UChar r3, UChar r2)
12117{
florian125e20d2012-10-07 15:42:37 +000012118 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012119
floriandb4fcaa2012-09-05 19:54:08 +000012120 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012121 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012122
12123 return "madbr";
12124}
12125
florian55085f82012-11-21 00:36:55 +000012126static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012127s390_irgen_MAEB(UChar r3, IRTemp op2addr, UChar r1)
12128{
12129 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012130 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012131
floriandb4fcaa2012-09-05 19:54:08 +000012132 put_fpr_w0(r1, qop(Iop_MAddF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012133 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012134
12135 return "maeb";
12136}
12137
florian55085f82012-11-21 00:36:55 +000012138static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012139s390_irgen_MADB(UChar r3, IRTemp op2addr, UChar r1)
12140{
12141 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012142 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012143
floriandb4fcaa2012-09-05 19:54:08 +000012144 put_fpr_dw0(r1, qop(Iop_MAddF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012145 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012146
12147 return "madb";
12148}
12149
florian55085f82012-11-21 00:36:55 +000012150static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012151s390_irgen_MSEBR(UChar r1, UChar r3, UChar r2)
12152{
florian125e20d2012-10-07 15:42:37 +000012153 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012154
floriandb4fcaa2012-09-05 19:54:08 +000012155 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012156 get_fpr_w0(r3), get_fpr_w0(r2), get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012157
12158 return "msebr";
12159}
12160
florian55085f82012-11-21 00:36:55 +000012161static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012162s390_irgen_MSDBR(UChar r1, UChar r3, UChar r2)
12163{
florian125e20d2012-10-07 15:42:37 +000012164 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
florian847684d2012-09-05 04:19:09 +000012165
floriandb4fcaa2012-09-05 19:54:08 +000012166 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012167 get_fpr_dw0(r3), get_fpr_dw0(r2), get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012168
12169 return "msdbr";
12170}
12171
florian55085f82012-11-21 00:36:55 +000012172static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012173s390_irgen_MSEB(UChar r3, IRTemp op2addr, UChar r1)
12174{
12175 IRExpr *op2 = load(Ity_F32, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012176 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012177
floriandb4fcaa2012-09-05 19:54:08 +000012178 put_fpr_w0(r1, qop(Iop_MSubF32, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012179 get_fpr_w0(r3), op2, get_fpr_w0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012180
12181 return "mseb";
12182}
12183
florian55085f82012-11-21 00:36:55 +000012184static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012185s390_irgen_MSDB(UChar r3, IRTemp op2addr, UChar r1)
12186{
12187 IRExpr *op2 = load(Ity_F64, mkexpr(op2addr));
florian125e20d2012-10-07 15:42:37 +000012188 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012189
floriandb4fcaa2012-09-05 19:54:08 +000012190 put_fpr_dw0(r1, qop(Iop_MSubF64, mkexpr(rounding_mode),
florian5906a6b2012-10-16 02:53:33 +000012191 get_fpr_dw0(r3), op2, get_fpr_dw0(r1)));
sewardj2019a972011-03-07 16:04:07 +000012192
12193 return "msdb";
12194}
12195
florian55085f82012-11-21 00:36:55 +000012196static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012197s390_irgen_SQEBR(UChar r1, UChar r2)
12198{
12199 IRTemp result = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012200 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012201
floriandb4fcaa2012-09-05 19:54:08 +000012202 assign(result, binop(Iop_SqrtF32, mkexpr(rounding_mode), get_fpr_w0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012203 put_fpr_w0(r1, mkexpr(result));
12204
12205 return "sqebr";
12206}
12207
florian55085f82012-11-21 00:36:55 +000012208static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012209s390_irgen_SQDBR(UChar r1, UChar r2)
12210{
12211 IRTemp result = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012212 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012213
floriandb4fcaa2012-09-05 19:54:08 +000012214 assign(result, binop(Iop_SqrtF64, mkexpr(rounding_mode), get_fpr_dw0(r2)));
sewardj2019a972011-03-07 16:04:07 +000012215 put_fpr_dw0(r1, mkexpr(result));
12216
12217 return "sqdbr";
12218}
12219
florian55085f82012-11-21 00:36:55 +000012220static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012221s390_irgen_SQXBR(UChar r1, UChar r2)
12222{
12223 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012224 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012225
floriandb4fcaa2012-09-05 19:54:08 +000012226 assign(result, binop(Iop_SqrtF128, mkexpr(rounding_mode),
12227 get_fpr_pair(r2)));
sewardj2019a972011-03-07 16:04:07 +000012228 put_fpr_pair(r1, mkexpr(result));
12229
12230 return "sqxbr";
12231}
12232
florian55085f82012-11-21 00:36:55 +000012233static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012234s390_irgen_SQEB(UChar r1, IRTemp op2addr)
12235{
12236 IRTemp op = newTemp(Ity_F32);
florian125e20d2012-10-07 15:42:37 +000012237 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012238
12239 assign(op, load(Ity_F32, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012240 put_fpr_w0(r1, binop(Iop_SqrtF32, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012241
12242 return "sqeb";
12243}
12244
florian55085f82012-11-21 00:36:55 +000012245static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012246s390_irgen_SQDB(UChar r1, IRTemp op2addr)
12247{
12248 IRTemp op = newTemp(Ity_F64);
florian125e20d2012-10-07 15:42:37 +000012249 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012250
12251 assign(op, load(Ity_F64, mkexpr(op2addr)));
floriandb4fcaa2012-09-05 19:54:08 +000012252 put_fpr_dw0(r1, binop(Iop_SqrtF64, mkexpr(rounding_mode), mkexpr(op)));
sewardj2019a972011-03-07 16:04:07 +000012253
12254 return "sqdb";
12255}
12256
florian55085f82012-11-21 00:36:55 +000012257static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012258s390_irgen_SXBR(UChar r1, UChar r2)
12259{
12260 IRTemp op1 = newTemp(Ity_F128);
12261 IRTemp op2 = newTemp(Ity_F128);
12262 IRTemp result = newTemp(Ity_F128);
florian125e20d2012-10-07 15:42:37 +000012263 IRTemp rounding_mode = encode_bfp_rounding_mode(S390_BFP_ROUND_PER_FPC);
sewardj2019a972011-03-07 16:04:07 +000012264
12265 assign(op1, get_fpr_pair(r1));
12266 assign(op2, get_fpr_pair(r2));
floriandb4fcaa2012-09-05 19:54:08 +000012267 assign(result, triop(Iop_SubF128, mkexpr(rounding_mode), mkexpr(op1),
sewardj2019a972011-03-07 16:04:07 +000012268 mkexpr(op2)));
12269 put_fpr_pair(r1, mkexpr(result));
12270 s390_cc_thunk_put1f128(S390_CC_OP_BFP_RESULT_128, result);
12271
12272 return "sxbr";
12273}
12274
florian55085f82012-11-21 00:36:55 +000012275static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012276s390_irgen_TCEB(UChar r1, IRTemp op2addr)
12277{
12278 IRTemp value = newTemp(Ity_F32);
12279
12280 assign(value, get_fpr_w0(r1));
12281
12282 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_32, value, op2addr);
12283
12284 return "tceb";
12285}
12286
florian55085f82012-11-21 00:36:55 +000012287static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012288s390_irgen_TCDB(UChar r1, IRTemp op2addr)
12289{
12290 IRTemp value = newTemp(Ity_F64);
12291
12292 assign(value, get_fpr_dw0(r1));
12293
12294 s390_cc_thunk_putFZ(S390_CC_OP_BFP_TDC_64, value, op2addr);
12295
12296 return "tcdb";
12297}
12298
florian55085f82012-11-21 00:36:55 +000012299static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012300s390_irgen_TCXB(UChar r1, IRTemp op2addr)
12301{
12302 IRTemp value = newTemp(Ity_F128);
12303
12304 assign(value, get_fpr_pair(r1));
12305
12306 s390_cc_thunk_put1f128Z(S390_CC_OP_BFP_TDC_128, value, op2addr);
12307
12308 return "tcxb";
12309}
12310
florian55085f82012-11-21 00:36:55 +000012311static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012312s390_irgen_LCDFR(UChar r1, UChar r2)
12313{
12314 IRTemp result = newTemp(Ity_F64);
12315
12316 assign(result, unop(Iop_NegF64, get_fpr_dw0(r2)));
12317 put_fpr_dw0(r1, mkexpr(result));
12318
12319 return "lcdfr";
12320}
12321
florian55085f82012-11-21 00:36:55 +000012322static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012323s390_irgen_LNDFR(UChar r1, UChar r2)
12324{
12325 IRTemp result = newTemp(Ity_F64);
12326
12327 assign(result, unop(Iop_NegF64, unop(Iop_AbsF64, get_fpr_dw0(r2))));
12328 put_fpr_dw0(r1, mkexpr(result));
12329
12330 return "lndfr";
12331}
12332
florian55085f82012-11-21 00:36:55 +000012333static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012334s390_irgen_LPDFR(UChar r1, UChar r2)
12335{
12336 IRTemp result = newTemp(Ity_F64);
12337
12338 assign(result, unop(Iop_AbsF64, get_fpr_dw0(r2)));
12339 put_fpr_dw0(r1, mkexpr(result));
12340
12341 return "lpdfr";
12342}
12343
florian55085f82012-11-21 00:36:55 +000012344static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012345s390_irgen_LDGR(UChar r1, UChar r2)
12346{
12347 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, get_gpr_dw0(r2)));
12348
12349 return "ldgr";
12350}
12351
florian55085f82012-11-21 00:36:55 +000012352static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012353s390_irgen_LGDR(UChar r1, UChar r2)
12354{
12355 put_gpr_dw0(r1, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)));
12356
12357 return "lgdr";
12358}
12359
12360
florian55085f82012-11-21 00:36:55 +000012361static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012362s390_irgen_CPSDR(UChar r3, UChar r1, UChar r2)
12363{
12364 IRTemp sign = newTemp(Ity_I64);
12365 IRTemp value = newTemp(Ity_I64);
12366
12367 assign(sign, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r3)),
12368 mkU64(1ULL << 63)));
12369 assign(value, binop(Iop_And64, unop(Iop_ReinterpF64asI64, get_fpr_dw0(r2)),
12370 mkU64((1ULL << 63) - 1)));
12371 put_fpr_dw0(r1, unop(Iop_ReinterpI64asF64, binop(Iop_Or64, mkexpr(value),
12372 mkexpr(sign))));
12373
12374 return "cpsdr";
12375}
12376
12377
sewardj2019a972011-03-07 16:04:07 +000012378static IRExpr *
12379s390_call_cvb(IRExpr *in)
12380{
12381 IRExpr **args, *call;
12382
12383 args = mkIRExprVec_1(in);
12384 call = mkIRExprCCall(Ity_I32, 0 /*regparm*/,
12385 "s390_do_cvb", &s390_do_cvb, args);
12386
12387 /* Nothing is excluded from definedness checking. */
12388 call->Iex.CCall.cee->mcx_mask = 0;
12389
12390 return call;
12391}
12392
florian55085f82012-11-21 00:36:55 +000012393static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012394s390_irgen_CVB(UChar r1, IRTemp op2addr)
12395{
12396 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12397
12398 return "cvb";
12399}
12400
florian55085f82012-11-21 00:36:55 +000012401static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012402s390_irgen_CVBY(UChar r1, IRTemp op2addr)
12403{
12404 put_gpr_w1(r1, s390_call_cvb(load(Ity_I64, mkexpr(op2addr))));
12405
12406 return "cvby";
12407}
12408
12409
sewardj2019a972011-03-07 16:04:07 +000012410static IRExpr *
12411s390_call_cvd(IRExpr *in)
12412{
12413 IRExpr **args, *call;
12414
12415 args = mkIRExprVec_1(in);
12416 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12417 "s390_do_cvd", &s390_do_cvd, args);
12418
12419 /* Nothing is excluded from definedness checking. */
12420 call->Iex.CCall.cee->mcx_mask = 0;
12421
12422 return call;
12423}
12424
florian55085f82012-11-21 00:36:55 +000012425static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012426s390_irgen_CVD(UChar r1, IRTemp op2addr)
12427{
florian11b8ee82012-08-06 13:35:33 +000012428 store(mkexpr(op2addr), s390_call_cvd(unop(Iop_32Uto64, get_gpr_w1(r1))));
sewardj2019a972011-03-07 16:04:07 +000012429
12430 return "cvd";
12431}
12432
florian55085f82012-11-21 00:36:55 +000012433static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012434s390_irgen_CVDY(UChar r1, IRTemp op2addr)
12435{
12436 store(mkexpr(op2addr), s390_call_cvd(get_gpr_w1(r1)));
12437
12438 return "cvdy";
12439}
12440
florian55085f82012-11-21 00:36:55 +000012441static const HChar *
sewardj2019a972011-03-07 16:04:07 +000012442s390_irgen_FLOGR(UChar r1, UChar r2)
12443{
12444 IRTemp input = newTemp(Ity_I64);
12445 IRTemp not_zero = newTemp(Ity_I64);
12446 IRTemp tmpnum = newTemp(Ity_I64);
12447 IRTemp num = newTemp(Ity_I64);
12448 IRTemp shift_amount = newTemp(Ity_I8);
12449
12450 /* We use the "count leading zeroes" operator because the number of
12451 leading zeroes is identical with the bit position of the first '1' bit.
12452 However, that operator does not work when the input value is zero.
12453 Therefore, we set the LSB of the input value to 1 and use Clz64 on
12454 the modified value. If input == 0, then the result is 64. Otherwise,
12455 the result of Clz64 is what we want. */
12456
12457 assign(input, get_gpr_dw0(r2));
12458 assign(not_zero, binop(Iop_Or64, mkexpr(input), mkU64(1)));
12459 assign(tmpnum, unop(Iop_Clz64, mkexpr(not_zero)));
12460
12461 /* num = (input == 0) ? 64 : tmpnum */
12462 assign(num, mkite(binop(Iop_CmpEQ64, mkexpr(input), mkU64(0)),
12463 /* == 0 */ mkU64(64),
12464 /* != 0 */ mkexpr(tmpnum)));
12465
12466 put_gpr_dw0(r1, mkexpr(num));
12467
12468 /* Set the leftmost '1' bit of the input value to zero. The general scheme
12469 is to first shift the input value by NUM + 1 bits to the left which
12470 causes the leftmost '1' bit to disappear. Then we shift logically to
12471 the right by NUM + 1 bits. Because the semantics of Iop_Shl64 and
12472 Iop_Shr64 are undefined if the shift-amount is greater than or equal to
12473 the width of the value-to-be-shifted, we need to special case
12474 NUM + 1 >= 64. This is equivalent to INPUT != 0 && INPUT != 1.
12475 For both such INPUT values the result will be 0. */
12476
12477 assign(shift_amount, unop(Iop_64to8, binop(Iop_Add64, mkexpr(num),
12478 mkU64(1))));
12479
12480 put_gpr_dw0(r1 + 1,
florian6ad49522011-09-09 02:38:55 +000012481 mkite(binop(Iop_CmpLE64U, mkexpr(input), mkU64(1)),
12482 /* == 0 || == 1*/ mkU64(0),
12483 /* otherwise */
12484 binop(Iop_Shr64,
12485 binop(Iop_Shl64, mkexpr(input),
12486 mkexpr(shift_amount)),
12487 mkexpr(shift_amount))));
sewardj2019a972011-03-07 16:04:07 +000012488
12489 /* Compare the original value as an unsigned integer with 0. */
12490 s390_cc_thunk_put2(S390_CC_OP_UNSIGNED_COMPARE, input,
12491 mktemp(Ity_I64, mkU64(0)), False);
12492
12493 return "flogr";
12494}
12495
florian55085f82012-11-21 00:36:55 +000012496static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012497s390_irgen_STCK(IRTemp op2addr)
12498{
12499 IRDirty *d;
12500 IRTemp cc = newTemp(Ity_I64);
12501
12502 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCK",
12503 &s390x_dirtyhelper_STCK,
12504 mkIRExprVec_1(mkexpr(op2addr)));
12505 d->mFx = Ifx_Write;
12506 d->mAddr = mkexpr(op2addr);
12507 d->mSize = 8;
12508 stmt(IRStmt_Dirty(d));
12509 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12510 mkexpr(cc), mkU64(0), mkU64(0));
12511 return "stck";
12512}
12513
florian55085f82012-11-21 00:36:55 +000012514static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012515s390_irgen_STCKF(IRTemp op2addr)
12516{
florianc5c669b2012-08-26 14:32:28 +000012517 if (! s390_host_has_stckf) {
floriane75dafa2012-09-01 17:54:09 +000012518 emulation_failure(EmFail_S390X_stckf);
florianc5c669b2012-08-26 14:32:28 +000012519 } else {
12520 IRTemp cc = newTemp(Ity_I64);
sewardj1e5fea62011-05-17 16:18:36 +000012521
florianc5c669b2012-08-26 14:32:28 +000012522 IRDirty *d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKF",
12523 &s390x_dirtyhelper_STCKF,
12524 mkIRExprVec_1(mkexpr(op2addr)));
12525 d->mFx = Ifx_Write;
12526 d->mAddr = mkexpr(op2addr);
12527 d->mSize = 8;
12528 stmt(IRStmt_Dirty(d));
12529 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12530 mkexpr(cc), mkU64(0), mkU64(0));
12531 }
sewardj1e5fea62011-05-17 16:18:36 +000012532 return "stckf";
12533}
12534
florian55085f82012-11-21 00:36:55 +000012535static const HChar *
sewardj1e5fea62011-05-17 16:18:36 +000012536s390_irgen_STCKE(IRTemp op2addr)
12537{
12538 IRDirty *d;
12539 IRTemp cc = newTemp(Ity_I64);
12540
12541 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STCKE",
12542 &s390x_dirtyhelper_STCKE,
12543 mkIRExprVec_1(mkexpr(op2addr)));
12544 d->mFx = Ifx_Write;
12545 d->mAddr = mkexpr(op2addr);
12546 d->mSize = 16;
12547 stmt(IRStmt_Dirty(d));
12548 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET),
12549 mkexpr(cc), mkU64(0), mkU64(0));
12550 return "stcke";
12551}
12552
florian55085f82012-11-21 00:36:55 +000012553static const HChar *
florian933065d2011-07-11 01:48:02 +000012554s390_irgen_STFLE(IRTemp op2addr)
12555{
florian4e0083e2012-08-26 03:41:56 +000012556 if (! s390_host_has_stfle) {
floriane75dafa2012-09-01 17:54:09 +000012557 emulation_failure(EmFail_S390X_stfle);
florian4e0083e2012-08-26 03:41:56 +000012558 return "stfle";
12559 }
12560
florian933065d2011-07-11 01:48:02 +000012561 IRDirty *d;
12562 IRTemp cc = newTemp(Ity_I64);
12563
12564 d = unsafeIRDirty_1_N(cc, 0, "s390x_dirtyhelper_STFLE",
12565 &s390x_dirtyhelper_STFLE,
12566 mkIRExprVec_1(mkexpr(op2addr)));
12567
12568 d->needsBBP = 1; /* Need to pass pointer to guest state to helper */
12569
sewardjc9069f22012-06-01 16:09:50 +000012570 d->nFxState = 1;
12571 vex_bzero(&d->fxState, sizeof(d->fxState));
12572
florian933065d2011-07-11 01:48:02 +000012573 d->fxState[0].fx = Ifx_Modify; /* read then write */
12574 d->fxState[0].offset = S390X_GUEST_OFFSET(guest_r0);
12575 d->fxState[0].size = sizeof(ULong);
florian933065d2011-07-11 01:48:02 +000012576
12577 d->mAddr = mkexpr(op2addr);
12578 /* Pretend all double words are written */
12579 d->mSize = S390_NUM_FACILITY_DW * sizeof(ULong);
12580 d->mFx = Ifx_Write;
12581
12582 stmt(IRStmt_Dirty(d));
12583
12584 s390_cc_thunk_fill(mkU64(S390_CC_OP_SET), mkexpr(cc), mkU64(0), mkU64(0));
12585
12586 return "stfle";
12587}
12588
florian55085f82012-11-21 00:36:55 +000012589static const HChar *
floriana4384a32011-08-11 16:58:45 +000012590s390_irgen_CKSM(UChar r1,UChar r2)
12591{
12592 IRTemp addr = newTemp(Ity_I64);
12593 IRTemp op = newTemp(Ity_I32);
12594 IRTemp len = newTemp(Ity_I64);
12595 IRTemp oldval = newTemp(Ity_I32);
12596 IRTemp mask = newTemp(Ity_I32);
12597 IRTemp newop = newTemp(Ity_I32);
12598 IRTemp result = newTemp(Ity_I32);
12599 IRTemp result1 = newTemp(Ity_I32);
12600 IRTemp inc = newTemp(Ity_I64);
12601
12602 assign(oldval, get_gpr_w1(r1));
12603 assign(addr, get_gpr_dw0(r2));
12604 assign(len, get_gpr_dw0(r2+1));
12605
12606 /* Condition code is always zero. */
12607 s390_cc_set(0);
12608
12609 /* If length is zero, there is no need to calculate the checksum */
florian6820ba52012-07-26 02:01:50 +000012610 next_insn_if(binop(Iop_CmpEQ64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012611
12612 /* Assiging the increment variable to adjust address and length
12613 later on. */
12614 assign(inc, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12615 mkexpr(len), mkU64(4)));
12616
12617 /* If length < 4 the final 4-byte 2nd operand value is computed by
12618 appending the remaining bytes to the right with 0. This is done
12619 by AND'ing the 4 bytes loaded from memory with an appropriate
12620 mask. If length >= 4, that mask is simply 0xffffffff. */
12621
12622 assign(mask, mkite(binop(Iop_CmpLT64U, mkexpr(len), mkU64(4)),
12623 /* Mask computation when len < 4:
12624 0xffffffff << (32 - (len % 4)*8) */
12625 binop(Iop_Shl32, mkU32(0xffffffff),
12626 unop(Iop_32to8,
12627 binop(Iop_Sub32, mkU32(32),
12628 binop(Iop_Shl32,
12629 unop(Iop_64to32,
12630 binop(Iop_And64,
12631 mkexpr(len), mkU64(3))),
12632 mkU8(3))))),
12633 mkU32(0xffffffff)));
12634
12635 assign(op, load(Ity_I32, mkexpr(addr)));
12636 assign(newop, binop(Iop_And32, mkexpr(op), mkexpr(mask)));
12637 assign(result, binop(Iop_Add32, mkexpr(newop), mkexpr(oldval)));
12638
12639 /* Checking for carry */
12640 assign(result1, mkite(binop(Iop_CmpLT32U, mkexpr(result), mkexpr(newop)),
12641 binop(Iop_Add32, mkexpr(result), mkU32(1)),
12642 mkexpr(result)));
12643
12644 put_gpr_w1(r1, mkexpr(result1));
12645 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr), mkexpr(inc)));
12646 put_gpr_dw0(r2+1, binop(Iop_Sub64, mkexpr(len), mkexpr(inc)));
12647
florian6820ba52012-07-26 02:01:50 +000012648 iterate_if(binop(Iop_CmpNE64, mkexpr(len), mkU64(0)));
floriana4384a32011-08-11 16:58:45 +000012649
12650 return "cksm";
12651}
12652
florian55085f82012-11-21 00:36:55 +000012653static const HChar *
florian9af37692012-01-15 21:01:16 +000012654s390_irgen_TROO(UChar m3, UChar r1, UChar r2)
12655{
12656 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12657 src_addr = newTemp(Ity_I64);
12658 des_addr = newTemp(Ity_I64);
12659 tab_addr = newTemp(Ity_I64);
12660 test_byte = newTemp(Ity_I8);
12661 src_len = newTemp(Ity_I64);
12662
12663 assign(src_addr, get_gpr_dw0(r2));
12664 assign(des_addr, get_gpr_dw0(r1));
12665 assign(tab_addr, get_gpr_dw0(1));
florian53518532012-01-18 14:00:31 +000012666 assign(src_len, get_gpr_dw0(r1+1));
florian9af37692012-01-15 21:01:16 +000012667 assign(test_byte, get_gpr_b7(0));
12668
12669 IRTemp op = newTemp(Ity_I8);
12670 IRTemp op1 = newTemp(Ity_I8);
12671 IRTemp result = newTemp(Ity_I64);
12672
12673 /* End of source string? We're done; proceed to next insn */
12674 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012675 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian9af37692012-01-15 21:01:16 +000012676
12677 /* Load character from source string, index translation table and
12678 store translated character in op1. */
12679 assign(op, load(Ity_I8, mkexpr(src_addr)));
12680
12681 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12682 mkexpr(tab_addr)));
12683 assign(op1, load(Ity_I8, mkexpr(result)));
12684
12685 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12686 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012687 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian9af37692012-01-15 21:01:16 +000012688 }
12689 store(get_gpr_dw0(r1), mkexpr(op1));
12690
12691 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12692 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12693 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12694
florian6820ba52012-07-26 02:01:50 +000012695 iterate();
florian9af37692012-01-15 21:01:16 +000012696
12697 return "troo";
12698}
12699
florian55085f82012-11-21 00:36:55 +000012700static const HChar *
florian730448f2012-02-04 17:07:07 +000012701s390_irgen_TRTO(UChar m3, UChar r1, UChar r2)
12702{
12703 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12704 src_addr = newTemp(Ity_I64);
12705 des_addr = newTemp(Ity_I64);
12706 tab_addr = newTemp(Ity_I64);
12707 test_byte = newTemp(Ity_I8);
12708 src_len = newTemp(Ity_I64);
12709
12710 assign(src_addr, get_gpr_dw0(r2));
12711 assign(des_addr, get_gpr_dw0(r1));
12712 assign(tab_addr, get_gpr_dw0(1));
12713 assign(src_len, get_gpr_dw0(r1+1));
12714 assign(test_byte, get_gpr_b7(0));
12715
12716 IRTemp op = newTemp(Ity_I16);
12717 IRTemp op1 = newTemp(Ity_I8);
12718 IRTemp result = newTemp(Ity_I64);
12719
12720 /* End of source string? We're done; proceed to next insn */
12721 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012722 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012723
12724 /* Load character from source string, index translation table and
12725 store translated character in op1. */
12726 assign(op, load(Ity_I16, mkexpr(src_addr)));
12727
12728 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12729 mkexpr(tab_addr)));
12730
12731 assign(op1, load(Ity_I8, mkexpr(result)));
12732
12733 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12734 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012735 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012736 }
12737 store(get_gpr_dw0(r1), mkexpr(op1));
12738
12739 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12740 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(1)));
12741 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12742
florian6820ba52012-07-26 02:01:50 +000012743 iterate();
florian730448f2012-02-04 17:07:07 +000012744
12745 return "trto";
12746}
12747
florian55085f82012-11-21 00:36:55 +000012748static const HChar *
florian730448f2012-02-04 17:07:07 +000012749s390_irgen_TROT(UChar m3, UChar r1, UChar r2)
12750{
12751 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12752 src_addr = newTemp(Ity_I64);
12753 des_addr = newTemp(Ity_I64);
12754 tab_addr = newTemp(Ity_I64);
12755 test_byte = newTemp(Ity_I16);
12756 src_len = newTemp(Ity_I64);
12757
12758 assign(src_addr, get_gpr_dw0(r2));
12759 assign(des_addr, get_gpr_dw0(r1));
12760 assign(tab_addr, get_gpr_dw0(1));
12761 assign(src_len, get_gpr_dw0(r1+1));
12762 assign(test_byte, get_gpr_hw3(0));
12763
12764 IRTemp op = newTemp(Ity_I8);
12765 IRTemp op1 = newTemp(Ity_I16);
12766 IRTemp result = newTemp(Ity_I64);
12767
12768 /* End of source string? We're done; proceed to next insn */
12769 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012770 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012771
12772 /* Load character from source string, index translation table and
12773 store translated character in op1. */
12774 assign(op, binop(Iop_Shl8, load(Ity_I8, mkexpr(src_addr)), mkU8(1)));
12775
12776 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12777 mkexpr(tab_addr)));
12778 assign(op1, load(Ity_I16, mkexpr(result)));
12779
12780 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12781 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012782 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012783 }
12784 store(get_gpr_dw0(r1), mkexpr(op1));
12785
12786 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12787 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12788 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12789
florian6820ba52012-07-26 02:01:50 +000012790 iterate();
florian730448f2012-02-04 17:07:07 +000012791
12792 return "trot";
12793}
12794
florian55085f82012-11-21 00:36:55 +000012795static const HChar *
florian730448f2012-02-04 17:07:07 +000012796s390_irgen_TRTT(UChar m3, UChar r1, UChar r2)
12797{
12798 IRTemp src_addr, des_addr, tab_addr, src_len, test_byte;
12799 src_addr = newTemp(Ity_I64);
12800 des_addr = newTemp(Ity_I64);
12801 tab_addr = newTemp(Ity_I64);
12802 test_byte = newTemp(Ity_I16);
12803 src_len = newTemp(Ity_I64);
12804
12805 assign(src_addr, get_gpr_dw0(r2));
12806 assign(des_addr, get_gpr_dw0(r1));
12807 assign(tab_addr, get_gpr_dw0(1));
12808 assign(src_len, get_gpr_dw0(r1+1));
12809 assign(test_byte, get_gpr_hw3(0));
12810
12811 IRTemp op = newTemp(Ity_I16);
12812 IRTemp op1 = newTemp(Ity_I16);
12813 IRTemp result = newTemp(Ity_I64);
12814
12815 /* End of source string? We're done; proceed to next insn */
12816 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012817 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012818
12819 /* Load character from source string, index translation table and
12820 store translated character in op1. */
12821 assign(op, binop(Iop_Shl16, load(Ity_I16, mkexpr(src_addr)), mkU8(1)));
12822
12823 assign(result, binop(Iop_Add64, unop(Iop_16Uto64, mkexpr(op)),
12824 mkexpr(tab_addr)));
12825 assign(op1, load(Ity_I16, mkexpr(result)));
12826
12827 if (! s390_host_has_etf2 || (m3 & 0x1) == 0) {
12828 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012829 next_insn_if(binop(Iop_CmpEQ16, mkexpr(op1), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012830 }
12831
12832 store(get_gpr_dw0(r1), mkexpr(op1));
12833
12834 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(src_addr), mkU64(2)));
12835 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(des_addr), mkU64(2)));
12836 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(2)));
12837
florian6820ba52012-07-26 02:01:50 +000012838 iterate();
florian730448f2012-02-04 17:07:07 +000012839
12840 return "trtt";
12841}
12842
florian55085f82012-11-21 00:36:55 +000012843static const HChar *
florian730448f2012-02-04 17:07:07 +000012844s390_irgen_TR(UChar length, IRTemp start1, IRTemp start2)
12845{
florianf87d4fb2012-05-05 02:55:24 +000012846 IRTemp len = newTemp(Ity_I64);
florian730448f2012-02-04 17:07:07 +000012847
florianf87d4fb2012-05-05 02:55:24 +000012848 assign(len, mkU64(length));
12849 s390_irgen_TR_EX(len, start1, start2);
florian730448f2012-02-04 17:07:07 +000012850
12851 return "tr";
12852}
12853
florian55085f82012-11-21 00:36:55 +000012854static const HChar *
florian730448f2012-02-04 17:07:07 +000012855s390_irgen_TRE(UChar r1,UChar r2)
12856{
12857 IRTemp src_addr, tab_addr, src_len, test_byte;
12858 src_addr = newTemp(Ity_I64);
12859 tab_addr = newTemp(Ity_I64);
12860 src_len = newTemp(Ity_I64);
12861 test_byte = newTemp(Ity_I8);
12862
12863 assign(src_addr, get_gpr_dw0(r1));
12864 assign(src_len, get_gpr_dw0(r1+1));
12865 assign(tab_addr, get_gpr_dw0(r2));
12866 assign(test_byte, get_gpr_b7(0));
12867
12868 IRTemp op = newTemp(Ity_I8);
12869 IRTemp op1 = newTemp(Ity_I8);
12870 IRTemp result = newTemp(Ity_I64);
12871
12872 /* End of source string? We're done; proceed to next insn */
12873 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012874 next_insn_if(binop(Iop_CmpEQ64, mkexpr(src_len), mkU64(0)));
florian730448f2012-02-04 17:07:07 +000012875
12876 /* Load character from source string and compare with test byte */
12877 assign(op, load(Ity_I8, mkexpr(src_addr)));
12878
12879 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012880 next_insn_if(binop(Iop_CmpEQ8, mkexpr(op), mkexpr(test_byte)));
florian730448f2012-02-04 17:07:07 +000012881
12882 assign(result, binop(Iop_Add64, unop(Iop_8Uto64, mkexpr(op)),
12883 mkexpr(tab_addr)));
12884
12885 assign(op1, load(Ity_I8, mkexpr(result)));
12886
12887 store(get_gpr_dw0(r1), mkexpr(op1));
12888 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(src_addr), mkU64(1)));
12889 put_gpr_dw0(r1+1, binop(Iop_Sub64, mkexpr(src_len), mkU64(1)));
12890
florian6820ba52012-07-26 02:01:50 +000012891 iterate();
florian730448f2012-02-04 17:07:07 +000012892
12893 return "tre";
12894}
12895
floriana0100c92012-07-20 00:06:35 +000012896static IRExpr *
12897s390_call_cu21(IRExpr *srcval, IRExpr *low_surrogate)
12898{
12899 IRExpr **args, *call;
12900 args = mkIRExprVec_2(srcval, low_surrogate);
12901 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
12902 "s390_do_cu21", &s390_do_cu21, args);
12903
12904 /* Nothing is excluded from definedness checking. */
12905 call->Iex.CCall.cee->mcx_mask = 0;
12906
12907 return call;
12908}
12909
florian55085f82012-11-21 00:36:55 +000012910static const HChar *
floriana0100c92012-07-20 00:06:35 +000012911s390_irgen_CU21(UChar m3, UChar r1, UChar r2)
12912{
12913 IRTemp addr1 = newTemp(Ity_I64);
12914 IRTemp addr2 = newTemp(Ity_I64);
12915 IRTemp len1 = newTemp(Ity_I64);
12916 IRTemp len2 = newTemp(Ity_I64);
12917
12918 assign(addr1, get_gpr_dw0(r1));
12919 assign(addr2, get_gpr_dw0(r2));
12920 assign(len1, get_gpr_dw0(r1 + 1));
12921 assign(len2, get_gpr_dw0(r2 + 1));
12922
12923 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
12924 there are less than 2 bytes left, then the 2nd operand is exhausted
12925 and we're done here. cc = 0 */
12926 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000012927 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
floriana0100c92012-07-20 00:06:35 +000012928
12929 /* There are at least two bytes there. Read them. */
12930 IRTemp srcval = newTemp(Ity_I32);
12931 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
12932
12933 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
12934 inside the interval [0xd800 - 0xdbff] */
12935 IRTemp is_high_surrogate = newTemp(Ity_I32);
12936 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
12937 mkU32(1), mkU32(0));
12938 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
12939 mkU32(1), mkU32(0));
12940 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
12941
12942 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
12943 then the 2nd operand is exhausted and we're done here. cc = 0 */
12944 IRExpr *not_enough_bytes =
12945 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
12946
florian6820ba52012-07-26 02:01:50 +000012947 next_insn_if(binop(Iop_CmpEQ32,
12948 binop(Iop_And32, mkexpr(is_high_surrogate),
12949 not_enough_bytes), mkU32(1)));
floriana0100c92012-07-20 00:06:35 +000012950
12951 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
12952 surrogate, read the next two bytes (low surrogate). */
12953 IRTemp low_surrogate = newTemp(Ity_I32);
12954 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
12955
12956 assign(low_surrogate,
12957 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
12958 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
12959 mkU32(0))); // any value is fine; it will not be used
12960
12961 /* Call the helper */
12962 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000012963 assign(retval, s390_call_cu21(unop(Iop_32Uto64, mkexpr(srcval)),
12964 unop(Iop_32Uto64, mkexpr(low_surrogate))));
floriana0100c92012-07-20 00:06:35 +000012965
12966 /* Before we can test whether the 1st operand is exhausted we need to
12967 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
12968 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
12969 IRExpr *invalid_low_surrogate =
12970 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
12971
12972 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000012973 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
floriana0100c92012-07-20 00:06:35 +000012974 }
12975
12976 /* Now test whether the 1st operand is exhausted */
12977 IRTemp num_bytes = newTemp(Ity_I64);
12978 assign(num_bytes, binop(Iop_And64,
12979 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
12980 mkU64(0xff)));
12981 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000012982 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
floriana0100c92012-07-20 00:06:35 +000012983
12984 /* Extract the bytes to be stored at addr1 */
12985 IRTemp data = newTemp(Ity_I64);
12986 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
12987
12988 /* To store the bytes construct 4 dirty helper calls. The helper calls
12989 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
12990 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000012991 UInt i;
floriana0100c92012-07-20 00:06:35 +000012992 for (i = 1; i <= 4; ++i) {
12993 IRDirty *d;
12994
12995 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
12996 &s390x_dirtyhelper_CUxy,
12997 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
12998 mkexpr(num_bytes)));
12999 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13000 d->mFx = Ifx_Write;
13001 d->mAddr = mkexpr(addr1);
13002 d->mSize = i;
13003 stmt(IRStmt_Dirty(d));
13004 }
13005
13006 /* Update source address and length */
13007 IRTemp num_src_bytes = newTemp(Ity_I64);
13008 assign(num_src_bytes,
13009 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13010 mkU64(4), mkU64(2)));
13011 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13012 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13013
13014 /* Update destination address and length */
13015 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13016 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13017
florian6820ba52012-07-26 02:01:50 +000013018 iterate();
floriana0100c92012-07-20 00:06:35 +000013019
13020 return "cu21";
13021}
13022
florian2a415a12012-07-21 17:41:36 +000013023static IRExpr *
13024s390_call_cu24(IRExpr *srcval, IRExpr *low_surrogate)
13025{
13026 IRExpr **args, *call;
13027 args = mkIRExprVec_2(srcval, low_surrogate);
13028 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13029 "s390_do_cu24", &s390_do_cu24, args);
13030
13031 /* Nothing is excluded from definedness checking. */
13032 call->Iex.CCall.cee->mcx_mask = 0;
13033
13034 return call;
13035}
13036
florian55085f82012-11-21 00:36:55 +000013037static const HChar *
florian2a415a12012-07-21 17:41:36 +000013038s390_irgen_CU24(UChar m3, UChar r1, UChar r2)
13039{
13040 IRTemp addr1 = newTemp(Ity_I64);
13041 IRTemp addr2 = newTemp(Ity_I64);
13042 IRTemp len1 = newTemp(Ity_I64);
13043 IRTemp len2 = newTemp(Ity_I64);
13044
13045 assign(addr1, get_gpr_dw0(r1));
13046 assign(addr2, get_gpr_dw0(r2));
13047 assign(len1, get_gpr_dw0(r1 + 1));
13048 assign(len2, get_gpr_dw0(r2 + 1));
13049
13050 /* We're processing the 2nd operand 2 bytes at a time. Therefore, if
13051 there are less than 2 bytes left, then the 2nd operand is exhausted
13052 and we're done here. cc = 0 */
13053 s390_cc_set(0);
florian6820ba52012-07-26 02:01:50 +000013054 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(2)));
florian2a415a12012-07-21 17:41:36 +000013055
13056 /* There are at least two bytes there. Read them. */
13057 IRTemp srcval = newTemp(Ity_I32);
13058 assign(srcval, unop(Iop_16Uto32, load(Ity_I16, mkexpr(addr2))));
13059
13060 /* Find out whether this is a high surrogate. I.e. SRCVAL lies
13061 inside the interval [0xd800 - 0xdbff] */
13062 IRTemp is_high_surrogate = newTemp(Ity_I32);
13063 IRExpr *flag1 = mkite(binop(Iop_CmpLE32U, mkU32(0xd800), mkexpr(srcval)),
13064 mkU32(1), mkU32(0));
13065 IRExpr *flag2 = mkite(binop(Iop_CmpLE32U, mkexpr(srcval), mkU32(0xdbff)),
13066 mkU32(1), mkU32(0));
13067 assign(is_high_surrogate, binop(Iop_And32, flag1, flag2));
13068
13069 /* If SRCVAL is a high surrogate and there are less than 4 bytes left,
13070 then the 2nd operand is exhausted and we're done here. cc = 0 */
13071 IRExpr *not_enough_bytes =
13072 mkite(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)), mkU32(1), mkU32(0));
13073
florian6820ba52012-07-26 02:01:50 +000013074 next_insn_if(binop(Iop_CmpEQ32,
13075 binop(Iop_And32, mkexpr(is_high_surrogate),
13076 not_enough_bytes),
13077 mkU32(1)));
florian2a415a12012-07-21 17:41:36 +000013078
13079 /* The 2nd operand is not exhausted. If the first 2 bytes are a high
13080 surrogate, read the next two bytes (low surrogate). */
13081 IRTemp low_surrogate = newTemp(Ity_I32);
13082 IRExpr *low_surrogate_addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
13083
13084 assign(low_surrogate,
13085 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13086 unop(Iop_16Uto32, load(Ity_I16, low_surrogate_addr)),
13087 mkU32(0))); // any value is fine; it will not be used
13088
13089 /* Call the helper */
13090 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013091 assign(retval, s390_call_cu24(unop(Iop_32Uto64, mkexpr(srcval)),
13092 unop(Iop_32Uto64, mkexpr(low_surrogate))));
florian2a415a12012-07-21 17:41:36 +000013093
13094 /* Before we can test whether the 1st operand is exhausted we need to
13095 test for an invalid low surrogate. Because cc=2 outranks cc=1. */
13096 if (s390_host_has_etf3 && (m3 & 0x1) == 1) {
13097 IRExpr *invalid_low_surrogate =
13098 binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13099
13100 s390_cc_set(2);
florian6820ba52012-07-26 02:01:50 +000013101 next_insn_if(binop(Iop_CmpEQ64, invalid_low_surrogate, mkU64(1)));
florian2a415a12012-07-21 17:41:36 +000013102 }
13103
13104 /* Now test whether the 1st operand is exhausted */
13105 s390_cc_set(1);
florian6820ba52012-07-26 02:01:50 +000013106 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkU64(4)));
florian2a415a12012-07-21 17:41:36 +000013107
13108 /* Extract the bytes to be stored at addr1 */
13109 IRExpr *data = unop(Iop_64to32, binop(Iop_Shr64, mkexpr(retval), mkU8(8)));
13110
13111 store(mkexpr(addr1), data);
13112
13113 /* Update source address and length */
13114 IRTemp num_src_bytes = newTemp(Ity_I64);
13115 assign(num_src_bytes,
13116 mkite(binop(Iop_CmpEQ32, mkexpr(is_high_surrogate), mkU32(1)),
13117 mkU64(4), mkU64(2)));
13118 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13119 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13120
13121 /* Update destination address and length */
13122 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkU64(4)));
13123 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkU64(4)));
13124
florian6820ba52012-07-26 02:01:50 +000013125 iterate();
florian2a415a12012-07-21 17:41:36 +000013126
13127 return "cu24";
13128}
floriana4384a32011-08-11 16:58:45 +000013129
florian956194b2012-07-28 22:18:32 +000013130static IRExpr *
13131s390_call_cu42(IRExpr *srcval)
13132{
13133 IRExpr **args, *call;
13134 args = mkIRExprVec_1(srcval);
13135 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13136 "s390_do_cu42", &s390_do_cu42, args);
13137
13138 /* Nothing is excluded from definedness checking. */
13139 call->Iex.CCall.cee->mcx_mask = 0;
13140
13141 return call;
13142}
13143
florian55085f82012-11-21 00:36:55 +000013144static const HChar *
florian956194b2012-07-28 22:18:32 +000013145s390_irgen_CU42(UChar r1, UChar r2)
13146{
13147 IRTemp addr1 = newTemp(Ity_I64);
13148 IRTemp addr2 = newTemp(Ity_I64);
13149 IRTemp len1 = newTemp(Ity_I64);
13150 IRTemp len2 = newTemp(Ity_I64);
13151
13152 assign(addr1, get_gpr_dw0(r1));
13153 assign(addr2, get_gpr_dw0(r2));
13154 assign(len1, get_gpr_dw0(r1 + 1));
13155 assign(len2, get_gpr_dw0(r2 + 1));
13156
13157 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13158 there are less than 4 bytes left, then the 2nd operand is exhausted
13159 and we're done here. cc = 0 */
13160 s390_cc_set(0);
13161 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13162
13163 /* Read the 2nd operand. */
13164 IRTemp srcval = newTemp(Ity_I32);
13165 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13166
13167 /* Call the helper */
13168 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013169 assign(retval, s390_call_cu42(unop(Iop_32Uto64, mkexpr(srcval))));
florian956194b2012-07-28 22:18:32 +000013170
13171 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13172 cc=2 outranks cc=1 (1st operand exhausted) */
13173 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13174
13175 s390_cc_set(2);
13176 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13177
13178 /* Now test whether the 1st operand is exhausted */
13179 IRTemp num_bytes = newTemp(Ity_I64);
13180 assign(num_bytes, binop(Iop_And64,
13181 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13182 mkU64(0xff)));
13183 s390_cc_set(1);
13184 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13185
13186 /* Extract the bytes to be stored at addr1 */
13187 IRTemp data = newTemp(Ity_I64);
13188 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13189
13190 /* To store the bytes construct 2 dirty helper calls. The helper calls
13191 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13192 that only one of them will be called at runtime. */
13193
13194 Int i;
13195 for (i = 2; i <= 4; ++i) {
13196 IRDirty *d;
13197
13198 if (i == 3) continue; // skip this one
13199
13200 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13201 &s390x_dirtyhelper_CUxy,
13202 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13203 mkexpr(num_bytes)));
13204 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13205 d->mFx = Ifx_Write;
13206 d->mAddr = mkexpr(addr1);
13207 d->mSize = i;
13208 stmt(IRStmt_Dirty(d));
13209 }
13210
13211 /* Update source address and length */
13212 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13213 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13214
13215 /* Update destination address and length */
13216 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13217 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13218
13219 iterate();
13220
13221 return "cu42";
13222}
13223
florian6d9b9b22012-08-03 18:35:39 +000013224static IRExpr *
florianaf2194f2012-08-06 00:07:54 +000013225s390_call_cu41(IRExpr *srcval)
13226{
13227 IRExpr **args, *call;
13228 args = mkIRExprVec_1(srcval);
13229 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13230 "s390_do_cu41", &s390_do_cu41, args);
13231
13232 /* Nothing is excluded from definedness checking. */
13233 call->Iex.CCall.cee->mcx_mask = 0;
13234
13235 return call;
13236}
13237
florian55085f82012-11-21 00:36:55 +000013238static const HChar *
florianaf2194f2012-08-06 00:07:54 +000013239s390_irgen_CU41(UChar r1, UChar r2)
13240{
13241 IRTemp addr1 = newTemp(Ity_I64);
13242 IRTemp addr2 = newTemp(Ity_I64);
13243 IRTemp len1 = newTemp(Ity_I64);
13244 IRTemp len2 = newTemp(Ity_I64);
13245
13246 assign(addr1, get_gpr_dw0(r1));
13247 assign(addr2, get_gpr_dw0(r2));
13248 assign(len1, get_gpr_dw0(r1 + 1));
13249 assign(len2, get_gpr_dw0(r2 + 1));
13250
13251 /* We're processing the 2nd operand 4 bytes at a time. Therefore, if
13252 there are less than 4 bytes left, then the 2nd operand is exhausted
13253 and we're done here. cc = 0 */
13254 s390_cc_set(0);
13255 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(4)));
13256
13257 /* Read the 2nd operand. */
13258 IRTemp srcval = newTemp(Ity_I32);
13259 assign(srcval, load(Ity_I32, mkexpr(addr2)));
13260
13261 /* Call the helper */
13262 IRTemp retval = newTemp(Ity_I64);
florian11b8ee82012-08-06 13:35:33 +000013263 assign(retval, s390_call_cu41(unop(Iop_32Uto64, mkexpr(srcval))));
florianaf2194f2012-08-06 00:07:54 +000013264
13265 /* If the UTF-32 character was invalid, set cc=2 and we're done.
13266 cc=2 outranks cc=1 (1st operand exhausted) */
13267 IRExpr *invalid_character = binop(Iop_And64, mkexpr(retval), mkU64(0xff));
13268
13269 s390_cc_set(2);
13270 next_insn_if(binop(Iop_CmpEQ64, invalid_character, mkU64(1)));
13271
13272 /* Now test whether the 1st operand is exhausted */
13273 IRTemp num_bytes = newTemp(Ity_I64);
13274 assign(num_bytes, binop(Iop_And64,
13275 binop(Iop_Shr64, mkexpr(retval), mkU8(8)),
13276 mkU64(0xff)));
13277 s390_cc_set(1);
13278 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13279
13280 /* Extract the bytes to be stored at addr1 */
13281 IRTemp data = newTemp(Ity_I64);
13282 assign(data, binop(Iop_Shr64, mkexpr(retval), mkU8(16)));
13283
13284 /* To store the bytes construct 4 dirty helper calls. The helper calls
13285 are guarded (num_bytes == 1, num_bytes == 2, etc) such that only
13286 one of them will be called at runtime. */
florianffbd84d2012-12-09 02:06:29 +000013287 UInt i;
florianaf2194f2012-08-06 00:07:54 +000013288 for (i = 1; i <= 4; ++i) {
13289 IRDirty *d;
13290
13291 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13292 &s390x_dirtyhelper_CUxy,
13293 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13294 mkexpr(num_bytes)));
13295 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13296 d->mFx = Ifx_Write;
13297 d->mAddr = mkexpr(addr1);
13298 d->mSize = i;
13299 stmt(IRStmt_Dirty(d));
13300 }
13301
13302 /* Update source address and length */
13303 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkU64(4)));
13304 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkU64(4)));
13305
13306 /* Update destination address and length */
13307 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13308 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13309
13310 iterate();
13311
13312 return "cu41";
13313}
13314
13315static IRExpr *
florian3f8a96a2012-08-05 02:59:55 +000013316s390_call_cu12_cu14_helper1(IRExpr *byte1, IRExpr *etf3_and_m3_is_1)
florian6d9b9b22012-08-03 18:35:39 +000013317{
13318 IRExpr **args, *call;
13319 args = mkIRExprVec_2(byte1, etf3_and_m3_is_1);
florian3f8a96a2012-08-05 02:59:55 +000013320 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/, "s390_do_cu12_cu14_helper1",
13321 &s390_do_cu12_cu14_helper1, args);
florian6d9b9b22012-08-03 18:35:39 +000013322
13323 /* Nothing is excluded from definedness checking. */
13324 call->Iex.CCall.cee->mcx_mask = 0;
13325
13326 return call;
13327}
13328
13329static IRExpr *
13330s390_call_cu12_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13331 IRExpr *byte4, IRExpr *stuff)
13332{
13333 IRExpr **args, *call;
13334 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13335 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13336 "s390_do_cu12_helper2", &s390_do_cu12_helper2, args);
13337
13338 /* Nothing is excluded from definedness checking. */
13339 call->Iex.CCall.cee->mcx_mask = 0;
13340
13341 return call;
13342}
13343
florian3f8a96a2012-08-05 02:59:55 +000013344static IRExpr *
13345s390_call_cu14_helper2(IRExpr *byte1, IRExpr *byte2, IRExpr *byte3,
13346 IRExpr *byte4, IRExpr *stuff)
13347{
13348 IRExpr **args, *call;
13349 args = mkIRExprVec_5(byte1, byte2, byte3, byte4, stuff);
13350 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13351 "s390_do_cu14_helper2", &s390_do_cu14_helper2, args);
13352
13353 /* Nothing is excluded from definedness checking. */
13354 call->Iex.CCall.cee->mcx_mask = 0;
13355
13356 return call;
13357}
13358
13359static void
13360s390_irgen_cu12_cu14(UChar m3, UChar r1, UChar r2, Bool is_cu12)
florian6d9b9b22012-08-03 18:35:39 +000013361{
13362 IRTemp addr1 = newTemp(Ity_I64);
13363 IRTemp addr2 = newTemp(Ity_I64);
13364 IRTemp len1 = newTemp(Ity_I64);
13365 IRTemp len2 = newTemp(Ity_I64);
13366
13367 assign(addr1, get_gpr_dw0(r1));
13368 assign(addr2, get_gpr_dw0(r2));
13369 assign(len1, get_gpr_dw0(r1 + 1));
13370 assign(len2, get_gpr_dw0(r2 + 1));
13371
13372 UInt extended_checking = s390_host_has_etf3 && (m3 & 0x1) == 1;
13373
13374 /* We're processing the 2nd operand 1 byte at a time. Therefore, if
13375 there is less than 1 byte left, then the 2nd operand is exhausted
13376 and we're done here. cc = 0 */
13377 s390_cc_set(0);
13378 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkU64(1)));
13379
13380 /* There is at least one byte there. Read it. */
florian11b8ee82012-08-06 13:35:33 +000013381 IRTemp byte1 = newTemp(Ity_I64);
13382 assign(byte1, unop(Iop_8Uto64, load(Ity_I8, mkexpr(addr2))));
florian6d9b9b22012-08-03 18:35:39 +000013383
13384 /* Call the helper to get number of bytes and invalid byte indicator */
13385 IRTemp retval1 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013386 assign(retval1, s390_call_cu12_cu14_helper1(mkexpr(byte1),
florian11b8ee82012-08-06 13:35:33 +000013387 mkU64(extended_checking)));
florian6d9b9b22012-08-03 18:35:39 +000013388
13389 /* Check for invalid 1st byte */
13390 IRExpr *is_invalid = unop(Iop_64to1, mkexpr(retval1));
13391 s390_cc_set(2);
13392 next_insn_if(is_invalid);
13393
13394 /* How many bytes do we have to read? */
13395 IRTemp num_src_bytes = newTemp(Ity_I64);
13396 assign(num_src_bytes, binop(Iop_Shr64, mkexpr(retval1), mkU8(8)));
13397
13398 /* Now test whether the 2nd operand is exhausted */
13399 s390_cc_set(0);
13400 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len2), mkexpr(num_src_bytes)));
13401
13402 /* Read the remaining bytes */
13403 IRExpr *cond, *addr, *byte2, *byte3, *byte4;
13404
13405 cond = binop(Iop_CmpLE64U, mkU64(2), mkexpr(num_src_bytes));
13406 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(1));
florian11b8ee82012-08-06 13:35:33 +000013407 byte2 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013408 cond = binop(Iop_CmpLE64U, mkU64(3), mkexpr(num_src_bytes));
13409 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(2));
florian11b8ee82012-08-06 13:35:33 +000013410 byte3 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013411 cond = binop(Iop_CmpLE64U, mkU64(4), mkexpr(num_src_bytes));
13412 addr = binop(Iop_Add64, mkexpr(addr2), mkU64(3));
florian11b8ee82012-08-06 13:35:33 +000013413 byte4 = mkite(cond, unop(Iop_8Uto64, load(Ity_I8, addr)), mkU64(0));
florian6d9b9b22012-08-03 18:35:39 +000013414
13415 /* Call the helper to get the converted value and invalid byte indicator.
13416 We can pass at most 5 arguments; therefore some encoding is needed
13417 here */
13418 IRExpr *stuff = binop(Iop_Or64,
13419 binop(Iop_Shl64, mkexpr(num_src_bytes), mkU8(1)),
13420 mkU64(extended_checking));
13421 IRTemp retval2 = newTemp(Ity_I64);
florian3f8a96a2012-08-05 02:59:55 +000013422
13423 if (is_cu12) {
13424 assign(retval2, s390_call_cu12_helper2(mkexpr(byte1), byte2, byte3,
13425 byte4, stuff));
13426 } else {
13427 assign(retval2, s390_call_cu14_helper2(mkexpr(byte1), byte2, byte3,
13428 byte4, stuff));
13429 }
florian6d9b9b22012-08-03 18:35:39 +000013430
13431 /* Check for invalid character */
13432 s390_cc_set(2);
13433 is_invalid = unop(Iop_64to1, mkexpr(retval2));
13434 next_insn_if(is_invalid);
13435
13436 /* Now test whether the 1st operand is exhausted */
13437 IRTemp num_bytes = newTemp(Ity_I64);
13438 assign(num_bytes, binop(Iop_And64,
13439 binop(Iop_Shr64, mkexpr(retval2), mkU8(8)),
13440 mkU64(0xff)));
13441 s390_cc_set(1);
13442 next_insn_if(binop(Iop_CmpLT64U, mkexpr(len1), mkexpr(num_bytes)));
13443
13444 /* Extract the bytes to be stored at addr1 */
13445 IRTemp data = newTemp(Ity_I64);
13446 assign(data, binop(Iop_Shr64, mkexpr(retval2), mkU8(16)));
13447
florian3f8a96a2012-08-05 02:59:55 +000013448 if (is_cu12) {
13449 /* To store the bytes construct 2 dirty helper calls. The helper calls
13450 are guarded (num_bytes == 2 and num_bytes == 4, respectively) such
13451 that only one of them will be called at runtime. */
florian6d9b9b22012-08-03 18:35:39 +000013452
florian3f8a96a2012-08-05 02:59:55 +000013453 Int i;
13454 for (i = 2; i <= 4; ++i) {
13455 IRDirty *d;
florian6d9b9b22012-08-03 18:35:39 +000013456
florian3f8a96a2012-08-05 02:59:55 +000013457 if (i == 3) continue; // skip this one
florian6d9b9b22012-08-03 18:35:39 +000013458
florian3f8a96a2012-08-05 02:59:55 +000013459 d = unsafeIRDirty_0_N(0 /* regparms */, "s390x_dirtyhelper_CUxy",
13460 &s390x_dirtyhelper_CUxy,
13461 mkIRExprVec_3(mkexpr(addr1), mkexpr(data),
13462 mkexpr(num_bytes)));
13463 d->guard = binop(Iop_CmpEQ64, mkexpr(num_bytes), mkU64(i));
13464 d->mFx = Ifx_Write;
13465 d->mAddr = mkexpr(addr1);
13466 d->mSize = i;
13467 stmt(IRStmt_Dirty(d));
13468 }
13469 } else {
13470 // cu14
13471 store(mkexpr(addr1), unop(Iop_64to32, mkexpr(data)));
florian6d9b9b22012-08-03 18:35:39 +000013472 }
13473
13474 /* Update source address and length */
13475 put_gpr_dw0(r2, binop(Iop_Add64, mkexpr(addr2), mkexpr(num_src_bytes)));
13476 put_gpr_dw0(r2 + 1, binop(Iop_Sub64, mkexpr(len2), mkexpr(num_src_bytes)));
13477
13478 /* Update destination address and length */
13479 put_gpr_dw0(r1, binop(Iop_Add64, mkexpr(addr1), mkexpr(num_bytes)));
13480 put_gpr_dw0(r1 + 1, binop(Iop_Sub64, mkexpr(len1), mkexpr(num_bytes)));
13481
13482 iterate();
florian3f8a96a2012-08-05 02:59:55 +000013483}
13484
florian55085f82012-11-21 00:36:55 +000013485static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013486s390_irgen_CU12(UChar m3, UChar r1, UChar r2)
13487{
13488 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 1);
florian6d9b9b22012-08-03 18:35:39 +000013489
13490 return "cu12";
13491}
13492
florian55085f82012-11-21 00:36:55 +000013493static const HChar *
florian3f8a96a2012-08-05 02:59:55 +000013494s390_irgen_CU14(UChar m3, UChar r1, UChar r2)
13495{
13496 s390_irgen_cu12_cu14(m3, r1, r2, /* is_cu12 = */ 0);
13497
13498 return "cu14";
13499}
13500
florian8c88cb62012-08-26 18:58:13 +000013501static IRExpr *
13502s390_call_ecag(IRExpr *op2addr)
13503{
13504 IRExpr **args, *call;
13505
13506 args = mkIRExprVec_1(op2addr);
13507 call = mkIRExprCCall(Ity_I64, 0 /*regparm*/,
13508 "s390_do_ecag", &s390_do_ecag, args);
13509
13510 /* Nothing is excluded from definedness checking. */
13511 call->Iex.CCall.cee->mcx_mask = 0;
13512
13513 return call;
13514}
13515
florian55085f82012-11-21 00:36:55 +000013516static const HChar *
floriand2129202012-09-01 20:01:39 +000013517s390_irgen_ECAG(UChar r1, UChar r3 __attribute__((unused)), IRTemp op2addr)
florian8c88cb62012-08-26 18:58:13 +000013518{
13519 if (! s390_host_has_gie) {
floriane75dafa2012-09-01 17:54:09 +000013520 emulation_failure(EmFail_S390X_ecag);
florian8c88cb62012-08-26 18:58:13 +000013521 } else {
13522 put_gpr_dw0(r1, s390_call_ecag(mkexpr(op2addr)));
13523 }
13524
13525 return "ecag";
13526}
13527
13528
florianb7def222012-12-04 04:45:32 +000013529/* New insns are added here.
13530 If an insn is contingent on a facility being installed also
13531 check whether the list of supported facilities in function
13532 s390x_dirtyhelper_STFLE needs updating */
13533
sewardj2019a972011-03-07 16:04:07 +000013534/*------------------------------------------------------------*/
13535/*--- Build IR for special instructions ---*/
13536/*------------------------------------------------------------*/
13537
florianb4df7682011-07-05 02:09:01 +000013538static void
sewardj2019a972011-03-07 16:04:07 +000013539s390_irgen_client_request(void)
13540{
13541 if (0)
13542 vex_printf("%%R3 = client_request ( %%R2 )\n");
13543
florianf9e1ed72012-04-17 02:41:56 +000013544 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13545 + S390_SPECIAL_OP_SIZE;
sewardj2019a972011-03-07 16:04:07 +000013546
florianf9e1ed72012-04-17 02:41:56 +000013547 dis_res->jk_StopHere = Ijk_ClientReq;
sewardj2019a972011-03-07 16:04:07 +000013548 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013549
13550 put_IA(mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013551}
13552
florianb4df7682011-07-05 02:09:01 +000013553static void
sewardj2019a972011-03-07 16:04:07 +000013554s390_irgen_guest_NRADDR(void)
13555{
13556 if (0)
13557 vex_printf("%%R3 = guest_NRADDR\n");
13558
floriane88b3c92011-07-05 02:48:39 +000013559 put_gpr_dw0(3, IRExpr_Get(S390X_GUEST_OFFSET(guest_NRADDR), Ity_I64));
sewardj2019a972011-03-07 16:04:07 +000013560}
13561
florianb4df7682011-07-05 02:09:01 +000013562static void
sewardj2019a972011-03-07 16:04:07 +000013563s390_irgen_call_noredir(void)
13564{
florianf9e1ed72012-04-17 02:41:56 +000013565 Addr64 next = guest_IA_curr_instr + S390_SPECIAL_OP_PREAMBLE_SIZE
13566 + S390_SPECIAL_OP_SIZE;
13567
sewardj2019a972011-03-07 16:04:07 +000013568 /* Continue after special op */
florianf9e1ed72012-04-17 02:41:56 +000013569 put_gpr_dw0(14, mkaddr_expr(next));
sewardj2019a972011-03-07 16:04:07 +000013570
13571 /* The address is in REG1, all parameters are in the right (guest) places */
florianf9e1ed72012-04-17 02:41:56 +000013572 put_IA(get_gpr_dw0(1));
sewardj2019a972011-03-07 16:04:07 +000013573
13574 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000013575 dis_res->jk_StopHere = Ijk_NoRedir;
sewardj2019a972011-03-07 16:04:07 +000013576}
13577
13578/* Force proper alignment for the structures below. */
13579#pragma pack(1)
13580
13581
13582static s390_decode_t
13583s390_decode_2byte_and_irgen(UChar *bytes)
13584{
13585 typedef union {
13586 struct {
13587 unsigned int op : 16;
13588 } E;
13589 struct {
13590 unsigned int op : 8;
13591 unsigned int i : 8;
13592 } I;
13593 struct {
13594 unsigned int op : 8;
13595 unsigned int r1 : 4;
13596 unsigned int r2 : 4;
13597 } RR;
13598 } formats;
13599 union {
13600 formats fmt;
13601 UShort value;
13602 } ovl;
13603
13604 vassert(sizeof(formats) == 2);
13605
florianffbd84d2012-12-09 02:06:29 +000013606 ((UChar *)(&ovl.value))[0] = bytes[0];
13607 ((UChar *)(&ovl.value))[1] = bytes[1];
sewardj2019a972011-03-07 16:04:07 +000013608
13609 switch (ovl.value & 0xffff) {
13610 case 0x0101: /* PR */ goto unimplemented;
13611 case 0x0102: /* UPT */ goto unimplemented;
13612 case 0x0104: /* PTFF */ goto unimplemented;
13613 case 0x0107: /* SCKPF */ goto unimplemented;
13614 case 0x010a: /* PFPO */ goto unimplemented;
13615 case 0x010b: /* TAM */ goto unimplemented;
13616 case 0x010c: /* SAM24 */ goto unimplemented;
13617 case 0x010d: /* SAM31 */ goto unimplemented;
13618 case 0x010e: /* SAM64 */ goto unimplemented;
13619 case 0x01ff: /* TRAP2 */ goto unimplemented;
13620 }
13621
13622 switch ((ovl.value & 0xff00) >> 8) {
13623 case 0x04: /* SPM */ goto unimplemented;
13624 case 0x05: /* BALR */ goto unimplemented;
13625 case 0x06: s390_format_RR_RR(s390_irgen_BCTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13626 goto ok;
13627 case 0x07: s390_format_RR(s390_irgen_BCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13628 goto ok;
13629 case 0x0a: s390_format_I(s390_irgen_SVC, ovl.fmt.I.i); goto ok;
13630 case 0x0b: /* BSM */ goto unimplemented;
13631 case 0x0c: /* BASSM */ goto unimplemented;
13632 case 0x0d: s390_format_RR_RR(s390_irgen_BASR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13633 goto ok;
florianb0c9a132011-09-08 15:37:39 +000013634 case 0x0e: s390_format_RR(s390_irgen_MVCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13635 goto ok;
13636 case 0x0f: s390_format_RR(s390_irgen_CLCL, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13637 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013638 case 0x10: s390_format_RR_RR(s390_irgen_LPR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13639 goto ok;
13640 case 0x11: s390_format_RR_RR(s390_irgen_LNR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13641 goto ok;
13642 case 0x12: s390_format_RR_RR(s390_irgen_LTR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13643 goto ok;
13644 case 0x13: s390_format_RR_RR(s390_irgen_LCR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13645 goto ok;
13646 case 0x14: s390_format_RR_RR(s390_irgen_NR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13647 goto ok;
13648 case 0x15: s390_format_RR_RR(s390_irgen_CLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13649 goto ok;
13650 case 0x16: s390_format_RR_RR(s390_irgen_OR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13651 goto ok;
13652 case 0x17: s390_format_RR_RR(s390_irgen_XR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13653 goto ok;
13654 case 0x18: s390_format_RR_RR(s390_irgen_LR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13655 goto ok;
13656 case 0x19: s390_format_RR_RR(s390_irgen_CR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13657 goto ok;
13658 case 0x1a: s390_format_RR_RR(s390_irgen_AR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13659 goto ok;
13660 case 0x1b: s390_format_RR_RR(s390_irgen_SR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13661 goto ok;
13662 case 0x1c: s390_format_RR_RR(s390_irgen_MR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13663 goto ok;
13664 case 0x1d: s390_format_RR_RR(s390_irgen_DR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13665 goto ok;
13666 case 0x1e: s390_format_RR_RR(s390_irgen_ALR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13667 goto ok;
13668 case 0x1f: s390_format_RR_RR(s390_irgen_SLR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13669 goto ok;
13670 case 0x20: /* LPDR */ goto unimplemented;
13671 case 0x21: /* LNDR */ goto unimplemented;
13672 case 0x22: /* LTDR */ goto unimplemented;
13673 case 0x23: /* LCDR */ goto unimplemented;
13674 case 0x24: /* HDR */ goto unimplemented;
13675 case 0x25: /* LDXR */ goto unimplemented;
13676 case 0x26: /* MXR */ goto unimplemented;
13677 case 0x27: /* MXDR */ goto unimplemented;
13678 case 0x28: s390_format_RR_FF(s390_irgen_LDR, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13679 goto ok;
13680 case 0x29: /* CDR */ goto unimplemented;
13681 case 0x2a: /* ADR */ goto unimplemented;
13682 case 0x2b: /* SDR */ goto unimplemented;
13683 case 0x2c: /* MDR */ goto unimplemented;
13684 case 0x2d: /* DDR */ goto unimplemented;
13685 case 0x2e: /* AWR */ goto unimplemented;
13686 case 0x2f: /* SWR */ goto unimplemented;
13687 case 0x30: /* LPER */ goto unimplemented;
13688 case 0x31: /* LNER */ goto unimplemented;
13689 case 0x32: /* LTER */ goto unimplemented;
13690 case 0x33: /* LCER */ goto unimplemented;
13691 case 0x34: /* HER */ goto unimplemented;
13692 case 0x35: /* LEDR */ goto unimplemented;
13693 case 0x36: /* AXR */ goto unimplemented;
13694 case 0x37: /* SXR */ goto unimplemented;
13695 case 0x38: s390_format_RR_FF(s390_irgen_LER, ovl.fmt.RR.r1, ovl.fmt.RR.r2);
13696 goto ok;
13697 case 0x39: /* CER */ goto unimplemented;
13698 case 0x3a: /* AER */ goto unimplemented;
13699 case 0x3b: /* SER */ goto unimplemented;
13700 case 0x3c: /* MDER */ goto unimplemented;
13701 case 0x3d: /* DER */ goto unimplemented;
13702 case 0x3e: /* AUR */ goto unimplemented;
13703 case 0x3f: /* SUR */ goto unimplemented;
13704 }
13705
13706 return S390_DECODE_UNKNOWN_INSN;
13707
13708ok:
13709 return S390_DECODE_OK;
13710
13711unimplemented:
13712 return S390_DECODE_UNIMPLEMENTED_INSN;
13713}
13714
13715static s390_decode_t
13716s390_decode_4byte_and_irgen(UChar *bytes)
13717{
13718 typedef union {
13719 struct {
13720 unsigned int op1 : 8;
13721 unsigned int r1 : 4;
13722 unsigned int op2 : 4;
13723 unsigned int i2 : 16;
13724 } RI;
13725 struct {
13726 unsigned int op : 16;
13727 unsigned int : 8;
13728 unsigned int r1 : 4;
13729 unsigned int r2 : 4;
13730 } RRE;
13731 struct {
13732 unsigned int op : 16;
13733 unsigned int r1 : 4;
13734 unsigned int : 4;
13735 unsigned int r3 : 4;
13736 unsigned int r2 : 4;
13737 } RRF;
13738 struct {
13739 unsigned int op : 16;
florian1c8f7ff2012-09-01 00:12:11 +000013740 unsigned int m3 : 4;
sewardj2019a972011-03-07 16:04:07 +000013741 unsigned int m4 : 4;
13742 unsigned int r1 : 4;
13743 unsigned int r2 : 4;
13744 } RRF2;
13745 struct {
13746 unsigned int op : 16;
13747 unsigned int r3 : 4;
13748 unsigned int : 4;
13749 unsigned int r1 : 4;
13750 unsigned int r2 : 4;
13751 } RRF3;
13752 struct {
13753 unsigned int op : 16;
13754 unsigned int r3 : 4;
13755 unsigned int : 4;
13756 unsigned int r1 : 4;
13757 unsigned int r2 : 4;
13758 } RRR;
13759 struct {
13760 unsigned int op : 16;
13761 unsigned int r3 : 4;
florian12390202012-11-10 22:34:14 +000013762 unsigned int m4 : 4;
sewardj2019a972011-03-07 16:04:07 +000013763 unsigned int r1 : 4;
13764 unsigned int r2 : 4;
13765 } RRF4;
13766 struct {
floriane38f6412012-12-21 17:32:12 +000013767 unsigned int op : 16;
13768 unsigned int : 4;
13769 unsigned int m4 : 4;
13770 unsigned int r1 : 4;
13771 unsigned int r2 : 4;
13772 } RRF5;
13773 struct {
sewardj2019a972011-03-07 16:04:07 +000013774 unsigned int op : 8;
13775 unsigned int r1 : 4;
13776 unsigned int r3 : 4;
13777 unsigned int b2 : 4;
13778 unsigned int d2 : 12;
13779 } RS;
13780 struct {
13781 unsigned int op : 8;
13782 unsigned int r1 : 4;
13783 unsigned int r3 : 4;
13784 unsigned int i2 : 16;
13785 } RSI;
13786 struct {
13787 unsigned int op : 8;
13788 unsigned int r1 : 4;
13789 unsigned int x2 : 4;
13790 unsigned int b2 : 4;
13791 unsigned int d2 : 12;
13792 } RX;
13793 struct {
13794 unsigned int op : 16;
13795 unsigned int b2 : 4;
13796 unsigned int d2 : 12;
13797 } S;
13798 struct {
13799 unsigned int op : 8;
13800 unsigned int i2 : 8;
13801 unsigned int b1 : 4;
13802 unsigned int d1 : 12;
13803 } SI;
13804 } formats;
13805 union {
13806 formats fmt;
13807 UInt value;
13808 } ovl;
13809
13810 vassert(sizeof(formats) == 4);
13811
florianffbd84d2012-12-09 02:06:29 +000013812 ((UChar *)(&ovl.value))[0] = bytes[0];
13813 ((UChar *)(&ovl.value))[1] = bytes[1];
13814 ((UChar *)(&ovl.value))[2] = bytes[2];
13815 ((UChar *)(&ovl.value))[3] = bytes[3];
sewardj2019a972011-03-07 16:04:07 +000013816
13817 switch ((ovl.value & 0xff0f0000) >> 16) {
13818 case 0xa500: s390_format_RI_RU(s390_irgen_IIHH, ovl.fmt.RI.r1,
13819 ovl.fmt.RI.i2); goto ok;
13820 case 0xa501: s390_format_RI_RU(s390_irgen_IIHL, ovl.fmt.RI.r1,
13821 ovl.fmt.RI.i2); goto ok;
13822 case 0xa502: s390_format_RI_RU(s390_irgen_IILH, ovl.fmt.RI.r1,
13823 ovl.fmt.RI.i2); goto ok;
13824 case 0xa503: s390_format_RI_RU(s390_irgen_IILL, ovl.fmt.RI.r1,
13825 ovl.fmt.RI.i2); goto ok;
13826 case 0xa504: s390_format_RI_RU(s390_irgen_NIHH, ovl.fmt.RI.r1,
13827 ovl.fmt.RI.i2); goto ok;
13828 case 0xa505: s390_format_RI_RU(s390_irgen_NIHL, ovl.fmt.RI.r1,
13829 ovl.fmt.RI.i2); goto ok;
13830 case 0xa506: s390_format_RI_RU(s390_irgen_NILH, ovl.fmt.RI.r1,
13831 ovl.fmt.RI.i2); goto ok;
13832 case 0xa507: s390_format_RI_RU(s390_irgen_NILL, ovl.fmt.RI.r1,
13833 ovl.fmt.RI.i2); goto ok;
13834 case 0xa508: s390_format_RI_RU(s390_irgen_OIHH, ovl.fmt.RI.r1,
13835 ovl.fmt.RI.i2); goto ok;
13836 case 0xa509: s390_format_RI_RU(s390_irgen_OIHL, ovl.fmt.RI.r1,
13837 ovl.fmt.RI.i2); goto ok;
13838 case 0xa50a: s390_format_RI_RU(s390_irgen_OILH, ovl.fmt.RI.r1,
13839 ovl.fmt.RI.i2); goto ok;
13840 case 0xa50b: s390_format_RI_RU(s390_irgen_OILL, ovl.fmt.RI.r1,
13841 ovl.fmt.RI.i2); goto ok;
13842 case 0xa50c: s390_format_RI_RU(s390_irgen_LLIHH, ovl.fmt.RI.r1,
13843 ovl.fmt.RI.i2); goto ok;
13844 case 0xa50d: s390_format_RI_RU(s390_irgen_LLIHL, ovl.fmt.RI.r1,
13845 ovl.fmt.RI.i2); goto ok;
13846 case 0xa50e: s390_format_RI_RU(s390_irgen_LLILH, ovl.fmt.RI.r1,
13847 ovl.fmt.RI.i2); goto ok;
13848 case 0xa50f: s390_format_RI_RU(s390_irgen_LLILL, ovl.fmt.RI.r1,
13849 ovl.fmt.RI.i2); goto ok;
13850 case 0xa700: s390_format_RI_RU(s390_irgen_TMLH, ovl.fmt.RI.r1,
13851 ovl.fmt.RI.i2); goto ok;
13852 case 0xa701: s390_format_RI_RU(s390_irgen_TMLL, ovl.fmt.RI.r1,
13853 ovl.fmt.RI.i2); goto ok;
13854 case 0xa702: s390_format_RI_RU(s390_irgen_TMHH, ovl.fmt.RI.r1,
13855 ovl.fmt.RI.i2); goto ok;
13856 case 0xa703: s390_format_RI_RU(s390_irgen_TMHL, ovl.fmt.RI.r1,
13857 ovl.fmt.RI.i2); goto ok;
13858 case 0xa704: s390_format_RI(s390_irgen_BRC, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13859 goto ok;
13860 case 0xa705: s390_format_RI_RP(s390_irgen_BRAS, ovl.fmt.RI.r1,
13861 ovl.fmt.RI.i2); goto ok;
13862 case 0xa706: s390_format_RI_RP(s390_irgen_BRCT, ovl.fmt.RI.r1,
13863 ovl.fmt.RI.i2); goto ok;
13864 case 0xa707: s390_format_RI_RP(s390_irgen_BRCTG, ovl.fmt.RI.r1,
13865 ovl.fmt.RI.i2); goto ok;
13866 case 0xa708: s390_format_RI_RI(s390_irgen_LHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13867 goto ok;
13868 case 0xa709: s390_format_RI_RI(s390_irgen_LGHI, ovl.fmt.RI.r1,
13869 ovl.fmt.RI.i2); goto ok;
13870 case 0xa70a: s390_format_RI_RI(s390_irgen_AHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13871 goto ok;
13872 case 0xa70b: s390_format_RI_RI(s390_irgen_AGHI, ovl.fmt.RI.r1,
13873 ovl.fmt.RI.i2); goto ok;
13874 case 0xa70c: s390_format_RI_RI(s390_irgen_MHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13875 goto ok;
13876 case 0xa70d: s390_format_RI_RI(s390_irgen_MGHI, ovl.fmt.RI.r1,
13877 ovl.fmt.RI.i2); goto ok;
13878 case 0xa70e: s390_format_RI_RI(s390_irgen_CHI, ovl.fmt.RI.r1, ovl.fmt.RI.i2);
13879 goto ok;
13880 case 0xa70f: s390_format_RI_RI(s390_irgen_CGHI, ovl.fmt.RI.r1,
13881 ovl.fmt.RI.i2); goto ok;
13882 }
13883
13884 switch ((ovl.value & 0xffff0000) >> 16) {
13885 case 0x8000: /* SSM */ goto unimplemented;
13886 case 0x8200: /* LPSW */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013887 case 0x9300: /* TS */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013888 case 0xb202: /* STIDP */ goto unimplemented;
13889 case 0xb204: /* SCK */ goto unimplemented;
florian7700fc92012-01-16 17:25:55 +000013890 case 0xb205: s390_format_S_RD(s390_irgen_STCK, ovl.fmt.S.b2, ovl.fmt.S.d2);
13891 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013892 case 0xb206: /* SCKC */ goto unimplemented;
13893 case 0xb207: /* STCKC */ goto unimplemented;
13894 case 0xb208: /* SPT */ goto unimplemented;
13895 case 0xb209: /* STPT */ goto unimplemented;
13896 case 0xb20a: /* SPKA */ goto unimplemented;
13897 case 0xb20b: /* IPK */ goto unimplemented;
13898 case 0xb20d: /* PTLB */ goto unimplemented;
13899 case 0xb210: /* SPX */ goto unimplemented;
13900 case 0xb211: /* STPX */ goto unimplemented;
13901 case 0xb212: /* STAP */ goto unimplemented;
13902 case 0xb214: /* SIE */ goto unimplemented;
13903 case 0xb218: /* PC */ goto unimplemented;
13904 case 0xb219: /* SAC */ goto unimplemented;
13905 case 0xb21a: /* CFC */ goto unimplemented;
13906 case 0xb221: /* IPTE */ goto unimplemented;
13907 case 0xb222: s390_format_RRE_R0(s390_irgen_IPM, ovl.fmt.RRE.r1); goto ok;
13908 case 0xb223: /* IVSK */ goto unimplemented;
13909 case 0xb224: /* IAC */ goto unimplemented;
13910 case 0xb225: /* SSAR */ goto unimplemented;
13911 case 0xb226: /* EPAR */ goto unimplemented;
13912 case 0xb227: /* ESAR */ goto unimplemented;
13913 case 0xb228: /* PT */ goto unimplemented;
13914 case 0xb229: /* ISKE */ goto unimplemented;
13915 case 0xb22a: /* RRBE */ goto unimplemented;
13916 case 0xb22b: /* SSKE */ goto unimplemented;
13917 case 0xb22c: /* TB */ goto unimplemented;
13918 case 0xb22d: /* DXR */ goto unimplemented;
13919 case 0xb22e: /* PGIN */ goto unimplemented;
13920 case 0xb22f: /* PGOUT */ goto unimplemented;
13921 case 0xb230: /* CSCH */ goto unimplemented;
13922 case 0xb231: /* HSCH */ goto unimplemented;
13923 case 0xb232: /* MSCH */ goto unimplemented;
13924 case 0xb233: /* SSCH */ goto unimplemented;
13925 case 0xb234: /* STSCH */ goto unimplemented;
13926 case 0xb235: /* TSCH */ goto unimplemented;
13927 case 0xb236: /* TPI */ goto unimplemented;
13928 case 0xb237: /* SAL */ goto unimplemented;
13929 case 0xb238: /* RSCH */ goto unimplemented;
13930 case 0xb239: /* STCRW */ goto unimplemented;
13931 case 0xb23a: /* STCPS */ goto unimplemented;
13932 case 0xb23b: /* RCHP */ goto unimplemented;
13933 case 0xb23c: /* SCHM */ goto unimplemented;
13934 case 0xb240: /* BAKR */ goto unimplemented;
floriana4384a32011-08-11 16:58:45 +000013935 case 0xb241: s390_format_RRE(s390_irgen_CKSM, ovl.fmt.RRE.r1,
13936 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000013937 case 0xb244: /* SQDR */ goto unimplemented;
13938 case 0xb245: /* SQER */ goto unimplemented;
13939 case 0xb246: /* STURA */ goto unimplemented;
13940 case 0xb247: /* MSTA */ goto unimplemented;
13941 case 0xb248: /* PALB */ goto unimplemented;
13942 case 0xb249: /* EREG */ goto unimplemented;
13943 case 0xb24a: /* ESTA */ goto unimplemented;
13944 case 0xb24b: /* LURA */ goto unimplemented;
13945 case 0xb24c: /* TAR */ goto unimplemented;
13946 case 0xb24d: s390_format_RRE(s390_irgen_CPYA, ovl.fmt.RRE.r1,
13947 ovl.fmt.RRE.r2); goto ok;
13948 case 0xb24e: s390_format_RRE(s390_irgen_SAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13949 goto ok;
13950 case 0xb24f: s390_format_RRE(s390_irgen_EAR, ovl.fmt.RRE.r1, ovl.fmt.RRE.r2);
13951 goto ok;
13952 case 0xb250: /* CSP */ goto unimplemented;
13953 case 0xb252: s390_format_RRE_RR(s390_irgen_MSR, ovl.fmt.RRE.r1,
13954 ovl.fmt.RRE.r2); goto ok;
13955 case 0xb254: /* MVPG */ goto unimplemented;
13956 case 0xb255: s390_format_RRE_RR(s390_irgen_MVST, ovl.fmt.RRE.r1,
13957 ovl.fmt.RRE.r2); goto ok;
13958 case 0xb257: /* CUSE */ goto unimplemented;
13959 case 0xb258: /* BSG */ goto unimplemented;
13960 case 0xb25a: /* BSA */ goto unimplemented;
13961 case 0xb25d: s390_format_RRE_RR(s390_irgen_CLST, ovl.fmt.RRE.r1,
13962 ovl.fmt.RRE.r2); goto ok;
13963 case 0xb25e: s390_format_RRE_RR(s390_irgen_SRST, ovl.fmt.RRE.r1,
13964 ovl.fmt.RRE.r2); goto ok;
13965 case 0xb263: /* CMPSC */ goto unimplemented;
13966 case 0xb274: /* SIGA */ goto unimplemented;
13967 case 0xb276: /* XSCH */ goto unimplemented;
13968 case 0xb277: /* RP */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013969 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 +000013970 case 0xb279: /* SACF */ goto unimplemented;
sewardj1e5fea62011-05-17 16:18:36 +000013971 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 +000013972 case 0xb27d: /* STSI */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000013973 case 0xb280: /* LPP */ goto unimplemented;
13974 case 0xb284: /* LCCTL */ goto unimplemented;
13975 case 0xb285: /* LPCTL */ goto unimplemented;
13976 case 0xb286: /* QSI */ goto unimplemented;
13977 case 0xb287: /* LSCTL */ goto unimplemented;
13978 case 0xb28e: /* QCTRI */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000013979 case 0xb299: s390_format_S_RD(s390_irgen_SRNM, ovl.fmt.S.b2, ovl.fmt.S.d2);
13980 goto ok;
13981 case 0xb29c: s390_format_S_RD(s390_irgen_STFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13982 goto ok;
13983 case 0xb29d: s390_format_S_RD(s390_irgen_LFPC, ovl.fmt.S.b2, ovl.fmt.S.d2);
13984 goto ok;
florian730448f2012-02-04 17:07:07 +000013985 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 +000013986 case 0xb2a6: s390_format_RRF_M0RERE(s390_irgen_CU21, ovl.fmt.RRF3.r3,
13987 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13988 goto ok;
florian6d9b9b22012-08-03 18:35:39 +000013989 case 0xb2a7: s390_format_RRF_M0RERE(s390_irgen_CU12, ovl.fmt.RRF3.r3,
13990 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
13991 goto ok;
florian933065d2011-07-11 01:48:02 +000013992 case 0xb2b0: s390_format_S_RD(s390_irgen_STFLE, ovl.fmt.S.b2, ovl.fmt.S.d2);
13993 goto ok;
sewardj2019a972011-03-07 16:04:07 +000013994 case 0xb2b1: /* STFL */ goto unimplemented;
13995 case 0xb2b2: /* LPSWE */ goto unimplemented;
florianf0fa1be2012-09-18 20:24:38 +000013996 case 0xb2b8: s390_irgen_srnmb_wrapper(ovl.fmt.S.b2, ovl.fmt.S.d2);
13997 goto ok;
florian82cdba62013-03-12 01:31:24 +000013998 case 0xb2b9: s390_format_S_RD(s390_irgen_SRNMT, ovl.fmt.S.b2, ovl.fmt.S.d2);
13999 goto ok;
sewardj2019a972011-03-07 16:04:07 +000014000 case 0xb2bd: /* LFAS */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014001 case 0xb2e0: /* SCCTR */ goto unimplemented;
14002 case 0xb2e1: /* SPCTR */ goto unimplemented;
14003 case 0xb2e4: /* ECCTR */ goto unimplemented;
14004 case 0xb2e5: /* EPCTR */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014005 case 0xb2e8: /* PPA */ goto unimplemented;
14006 case 0xb2ec: /* ETND */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014007 case 0xb2ed: /* ECPGA */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014008 case 0xb2f8: /* TEND */ goto unimplemented;
14009 case 0xb2fa: /* NIAI */ goto unimplemented;
14010 case 0xb2fc: /* TABORT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014011 case 0xb2ff: /* TRAP4 */ goto unimplemented;
14012 case 0xb300: s390_format_RRE_FF(s390_irgen_LPEBR, ovl.fmt.RRE.r1,
14013 ovl.fmt.RRE.r2); goto ok;
14014 case 0xb301: s390_format_RRE_FF(s390_irgen_LNEBR, ovl.fmt.RRE.r1,
14015 ovl.fmt.RRE.r2); goto ok;
14016 case 0xb302: s390_format_RRE_FF(s390_irgen_LTEBR, ovl.fmt.RRE.r1,
14017 ovl.fmt.RRE.r2); goto ok;
14018 case 0xb303: s390_format_RRE_FF(s390_irgen_LCEBR, ovl.fmt.RRE.r1,
14019 ovl.fmt.RRE.r2); goto ok;
14020 case 0xb304: s390_format_RRE_FF(s390_irgen_LDEBR, ovl.fmt.RRE.r1,
14021 ovl.fmt.RRE.r2); goto ok;
14022 case 0xb305: s390_format_RRE_FF(s390_irgen_LXDBR, ovl.fmt.RRE.r1,
14023 ovl.fmt.RRE.r2); goto ok;
14024 case 0xb306: s390_format_RRE_FF(s390_irgen_LXEBR, ovl.fmt.RRE.r1,
14025 ovl.fmt.RRE.r2); goto ok;
14026 case 0xb307: /* MXDBR */ goto unimplemented;
14027 case 0xb308: /* KEBR */ goto unimplemented;
14028 case 0xb309: s390_format_RRE_FF(s390_irgen_CEBR, ovl.fmt.RRE.r1,
14029 ovl.fmt.RRE.r2); goto ok;
14030 case 0xb30a: s390_format_RRE_FF(s390_irgen_AEBR, ovl.fmt.RRE.r1,
14031 ovl.fmt.RRE.r2); goto ok;
14032 case 0xb30b: s390_format_RRE_FF(s390_irgen_SEBR, ovl.fmt.RRE.r1,
14033 ovl.fmt.RRE.r2); goto ok;
14034 case 0xb30c: /* MDEBR */ goto unimplemented;
14035 case 0xb30d: s390_format_RRE_FF(s390_irgen_DEBR, ovl.fmt.RRE.r1,
14036 ovl.fmt.RRE.r2); goto ok;
14037 case 0xb30e: s390_format_RRF_F0FF(s390_irgen_MAEBR, ovl.fmt.RRF.r1,
14038 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14039 case 0xb30f: s390_format_RRF_F0FF(s390_irgen_MSEBR, ovl.fmt.RRF.r1,
14040 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14041 case 0xb310: s390_format_RRE_FF(s390_irgen_LPDBR, ovl.fmt.RRE.r1,
14042 ovl.fmt.RRE.r2); goto ok;
14043 case 0xb311: s390_format_RRE_FF(s390_irgen_LNDBR, ovl.fmt.RRE.r1,
14044 ovl.fmt.RRE.r2); goto ok;
14045 case 0xb312: s390_format_RRE_FF(s390_irgen_LTDBR, ovl.fmt.RRE.r1,
14046 ovl.fmt.RRE.r2); goto ok;
14047 case 0xb313: s390_format_RRE_FF(s390_irgen_LCDBR, ovl.fmt.RRE.r1,
14048 ovl.fmt.RRE.r2); goto ok;
14049 case 0xb314: s390_format_RRE_FF(s390_irgen_SQEBR, ovl.fmt.RRE.r1,
14050 ovl.fmt.RRE.r2); goto ok;
14051 case 0xb315: s390_format_RRE_FF(s390_irgen_SQDBR, ovl.fmt.RRE.r1,
14052 ovl.fmt.RRE.r2); goto ok;
14053 case 0xb316: s390_format_RRE_FF(s390_irgen_SQXBR, ovl.fmt.RRE.r1,
14054 ovl.fmt.RRE.r2); goto ok;
14055 case 0xb317: s390_format_RRE_FF(s390_irgen_MEEBR, ovl.fmt.RRE.r1,
14056 ovl.fmt.RRE.r2); goto ok;
14057 case 0xb318: /* KDBR */ goto unimplemented;
14058 case 0xb319: s390_format_RRE_FF(s390_irgen_CDBR, ovl.fmt.RRE.r1,
14059 ovl.fmt.RRE.r2); goto ok;
14060 case 0xb31a: s390_format_RRE_FF(s390_irgen_ADBR, ovl.fmt.RRE.r1,
14061 ovl.fmt.RRE.r2); goto ok;
14062 case 0xb31b: s390_format_RRE_FF(s390_irgen_SDBR, ovl.fmt.RRE.r1,
14063 ovl.fmt.RRE.r2); goto ok;
14064 case 0xb31c: s390_format_RRE_FF(s390_irgen_MDBR, ovl.fmt.RRE.r1,
14065 ovl.fmt.RRE.r2); goto ok;
14066 case 0xb31d: s390_format_RRE_FF(s390_irgen_DDBR, ovl.fmt.RRE.r1,
14067 ovl.fmt.RRE.r2); goto ok;
14068 case 0xb31e: s390_format_RRF_F0FF(s390_irgen_MADBR, ovl.fmt.RRF.r1,
14069 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14070 case 0xb31f: s390_format_RRF_F0FF(s390_irgen_MSDBR, ovl.fmt.RRF.r1,
14071 ovl.fmt.RRF.r3, ovl.fmt.RRF.r2); goto ok;
14072 case 0xb324: /* LDER */ goto unimplemented;
14073 case 0xb325: /* LXDR */ goto unimplemented;
14074 case 0xb326: /* LXER */ goto unimplemented;
14075 case 0xb32e: /* MAER */ goto unimplemented;
14076 case 0xb32f: /* MSER */ goto unimplemented;
14077 case 0xb336: /* SQXR */ goto unimplemented;
14078 case 0xb337: /* MEER */ goto unimplemented;
14079 case 0xb338: /* MAYLR */ goto unimplemented;
14080 case 0xb339: /* MYLR */ goto unimplemented;
14081 case 0xb33a: /* MAYR */ goto unimplemented;
14082 case 0xb33b: /* MYR */ goto unimplemented;
14083 case 0xb33c: /* MAYHR */ goto unimplemented;
14084 case 0xb33d: /* MYHR */ goto unimplemented;
14085 case 0xb33e: /* MADR */ goto unimplemented;
14086 case 0xb33f: /* MSDR */ goto unimplemented;
14087 case 0xb340: s390_format_RRE_FF(s390_irgen_LPXBR, ovl.fmt.RRE.r1,
14088 ovl.fmt.RRE.r2); goto ok;
14089 case 0xb341: s390_format_RRE_FF(s390_irgen_LNXBR, ovl.fmt.RRE.r1,
14090 ovl.fmt.RRE.r2); goto ok;
14091 case 0xb342: s390_format_RRE_FF(s390_irgen_LTXBR, ovl.fmt.RRE.r1,
14092 ovl.fmt.RRE.r2); goto ok;
14093 case 0xb343: s390_format_RRE_FF(s390_irgen_LCXBR, ovl.fmt.RRE.r1,
14094 ovl.fmt.RRE.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014095 case 0xb344: s390_format_RRF_UUFF(s390_irgen_LEDBR, ovl.fmt.RRF2.m3,
14096 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14097 ovl.fmt.RRF2.r2); goto ok;
14098 case 0xb345: s390_format_RRF_UUFF(s390_irgen_LDXBR, ovl.fmt.RRF2.m3,
14099 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14100 ovl.fmt.RRF2.r2); goto ok;
14101 case 0xb346: s390_format_RRF_UUFF(s390_irgen_LEXBR, ovl.fmt.RRF2.m3,
14102 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14103 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014104 case 0xb347: /* FIXBR */ goto unimplemented;
14105 case 0xb348: /* KXBR */ goto unimplemented;
14106 case 0xb349: s390_format_RRE_FF(s390_irgen_CXBR, ovl.fmt.RRE.r1,
14107 ovl.fmt.RRE.r2); goto ok;
14108 case 0xb34a: s390_format_RRE_FF(s390_irgen_AXBR, ovl.fmt.RRE.r1,
14109 ovl.fmt.RRE.r2); goto ok;
14110 case 0xb34b: s390_format_RRE_FF(s390_irgen_SXBR, ovl.fmt.RRE.r1,
14111 ovl.fmt.RRE.r2); goto ok;
14112 case 0xb34c: s390_format_RRE_FF(s390_irgen_MXBR, ovl.fmt.RRE.r1,
14113 ovl.fmt.RRE.r2); goto ok;
14114 case 0xb34d: s390_format_RRE_FF(s390_irgen_DXBR, ovl.fmt.RRE.r1,
14115 ovl.fmt.RRE.r2); goto ok;
14116 case 0xb350: /* TBEDR */ goto unimplemented;
14117 case 0xb351: /* TBDR */ goto unimplemented;
14118 case 0xb353: /* DIEBR */ goto unimplemented;
14119 case 0xb357: /* FIEBR */ goto unimplemented;
14120 case 0xb358: /* THDER */ goto unimplemented;
14121 case 0xb359: /* THDR */ goto unimplemented;
14122 case 0xb35b: /* DIDBR */ goto unimplemented;
14123 case 0xb35f: /* FIDBR */ goto unimplemented;
14124 case 0xb360: /* LPXR */ goto unimplemented;
14125 case 0xb361: /* LNXR */ goto unimplemented;
14126 case 0xb362: /* LTXR */ goto unimplemented;
14127 case 0xb363: /* LCXR */ goto unimplemented;
14128 case 0xb365: s390_format_RRE_FF(s390_irgen_LXR, ovl.fmt.RRE.r1,
14129 ovl.fmt.RRE.r2); goto ok;
14130 case 0xb366: /* LEXR */ goto unimplemented;
14131 case 0xb367: /* FIXR */ goto unimplemented;
14132 case 0xb369: /* CXR */ goto unimplemented;
14133 case 0xb370: s390_format_RRE_FF(s390_irgen_LPDFR, ovl.fmt.RRE.r1,
14134 ovl.fmt.RRE.r2); goto ok;
14135 case 0xb371: s390_format_RRE_FF(s390_irgen_LNDFR, ovl.fmt.RRE.r1,
14136 ovl.fmt.RRE.r2); goto ok;
14137 case 0xb372: s390_format_RRF_F0FF2(s390_irgen_CPSDR, ovl.fmt.RRF3.r3,
14138 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14139 goto ok;
14140 case 0xb373: s390_format_RRE_FF(s390_irgen_LCDFR, ovl.fmt.RRE.r1,
14141 ovl.fmt.RRE.r2); goto ok;
14142 case 0xb374: s390_format_RRE_F0(s390_irgen_LZER, ovl.fmt.RRE.r1); goto ok;
14143 case 0xb375: s390_format_RRE_F0(s390_irgen_LZDR, ovl.fmt.RRE.r1); goto ok;
14144 case 0xb376: s390_format_RRE_F0(s390_irgen_LZXR, ovl.fmt.RRE.r1); goto ok;
14145 case 0xb377: /* FIER */ goto unimplemented;
14146 case 0xb37f: /* FIDR */ goto unimplemented;
14147 case 0xb384: s390_format_RRE_R0(s390_irgen_SFPC, ovl.fmt.RRE.r1); goto ok;
14148 case 0xb385: /* SFASR */ goto unimplemented;
14149 case 0xb38c: s390_format_RRE_R0(s390_irgen_EFPC, ovl.fmt.RRE.r1); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014150 case 0xb390: s390_format_RRF_UUFR(s390_irgen_CELFBR, ovl.fmt.RRF2.m3,
14151 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14152 ovl.fmt.RRF2.r2); goto ok;
14153 case 0xb391: s390_format_RRF_UUFR(s390_irgen_CDLFBR, ovl.fmt.RRF2.m3,
14154 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14155 ovl.fmt.RRF2.r2); goto ok;
14156 case 0xb392: s390_format_RRF_UUFR(s390_irgen_CXLFBR, ovl.fmt.RRF2.m3,
14157 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14158 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014159 case 0xb394: s390_format_RRF_UUFR(s390_irgen_CEFBR, ovl.fmt.RRF2.m3,
14160 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14161 ovl.fmt.RRF2.r2); goto ok;
14162 case 0xb395: s390_format_RRF_UUFR(s390_irgen_CDFBR, ovl.fmt.RRF2.m3,
14163 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14164 ovl.fmt.RRF2.r2); goto ok;
14165 case 0xb396: s390_format_RRF_UUFR(s390_irgen_CXFBR, ovl.fmt.RRF2.m3,
14166 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14167 ovl.fmt.RRF2.r2); goto ok;
14168 case 0xb398: s390_format_RRF_UURF(s390_irgen_CFEBR, ovl.fmt.RRF2.m3,
14169 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14170 ovl.fmt.RRF2.r2); goto ok;
14171 case 0xb399: s390_format_RRF_UURF(s390_irgen_CFDBR, ovl.fmt.RRF2.m3,
14172 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14173 ovl.fmt.RRF2.r2); goto ok;
14174 case 0xb39a: s390_format_RRF_UURF(s390_irgen_CFXBR, ovl.fmt.RRF2.m3,
14175 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14176 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014177 case 0xb39c: s390_format_RRF_UURF(s390_irgen_CLFEBR, ovl.fmt.RRF2.m3,
14178 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14179 ovl.fmt.RRF2.r2); goto ok;
14180 case 0xb39d: s390_format_RRF_UURF(s390_irgen_CLFDBR, ovl.fmt.RRF2.m3,
14181 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14182 ovl.fmt.RRF2.r2); goto ok;
14183 case 0xb39e: s390_format_RRF_UURF(s390_irgen_CLFXBR, ovl.fmt.RRF2.m3,
14184 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14185 ovl.fmt.RRF2.r2); goto ok;
14186 case 0xb3a0: s390_format_RRF_UUFR(s390_irgen_CELGBR, ovl.fmt.RRF2.m3,
14187 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14188 ovl.fmt.RRF2.r2); goto ok;
14189 case 0xb3a1: s390_format_RRF_UUFR(s390_irgen_CDLGBR, ovl.fmt.RRF2.m3,
14190 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14191 ovl.fmt.RRF2.r2); goto ok;
14192 case 0xb3a2: s390_format_RRF_UUFR(s390_irgen_CXLGBR, ovl.fmt.RRF2.m3,
14193 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14194 ovl.fmt.RRF2.r2); goto ok;
florian4b8efad2012-09-02 18:07:08 +000014195 case 0xb3a4: s390_format_RRF_UUFR(s390_irgen_CEGBR, ovl.fmt.RRF2.m3,
14196 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14197 ovl.fmt.RRF2.r2); goto ok;
14198 case 0xb3a5: s390_format_RRF_UUFR(s390_irgen_CDGBR, ovl.fmt.RRF2.m3,
14199 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14200 ovl.fmt.RRF2.r2); goto ok;
14201 case 0xb3a6: s390_format_RRF_UUFR(s390_irgen_CXGBR, ovl.fmt.RRF2.m3,
14202 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14203 ovl.fmt.RRF2.r2); goto ok;
14204 case 0xb3a8: s390_format_RRF_UURF(s390_irgen_CGEBR, ovl.fmt.RRF2.m3,
14205 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14206 ovl.fmt.RRF2.r2); goto ok;
14207 case 0xb3a9: s390_format_RRF_UURF(s390_irgen_CGDBR, ovl.fmt.RRF2.m3,
14208 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14209 ovl.fmt.RRF2.r2); goto ok;
14210 case 0xb3aa: s390_format_RRF_UURF(s390_irgen_CGXBR, ovl.fmt.RRF2.m3,
14211 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14212 ovl.fmt.RRF2.r2); goto ok;
florian1c8f7ff2012-09-01 00:12:11 +000014213 case 0xb3ac: s390_format_RRF_UURF(s390_irgen_CLGEBR, ovl.fmt.RRF2.m3,
14214 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14215 ovl.fmt.RRF2.r2); goto ok;
14216 case 0xb3ad: s390_format_RRF_UURF(s390_irgen_CLGDBR, ovl.fmt.RRF2.m3,
14217 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14218 ovl.fmt.RRF2.r2); goto ok;
14219 case 0xb3ae: s390_format_RRF_UURF(s390_irgen_CLGXBR, ovl.fmt.RRF2.m3,
14220 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14221 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014222 case 0xb3b4: /* CEFR */ goto unimplemented;
14223 case 0xb3b5: /* CDFR */ goto unimplemented;
14224 case 0xb3b6: /* CXFR */ goto unimplemented;
14225 case 0xb3b8: /* CFER */ goto unimplemented;
14226 case 0xb3b9: /* CFDR */ goto unimplemented;
14227 case 0xb3ba: /* CFXR */ goto unimplemented;
14228 case 0xb3c1: s390_format_RRE_FR(s390_irgen_LDGR, ovl.fmt.RRE.r1,
14229 ovl.fmt.RRE.r2); goto ok;
14230 case 0xb3c4: /* CEGR */ goto unimplemented;
14231 case 0xb3c5: /* CDGR */ goto unimplemented;
14232 case 0xb3c6: /* CXGR */ goto unimplemented;
14233 case 0xb3c8: /* CGER */ goto unimplemented;
14234 case 0xb3c9: /* CGDR */ goto unimplemented;
14235 case 0xb3ca: /* CGXR */ goto unimplemented;
14236 case 0xb3cd: s390_format_RRE_RF(s390_irgen_LGDR, ovl.fmt.RRE.r1,
14237 ovl.fmt.RRE.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014238 case 0xb3d0: s390_format_RRF_FUFF2(s390_irgen_MDTRA, ovl.fmt.RRF4.r3,
14239 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14240 ovl.fmt.RRF4.r2); goto ok;
14241 case 0xb3d1: s390_format_RRF_FUFF2(s390_irgen_DDTRA, ovl.fmt.RRF4.r3,
14242 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14243 ovl.fmt.RRF4.r2); goto ok;
14244 case 0xb3d2: s390_format_RRF_FUFF2(s390_irgen_ADTRA, ovl.fmt.RRF4.r3,
14245 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14246 ovl.fmt.RRF4.r2); goto ok;
14247 case 0xb3d3: s390_format_RRF_FUFF2(s390_irgen_SDTRA, ovl.fmt.RRF4.r3,
14248 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14249 ovl.fmt.RRF4.r2); goto ok;
floriane38f6412012-12-21 17:32:12 +000014250 case 0xb3d4: s390_format_RRF_0UFF(s390_irgen_LDETR, ovl.fmt.RRF5.m4,
14251 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14252 case 0xb3d5: s390_format_RRF_UUFF(s390_irgen_LEDTR, ovl.fmt.RRF2.m3,
14253 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14254 ovl.fmt.RRF2.r2); goto ok;
florian12390202012-11-10 22:34:14 +000014255 case 0xb3d6: s390_format_RRE_FF(s390_irgen_LTDTR, ovl.fmt.RRE.r1,
14256 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014257 case 0xb3d7: /* FIDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014258 case 0xb3d8: s390_format_RRF_FUFF2(s390_irgen_MXTRA, ovl.fmt.RRF4.r3,
14259 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14260 ovl.fmt.RRF4.r2); goto ok;
14261 case 0xb3d9: s390_format_RRF_FUFF2(s390_irgen_DXTRA, ovl.fmt.RRF4.r3,
14262 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14263 ovl.fmt.RRF4.r2); goto ok;
14264 case 0xb3da: s390_format_RRF_FUFF2(s390_irgen_AXTRA, ovl.fmt.RRF4.r3,
14265 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14266 ovl.fmt.RRF4.r2); goto ok;
14267 case 0xb3db: s390_format_RRF_FUFF2(s390_irgen_SXTRA, ovl.fmt.RRF4.r3,
14268 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14269 ovl.fmt.RRF4.r2); goto ok;
14270 case 0xb3dc: s390_format_RRF_0UFF(s390_irgen_LXDTR, ovl.fmt.RRF5.m4,
14271 ovl.fmt.RRF5.r1, ovl.fmt.RRF5.r2); goto ok;
14272 case 0xb3dd: s390_format_RRF_UUFF(s390_irgen_LDXTR, ovl.fmt.RRF2.m3,
14273 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14274 ovl.fmt.RRF2.r2); goto ok;
14275 case 0xb3de: s390_format_RRE_FF(s390_irgen_LTXTR, ovl.fmt.RRE.r1,
14276 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014277 case 0xb3df: /* FIXTR */ goto unimplemented;
14278 case 0xb3e0: /* KDTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014279 case 0xb3e1: s390_format_RRF_UURF(s390_irgen_CGDTR, ovl.fmt.RRF2.m3,
14280 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14281 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014282 case 0xb3e2: /* CUDTR */ goto unimplemented;
14283 case 0xb3e3: /* CSDTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014284 case 0xb3e4: s390_format_RRE_FF(s390_irgen_CDTR, ovl.fmt.RRE.r1,
14285 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014286 case 0xb3e5: s390_format_RRE_RF(s390_irgen_EEDTR, ovl.fmt.RRE.r1,
14287 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014288 case 0xb3e7: s390_format_RRE_RF(s390_irgen_ESDTR, ovl.fmt.RRE.r1,
14289 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014290 case 0xb3e8: /* KXTR */ goto unimplemented;
floriana887acd2013-02-08 23:32:54 +000014291 case 0xb3e9: s390_format_RRF_UURF(s390_irgen_CGXTR, ovl.fmt.RRF2.m3,
14292 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14293 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014294 case 0xb3ea: /* CUXTR */ goto unimplemented;
14295 case 0xb3eb: /* CSXTR */ goto unimplemented;
floriane38f6412012-12-21 17:32:12 +000014296 case 0xb3ec: s390_format_RRE_FF(s390_irgen_CXTR, ovl.fmt.RRE.r1,
14297 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014298 case 0xb3ed: s390_format_RRE_RF(s390_irgen_EEXTR, ovl.fmt.RRE.r1,
14299 ovl.fmt.RRE.r2); goto ok;
floriance9e3db2012-12-27 20:14:03 +000014300 case 0xb3ef: s390_format_RRE_RF(s390_irgen_ESXTR, ovl.fmt.RRE.r1,
14301 ovl.fmt.RRE.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014302 case 0xb3f1: s390_format_RRF_UUFR(s390_irgen_CDGTRA, ovl.fmt.RRF2.m3,
14303 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14304 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014305 case 0xb3f2: /* CDUTR */ goto unimplemented;
14306 case 0xb3f3: /* CDSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014307 case 0xb3f4: s390_format_RRE_FF(s390_irgen_CEDTR, ovl.fmt.RRE.r1,
14308 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014309 case 0xb3f5: s390_format_RRF_FUFF(s390_irgen_QADTR, ovl.fmt.RRF4.r3,
14310 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14311 ovl.fmt.RRF4.r2); goto ok;
14312 case 0xb3f6: s390_format_RRF_F0FR(s390_irgen_IEDTR, ovl.fmt.RRF3.r3,
14313 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14314 case 0xb3f7: s390_format_RRF_FFRU(s390_irgen_RRDTR, ovl.fmt.RRF4.r3,
14315 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14316 ovl.fmt.RRF4.r2); goto ok;
floriana887acd2013-02-08 23:32:54 +000014317 case 0xb3f9: s390_format_RRF_UUFR(s390_irgen_CXGTR, ovl.fmt.RRF2.m3,
14318 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14319 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014320 case 0xb3fa: /* CXUTR */ goto unimplemented;
14321 case 0xb3fb: /* CXSTR */ goto unimplemented;
florian20c6bca2012-12-26 17:47:19 +000014322 case 0xb3fc: s390_format_RRE_FF(s390_irgen_CEXTR, ovl.fmt.RRE.r1,
14323 ovl.fmt.RRE.r2); goto ok;
florian5c539732013-02-14 14:27:12 +000014324 case 0xb3fd: s390_format_RRF_FUFF(s390_irgen_QAXTR, ovl.fmt.RRF4.r3,
14325 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14326 ovl.fmt.RRF4.r2); goto ok;
14327 case 0xb3fe: s390_format_RRF_F0FR(s390_irgen_IEXTR, ovl.fmt.RRF3.r3,
14328 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14329 case 0xb3ff: s390_format_RRF_FFRU(s390_irgen_RRXTR, ovl.fmt.RRF4.r3,
14330 ovl.fmt.RRF4.m4, ovl.fmt.RRF4.r1,
14331 ovl.fmt.RRF4.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014332 case 0xb900: s390_format_RRE_RR(s390_irgen_LPGR, ovl.fmt.RRE.r1,
14333 ovl.fmt.RRE.r2); goto ok;
14334 case 0xb901: s390_format_RRE_RR(s390_irgen_LNGR, ovl.fmt.RRE.r1,
14335 ovl.fmt.RRE.r2); goto ok;
14336 case 0xb902: s390_format_RRE_RR(s390_irgen_LTGR, ovl.fmt.RRE.r1,
14337 ovl.fmt.RRE.r2); goto ok;
14338 case 0xb903: s390_format_RRE_RR(s390_irgen_LCGR, ovl.fmt.RRE.r1,
14339 ovl.fmt.RRE.r2); goto ok;
14340 case 0xb904: s390_format_RRE_RR(s390_irgen_LGR, ovl.fmt.RRE.r1,
14341 ovl.fmt.RRE.r2); goto ok;
14342 case 0xb905: /* LURAG */ goto unimplemented;
14343 case 0xb906: s390_format_RRE_RR(s390_irgen_LGBR, ovl.fmt.RRE.r1,
14344 ovl.fmt.RRE.r2); goto ok;
14345 case 0xb907: s390_format_RRE_RR(s390_irgen_LGHR, ovl.fmt.RRE.r1,
14346 ovl.fmt.RRE.r2); goto ok;
14347 case 0xb908: s390_format_RRE_RR(s390_irgen_AGR, ovl.fmt.RRE.r1,
14348 ovl.fmt.RRE.r2); goto ok;
14349 case 0xb909: s390_format_RRE_RR(s390_irgen_SGR, ovl.fmt.RRE.r1,
14350 ovl.fmt.RRE.r2); goto ok;
14351 case 0xb90a: s390_format_RRE_RR(s390_irgen_ALGR, ovl.fmt.RRE.r1,
14352 ovl.fmt.RRE.r2); goto ok;
14353 case 0xb90b: s390_format_RRE_RR(s390_irgen_SLGR, ovl.fmt.RRE.r1,
14354 ovl.fmt.RRE.r2); goto ok;
14355 case 0xb90c: s390_format_RRE_RR(s390_irgen_MSGR, ovl.fmt.RRE.r1,
14356 ovl.fmt.RRE.r2); goto ok;
14357 case 0xb90d: s390_format_RRE_RR(s390_irgen_DSGR, ovl.fmt.RRE.r1,
14358 ovl.fmt.RRE.r2); goto ok;
14359 case 0xb90e: /* EREGG */ goto unimplemented;
14360 case 0xb90f: s390_format_RRE_RR(s390_irgen_LRVGR, ovl.fmt.RRE.r1,
14361 ovl.fmt.RRE.r2); goto ok;
14362 case 0xb910: s390_format_RRE_RR(s390_irgen_LPGFR, ovl.fmt.RRE.r1,
14363 ovl.fmt.RRE.r2); goto ok;
14364 case 0xb911: s390_format_RRE_RR(s390_irgen_LNGFR, ovl.fmt.RRE.r1,
14365 ovl.fmt.RRE.r2); goto ok;
14366 case 0xb912: s390_format_RRE_RR(s390_irgen_LTGFR, ovl.fmt.RRE.r1,
14367 ovl.fmt.RRE.r2); goto ok;
14368 case 0xb913: s390_format_RRE_RR(s390_irgen_LCGFR, ovl.fmt.RRE.r1,
14369 ovl.fmt.RRE.r2); goto ok;
14370 case 0xb914: s390_format_RRE_RR(s390_irgen_LGFR, ovl.fmt.RRE.r1,
14371 ovl.fmt.RRE.r2); goto ok;
14372 case 0xb916: s390_format_RRE_RR(s390_irgen_LLGFR, ovl.fmt.RRE.r1,
14373 ovl.fmt.RRE.r2); goto ok;
14374 case 0xb917: s390_format_RRE_RR(s390_irgen_LLGTR, ovl.fmt.RRE.r1,
14375 ovl.fmt.RRE.r2); goto ok;
14376 case 0xb918: s390_format_RRE_RR(s390_irgen_AGFR, ovl.fmt.RRE.r1,
14377 ovl.fmt.RRE.r2); goto ok;
14378 case 0xb919: s390_format_RRE_RR(s390_irgen_SGFR, ovl.fmt.RRE.r1,
14379 ovl.fmt.RRE.r2); goto ok;
14380 case 0xb91a: s390_format_RRE_RR(s390_irgen_ALGFR, ovl.fmt.RRE.r1,
14381 ovl.fmt.RRE.r2); goto ok;
14382 case 0xb91b: s390_format_RRE_RR(s390_irgen_SLGFR, ovl.fmt.RRE.r1,
14383 ovl.fmt.RRE.r2); goto ok;
14384 case 0xb91c: s390_format_RRE_RR(s390_irgen_MSGFR, ovl.fmt.RRE.r1,
14385 ovl.fmt.RRE.r2); goto ok;
14386 case 0xb91d: s390_format_RRE_RR(s390_irgen_DSGFR, ovl.fmt.RRE.r1,
14387 ovl.fmt.RRE.r2); goto ok;
14388 case 0xb91e: /* KMAC */ goto unimplemented;
14389 case 0xb91f: s390_format_RRE_RR(s390_irgen_LRVR, ovl.fmt.RRE.r1,
14390 ovl.fmt.RRE.r2); goto ok;
14391 case 0xb920: s390_format_RRE_RR(s390_irgen_CGR, ovl.fmt.RRE.r1,
14392 ovl.fmt.RRE.r2); goto ok;
14393 case 0xb921: s390_format_RRE_RR(s390_irgen_CLGR, ovl.fmt.RRE.r1,
14394 ovl.fmt.RRE.r2); goto ok;
14395 case 0xb925: /* STURG */ goto unimplemented;
14396 case 0xb926: s390_format_RRE_RR(s390_irgen_LBR, ovl.fmt.RRE.r1,
14397 ovl.fmt.RRE.r2); goto ok;
14398 case 0xb927: s390_format_RRE_RR(s390_irgen_LHR, ovl.fmt.RRE.r1,
14399 ovl.fmt.RRE.r2); goto ok;
14400 case 0xb928: /* PCKMO */ goto unimplemented;
florian76a14242012-12-07 04:42:53 +000014401 case 0xb92a: /* KMF */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000014402 case 0xb92b: /* KMO */ goto unimplemented;
14403 case 0xb92c: /* PCC */ goto unimplemented;
14404 case 0xb92d: /* KMCTR */ goto unimplemented;
14405 case 0xb92e: /* KM */ goto unimplemented;
14406 case 0xb92f: /* KMC */ goto unimplemented;
14407 case 0xb930: s390_format_RRE_RR(s390_irgen_CGFR, ovl.fmt.RRE.r1,
14408 ovl.fmt.RRE.r2); goto ok;
14409 case 0xb931: s390_format_RRE_RR(s390_irgen_CLGFR, ovl.fmt.RRE.r1,
14410 ovl.fmt.RRE.r2); goto ok;
14411 case 0xb93e: /* KIMD */ goto unimplemented;
14412 case 0xb93f: /* KLMD */ goto unimplemented;
florian5f034622013-01-13 02:29:05 +000014413 case 0xb941: s390_format_RRF_UURF(s390_irgen_CFDTR, ovl.fmt.RRF2.m3,
14414 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14415 ovl.fmt.RRF2.r2); goto ok;
14416 case 0xb942: s390_format_RRF_UURF(s390_irgen_CLGDTR, ovl.fmt.RRF2.m3,
14417 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14418 ovl.fmt.RRF2.r2); goto ok;
14419 case 0xb943: s390_format_RRF_UURF(s390_irgen_CLFDTR, ovl.fmt.RRF2.m3,
14420 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14421 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014422 case 0xb946: s390_format_RRE_RR(s390_irgen_BCTGR, ovl.fmt.RRE.r1,
14423 ovl.fmt.RRE.r2); goto ok;
florian5f034622013-01-13 02:29:05 +000014424 case 0xb949: s390_format_RRF_UURF(s390_irgen_CFXTR, ovl.fmt.RRF2.m3,
14425 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14426 ovl.fmt.RRF2.r2); goto ok;
14427 case 0xb94a: s390_format_RRF_UURF(s390_irgen_CLGXTR, ovl.fmt.RRF2.m3,
14428 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14429 ovl.fmt.RRF2.r2); goto ok;
14430 case 0xb94b: s390_format_RRF_UURF(s390_irgen_CLFXTR, ovl.fmt.RRF2.m3,
14431 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14432 ovl.fmt.RRF2.r2); goto ok;
14433 case 0xb951: s390_format_RRF_UUFR(s390_irgen_CDFTR, ovl.fmt.RRF2.m3,
14434 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14435 ovl.fmt.RRF2.r2); goto ok;
14436 case 0xb952: s390_format_RRF_UUFR(s390_irgen_CDLGTR, ovl.fmt.RRF2.m3,
14437 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14438 ovl.fmt.RRF2.r2); goto ok;
14439 case 0xb953: s390_format_RRF_UUFR(s390_irgen_CDLFTR, ovl.fmt.RRF2.m3,
14440 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14441 ovl.fmt.RRF2.r2); goto ok;
14442 case 0xb959: s390_format_RRF_UUFR(s390_irgen_CXFTR, ovl.fmt.RRF2.m3,
14443 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14444 ovl.fmt.RRF2.r2); goto ok;
14445 case 0xb95a: s390_format_RRF_UUFR(s390_irgen_CXLGTR, ovl.fmt.RRF2.m3,
14446 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14447 ovl.fmt.RRF2.r2); goto ok;
14448 case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3,
14449 ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1,
14450 ovl.fmt.RRF2.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014451 case 0xb960: /* CGRT */ goto unimplemented;
14452 case 0xb961: /* CLGRT */ goto unimplemented;
14453 case 0xb972: /* CRT */ goto unimplemented;
14454 case 0xb973: /* CLRT */ goto unimplemented;
14455 case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1,
14456 ovl.fmt.RRE.r2); goto ok;
14457 case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1,
14458 ovl.fmt.RRE.r2); goto ok;
14459 case 0xb982: s390_format_RRE_RR(s390_irgen_XGR, ovl.fmt.RRE.r1,
14460 ovl.fmt.RRE.r2); goto ok;
14461 case 0xb983: s390_format_RRE_RR(s390_irgen_FLOGR, ovl.fmt.RRE.r1,
14462 ovl.fmt.RRE.r2); goto ok;
14463 case 0xb984: s390_format_RRE_RR(s390_irgen_LLGCR, ovl.fmt.RRE.r1,
14464 ovl.fmt.RRE.r2); goto ok;
14465 case 0xb985: s390_format_RRE_RR(s390_irgen_LLGHR, ovl.fmt.RRE.r1,
14466 ovl.fmt.RRE.r2); goto ok;
14467 case 0xb986: s390_format_RRE_RR(s390_irgen_MLGR, ovl.fmt.RRE.r1,
14468 ovl.fmt.RRE.r2); goto ok;
14469 case 0xb987: s390_format_RRE_RR(s390_irgen_DLGR, ovl.fmt.RRE.r1,
14470 ovl.fmt.RRE.r2); goto ok;
14471 case 0xb988: s390_format_RRE_RR(s390_irgen_ALCGR, ovl.fmt.RRE.r1,
14472 ovl.fmt.RRE.r2); goto ok;
14473 case 0xb989: s390_format_RRE_RR(s390_irgen_SLBGR, ovl.fmt.RRE.r1,
14474 ovl.fmt.RRE.r2); goto ok;
14475 case 0xb98a: /* CSPG */ goto unimplemented;
14476 case 0xb98d: /* EPSW */ goto unimplemented;
14477 case 0xb98e: /* IDTE */ goto unimplemented;
florian2289cd42012-12-05 04:23:42 +000014478 case 0xb98f: /* CRDTE */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000014479 case 0xb990: s390_format_RRF_M0RERE(s390_irgen_TRTT, ovl.fmt.RRF3.r3,
14480 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14481 case 0xb991: s390_format_RRF_M0RERE(s390_irgen_TRTO, ovl.fmt.RRF3.r3,
14482 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
14483 case 0xb992: s390_format_RRF_M0RERE(s390_irgen_TROT, ovl.fmt.RRF3.r3,
14484 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
florian9af37692012-01-15 21:01:16 +000014485 case 0xb993: s390_format_RRF_M0RERE(s390_irgen_TROO, ovl.fmt.RRF3.r3,
14486 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014487 case 0xb994: s390_format_RRE_RR(s390_irgen_LLCR, ovl.fmt.RRE.r1,
14488 ovl.fmt.RRE.r2); goto ok;
14489 case 0xb995: s390_format_RRE_RR(s390_irgen_LLHR, ovl.fmt.RRE.r1,
14490 ovl.fmt.RRE.r2); goto ok;
14491 case 0xb996: s390_format_RRE_RR(s390_irgen_MLR, ovl.fmt.RRE.r1,
14492 ovl.fmt.RRE.r2); goto ok;
14493 case 0xb997: s390_format_RRE_RR(s390_irgen_DLR, ovl.fmt.RRE.r1,
14494 ovl.fmt.RRE.r2); goto ok;
14495 case 0xb998: s390_format_RRE_RR(s390_irgen_ALCR, ovl.fmt.RRE.r1,
14496 ovl.fmt.RRE.r2); goto ok;
14497 case 0xb999: s390_format_RRE_RR(s390_irgen_SLBR, ovl.fmt.RRE.r1,
14498 ovl.fmt.RRE.r2); goto ok;
14499 case 0xb99a: /* EPAIR */ goto unimplemented;
14500 case 0xb99b: /* ESAIR */ goto unimplemented;
14501 case 0xb99d: /* ESEA */ goto unimplemented;
14502 case 0xb99e: /* PTI */ goto unimplemented;
14503 case 0xb99f: /* SSAIR */ goto unimplemented;
14504 case 0xb9a2: /* PTF */ goto unimplemented;
14505 case 0xb9aa: /* LPTEA */ goto unimplemented;
14506 case 0xb9ae: /* RRBM */ goto unimplemented;
14507 case 0xb9af: /* PFMF */ goto unimplemented;
florian3f8a96a2012-08-05 02:59:55 +000014508 case 0xb9b0: s390_format_RRF_M0RERE(s390_irgen_CU14, ovl.fmt.RRF3.r3,
14509 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14510 goto ok;
florian2a415a12012-07-21 17:41:36 +000014511 case 0xb9b1: s390_format_RRF_M0RERE(s390_irgen_CU24, ovl.fmt.RRF3.r3,
14512 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2);
14513 goto ok;
florianaf2194f2012-08-06 00:07:54 +000014514 case 0xb9b2: s390_format_RRE_RR(s390_irgen_CU41, ovl.fmt.RRE.r1,
14515 ovl.fmt.RRE.r2); goto ok;
florian956194b2012-07-28 22:18:32 +000014516 case 0xb9b3: s390_format_RRE_RR(s390_irgen_CU42, ovl.fmt.RRE.r1,
14517 ovl.fmt.RRE.r2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014518 case 0xb9bd: /* TRTRE */ goto unimplemented;
14519 case 0xb9be: /* SRSTU */ goto unimplemented;
14520 case 0xb9bf: /* TRTE */ goto unimplemented;
14521 case 0xb9c8: s390_format_RRF_R0RR2(s390_irgen_AHHHR, ovl.fmt.RRF4.r3,
14522 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14523 goto ok;
14524 case 0xb9c9: s390_format_RRF_R0RR2(s390_irgen_SHHHR, ovl.fmt.RRF4.r3,
14525 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14526 goto ok;
14527 case 0xb9ca: s390_format_RRF_R0RR2(s390_irgen_ALHHHR, ovl.fmt.RRF4.r3,
14528 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14529 goto ok;
14530 case 0xb9cb: s390_format_RRF_R0RR2(s390_irgen_SLHHHR, ovl.fmt.RRF4.r3,
14531 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14532 goto ok;
14533 case 0xb9cd: s390_format_RRE_RR(s390_irgen_CHHR, ovl.fmt.RRE.r1,
14534 ovl.fmt.RRE.r2); goto ok;
14535 case 0xb9cf: s390_format_RRE_RR(s390_irgen_CLHHR, ovl.fmt.RRE.r1,
14536 ovl.fmt.RRE.r2); goto ok;
14537 case 0xb9d8: s390_format_RRF_R0RR2(s390_irgen_AHHLR, ovl.fmt.RRF4.r3,
14538 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14539 goto ok;
14540 case 0xb9d9: s390_format_RRF_R0RR2(s390_irgen_SHHLR, ovl.fmt.RRF4.r3,
14541 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14542 goto ok;
14543 case 0xb9da: s390_format_RRF_R0RR2(s390_irgen_ALHHLR, ovl.fmt.RRF4.r3,
14544 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14545 goto ok;
14546 case 0xb9db: s390_format_RRF_R0RR2(s390_irgen_SLHHLR, ovl.fmt.RRF4.r3,
14547 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14548 goto ok;
14549 case 0xb9dd: s390_format_RRE_RR(s390_irgen_CHLR, ovl.fmt.RRE.r1,
14550 ovl.fmt.RRE.r2); goto ok;
14551 case 0xb9df: s390_format_RRE_RR(s390_irgen_CLHLR, ovl.fmt.RRE.r1,
14552 ovl.fmt.RRE.r2); goto ok;
14553 case 0xb9e1: /* POPCNT */ goto unimplemented;
sewardjd7bde722011-04-05 13:19:33 +000014554 case 0xb9e2: s390_format_RRF_U0RR(s390_irgen_LOCGR, ovl.fmt.RRF3.r3,
14555 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14556 S390_XMNM_LOCGR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014557 case 0xb9e4: s390_format_RRF_R0RR2(s390_irgen_NGRK, ovl.fmt.RRF4.r3,
14558 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14559 goto ok;
14560 case 0xb9e6: s390_format_RRF_R0RR2(s390_irgen_OGRK, ovl.fmt.RRF4.r3,
14561 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14562 goto ok;
14563 case 0xb9e7: s390_format_RRF_R0RR2(s390_irgen_XGRK, ovl.fmt.RRF4.r3,
14564 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14565 goto ok;
14566 case 0xb9e8: s390_format_RRF_R0RR2(s390_irgen_AGRK, ovl.fmt.RRF4.r3,
14567 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14568 goto ok;
14569 case 0xb9e9: s390_format_RRF_R0RR2(s390_irgen_SGRK, ovl.fmt.RRF4.r3,
14570 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14571 goto ok;
14572 case 0xb9ea: s390_format_RRF_R0RR2(s390_irgen_ALGRK, ovl.fmt.RRF4.r3,
14573 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14574 goto ok;
14575 case 0xb9eb: s390_format_RRF_R0RR2(s390_irgen_SLGRK, ovl.fmt.RRF4.r3,
14576 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14577 goto ok;
sewardjd7bde722011-04-05 13:19:33 +000014578 case 0xb9f2: s390_format_RRF_U0RR(s390_irgen_LOCR, ovl.fmt.RRF3.r3,
14579 ovl.fmt.RRF3.r1, ovl.fmt.RRF3.r2,
14580 S390_XMNM_LOCR); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014581 case 0xb9f4: s390_format_RRF_R0RR2(s390_irgen_NRK, ovl.fmt.RRF4.r3,
14582 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14583 goto ok;
14584 case 0xb9f6: s390_format_RRF_R0RR2(s390_irgen_ORK, ovl.fmt.RRF4.r3,
14585 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14586 goto ok;
14587 case 0xb9f7: s390_format_RRF_R0RR2(s390_irgen_XRK, ovl.fmt.RRF4.r3,
14588 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14589 goto ok;
14590 case 0xb9f8: s390_format_RRF_R0RR2(s390_irgen_ARK, ovl.fmt.RRF4.r3,
14591 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14592 goto ok;
14593 case 0xb9f9: s390_format_RRF_R0RR2(s390_irgen_SRK, ovl.fmt.RRF4.r3,
14594 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14595 goto ok;
14596 case 0xb9fa: s390_format_RRF_R0RR2(s390_irgen_ALRK, ovl.fmt.RRF4.r3,
14597 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14598 goto ok;
14599 case 0xb9fb: s390_format_RRF_R0RR2(s390_irgen_SLRK, ovl.fmt.RRF4.r3,
14600 ovl.fmt.RRF4.r1, ovl.fmt.RRF4.r2);
14601 goto ok;
14602 }
14603
14604 switch ((ovl.value & 0xff000000) >> 24) {
14605 case 0x40: s390_format_RX_RRRD(s390_irgen_STH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14606 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14607 case 0x41: s390_format_RX_RRRD(s390_irgen_LA, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14608 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14609 case 0x42: s390_format_RX_RRRD(s390_irgen_STC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14610 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14611 case 0x43: s390_format_RX_RRRD(s390_irgen_IC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14612 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14613 case 0x44: s390_format_RX_RRRD(s390_irgen_EX, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14614 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14615 case 0x45: /* BAL */ goto unimplemented;
14616 case 0x46: s390_format_RX_RRRD(s390_irgen_BCT, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14617 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14618 case 0x47: s390_format_RX(s390_irgen_BC, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14619 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14620 case 0x48: s390_format_RX_RRRD(s390_irgen_LH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14621 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14622 case 0x49: s390_format_RX_RRRD(s390_irgen_CH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14623 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14624 case 0x4a: s390_format_RX_RRRD(s390_irgen_AH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14625 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14626 case 0x4b: s390_format_RX_RRRD(s390_irgen_SH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14627 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14628 case 0x4c: s390_format_RX_RRRD(s390_irgen_MH, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14629 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14630 case 0x4d: s390_format_RX_RRRD(s390_irgen_BAS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14631 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14632 case 0x4e: s390_format_RX_RRRD(s390_irgen_CVD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14633 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14634 case 0x4f: s390_format_RX_RRRD(s390_irgen_CVB, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14635 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14636 case 0x50: s390_format_RX_RRRD(s390_irgen_ST, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14637 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14638 case 0x51: s390_format_RX_RRRD(s390_irgen_LAE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14639 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14640 case 0x54: s390_format_RX_RRRD(s390_irgen_N, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14641 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14642 case 0x55: s390_format_RX_RRRD(s390_irgen_CL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14643 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14644 case 0x56: s390_format_RX_RRRD(s390_irgen_O, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14645 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14646 case 0x57: s390_format_RX_RRRD(s390_irgen_X, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14647 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14648 case 0x58: s390_format_RX_RRRD(s390_irgen_L, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14649 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14650 case 0x59: s390_format_RX_RRRD(s390_irgen_C, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14651 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14652 case 0x5a: s390_format_RX_RRRD(s390_irgen_A, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14653 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14654 case 0x5b: s390_format_RX_RRRD(s390_irgen_S, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14655 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14656 case 0x5c: s390_format_RX_RRRD(s390_irgen_M, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14657 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14658 case 0x5d: s390_format_RX_RRRD(s390_irgen_D, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14659 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14660 case 0x5e: s390_format_RX_RRRD(s390_irgen_AL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14661 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14662 case 0x5f: s390_format_RX_RRRD(s390_irgen_SL, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14663 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14664 case 0x60: s390_format_RX_FRRD(s390_irgen_STD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14665 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14666 case 0x67: /* MXD */ goto unimplemented;
14667 case 0x68: s390_format_RX_FRRD(s390_irgen_LD, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14668 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14669 case 0x69: /* CD */ goto unimplemented;
14670 case 0x6a: /* AD */ goto unimplemented;
14671 case 0x6b: /* SD */ goto unimplemented;
14672 case 0x6c: /* MD */ goto unimplemented;
14673 case 0x6d: /* DD */ goto unimplemented;
14674 case 0x6e: /* AW */ goto unimplemented;
14675 case 0x6f: /* SW */ goto unimplemented;
14676 case 0x70: s390_format_RX_FRRD(s390_irgen_STE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14677 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14678 case 0x71: s390_format_RX_RRRD(s390_irgen_MS, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14679 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14680 case 0x78: s390_format_RX_FRRD(s390_irgen_LE, ovl.fmt.RX.r1, ovl.fmt.RX.x2,
14681 ovl.fmt.RX.b2, ovl.fmt.RX.d2); goto ok;
14682 case 0x79: /* CE */ goto unimplemented;
14683 case 0x7a: /* AE */ goto unimplemented;
14684 case 0x7b: /* SE */ goto unimplemented;
14685 case 0x7c: /* MDE */ goto unimplemented;
14686 case 0x7d: /* DE */ goto unimplemented;
14687 case 0x7e: /* AU */ goto unimplemented;
14688 case 0x7f: /* SU */ goto unimplemented;
14689 case 0x83: /* DIAG */ goto unimplemented;
14690 case 0x84: s390_format_RSI_RRP(s390_irgen_BRXH, ovl.fmt.RSI.r1,
14691 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14692 case 0x85: s390_format_RSI_RRP(s390_irgen_BRXLE, ovl.fmt.RSI.r1,
14693 ovl.fmt.RSI.r3, ovl.fmt.RSI.i2); goto ok;
14694 case 0x86: s390_format_RS_RRRD(s390_irgen_BXH, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14695 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14696 case 0x87: s390_format_RS_RRRD(s390_irgen_BXLE, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14697 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14698 case 0x88: s390_format_RS_R0RD(s390_irgen_SRL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14699 ovl.fmt.RS.d2); goto ok;
14700 case 0x89: s390_format_RS_R0RD(s390_irgen_SLL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14701 ovl.fmt.RS.d2); goto ok;
14702 case 0x8a: s390_format_RS_R0RD(s390_irgen_SRA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14703 ovl.fmt.RS.d2); goto ok;
14704 case 0x8b: s390_format_RS_R0RD(s390_irgen_SLA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14705 ovl.fmt.RS.d2); goto ok;
14706 case 0x8c: s390_format_RS_R0RD(s390_irgen_SRDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14707 ovl.fmt.RS.d2); goto ok;
14708 case 0x8d: s390_format_RS_R0RD(s390_irgen_SLDL, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14709 ovl.fmt.RS.d2); goto ok;
14710 case 0x8e: s390_format_RS_R0RD(s390_irgen_SRDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14711 ovl.fmt.RS.d2); goto ok;
14712 case 0x8f: s390_format_RS_R0RD(s390_irgen_SLDA, ovl.fmt.RS.r1, ovl.fmt.RS.b2,
14713 ovl.fmt.RS.d2); goto ok;
14714 case 0x90: s390_format_RS_RRRD(s390_irgen_STM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14715 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14716 case 0x91: s390_format_SI_URD(s390_irgen_TM, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14717 ovl.fmt.SI.d1); goto ok;
14718 case 0x92: s390_format_SI_URD(s390_irgen_MVI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14719 ovl.fmt.SI.d1); goto ok;
14720 case 0x94: s390_format_SI_URD(s390_irgen_NI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14721 ovl.fmt.SI.d1); goto ok;
14722 case 0x95: s390_format_SI_URD(s390_irgen_CLI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14723 ovl.fmt.SI.d1); goto ok;
14724 case 0x96: s390_format_SI_URD(s390_irgen_OI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14725 ovl.fmt.SI.d1); goto ok;
14726 case 0x97: s390_format_SI_URD(s390_irgen_XI, ovl.fmt.SI.i2, ovl.fmt.SI.b1,
14727 ovl.fmt.SI.d1); goto ok;
14728 case 0x98: s390_format_RS_RRRD(s390_irgen_LM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14729 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14730 case 0x99: /* TRACE */ goto unimplemented;
14731 case 0x9a: s390_format_RS_AARD(s390_irgen_LAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14732 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14733 case 0x9b: s390_format_RS_AARD(s390_irgen_STAM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14734 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14735 case 0xa8: s390_format_RS_RRRD(s390_irgen_MVCLE, ovl.fmt.RS.r1,
14736 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14737 goto ok;
14738 case 0xa9: s390_format_RS_RRRD(s390_irgen_CLCLE, ovl.fmt.RS.r1,
14739 ovl.fmt.RS.r3, ovl.fmt.RS.b2, ovl.fmt.RS.d2);
14740 goto ok;
14741 case 0xac: /* STNSM */ goto unimplemented;
14742 case 0xad: /* STOSM */ goto unimplemented;
14743 case 0xae: /* SIGP */ goto unimplemented;
14744 case 0xaf: /* MC */ goto unimplemented;
14745 case 0xb1: /* LRA */ goto unimplemented;
14746 case 0xb6: /* STCTL */ goto unimplemented;
14747 case 0xb7: /* LCTL */ goto unimplemented;
14748 case 0xba: s390_format_RS_RRRD(s390_irgen_CS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14749 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
florian448cbba2012-06-06 02:26:01 +000014750 case 0xbb: s390_format_RS_RRRD(s390_irgen_CDS, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14751 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000014752 case 0xbd: s390_format_RS_RURD(s390_irgen_CLM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14753 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14754 case 0xbe: s390_format_RS_RURD(s390_irgen_STCM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14755 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14756 case 0xbf: s390_format_RS_RURD(s390_irgen_ICM, ovl.fmt.RS.r1, ovl.fmt.RS.r3,
14757 ovl.fmt.RS.b2, ovl.fmt.RS.d2); goto ok;
14758 }
14759
14760 return S390_DECODE_UNKNOWN_INSN;
14761
14762ok:
14763 return S390_DECODE_OK;
14764
14765unimplemented:
14766 return S390_DECODE_UNIMPLEMENTED_INSN;
14767}
14768
14769static s390_decode_t
14770s390_decode_6byte_and_irgen(UChar *bytes)
14771{
14772 typedef union {
14773 struct {
14774 unsigned int op1 : 8;
14775 unsigned int r1 : 4;
14776 unsigned int r3 : 4;
14777 unsigned int i2 : 16;
14778 unsigned int : 8;
14779 unsigned int op2 : 8;
14780 } RIE;
14781 struct {
14782 unsigned int op1 : 8;
14783 unsigned int r1 : 4;
14784 unsigned int r2 : 4;
14785 unsigned int i3 : 8;
14786 unsigned int i4 : 8;
14787 unsigned int i5 : 8;
14788 unsigned int op2 : 8;
14789 } RIE_RRUUU;
14790 struct {
14791 unsigned int op1 : 8;
14792 unsigned int r1 : 4;
14793 unsigned int : 4;
14794 unsigned int i2 : 16;
14795 unsigned int m3 : 4;
14796 unsigned int : 4;
14797 unsigned int op2 : 8;
14798 } RIEv1;
14799 struct {
14800 unsigned int op1 : 8;
14801 unsigned int r1 : 4;
14802 unsigned int r2 : 4;
14803 unsigned int i4 : 16;
14804 unsigned int m3 : 4;
14805 unsigned int : 4;
14806 unsigned int op2 : 8;
14807 } RIE_RRPU;
14808 struct {
14809 unsigned int op1 : 8;
14810 unsigned int r1 : 4;
14811 unsigned int m3 : 4;
14812 unsigned int i4 : 16;
14813 unsigned int i2 : 8;
14814 unsigned int op2 : 8;
14815 } RIEv3;
14816 struct {
14817 unsigned int op1 : 8;
14818 unsigned int r1 : 4;
14819 unsigned int op2 : 4;
14820 unsigned int i2 : 32;
14821 } RIL;
14822 struct {
14823 unsigned int op1 : 8;
14824 unsigned int r1 : 4;
14825 unsigned int m3 : 4;
14826 unsigned int b4 : 4;
14827 unsigned int d4 : 12;
14828 unsigned int i2 : 8;
14829 unsigned int op2 : 8;
14830 } RIS;
14831 struct {
14832 unsigned int op1 : 8;
14833 unsigned int r1 : 4;
14834 unsigned int r2 : 4;
14835 unsigned int b4 : 4;
14836 unsigned int d4 : 12;
14837 unsigned int m3 : 4;
14838 unsigned int : 4;
14839 unsigned int op2 : 8;
14840 } RRS;
14841 struct {
14842 unsigned int op1 : 8;
14843 unsigned int l1 : 4;
14844 unsigned int : 4;
14845 unsigned int b1 : 4;
14846 unsigned int d1 : 12;
14847 unsigned int : 8;
14848 unsigned int op2 : 8;
14849 } RSL;
14850 struct {
14851 unsigned int op1 : 8;
14852 unsigned int r1 : 4;
14853 unsigned int r3 : 4;
14854 unsigned int b2 : 4;
14855 unsigned int dl2 : 12;
14856 unsigned int dh2 : 8;
14857 unsigned int op2 : 8;
14858 } RSY;
14859 struct {
14860 unsigned int op1 : 8;
14861 unsigned int r1 : 4;
14862 unsigned int x2 : 4;
14863 unsigned int b2 : 4;
14864 unsigned int d2 : 12;
14865 unsigned int : 8;
14866 unsigned int op2 : 8;
14867 } RXE;
14868 struct {
14869 unsigned int op1 : 8;
14870 unsigned int r3 : 4;
14871 unsigned int x2 : 4;
14872 unsigned int b2 : 4;
14873 unsigned int d2 : 12;
14874 unsigned int r1 : 4;
14875 unsigned int : 4;
14876 unsigned int op2 : 8;
14877 } RXF;
14878 struct {
14879 unsigned int op1 : 8;
14880 unsigned int r1 : 4;
14881 unsigned int x2 : 4;
14882 unsigned int b2 : 4;
14883 unsigned int dl2 : 12;
14884 unsigned int dh2 : 8;
14885 unsigned int op2 : 8;
14886 } RXY;
14887 struct {
14888 unsigned int op1 : 8;
14889 unsigned int i2 : 8;
14890 unsigned int b1 : 4;
14891 unsigned int dl1 : 12;
14892 unsigned int dh1 : 8;
14893 unsigned int op2 : 8;
14894 } SIY;
14895 struct {
14896 unsigned int op : 8;
14897 unsigned int l : 8;
14898 unsigned int b1 : 4;
14899 unsigned int d1 : 12;
14900 unsigned int b2 : 4;
14901 unsigned int d2 : 12;
14902 } SS;
14903 struct {
14904 unsigned int op : 8;
14905 unsigned int l1 : 4;
14906 unsigned int l2 : 4;
14907 unsigned int b1 : 4;
14908 unsigned int d1 : 12;
14909 unsigned int b2 : 4;
14910 unsigned int d2 : 12;
14911 } SS_LLRDRD;
14912 struct {
14913 unsigned int op : 8;
14914 unsigned int r1 : 4;
14915 unsigned int r3 : 4;
14916 unsigned int b2 : 4;
14917 unsigned int d2 : 12;
14918 unsigned int b4 : 4;
14919 unsigned int d4 : 12;
14920 } SS_RRRDRD2;
14921 struct {
14922 unsigned int op : 16;
14923 unsigned int b1 : 4;
14924 unsigned int d1 : 12;
14925 unsigned int b2 : 4;
14926 unsigned int d2 : 12;
14927 } SSE;
14928 struct {
14929 unsigned int op1 : 8;
14930 unsigned int r3 : 4;
14931 unsigned int op2 : 4;
14932 unsigned int b1 : 4;
14933 unsigned int d1 : 12;
14934 unsigned int b2 : 4;
14935 unsigned int d2 : 12;
14936 } SSF;
14937 struct {
14938 unsigned int op : 16;
14939 unsigned int b1 : 4;
14940 unsigned int d1 : 12;
14941 unsigned int i2 : 16;
14942 } SIL;
14943 } formats;
14944 union {
14945 formats fmt;
14946 ULong value;
14947 } ovl;
14948
14949 vassert(sizeof(formats) == 6);
14950
florianffbd84d2012-12-09 02:06:29 +000014951 ((UChar *)(&ovl.value))[0] = bytes[0];
14952 ((UChar *)(&ovl.value))[1] = bytes[1];
14953 ((UChar *)(&ovl.value))[2] = bytes[2];
14954 ((UChar *)(&ovl.value))[3] = bytes[3];
14955 ((UChar *)(&ovl.value))[4] = bytes[4];
14956 ((UChar *)(&ovl.value))[5] = bytes[5];
14957 ((UChar *)(&ovl.value))[6] = 0x0;
14958 ((UChar *)(&ovl.value))[7] = 0x0;
sewardj2019a972011-03-07 16:04:07 +000014959
14960 switch ((ovl.value >> 16) & 0xff00000000ffULL) {
14961 case 0xe30000000002ULL: s390_format_RXY_RRRD(s390_irgen_LTG, 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 0xe30000000003ULL: /* LRAG */ goto unimplemented;
14966 case 0xe30000000004ULL: s390_format_RXY_RRRD(s390_irgen_LG, ovl.fmt.RXY.r1,
14967 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14968 ovl.fmt.RXY.dl2,
14969 ovl.fmt.RXY.dh2); goto ok;
14970 case 0xe30000000006ULL: s390_format_RXY_RRRD(s390_irgen_CVBY, 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 0xe30000000008ULL: s390_format_RXY_RRRD(s390_irgen_AG, 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 0xe30000000009ULL: s390_format_RXY_RRRD(s390_irgen_SG, 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 0xe3000000000aULL: s390_format_RXY_RRRD(s390_irgen_ALG, 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 0xe3000000000bULL: s390_format_RXY_RRRD(s390_irgen_SLG, ovl.fmt.RXY.r1,
14987 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14988 ovl.fmt.RXY.dl2,
14989 ovl.fmt.RXY.dh2); goto ok;
14990 case 0xe3000000000cULL: s390_format_RXY_RRRD(s390_irgen_MSG, ovl.fmt.RXY.r1,
14991 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14992 ovl.fmt.RXY.dl2,
14993 ovl.fmt.RXY.dh2); goto ok;
14994 case 0xe3000000000dULL: s390_format_RXY_RRRD(s390_irgen_DSG, ovl.fmt.RXY.r1,
14995 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
14996 ovl.fmt.RXY.dl2,
14997 ovl.fmt.RXY.dh2); goto ok;
14998 case 0xe3000000000eULL: /* CVBG */ goto unimplemented;
14999 case 0xe3000000000fULL: s390_format_RXY_RRRD(s390_irgen_LRVG, ovl.fmt.RXY.r1,
15000 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15001 ovl.fmt.RXY.dl2,
15002 ovl.fmt.RXY.dh2); goto ok;
15003 case 0xe30000000012ULL: s390_format_RXY_RRRD(s390_irgen_LT, ovl.fmt.RXY.r1,
15004 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15005 ovl.fmt.RXY.dl2,
15006 ovl.fmt.RXY.dh2); goto ok;
15007 case 0xe30000000013ULL: /* LRAY */ goto unimplemented;
15008 case 0xe30000000014ULL: s390_format_RXY_RRRD(s390_irgen_LGF, ovl.fmt.RXY.r1,
15009 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15010 ovl.fmt.RXY.dl2,
15011 ovl.fmt.RXY.dh2); goto ok;
15012 case 0xe30000000015ULL: s390_format_RXY_RRRD(s390_irgen_LGH, ovl.fmt.RXY.r1,
15013 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15014 ovl.fmt.RXY.dl2,
15015 ovl.fmt.RXY.dh2); goto ok;
15016 case 0xe30000000016ULL: s390_format_RXY_RRRD(s390_irgen_LLGF, ovl.fmt.RXY.r1,
15017 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15018 ovl.fmt.RXY.dl2,
15019 ovl.fmt.RXY.dh2); goto ok;
15020 case 0xe30000000017ULL: s390_format_RXY_RRRD(s390_irgen_LLGT, ovl.fmt.RXY.r1,
15021 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15022 ovl.fmt.RXY.dl2,
15023 ovl.fmt.RXY.dh2); goto ok;
15024 case 0xe30000000018ULL: s390_format_RXY_RRRD(s390_irgen_AGF, ovl.fmt.RXY.r1,
15025 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15026 ovl.fmt.RXY.dl2,
15027 ovl.fmt.RXY.dh2); goto ok;
15028 case 0xe30000000019ULL: s390_format_RXY_RRRD(s390_irgen_SGF, ovl.fmt.RXY.r1,
15029 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15030 ovl.fmt.RXY.dl2,
15031 ovl.fmt.RXY.dh2); goto ok;
15032 case 0xe3000000001aULL: s390_format_RXY_RRRD(s390_irgen_ALGF, ovl.fmt.RXY.r1,
15033 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15034 ovl.fmt.RXY.dl2,
15035 ovl.fmt.RXY.dh2); goto ok;
15036 case 0xe3000000001bULL: s390_format_RXY_RRRD(s390_irgen_SLGF, ovl.fmt.RXY.r1,
15037 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15038 ovl.fmt.RXY.dl2,
15039 ovl.fmt.RXY.dh2); goto ok;
15040 case 0xe3000000001cULL: s390_format_RXY_RRRD(s390_irgen_MSGF, ovl.fmt.RXY.r1,
15041 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15042 ovl.fmt.RXY.dl2,
15043 ovl.fmt.RXY.dh2); goto ok;
15044 case 0xe3000000001dULL: s390_format_RXY_RRRD(s390_irgen_DSGF, ovl.fmt.RXY.r1,
15045 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15046 ovl.fmt.RXY.dl2,
15047 ovl.fmt.RXY.dh2); goto ok;
15048 case 0xe3000000001eULL: s390_format_RXY_RRRD(s390_irgen_LRV, ovl.fmt.RXY.r1,
15049 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15050 ovl.fmt.RXY.dl2,
15051 ovl.fmt.RXY.dh2); goto ok;
15052 case 0xe3000000001fULL: s390_format_RXY_RRRD(s390_irgen_LRVH, ovl.fmt.RXY.r1,
15053 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15054 ovl.fmt.RXY.dl2,
15055 ovl.fmt.RXY.dh2); goto ok;
15056 case 0xe30000000020ULL: s390_format_RXY_RRRD(s390_irgen_CG, ovl.fmt.RXY.r1,
15057 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15058 ovl.fmt.RXY.dl2,
15059 ovl.fmt.RXY.dh2); goto ok;
15060 case 0xe30000000021ULL: s390_format_RXY_RRRD(s390_irgen_CLG, ovl.fmt.RXY.r1,
15061 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15062 ovl.fmt.RXY.dl2,
15063 ovl.fmt.RXY.dh2); goto ok;
15064 case 0xe30000000024ULL: s390_format_RXY_RRRD(s390_irgen_STG, ovl.fmt.RXY.r1,
15065 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15066 ovl.fmt.RXY.dl2,
15067 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015068 case 0xe30000000025ULL: /* NTSTG */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015069 case 0xe30000000026ULL: s390_format_RXY_RRRD(s390_irgen_CVDY, ovl.fmt.RXY.r1,
15070 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15071 ovl.fmt.RXY.dl2,
15072 ovl.fmt.RXY.dh2); goto ok;
15073 case 0xe3000000002eULL: /* CVDG */ goto unimplemented;
15074 case 0xe3000000002fULL: s390_format_RXY_RRRD(s390_irgen_STRVG,
15075 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15076 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15077 ovl.fmt.RXY.dh2); goto ok;
15078 case 0xe30000000030ULL: s390_format_RXY_RRRD(s390_irgen_CGF, ovl.fmt.RXY.r1,
15079 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15080 ovl.fmt.RXY.dl2,
15081 ovl.fmt.RXY.dh2); goto ok;
15082 case 0xe30000000031ULL: s390_format_RXY_RRRD(s390_irgen_CLGF, ovl.fmt.RXY.r1,
15083 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15084 ovl.fmt.RXY.dl2,
15085 ovl.fmt.RXY.dh2); goto ok;
15086 case 0xe30000000032ULL: s390_format_RXY_RRRD(s390_irgen_LTGF, ovl.fmt.RXY.r1,
15087 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15088 ovl.fmt.RXY.dl2,
15089 ovl.fmt.RXY.dh2); goto ok;
15090 case 0xe30000000034ULL: s390_format_RXY_RRRD(s390_irgen_CGH, ovl.fmt.RXY.r1,
15091 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15092 ovl.fmt.RXY.dl2,
15093 ovl.fmt.RXY.dh2); goto ok;
15094 case 0xe30000000036ULL: s390_format_RXY_URRD(s390_irgen_PFD, ovl.fmt.RXY.r1,
15095 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15096 ovl.fmt.RXY.dl2,
15097 ovl.fmt.RXY.dh2); goto ok;
15098 case 0xe3000000003eULL: s390_format_RXY_RRRD(s390_irgen_STRV, ovl.fmt.RXY.r1,
15099 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15100 ovl.fmt.RXY.dl2,
15101 ovl.fmt.RXY.dh2); goto ok;
15102 case 0xe3000000003fULL: s390_format_RXY_RRRD(s390_irgen_STRVH,
15103 ovl.fmt.RXY.r1, ovl.fmt.RXY.x2,
15104 ovl.fmt.RXY.b2, ovl.fmt.RXY.dl2,
15105 ovl.fmt.RXY.dh2); goto ok;
15106 case 0xe30000000046ULL: s390_format_RXY_RRRD(s390_irgen_BCTG, ovl.fmt.RXY.r1,
15107 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15108 ovl.fmt.RXY.dl2,
15109 ovl.fmt.RXY.dh2); goto ok;
15110 case 0xe30000000050ULL: s390_format_RXY_RRRD(s390_irgen_STY, ovl.fmt.RXY.r1,
15111 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15112 ovl.fmt.RXY.dl2,
15113 ovl.fmt.RXY.dh2); goto ok;
15114 case 0xe30000000051ULL: s390_format_RXY_RRRD(s390_irgen_MSY, ovl.fmt.RXY.r1,
15115 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15116 ovl.fmt.RXY.dl2,
15117 ovl.fmt.RXY.dh2); goto ok;
15118 case 0xe30000000054ULL: s390_format_RXY_RRRD(s390_irgen_NY, ovl.fmt.RXY.r1,
15119 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15120 ovl.fmt.RXY.dl2,
15121 ovl.fmt.RXY.dh2); goto ok;
15122 case 0xe30000000055ULL: s390_format_RXY_RRRD(s390_irgen_CLY, ovl.fmt.RXY.r1,
15123 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15124 ovl.fmt.RXY.dl2,
15125 ovl.fmt.RXY.dh2); goto ok;
15126 case 0xe30000000056ULL: s390_format_RXY_RRRD(s390_irgen_OY, ovl.fmt.RXY.r1,
15127 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15128 ovl.fmt.RXY.dl2,
15129 ovl.fmt.RXY.dh2); goto ok;
15130 case 0xe30000000057ULL: s390_format_RXY_RRRD(s390_irgen_XY, ovl.fmt.RXY.r1,
15131 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15132 ovl.fmt.RXY.dl2,
15133 ovl.fmt.RXY.dh2); goto ok;
15134 case 0xe30000000058ULL: s390_format_RXY_RRRD(s390_irgen_LY, ovl.fmt.RXY.r1,
15135 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15136 ovl.fmt.RXY.dl2,
15137 ovl.fmt.RXY.dh2); goto ok;
15138 case 0xe30000000059ULL: s390_format_RXY_RRRD(s390_irgen_CY, ovl.fmt.RXY.r1,
15139 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15140 ovl.fmt.RXY.dl2,
15141 ovl.fmt.RXY.dh2); goto ok;
15142 case 0xe3000000005aULL: s390_format_RXY_RRRD(s390_irgen_AY, ovl.fmt.RXY.r1,
15143 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15144 ovl.fmt.RXY.dl2,
15145 ovl.fmt.RXY.dh2); goto ok;
15146 case 0xe3000000005bULL: s390_format_RXY_RRRD(s390_irgen_SY, ovl.fmt.RXY.r1,
15147 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15148 ovl.fmt.RXY.dl2,
15149 ovl.fmt.RXY.dh2); goto ok;
15150 case 0xe3000000005cULL: s390_format_RXY_RRRD(s390_irgen_MFY, ovl.fmt.RXY.r1,
15151 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15152 ovl.fmt.RXY.dl2,
15153 ovl.fmt.RXY.dh2); goto ok;
15154 case 0xe3000000005eULL: s390_format_RXY_RRRD(s390_irgen_ALY, ovl.fmt.RXY.r1,
15155 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15156 ovl.fmt.RXY.dl2,
15157 ovl.fmt.RXY.dh2); goto ok;
15158 case 0xe3000000005fULL: s390_format_RXY_RRRD(s390_irgen_SLY, ovl.fmt.RXY.r1,
15159 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15160 ovl.fmt.RXY.dl2,
15161 ovl.fmt.RXY.dh2); goto ok;
15162 case 0xe30000000070ULL: s390_format_RXY_RRRD(s390_irgen_STHY, ovl.fmt.RXY.r1,
15163 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15164 ovl.fmt.RXY.dl2,
15165 ovl.fmt.RXY.dh2); goto ok;
15166 case 0xe30000000071ULL: s390_format_RXY_RRRD(s390_irgen_LAY, ovl.fmt.RXY.r1,
15167 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15168 ovl.fmt.RXY.dl2,
15169 ovl.fmt.RXY.dh2); goto ok;
15170 case 0xe30000000072ULL: s390_format_RXY_RRRD(s390_irgen_STCY, ovl.fmt.RXY.r1,
15171 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15172 ovl.fmt.RXY.dl2,
15173 ovl.fmt.RXY.dh2); goto ok;
15174 case 0xe30000000073ULL: s390_format_RXY_RRRD(s390_irgen_ICY, ovl.fmt.RXY.r1,
15175 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15176 ovl.fmt.RXY.dl2,
15177 ovl.fmt.RXY.dh2); goto ok;
15178 case 0xe30000000075ULL: s390_format_RXY_RRRD(s390_irgen_LAEY, ovl.fmt.RXY.r1,
15179 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15180 ovl.fmt.RXY.dl2,
15181 ovl.fmt.RXY.dh2); goto ok;
15182 case 0xe30000000076ULL: s390_format_RXY_RRRD(s390_irgen_LB, ovl.fmt.RXY.r1,
15183 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15184 ovl.fmt.RXY.dl2,
15185 ovl.fmt.RXY.dh2); goto ok;
15186 case 0xe30000000077ULL: s390_format_RXY_RRRD(s390_irgen_LGB, ovl.fmt.RXY.r1,
15187 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15188 ovl.fmt.RXY.dl2,
15189 ovl.fmt.RXY.dh2); goto ok;
15190 case 0xe30000000078ULL: s390_format_RXY_RRRD(s390_irgen_LHY, ovl.fmt.RXY.r1,
15191 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15192 ovl.fmt.RXY.dl2,
15193 ovl.fmt.RXY.dh2); goto ok;
15194 case 0xe30000000079ULL: s390_format_RXY_RRRD(s390_irgen_CHY, ovl.fmt.RXY.r1,
15195 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15196 ovl.fmt.RXY.dl2,
15197 ovl.fmt.RXY.dh2); goto ok;
15198 case 0xe3000000007aULL: s390_format_RXY_RRRD(s390_irgen_AHY, ovl.fmt.RXY.r1,
15199 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15200 ovl.fmt.RXY.dl2,
15201 ovl.fmt.RXY.dh2); goto ok;
15202 case 0xe3000000007bULL: s390_format_RXY_RRRD(s390_irgen_SHY, ovl.fmt.RXY.r1,
15203 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15204 ovl.fmt.RXY.dl2,
15205 ovl.fmt.RXY.dh2); goto ok;
15206 case 0xe3000000007cULL: s390_format_RXY_RRRD(s390_irgen_MHY, ovl.fmt.RXY.r1,
15207 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15208 ovl.fmt.RXY.dl2,
15209 ovl.fmt.RXY.dh2); goto ok;
15210 case 0xe30000000080ULL: s390_format_RXY_RRRD(s390_irgen_NG, ovl.fmt.RXY.r1,
15211 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15212 ovl.fmt.RXY.dl2,
15213 ovl.fmt.RXY.dh2); goto ok;
15214 case 0xe30000000081ULL: s390_format_RXY_RRRD(s390_irgen_OG, ovl.fmt.RXY.r1,
15215 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15216 ovl.fmt.RXY.dl2,
15217 ovl.fmt.RXY.dh2); goto ok;
15218 case 0xe30000000082ULL: s390_format_RXY_RRRD(s390_irgen_XG, ovl.fmt.RXY.r1,
15219 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15220 ovl.fmt.RXY.dl2,
15221 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015222 case 0xe30000000085ULL: /* LGAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015223 case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1,
15224 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15225 ovl.fmt.RXY.dl2,
15226 ovl.fmt.RXY.dh2); goto ok;
15227 case 0xe30000000087ULL: s390_format_RXY_RRRD(s390_irgen_DLG, ovl.fmt.RXY.r1,
15228 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15229 ovl.fmt.RXY.dl2,
15230 ovl.fmt.RXY.dh2); goto ok;
15231 case 0xe30000000088ULL: s390_format_RXY_RRRD(s390_irgen_ALCG, ovl.fmt.RXY.r1,
15232 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15233 ovl.fmt.RXY.dl2,
15234 ovl.fmt.RXY.dh2); goto ok;
15235 case 0xe30000000089ULL: s390_format_RXY_RRRD(s390_irgen_SLBG, ovl.fmt.RXY.r1,
15236 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15237 ovl.fmt.RXY.dl2,
15238 ovl.fmt.RXY.dh2); goto ok;
15239 case 0xe3000000008eULL: s390_format_RXY_RRRD(s390_irgen_STPQ, ovl.fmt.RXY.r1,
15240 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15241 ovl.fmt.RXY.dl2,
15242 ovl.fmt.RXY.dh2); goto ok;
15243 case 0xe3000000008fULL: s390_format_RXY_RRRD(s390_irgen_LPQ, ovl.fmt.RXY.r1,
15244 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15245 ovl.fmt.RXY.dl2,
15246 ovl.fmt.RXY.dh2); goto ok;
15247 case 0xe30000000090ULL: s390_format_RXY_RRRD(s390_irgen_LLGC, ovl.fmt.RXY.r1,
15248 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15249 ovl.fmt.RXY.dl2,
15250 ovl.fmt.RXY.dh2); goto ok;
15251 case 0xe30000000091ULL: s390_format_RXY_RRRD(s390_irgen_LLGH, ovl.fmt.RXY.r1,
15252 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15253 ovl.fmt.RXY.dl2,
15254 ovl.fmt.RXY.dh2); goto ok;
15255 case 0xe30000000094ULL: s390_format_RXY_RRRD(s390_irgen_LLC, ovl.fmt.RXY.r1,
15256 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15257 ovl.fmt.RXY.dl2,
15258 ovl.fmt.RXY.dh2); goto ok;
15259 case 0xe30000000095ULL: s390_format_RXY_RRRD(s390_irgen_LLH, ovl.fmt.RXY.r1,
15260 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15261 ovl.fmt.RXY.dl2,
15262 ovl.fmt.RXY.dh2); goto ok;
15263 case 0xe30000000096ULL: s390_format_RXY_RRRD(s390_irgen_ML, ovl.fmt.RXY.r1,
15264 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15265 ovl.fmt.RXY.dl2,
15266 ovl.fmt.RXY.dh2); goto ok;
15267 case 0xe30000000097ULL: s390_format_RXY_RRRD(s390_irgen_DL, ovl.fmt.RXY.r1,
15268 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15269 ovl.fmt.RXY.dl2,
15270 ovl.fmt.RXY.dh2); goto ok;
15271 case 0xe30000000098ULL: s390_format_RXY_RRRD(s390_irgen_ALC, ovl.fmt.RXY.r1,
15272 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15273 ovl.fmt.RXY.dl2,
15274 ovl.fmt.RXY.dh2); goto ok;
15275 case 0xe30000000099ULL: s390_format_RXY_RRRD(s390_irgen_SLB, ovl.fmt.RXY.r1,
15276 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15277 ovl.fmt.RXY.dl2,
15278 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015279 case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented;
15280 case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented;
15281 case 0xe3000000009fULL: /* LAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015282 case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1,
15283 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15284 ovl.fmt.RXY.dl2,
15285 ovl.fmt.RXY.dh2); goto ok;
15286 case 0xe300000000c2ULL: s390_format_RXY_RRRD(s390_irgen_LLCH, ovl.fmt.RXY.r1,
15287 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15288 ovl.fmt.RXY.dl2,
15289 ovl.fmt.RXY.dh2); goto ok;
15290 case 0xe300000000c3ULL: s390_format_RXY_RRRD(s390_irgen_STCH, ovl.fmt.RXY.r1,
15291 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15292 ovl.fmt.RXY.dl2,
15293 ovl.fmt.RXY.dh2); goto ok;
15294 case 0xe300000000c4ULL: s390_format_RXY_RRRD(s390_irgen_LHH, ovl.fmt.RXY.r1,
15295 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15296 ovl.fmt.RXY.dl2,
15297 ovl.fmt.RXY.dh2); goto ok;
15298 case 0xe300000000c6ULL: s390_format_RXY_RRRD(s390_irgen_LLHH, ovl.fmt.RXY.r1,
15299 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15300 ovl.fmt.RXY.dl2,
15301 ovl.fmt.RXY.dh2); goto ok;
15302 case 0xe300000000c7ULL: s390_format_RXY_RRRD(s390_irgen_STHH, ovl.fmt.RXY.r1,
15303 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15304 ovl.fmt.RXY.dl2,
15305 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015306 case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015307 case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1,
15308 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15309 ovl.fmt.RXY.dl2,
15310 ovl.fmt.RXY.dh2); goto ok;
15311 case 0xe300000000cbULL: s390_format_RXY_RRRD(s390_irgen_STFH, ovl.fmt.RXY.r1,
15312 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15313 ovl.fmt.RXY.dl2,
15314 ovl.fmt.RXY.dh2); goto ok;
15315 case 0xe300000000cdULL: s390_format_RXY_RRRD(s390_irgen_CHF, ovl.fmt.RXY.r1,
15316 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15317 ovl.fmt.RXY.dl2,
15318 ovl.fmt.RXY.dh2); goto ok;
15319 case 0xe300000000cfULL: s390_format_RXY_RRRD(s390_irgen_CLHF, ovl.fmt.RXY.r1,
15320 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15321 ovl.fmt.RXY.dl2,
15322 ovl.fmt.RXY.dh2); goto ok;
15323 case 0xeb0000000004ULL: s390_format_RSY_RRRD(s390_irgen_LMG, ovl.fmt.RSY.r1,
15324 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15325 ovl.fmt.RSY.dl2,
15326 ovl.fmt.RSY.dh2); goto ok;
15327 case 0xeb000000000aULL: s390_format_RSY_RRRD(s390_irgen_SRAG, ovl.fmt.RSY.r1,
15328 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15329 ovl.fmt.RSY.dl2,
15330 ovl.fmt.RSY.dh2); goto ok;
15331 case 0xeb000000000bULL: s390_format_RSY_RRRD(s390_irgen_SLAG, ovl.fmt.RSY.r1,
15332 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15333 ovl.fmt.RSY.dl2,
15334 ovl.fmt.RSY.dh2); goto ok;
15335 case 0xeb000000000cULL: s390_format_RSY_RRRD(s390_irgen_SRLG, ovl.fmt.RSY.r1,
15336 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15337 ovl.fmt.RSY.dl2,
15338 ovl.fmt.RSY.dh2); goto ok;
15339 case 0xeb000000000dULL: s390_format_RSY_RRRD(s390_irgen_SLLG, ovl.fmt.RSY.r1,
15340 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15341 ovl.fmt.RSY.dl2,
15342 ovl.fmt.RSY.dh2); goto ok;
15343 case 0xeb000000000fULL: /* TRACG */ goto unimplemented;
15344 case 0xeb0000000014ULL: s390_format_RSY_RRRD(s390_irgen_CSY, ovl.fmt.RSY.r1,
15345 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15346 ovl.fmt.RSY.dl2,
15347 ovl.fmt.RSY.dh2); goto ok;
15348 case 0xeb000000001cULL: s390_format_RSY_RRRD(s390_irgen_RLLG, ovl.fmt.RSY.r1,
15349 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15350 ovl.fmt.RSY.dl2,
15351 ovl.fmt.RSY.dh2); goto ok;
15352 case 0xeb000000001dULL: s390_format_RSY_RRRD(s390_irgen_RLL, ovl.fmt.RSY.r1,
15353 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15354 ovl.fmt.RSY.dl2,
15355 ovl.fmt.RSY.dh2); goto ok;
15356 case 0xeb0000000020ULL: s390_format_RSY_RURD(s390_irgen_CLMH, ovl.fmt.RSY.r1,
15357 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15358 ovl.fmt.RSY.dl2,
15359 ovl.fmt.RSY.dh2); goto ok;
15360 case 0xeb0000000021ULL: s390_format_RSY_RURD(s390_irgen_CLMY, ovl.fmt.RSY.r1,
15361 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15362 ovl.fmt.RSY.dl2,
15363 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015364 case 0xeb0000000023ULL: /* CLT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015365 case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1,
15366 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15367 ovl.fmt.RSY.dl2,
15368 ovl.fmt.RSY.dh2); goto ok;
15369 case 0xeb0000000025ULL: /* STCTG */ goto unimplemented;
15370 case 0xeb0000000026ULL: s390_format_RSY_RRRD(s390_irgen_STMH, ovl.fmt.RSY.r1,
15371 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15372 ovl.fmt.RSY.dl2,
15373 ovl.fmt.RSY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015374 case 0xeb000000002bULL: /* CLGT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015375 case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH,
15376 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15377 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15378 ovl.fmt.RSY.dh2); goto ok;
15379 case 0xeb000000002dULL: s390_format_RSY_RURD(s390_irgen_STCMY,
15380 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15381 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15382 ovl.fmt.RSY.dh2); goto ok;
15383 case 0xeb000000002fULL: /* LCTLG */ goto unimplemented;
15384 case 0xeb0000000030ULL: s390_format_RSY_RRRD(s390_irgen_CSG, ovl.fmt.RSY.r1,
15385 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15386 ovl.fmt.RSY.dl2,
15387 ovl.fmt.RSY.dh2); goto ok;
florian448cbba2012-06-06 02:26:01 +000015388 case 0xeb0000000031ULL: s390_format_RSY_RRRD(s390_irgen_CDSY, ovl.fmt.RSY.r1,
15389 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15390 ovl.fmt.RSY.dl2,
15391 ovl.fmt.RSY.dh2); goto ok;
15392 case 0xeb000000003eULL: s390_format_RSY_RRRD(s390_irgen_CDSG, ovl.fmt.RSY.r1,
15393 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15394 ovl.fmt.RSY.dl2,
15395 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015396 case 0xeb0000000044ULL: s390_format_RSY_RRRD(s390_irgen_BXHG, ovl.fmt.RSY.r1,
15397 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15398 ovl.fmt.RSY.dl2,
15399 ovl.fmt.RSY.dh2); goto ok;
15400 case 0xeb0000000045ULL: s390_format_RSY_RRRD(s390_irgen_BXLEG,
15401 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15402 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15403 ovl.fmt.RSY.dh2); goto ok;
florian8c88cb62012-08-26 18:58:13 +000015404 case 0xeb000000004cULL: s390_format_RSY_RRRD(s390_irgen_ECAG, ovl.fmt.RSY.r1,
15405 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15406 ovl.fmt.RSY.dl2,
15407 ovl.fmt.RSY.dh2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015408 case 0xeb0000000051ULL: s390_format_SIY_URD(s390_irgen_TMY, ovl.fmt.SIY.i2,
15409 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15410 ovl.fmt.SIY.dh1); goto ok;
15411 case 0xeb0000000052ULL: s390_format_SIY_URD(s390_irgen_MVIY, ovl.fmt.SIY.i2,
15412 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15413 ovl.fmt.SIY.dh1); goto ok;
15414 case 0xeb0000000054ULL: s390_format_SIY_URD(s390_irgen_NIY, ovl.fmt.SIY.i2,
15415 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15416 ovl.fmt.SIY.dh1); goto ok;
15417 case 0xeb0000000055ULL: s390_format_SIY_URD(s390_irgen_CLIY, ovl.fmt.SIY.i2,
15418 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15419 ovl.fmt.SIY.dh1); goto ok;
15420 case 0xeb0000000056ULL: s390_format_SIY_URD(s390_irgen_OIY, ovl.fmt.SIY.i2,
15421 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15422 ovl.fmt.SIY.dh1); goto ok;
15423 case 0xeb0000000057ULL: s390_format_SIY_URD(s390_irgen_XIY, ovl.fmt.SIY.i2,
15424 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15425 ovl.fmt.SIY.dh1); goto ok;
15426 case 0xeb000000006aULL: s390_format_SIY_IRD(s390_irgen_ASI, ovl.fmt.SIY.i2,
15427 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15428 ovl.fmt.SIY.dh1); goto ok;
15429 case 0xeb000000006eULL: s390_format_SIY_IRD(s390_irgen_ALSI, ovl.fmt.SIY.i2,
15430 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15431 ovl.fmt.SIY.dh1); goto ok;
15432 case 0xeb000000007aULL: s390_format_SIY_IRD(s390_irgen_AGSI, ovl.fmt.SIY.i2,
15433 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15434 ovl.fmt.SIY.dh1); goto ok;
15435 case 0xeb000000007eULL: s390_format_SIY_IRD(s390_irgen_ALGSI, ovl.fmt.SIY.i2,
15436 ovl.fmt.SIY.b1, ovl.fmt.SIY.dl1,
15437 ovl.fmt.SIY.dh1); goto ok;
15438 case 0xeb0000000080ULL: s390_format_RSY_RURD(s390_irgen_ICMH, ovl.fmt.RSY.r1,
15439 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15440 ovl.fmt.RSY.dl2,
15441 ovl.fmt.RSY.dh2); goto ok;
15442 case 0xeb0000000081ULL: s390_format_RSY_RURD(s390_irgen_ICMY, ovl.fmt.RSY.r1,
15443 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15444 ovl.fmt.RSY.dl2,
15445 ovl.fmt.RSY.dh2); goto ok;
15446 case 0xeb000000008eULL: /* MVCLU */ goto unimplemented;
15447 case 0xeb000000008fULL: /* CLCLU */ goto unimplemented;
15448 case 0xeb0000000090ULL: s390_format_RSY_RRRD(s390_irgen_STMY, ovl.fmt.RSY.r1,
15449 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15450 ovl.fmt.RSY.dl2,
15451 ovl.fmt.RSY.dh2); goto ok;
15452 case 0xeb0000000096ULL: s390_format_RSY_RRRD(s390_irgen_LMH, ovl.fmt.RSY.r1,
15453 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15454 ovl.fmt.RSY.dl2,
15455 ovl.fmt.RSY.dh2); goto ok;
15456 case 0xeb0000000098ULL: s390_format_RSY_RRRD(s390_irgen_LMY, ovl.fmt.RSY.r1,
15457 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15458 ovl.fmt.RSY.dl2,
15459 ovl.fmt.RSY.dh2); goto ok;
15460 case 0xeb000000009aULL: s390_format_RSY_AARD(s390_irgen_LAMY, ovl.fmt.RSY.r1,
15461 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15462 ovl.fmt.RSY.dl2,
15463 ovl.fmt.RSY.dh2); goto ok;
15464 case 0xeb000000009bULL: s390_format_RSY_AARD(s390_irgen_STAMY,
15465 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15466 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15467 ovl.fmt.RSY.dh2); goto ok;
15468 case 0xeb00000000c0ULL: /* TP */ goto unimplemented;
15469 case 0xeb00000000dcULL: s390_format_RSY_RRRD(s390_irgen_SRAK, ovl.fmt.RSY.r1,
15470 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15471 ovl.fmt.RSY.dl2,
15472 ovl.fmt.RSY.dh2); goto ok;
15473 case 0xeb00000000ddULL: s390_format_RSY_RRRD(s390_irgen_SLAK, ovl.fmt.RSY.r1,
15474 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15475 ovl.fmt.RSY.dl2,
15476 ovl.fmt.RSY.dh2); goto ok;
15477 case 0xeb00000000deULL: s390_format_RSY_RRRD(s390_irgen_SRLK, ovl.fmt.RSY.r1,
15478 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15479 ovl.fmt.RSY.dl2,
15480 ovl.fmt.RSY.dh2); goto ok;
15481 case 0xeb00000000dfULL: s390_format_RSY_RRRD(s390_irgen_SLLK, ovl.fmt.RSY.r1,
15482 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15483 ovl.fmt.RSY.dl2,
15484 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015485 case 0xeb00000000e2ULL: s390_format_RSY_RDRM(s390_irgen_LOCG, ovl.fmt.RSY.r1,
15486 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15487 ovl.fmt.RSY.dl2,
15488 ovl.fmt.RSY.dh2,
15489 S390_XMNM_LOCG); goto ok;
15490 case 0xeb00000000e3ULL: s390_format_RSY_RDRM(s390_irgen_STOCG,
15491 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15492 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15493 ovl.fmt.RSY.dh2,
15494 S390_XMNM_STOCG); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015495 case 0xeb00000000e4ULL: s390_format_RSY_RRRD(s390_irgen_LANG, ovl.fmt.RSY.r1,
15496 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15497 ovl.fmt.RSY.dl2,
15498 ovl.fmt.RSY.dh2); goto ok;
15499 case 0xeb00000000e6ULL: s390_format_RSY_RRRD(s390_irgen_LAOG, ovl.fmt.RSY.r1,
15500 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15501 ovl.fmt.RSY.dl2,
15502 ovl.fmt.RSY.dh2); goto ok;
15503 case 0xeb00000000e7ULL: s390_format_RSY_RRRD(s390_irgen_LAXG, ovl.fmt.RSY.r1,
15504 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15505 ovl.fmt.RSY.dl2,
15506 ovl.fmt.RSY.dh2); goto ok;
15507 case 0xeb00000000e8ULL: s390_format_RSY_RRRD(s390_irgen_LAAG, ovl.fmt.RSY.r1,
15508 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15509 ovl.fmt.RSY.dl2,
15510 ovl.fmt.RSY.dh2); goto ok;
15511 case 0xeb00000000eaULL: s390_format_RSY_RRRD(s390_irgen_LAALG,
15512 ovl.fmt.RSY.r1, ovl.fmt.RSY.r3,
15513 ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2,
15514 ovl.fmt.RSY.dh2); goto ok;
sewardjd7bde722011-04-05 13:19:33 +000015515 case 0xeb00000000f2ULL: s390_format_RSY_RDRM(s390_irgen_LOC, ovl.fmt.RSY.r1,
15516 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15517 ovl.fmt.RSY.dl2,
15518 ovl.fmt.RSY.dh2, S390_XMNM_LOC);
15519 goto ok;
15520 case 0xeb00000000f3ULL: s390_format_RSY_RDRM(s390_irgen_STOC, ovl.fmt.RSY.r1,
15521 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15522 ovl.fmt.RSY.dl2,
15523 ovl.fmt.RSY.dh2,
15524 S390_XMNM_STOC); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015525 case 0xeb00000000f4ULL: s390_format_RSY_RRRD(s390_irgen_LAN, ovl.fmt.RSY.r1,
15526 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15527 ovl.fmt.RSY.dl2,
15528 ovl.fmt.RSY.dh2); goto ok;
15529 case 0xeb00000000f6ULL: s390_format_RSY_RRRD(s390_irgen_LAO, ovl.fmt.RSY.r1,
15530 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15531 ovl.fmt.RSY.dl2,
15532 ovl.fmt.RSY.dh2); goto ok;
15533 case 0xeb00000000f7ULL: s390_format_RSY_RRRD(s390_irgen_LAX, ovl.fmt.RSY.r1,
15534 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15535 ovl.fmt.RSY.dl2,
15536 ovl.fmt.RSY.dh2); goto ok;
15537 case 0xeb00000000f8ULL: s390_format_RSY_RRRD(s390_irgen_LAA, ovl.fmt.RSY.r1,
15538 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15539 ovl.fmt.RSY.dl2,
15540 ovl.fmt.RSY.dh2); goto ok;
15541 case 0xeb00000000faULL: s390_format_RSY_RRRD(s390_irgen_LAAL, ovl.fmt.RSY.r1,
15542 ovl.fmt.RSY.r3, ovl.fmt.RSY.b2,
15543 ovl.fmt.RSY.dl2,
15544 ovl.fmt.RSY.dh2); goto ok;
15545 case 0xec0000000044ULL: s390_format_RIE_RRP(s390_irgen_BRXHG, ovl.fmt.RIE.r1,
15546 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15547 goto ok;
15548 case 0xec0000000045ULL: s390_format_RIE_RRP(s390_irgen_BRXLG, ovl.fmt.RIE.r1,
15549 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15550 goto ok;
15551 case 0xec0000000051ULL: /* RISBLG */ goto unimplemented;
15552 case 0xec0000000054ULL: s390_format_RIE_RRUUU(s390_irgen_RNSBG,
15553 ovl.fmt.RIE_RRUUU.r1,
15554 ovl.fmt.RIE_RRUUU.r2,
15555 ovl.fmt.RIE_RRUUU.i3,
15556 ovl.fmt.RIE_RRUUU.i4,
15557 ovl.fmt.RIE_RRUUU.i5);
15558 goto ok;
15559 case 0xec0000000055ULL: s390_format_RIE_RRUUU(s390_irgen_RISBG,
15560 ovl.fmt.RIE_RRUUU.r1,
15561 ovl.fmt.RIE_RRUUU.r2,
15562 ovl.fmt.RIE_RRUUU.i3,
15563 ovl.fmt.RIE_RRUUU.i4,
15564 ovl.fmt.RIE_RRUUU.i5);
15565 goto ok;
15566 case 0xec0000000056ULL: s390_format_RIE_RRUUU(s390_irgen_ROSBG,
15567 ovl.fmt.RIE_RRUUU.r1,
15568 ovl.fmt.RIE_RRUUU.r2,
15569 ovl.fmt.RIE_RRUUU.i3,
15570 ovl.fmt.RIE_RRUUU.i4,
15571 ovl.fmt.RIE_RRUUU.i5);
15572 goto ok;
15573 case 0xec0000000057ULL: s390_format_RIE_RRUUU(s390_irgen_RXSBG,
15574 ovl.fmt.RIE_RRUUU.r1,
15575 ovl.fmt.RIE_RRUUU.r2,
15576 ovl.fmt.RIE_RRUUU.i3,
15577 ovl.fmt.RIE_RRUUU.i4,
15578 ovl.fmt.RIE_RRUUU.i5);
15579 goto ok;
florian2289cd42012-12-05 04:23:42 +000015580 case 0xec0000000059ULL: /* RISBGN */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015581 case 0xec000000005dULL: /* RISBHG */ goto unimplemented;
15582 case 0xec0000000064ULL: s390_format_RIE_RRPU(s390_irgen_CGRJ,
15583 ovl.fmt.RIE_RRPU.r1,
15584 ovl.fmt.RIE_RRPU.r2,
15585 ovl.fmt.RIE_RRPU.i4,
15586 ovl.fmt.RIE_RRPU.m3); goto ok;
15587 case 0xec0000000065ULL: s390_format_RIE_RRPU(s390_irgen_CLGRJ,
15588 ovl.fmt.RIE_RRPU.r1,
15589 ovl.fmt.RIE_RRPU.r2,
15590 ovl.fmt.RIE_RRPU.i4,
15591 ovl.fmt.RIE_RRPU.m3); goto ok;
15592 case 0xec0000000070ULL: /* CGIT */ goto unimplemented;
15593 case 0xec0000000071ULL: /* CLGIT */ goto unimplemented;
15594 case 0xec0000000072ULL: /* CIT */ goto unimplemented;
15595 case 0xec0000000073ULL: /* CLFIT */ goto unimplemented;
15596 case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ,
15597 ovl.fmt.RIE_RRPU.r1,
15598 ovl.fmt.RIE_RRPU.r2,
15599 ovl.fmt.RIE_RRPU.i4,
15600 ovl.fmt.RIE_RRPU.m3); goto ok;
15601 case 0xec0000000077ULL: s390_format_RIE_RRPU(s390_irgen_CLRJ,
15602 ovl.fmt.RIE_RRPU.r1,
15603 ovl.fmt.RIE_RRPU.r2,
15604 ovl.fmt.RIE_RRPU.i4,
15605 ovl.fmt.RIE_RRPU.m3); goto ok;
15606 case 0xec000000007cULL: s390_format_RIE_RUPI(s390_irgen_CGIJ,
15607 ovl.fmt.RIEv3.r1,
15608 ovl.fmt.RIEv3.m3,
15609 ovl.fmt.RIEv3.i4,
15610 ovl.fmt.RIEv3.i2); goto ok;
15611 case 0xec000000007dULL: s390_format_RIE_RUPU(s390_irgen_CLGIJ,
15612 ovl.fmt.RIEv3.r1,
15613 ovl.fmt.RIEv3.m3,
15614 ovl.fmt.RIEv3.i4,
15615 ovl.fmt.RIEv3.i2); goto ok;
15616 case 0xec000000007eULL: s390_format_RIE_RUPI(s390_irgen_CIJ,
15617 ovl.fmt.RIEv3.r1,
15618 ovl.fmt.RIEv3.m3,
15619 ovl.fmt.RIEv3.i4,
15620 ovl.fmt.RIEv3.i2); goto ok;
15621 case 0xec000000007fULL: s390_format_RIE_RUPU(s390_irgen_CLIJ,
15622 ovl.fmt.RIEv3.r1,
15623 ovl.fmt.RIEv3.m3,
15624 ovl.fmt.RIEv3.i4,
15625 ovl.fmt.RIEv3.i2); goto ok;
15626 case 0xec00000000d8ULL: s390_format_RIE_RRI0(s390_irgen_AHIK, ovl.fmt.RIE.r1,
15627 ovl.fmt.RIE.r3, ovl.fmt.RIE.i2);
15628 goto ok;
15629 case 0xec00000000d9ULL: s390_format_RIE_RRI0(s390_irgen_AGHIK,
15630 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15631 ovl.fmt.RIE.i2); goto ok;
15632 case 0xec00000000daULL: s390_format_RIE_RRI0(s390_irgen_ALHSIK,
15633 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15634 ovl.fmt.RIE.i2); goto ok;
15635 case 0xec00000000dbULL: s390_format_RIE_RRI0(s390_irgen_ALGHSIK,
15636 ovl.fmt.RIE.r1, ovl.fmt.RIE.r3,
15637 ovl.fmt.RIE.i2); goto ok;
15638 case 0xec00000000e4ULL: s390_format_RRS(s390_irgen_CGRB, ovl.fmt.RRS.r1,
15639 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15640 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15641 goto ok;
15642 case 0xec00000000e5ULL: s390_format_RRS(s390_irgen_CLGRB, ovl.fmt.RRS.r1,
15643 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15644 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15645 goto ok;
15646 case 0xec00000000f6ULL: s390_format_RRS(s390_irgen_CRB, ovl.fmt.RRS.r1,
15647 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15648 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15649 goto ok;
15650 case 0xec00000000f7ULL: s390_format_RRS(s390_irgen_CLRB, ovl.fmt.RRS.r1,
15651 ovl.fmt.RRS.r2, ovl.fmt.RRS.b4,
15652 ovl.fmt.RRS.d4, ovl.fmt.RRS.m3);
15653 goto ok;
15654 case 0xec00000000fcULL: s390_format_RIS_RURDI(s390_irgen_CGIB,
15655 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15656 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15657 ovl.fmt.RIS.i2); goto ok;
15658 case 0xec00000000fdULL: s390_format_RIS_RURDU(s390_irgen_CLGIB,
15659 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15660 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15661 ovl.fmt.RIS.i2); goto ok;
15662 case 0xec00000000feULL: s390_format_RIS_RURDI(s390_irgen_CIB, ovl.fmt.RIS.r1,
15663 ovl.fmt.RIS.m3, ovl.fmt.RIS.b4,
15664 ovl.fmt.RIS.d4,
15665 ovl.fmt.RIS.i2); goto ok;
15666 case 0xec00000000ffULL: s390_format_RIS_RURDU(s390_irgen_CLIB,
15667 ovl.fmt.RIS.r1, ovl.fmt.RIS.m3,
15668 ovl.fmt.RIS.b4, ovl.fmt.RIS.d4,
15669 ovl.fmt.RIS.i2); goto ok;
15670 case 0xed0000000004ULL: s390_format_RXE_FRRD(s390_irgen_LDEB, ovl.fmt.RXE.r1,
15671 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15672 ovl.fmt.RXE.d2); goto ok;
15673 case 0xed0000000005ULL: s390_format_RXE_FRRD(s390_irgen_LXDB, ovl.fmt.RXE.r1,
15674 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15675 ovl.fmt.RXE.d2); goto ok;
15676 case 0xed0000000006ULL: s390_format_RXE_FRRD(s390_irgen_LXEB, ovl.fmt.RXE.r1,
15677 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15678 ovl.fmt.RXE.d2); goto ok;
15679 case 0xed0000000007ULL: /* MXDB */ goto unimplemented;
15680 case 0xed0000000008ULL: /* KEB */ goto unimplemented;
15681 case 0xed0000000009ULL: s390_format_RXE_FRRD(s390_irgen_CEB, ovl.fmt.RXE.r1,
15682 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15683 ovl.fmt.RXE.d2); goto ok;
15684 case 0xed000000000aULL: s390_format_RXE_FRRD(s390_irgen_AEB, ovl.fmt.RXE.r1,
15685 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15686 ovl.fmt.RXE.d2); goto ok;
15687 case 0xed000000000bULL: s390_format_RXE_FRRD(s390_irgen_SEB, ovl.fmt.RXE.r1,
15688 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15689 ovl.fmt.RXE.d2); goto ok;
15690 case 0xed000000000cULL: /* MDEB */ goto unimplemented;
15691 case 0xed000000000dULL: s390_format_RXE_FRRD(s390_irgen_DEB, ovl.fmt.RXE.r1,
15692 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15693 ovl.fmt.RXE.d2); goto ok;
15694 case 0xed000000000eULL: s390_format_RXF_FRRDF(s390_irgen_MAEB,
15695 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15696 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15697 ovl.fmt.RXF.r1); goto ok;
15698 case 0xed000000000fULL: s390_format_RXF_FRRDF(s390_irgen_MSEB,
15699 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15700 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15701 ovl.fmt.RXF.r1); goto ok;
15702 case 0xed0000000010ULL: s390_format_RXE_FRRD(s390_irgen_TCEB, ovl.fmt.RXE.r1,
15703 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15704 ovl.fmt.RXE.d2); goto ok;
15705 case 0xed0000000011ULL: s390_format_RXE_FRRD(s390_irgen_TCDB, ovl.fmt.RXE.r1,
15706 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15707 ovl.fmt.RXE.d2); goto ok;
15708 case 0xed0000000012ULL: s390_format_RXE_FRRD(s390_irgen_TCXB, ovl.fmt.RXE.r1,
15709 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15710 ovl.fmt.RXE.d2); goto ok;
15711 case 0xed0000000014ULL: s390_format_RXE_FRRD(s390_irgen_SQEB, ovl.fmt.RXE.r1,
15712 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15713 ovl.fmt.RXE.d2); goto ok;
15714 case 0xed0000000015ULL: s390_format_RXE_FRRD(s390_irgen_SQDB, ovl.fmt.RXE.r1,
15715 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15716 ovl.fmt.RXE.d2); goto ok;
15717 case 0xed0000000017ULL: s390_format_RXE_FRRD(s390_irgen_MEEB, ovl.fmt.RXE.r1,
15718 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15719 ovl.fmt.RXE.d2); goto ok;
15720 case 0xed0000000018ULL: /* KDB */ goto unimplemented;
15721 case 0xed0000000019ULL: s390_format_RXE_FRRD(s390_irgen_CDB, ovl.fmt.RXE.r1,
15722 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15723 ovl.fmt.RXE.d2); goto ok;
15724 case 0xed000000001aULL: s390_format_RXE_FRRD(s390_irgen_ADB, ovl.fmt.RXE.r1,
15725 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15726 ovl.fmt.RXE.d2); goto ok;
15727 case 0xed000000001bULL: s390_format_RXE_FRRD(s390_irgen_SDB, ovl.fmt.RXE.r1,
15728 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15729 ovl.fmt.RXE.d2); goto ok;
15730 case 0xed000000001cULL: s390_format_RXE_FRRD(s390_irgen_MDB, ovl.fmt.RXE.r1,
15731 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15732 ovl.fmt.RXE.d2); goto ok;
15733 case 0xed000000001dULL: s390_format_RXE_FRRD(s390_irgen_DDB, ovl.fmt.RXE.r1,
15734 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15735 ovl.fmt.RXE.d2); goto ok;
15736 case 0xed000000001eULL: s390_format_RXF_FRRDF(s390_irgen_MADB,
15737 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15738 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15739 ovl.fmt.RXF.r1); goto ok;
15740 case 0xed000000001fULL: s390_format_RXF_FRRDF(s390_irgen_MSDB,
15741 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15742 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15743 ovl.fmt.RXF.r1); goto ok;
15744 case 0xed0000000024ULL: /* LDE */ goto unimplemented;
15745 case 0xed0000000025ULL: /* LXD */ goto unimplemented;
15746 case 0xed0000000026ULL: /* LXE */ goto unimplemented;
15747 case 0xed000000002eULL: /* MAE */ goto unimplemented;
15748 case 0xed000000002fULL: /* MSE */ goto unimplemented;
15749 case 0xed0000000034ULL: /* SQE */ goto unimplemented;
15750 case 0xed0000000035ULL: /* SQD */ goto unimplemented;
15751 case 0xed0000000037ULL: /* MEE */ goto unimplemented;
15752 case 0xed0000000038ULL: /* MAYL */ goto unimplemented;
15753 case 0xed0000000039ULL: /* MYL */ goto unimplemented;
15754 case 0xed000000003aULL: /* MAY */ goto unimplemented;
15755 case 0xed000000003bULL: /* MY */ goto unimplemented;
15756 case 0xed000000003cULL: /* MAYH */ goto unimplemented;
15757 case 0xed000000003dULL: /* MYH */ goto unimplemented;
15758 case 0xed000000003eULL: /* MAD */ goto unimplemented;
15759 case 0xed000000003fULL: /* MSD */ goto unimplemented;
florian1b901d42013-01-01 22:19:24 +000015760 case 0xed0000000040ULL: s390_format_RXF_FRRDF(s390_irgen_SLDT,
15761 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15762 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15763 ovl.fmt.RXF.r1); goto ok;
15764 case 0xed0000000041ULL: s390_format_RXF_FRRDF(s390_irgen_SRDT,
15765 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15766 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15767 ovl.fmt.RXF.r1); goto ok;
15768 case 0xed0000000048ULL: s390_format_RXF_FRRDF(s390_irgen_SLXT,
15769 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15770 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15771 ovl.fmt.RXF.r1); goto ok;
15772 case 0xed0000000049ULL: s390_format_RXF_FRRDF(s390_irgen_SRXT,
15773 ovl.fmt.RXF.r3, ovl.fmt.RXF.x2,
15774 ovl.fmt.RXF.b2, ovl.fmt.RXF.d2,
15775 ovl.fmt.RXF.r1); goto ok;
floriance9e3db2012-12-27 20:14:03 +000015776 case 0xed0000000050ULL: s390_format_RXE_FRRD(s390_irgen_TDCET, ovl.fmt.RXE.r1,
15777 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15778 ovl.fmt.RXE.d2); goto ok;
15779 case 0xed0000000051ULL: s390_format_RXE_FRRD(s390_irgen_TDGET, ovl.fmt.RXE.r1,
15780 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15781 ovl.fmt.RXE.d2); goto ok;
15782 case 0xed0000000054ULL: s390_format_RXE_FRRD(s390_irgen_TDCDT, ovl.fmt.RXE.r1,
15783 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15784 ovl.fmt.RXE.d2); goto ok;
15785 case 0xed0000000055ULL: s390_format_RXE_FRRD(s390_irgen_TDGDT, ovl.fmt.RXE.r1,
15786 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15787 ovl.fmt.RXE.d2); goto ok;
15788 case 0xed0000000058ULL: s390_format_RXE_FRRD(s390_irgen_TDCXT, ovl.fmt.RXE.r1,
15789 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15790 ovl.fmt.RXE.d2); goto ok;
15791 case 0xed0000000059ULL: s390_format_RXE_FRRD(s390_irgen_TDGXT, ovl.fmt.RXE.r1,
15792 ovl.fmt.RXE.x2, ovl.fmt.RXE.b2,
15793 ovl.fmt.RXE.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015794 case 0xed0000000064ULL: s390_format_RXY_FRRD(s390_irgen_LEY, ovl.fmt.RXY.r1,
15795 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15796 ovl.fmt.RXY.dl2,
15797 ovl.fmt.RXY.dh2); goto ok;
15798 case 0xed0000000065ULL: s390_format_RXY_FRRD(s390_irgen_LDY, ovl.fmt.RXY.r1,
15799 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15800 ovl.fmt.RXY.dl2,
15801 ovl.fmt.RXY.dh2); goto ok;
15802 case 0xed0000000066ULL: s390_format_RXY_FRRD(s390_irgen_STEY, ovl.fmt.RXY.r1,
15803 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15804 ovl.fmt.RXY.dl2,
15805 ovl.fmt.RXY.dh2); goto ok;
15806 case 0xed0000000067ULL: s390_format_RXY_FRRD(s390_irgen_STDY, ovl.fmt.RXY.r1,
15807 ovl.fmt.RXY.x2, ovl.fmt.RXY.b2,
15808 ovl.fmt.RXY.dl2,
15809 ovl.fmt.RXY.dh2); goto ok;
florian2289cd42012-12-05 04:23:42 +000015810 case 0xed00000000a8ULL: /* CZDT */ goto unimplemented;
15811 case 0xed00000000a9ULL: /* CZXT */ goto unimplemented;
15812 case 0xed00000000aaULL: /* CDZT */ goto unimplemented;
15813 case 0xed00000000abULL: /* CXZT */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015814 }
15815
15816 switch (((ovl.value >> 16) & 0xff0f00000000ULL) >> 32) {
15817 case 0xc000ULL: s390_format_RIL_RP(s390_irgen_LARL, ovl.fmt.RIL.r1,
15818 ovl.fmt.RIL.i2); goto ok;
15819 case 0xc001ULL: s390_format_RIL_RI(s390_irgen_LGFI, ovl.fmt.RIL.r1,
15820 ovl.fmt.RIL.i2); goto ok;
15821 case 0xc004ULL: s390_format_RIL(s390_irgen_BRCL, ovl.fmt.RIL.r1,
15822 ovl.fmt.RIL.i2); goto ok;
15823 case 0xc005ULL: s390_format_RIL_RP(s390_irgen_BRASL, ovl.fmt.RIL.r1,
15824 ovl.fmt.RIL.i2); goto ok;
15825 case 0xc006ULL: s390_format_RIL_RU(s390_irgen_XIHF, ovl.fmt.RIL.r1,
15826 ovl.fmt.RIL.i2); goto ok;
15827 case 0xc007ULL: s390_format_RIL_RU(s390_irgen_XILF, ovl.fmt.RIL.r1,
15828 ovl.fmt.RIL.i2); goto ok;
15829 case 0xc008ULL: s390_format_RIL_RU(s390_irgen_IIHF, ovl.fmt.RIL.r1,
15830 ovl.fmt.RIL.i2); goto ok;
15831 case 0xc009ULL: s390_format_RIL_RU(s390_irgen_IILF, ovl.fmt.RIL.r1,
15832 ovl.fmt.RIL.i2); goto ok;
15833 case 0xc00aULL: s390_format_RIL_RU(s390_irgen_NIHF, ovl.fmt.RIL.r1,
15834 ovl.fmt.RIL.i2); goto ok;
15835 case 0xc00bULL: s390_format_RIL_RU(s390_irgen_NILF, ovl.fmt.RIL.r1,
15836 ovl.fmt.RIL.i2); goto ok;
15837 case 0xc00cULL: s390_format_RIL_RU(s390_irgen_OIHF, ovl.fmt.RIL.r1,
15838 ovl.fmt.RIL.i2); goto ok;
15839 case 0xc00dULL: s390_format_RIL_RU(s390_irgen_OILF, ovl.fmt.RIL.r1,
15840 ovl.fmt.RIL.i2); goto ok;
15841 case 0xc00eULL: s390_format_RIL_RU(s390_irgen_LLIHF, ovl.fmt.RIL.r1,
15842 ovl.fmt.RIL.i2); goto ok;
15843 case 0xc00fULL: s390_format_RIL_RU(s390_irgen_LLILF, ovl.fmt.RIL.r1,
15844 ovl.fmt.RIL.i2); goto ok;
15845 case 0xc200ULL: s390_format_RIL_RI(s390_irgen_MSGFI, ovl.fmt.RIL.r1,
15846 ovl.fmt.RIL.i2); goto ok;
15847 case 0xc201ULL: s390_format_RIL_RI(s390_irgen_MSFI, ovl.fmt.RIL.r1,
15848 ovl.fmt.RIL.i2); goto ok;
15849 case 0xc204ULL: s390_format_RIL_RU(s390_irgen_SLGFI, ovl.fmt.RIL.r1,
15850 ovl.fmt.RIL.i2); goto ok;
15851 case 0xc205ULL: s390_format_RIL_RU(s390_irgen_SLFI, ovl.fmt.RIL.r1,
15852 ovl.fmt.RIL.i2); goto ok;
15853 case 0xc208ULL: s390_format_RIL_RI(s390_irgen_AGFI, ovl.fmt.RIL.r1,
15854 ovl.fmt.RIL.i2); goto ok;
15855 case 0xc209ULL: s390_format_RIL_RI(s390_irgen_AFI, ovl.fmt.RIL.r1,
15856 ovl.fmt.RIL.i2); goto ok;
15857 case 0xc20aULL: s390_format_RIL_RU(s390_irgen_ALGFI, ovl.fmt.RIL.r1,
15858 ovl.fmt.RIL.i2); goto ok;
15859 case 0xc20bULL: s390_format_RIL_RU(s390_irgen_ALFI, ovl.fmt.RIL.r1,
15860 ovl.fmt.RIL.i2); goto ok;
15861 case 0xc20cULL: s390_format_RIL_RI(s390_irgen_CGFI, ovl.fmt.RIL.r1,
15862 ovl.fmt.RIL.i2); goto ok;
15863 case 0xc20dULL: s390_format_RIL_RI(s390_irgen_CFI, ovl.fmt.RIL.r1,
15864 ovl.fmt.RIL.i2); goto ok;
15865 case 0xc20eULL: s390_format_RIL_RU(s390_irgen_CLGFI, ovl.fmt.RIL.r1,
15866 ovl.fmt.RIL.i2); goto ok;
15867 case 0xc20fULL: s390_format_RIL_RU(s390_irgen_CLFI, ovl.fmt.RIL.r1,
15868 ovl.fmt.RIL.i2); goto ok;
15869 case 0xc402ULL: s390_format_RIL_RP(s390_irgen_LLHRL, ovl.fmt.RIL.r1,
15870 ovl.fmt.RIL.i2); goto ok;
15871 case 0xc404ULL: s390_format_RIL_RP(s390_irgen_LGHRL, ovl.fmt.RIL.r1,
15872 ovl.fmt.RIL.i2); goto ok;
15873 case 0xc405ULL: s390_format_RIL_RP(s390_irgen_LHRL, ovl.fmt.RIL.r1,
15874 ovl.fmt.RIL.i2); goto ok;
15875 case 0xc406ULL: s390_format_RIL_RP(s390_irgen_LLGHRL, ovl.fmt.RIL.r1,
15876 ovl.fmt.RIL.i2); goto ok;
15877 case 0xc407ULL: s390_format_RIL_RP(s390_irgen_STHRL, ovl.fmt.RIL.r1,
15878 ovl.fmt.RIL.i2); goto ok;
15879 case 0xc408ULL: s390_format_RIL_RP(s390_irgen_LGRL, ovl.fmt.RIL.r1,
15880 ovl.fmt.RIL.i2); goto ok;
15881 case 0xc40bULL: s390_format_RIL_RP(s390_irgen_STGRL, ovl.fmt.RIL.r1,
15882 ovl.fmt.RIL.i2); goto ok;
15883 case 0xc40cULL: s390_format_RIL_RP(s390_irgen_LGFRL, ovl.fmt.RIL.r1,
15884 ovl.fmt.RIL.i2); goto ok;
15885 case 0xc40dULL: s390_format_RIL_RP(s390_irgen_LRL, ovl.fmt.RIL.r1,
15886 ovl.fmt.RIL.i2); goto ok;
15887 case 0xc40eULL: s390_format_RIL_RP(s390_irgen_LLGFRL, ovl.fmt.RIL.r1,
15888 ovl.fmt.RIL.i2); goto ok;
15889 case 0xc40fULL: s390_format_RIL_RP(s390_irgen_STRL, ovl.fmt.RIL.r1,
15890 ovl.fmt.RIL.i2); goto ok;
15891 case 0xc600ULL: s390_format_RIL_RP(s390_irgen_EXRL, ovl.fmt.RIL.r1,
15892 ovl.fmt.RIL.i2); goto ok;
15893 case 0xc602ULL: s390_format_RIL_UP(s390_irgen_PFDRL, ovl.fmt.RIL.r1,
15894 ovl.fmt.RIL.i2); goto ok;
15895 case 0xc604ULL: s390_format_RIL_RP(s390_irgen_CGHRL, ovl.fmt.RIL.r1,
15896 ovl.fmt.RIL.i2); goto ok;
15897 case 0xc605ULL: s390_format_RIL_RP(s390_irgen_CHRL, ovl.fmt.RIL.r1,
15898 ovl.fmt.RIL.i2); goto ok;
15899 case 0xc606ULL: s390_format_RIL_RP(s390_irgen_CLGHRL, ovl.fmt.RIL.r1,
15900 ovl.fmt.RIL.i2); goto ok;
15901 case 0xc607ULL: s390_format_RIL_RP(s390_irgen_CLHRL, ovl.fmt.RIL.r1,
15902 ovl.fmt.RIL.i2); goto ok;
15903 case 0xc608ULL: s390_format_RIL_RP(s390_irgen_CGRL, ovl.fmt.RIL.r1,
15904 ovl.fmt.RIL.i2); goto ok;
15905 case 0xc60aULL: s390_format_RIL_RP(s390_irgen_CLGRL, ovl.fmt.RIL.r1,
15906 ovl.fmt.RIL.i2); goto ok;
15907 case 0xc60cULL: s390_format_RIL_RP(s390_irgen_CGFRL, ovl.fmt.RIL.r1,
15908 ovl.fmt.RIL.i2); goto ok;
15909 case 0xc60dULL: s390_format_RIL_RP(s390_irgen_CRL, ovl.fmt.RIL.r1,
15910 ovl.fmt.RIL.i2); goto ok;
15911 case 0xc60eULL: s390_format_RIL_RP(s390_irgen_CLGFRL, ovl.fmt.RIL.r1,
15912 ovl.fmt.RIL.i2); goto ok;
15913 case 0xc60fULL: s390_format_RIL_RP(s390_irgen_CLRL, ovl.fmt.RIL.r1,
15914 ovl.fmt.RIL.i2); goto ok;
15915 case 0xc800ULL: /* MVCOS */ goto unimplemented;
15916 case 0xc801ULL: /* ECTG */ goto unimplemented;
15917 case 0xc802ULL: /* CSST */ goto unimplemented;
15918 case 0xc804ULL: /* LPD */ goto unimplemented;
15919 case 0xc805ULL: /* LPDG */ goto unimplemented;
15920 case 0xcc06ULL: /* BRCTH */ goto unimplemented;
15921 case 0xcc08ULL: s390_format_RIL_RI(s390_irgen_AIH, ovl.fmt.RIL.r1,
15922 ovl.fmt.RIL.i2); goto ok;
15923 case 0xcc0aULL: s390_format_RIL_RI(s390_irgen_ALSIH, ovl.fmt.RIL.r1,
15924 ovl.fmt.RIL.i2); goto ok;
15925 case 0xcc0bULL: s390_format_RIL_RI(s390_irgen_ALSIHN, ovl.fmt.RIL.r1,
15926 ovl.fmt.RIL.i2); goto ok;
15927 case 0xcc0dULL: s390_format_RIL_RI(s390_irgen_CIH, ovl.fmt.RIL.r1,
15928 ovl.fmt.RIL.i2); goto ok;
15929 case 0xcc0fULL: s390_format_RIL_RU(s390_irgen_CLIH, ovl.fmt.RIL.r1,
15930 ovl.fmt.RIL.i2); goto ok;
15931 }
15932
15933 switch (((ovl.value >> 16) & 0xff0000000000ULL) >> 40) {
florian2289cd42012-12-05 04:23:42 +000015934 case 0xc5ULL: /* BPRP */ goto unimplemented;
15935 case 0xc7ULL: /* BPP */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000015936 case 0xd0ULL: /* TRTR */ goto unimplemented;
15937 case 0xd1ULL: /* MVN */ goto unimplemented;
15938 case 0xd2ULL: s390_format_SS_L0RDRD(s390_irgen_MVC, ovl.fmt.SS.l,
15939 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15940 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15941 case 0xd3ULL: /* MVZ */ goto unimplemented;
15942 case 0xd4ULL: s390_format_SS_L0RDRD(s390_irgen_NC, ovl.fmt.SS.l,
15943 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15944 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15945 case 0xd5ULL: s390_format_SS_L0RDRD(s390_irgen_CLC, ovl.fmt.SS.l,
15946 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15947 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
15948 case 0xd6ULL: s390_format_SS_L0RDRD(s390_irgen_OC, ovl.fmt.SS.l,
15949 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15950 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardjb63967e2011-03-24 08:50:04 +000015951 case 0xd7ULL:
15952 if (ovl.fmt.SS.b1 == ovl.fmt.SS.b2 && ovl.fmt.SS.d1 == ovl.fmt.SS.d2)
15953 s390_irgen_XC_sameloc(ovl.fmt.SS.l, ovl.fmt.SS.b1, ovl.fmt.SS.d1);
15954 else
15955 s390_format_SS_L0RDRD(s390_irgen_XC, ovl.fmt.SS.l,
15956 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15957 ovl.fmt.SS.b2, ovl.fmt.SS.d2);
15958 goto ok;
sewardj2019a972011-03-07 16:04:07 +000015959 case 0xd9ULL: /* MVCK */ goto unimplemented;
15960 case 0xdaULL: /* MVCP */ goto unimplemented;
15961 case 0xdbULL: /* MVCS */ goto unimplemented;
florian730448f2012-02-04 17:07:07 +000015962 case 0xdcULL: s390_format_SS_L0RDRD(s390_irgen_TR, ovl.fmt.SS.l,
15963 ovl.fmt.SS.b1, ovl.fmt.SS.d1,
15964 ovl.fmt.SS.b2, ovl.fmt.SS.d2); goto ok;
sewardj2019a972011-03-07 16:04:07 +000015965 case 0xddULL: /* TRT */ goto unimplemented;
15966 case 0xdeULL: /* ED */ goto unimplemented;
15967 case 0xdfULL: /* EDMK */ goto unimplemented;
15968 case 0xe1ULL: /* PKU */ goto unimplemented;
15969 case 0xe2ULL: /* UNPKU */ goto unimplemented;
15970 case 0xe8ULL: /* MVCIN */ goto unimplemented;
15971 case 0xe9ULL: /* PKA */ goto unimplemented;
15972 case 0xeaULL: /* UNPKA */ goto unimplemented;
15973 case 0xeeULL: /* PLO */ goto unimplemented;
15974 case 0xefULL: /* LMD */ goto unimplemented;
15975 case 0xf0ULL: /* SRP */ goto unimplemented;
15976 case 0xf1ULL: /* MVO */ goto unimplemented;
15977 case 0xf2ULL: /* PACK */ goto unimplemented;
15978 case 0xf3ULL: /* UNPK */ goto unimplemented;
15979 case 0xf8ULL: /* ZAP */ goto unimplemented;
15980 case 0xf9ULL: /* CP */ goto unimplemented;
15981 case 0xfaULL: /* AP */ goto unimplemented;
15982 case 0xfbULL: /* SP */ goto unimplemented;
15983 case 0xfcULL: /* MP */ goto unimplemented;
15984 case 0xfdULL: /* DP */ goto unimplemented;
15985 }
15986
15987 switch (((ovl.value >> 16) & 0xffff00000000ULL) >> 32) {
15988 case 0xe500ULL: /* LASP */ goto unimplemented;
15989 case 0xe501ULL: /* TPROT */ goto unimplemented;
15990 case 0xe502ULL: /* STRAG */ goto unimplemented;
15991 case 0xe50eULL: /* MVCSK */ goto unimplemented;
15992 case 0xe50fULL: /* MVCDK */ goto unimplemented;
15993 case 0xe544ULL: s390_format_SIL_RDI(s390_irgen_MVHHI, ovl.fmt.SIL.b1,
15994 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15995 goto ok;
15996 case 0xe548ULL: s390_format_SIL_RDI(s390_irgen_MVGHI, ovl.fmt.SIL.b1,
15997 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
15998 goto ok;
15999 case 0xe54cULL: s390_format_SIL_RDI(s390_irgen_MVHI, ovl.fmt.SIL.b1,
16000 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16001 goto ok;
16002 case 0xe554ULL: s390_format_SIL_RDI(s390_irgen_CHHSI, ovl.fmt.SIL.b1,
16003 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16004 goto ok;
16005 case 0xe555ULL: s390_format_SIL_RDU(s390_irgen_CLHHSI, ovl.fmt.SIL.b1,
16006 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16007 goto ok;
16008 case 0xe558ULL: s390_format_SIL_RDI(s390_irgen_CGHSI, ovl.fmt.SIL.b1,
16009 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16010 goto ok;
16011 case 0xe559ULL: s390_format_SIL_RDU(s390_irgen_CLGHSI, ovl.fmt.SIL.b1,
16012 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16013 goto ok;
16014 case 0xe55cULL: s390_format_SIL_RDI(s390_irgen_CHSI, ovl.fmt.SIL.b1,
16015 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16016 goto ok;
16017 case 0xe55dULL: s390_format_SIL_RDU(s390_irgen_CLFHSI, ovl.fmt.SIL.b1,
16018 ovl.fmt.SIL.d1, ovl.fmt.SIL.i2);
16019 goto ok;
florian2289cd42012-12-05 04:23:42 +000016020 case 0xe560ULL: /* TBEGIN */ goto unimplemented;
16021 case 0xe561ULL: /* TBEGINC */ goto unimplemented;
sewardj2019a972011-03-07 16:04:07 +000016022 }
16023
16024 return S390_DECODE_UNKNOWN_INSN;
16025
16026ok:
16027 return S390_DECODE_OK;
16028
16029unimplemented:
16030 return S390_DECODE_UNIMPLEMENTED_INSN;
16031}
16032
16033/* Handle "special" instructions. */
16034static s390_decode_t
16035s390_decode_special_and_irgen(UChar *bytes)
16036{
16037 s390_decode_t status = S390_DECODE_OK;
16038
16039 /* Got a "Special" instruction preamble. Which one is it? */
16040 if (bytes[0] == 0x18 && bytes[1] == 0x22 /* lr %r2, %r2 */) {
16041 s390_irgen_client_request();
16042 } else if (bytes[0] == 0x18 && bytes[1] == 0x33 /* lr %r3, %r3 */) {
16043 s390_irgen_guest_NRADDR();
16044 } else if (bytes[0] == 0x18 && bytes[1] == 0x44 /* lr %r4, %r4 */) {
16045 s390_irgen_call_noredir();
florian2245ce92012-08-28 16:49:30 +000016046 } else if (bytes[0] == 0x18 && bytes[1] == 0x55 /* lr %r5, %r5 */) {
16047 vex_inject_ir(irsb, Iend_BE);
16048
16049 /* Invalidate the current insn. The reason is that the IRop we're
16050 injecting here can change. In which case the translation has to
16051 be redone. For ease of handling, we simply invalidate all the
16052 time. */
16053 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TISTART),
16054 mkU64(guest_IA_curr_instr)));
16055 stmt(IRStmt_Put(S390X_GUEST_OFFSET(guest_TILEN),
16056 mkU64(guest_IA_next_instr - guest_IA_curr_instr)));
16057 vassert(guest_IA_next_instr - guest_IA_curr_instr ==
16058 S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE);
16059
16060 put_IA(mkaddr_expr(guest_IA_next_instr));
16061 dis_res->whatNext = Dis_StopHere;
16062 dis_res->jk_StopHere = Ijk_TInval;
sewardj2019a972011-03-07 16:04:07 +000016063 } else {
16064 /* We don't know what it is. */
16065 return S390_DECODE_UNKNOWN_SPECIAL_INSN;
16066 }
16067
16068 dis_res->len = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16069
16070 return status;
16071}
16072
16073
16074/* Function returns # bytes that were decoded or 0 in case of failure */
florianb4df7682011-07-05 02:09:01 +000016075static UInt
sewardj2019a972011-03-07 16:04:07 +000016076s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
16077{
16078 s390_decode_t status;
16079
16080 dis_res = dres;
16081
16082 /* Spot the 8-byte preamble: 18ff lr r15,r15
16083 1811 lr r1,r1
16084 1822 lr r2,r2
16085 1833 lr r3,r3 */
16086 if (bytes[ 0] == 0x18 && bytes[ 1] == 0xff && bytes[ 2] == 0x18 &&
16087 bytes[ 3] == 0x11 && bytes[ 4] == 0x18 && bytes[ 5] == 0x22 &&
16088 bytes[ 6] == 0x18 && bytes[ 7] == 0x33) {
16089
16090 /* Handle special instruction that follows that preamble. */
16091 if (0) vex_printf("special function handling...\n");
florian2c8ed942011-08-01 22:07:51 +000016092
16093 insn_length = S390_SPECIAL_OP_PREAMBLE_SIZE + S390_SPECIAL_OP_SIZE;
16094 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16095
16096 status =
16097 s390_decode_special_and_irgen(bytes + S390_SPECIAL_OP_PREAMBLE_SIZE);
sewardj2019a972011-03-07 16:04:07 +000016098 } else {
16099 /* Handle normal instructions. */
16100 switch (insn_length) {
16101 case 2:
16102 status = s390_decode_2byte_and_irgen(bytes);
16103 break;
16104
16105 case 4:
16106 status = s390_decode_4byte_and_irgen(bytes);
16107 break;
16108
16109 case 6:
16110 status = s390_decode_6byte_and_irgen(bytes);
16111 break;
16112
16113 default:
16114 status = S390_DECODE_ERROR;
16115 break;
16116 }
16117 }
florian5fcbba22011-07-27 20:40:22 +000016118 /* If next instruction is execute, stop here */
florianf9e1ed72012-04-17 02:41:56 +000016119 if (dis_res->whatNext == Dis_Continue && bytes[insn_length] == 0x44) {
16120 put_IA(mkaddr_expr(guest_IA_next_instr));
sewardj2019a972011-03-07 16:04:07 +000016121 dis_res->whatNext = Dis_StopHere;
florianf9e1ed72012-04-17 02:41:56 +000016122 dis_res->jk_StopHere = Ijk_Boring;
sewardj2019a972011-03-07 16:04:07 +000016123 }
16124
16125 if (status == S390_DECODE_OK) return insn_length; /* OK */
16126
16127 /* Decoding failed somehow */
sewardj442e51a2012-12-06 18:08:04 +000016128 if (sigill_diag) {
16129 vex_printf("vex s390->IR: ");
16130 switch (status) {
16131 case S390_DECODE_UNKNOWN_INSN:
16132 vex_printf("unknown insn: ");
16133 break;
sewardj2019a972011-03-07 16:04:07 +000016134
sewardj442e51a2012-12-06 18:08:04 +000016135 case S390_DECODE_UNIMPLEMENTED_INSN:
16136 vex_printf("unimplemented insn: ");
16137 break;
sewardj2019a972011-03-07 16:04:07 +000016138
sewardj442e51a2012-12-06 18:08:04 +000016139 case S390_DECODE_UNKNOWN_SPECIAL_INSN:
16140 vex_printf("unimplemented special insn: ");
16141 break;
sewardj2019a972011-03-07 16:04:07 +000016142
sewardj442e51a2012-12-06 18:08:04 +000016143 default:
16144 case S390_DECODE_ERROR:
16145 vex_printf("decoding error: ");
16146 break;
16147 }
16148
16149 vex_printf("%02x%02x", bytes[0], bytes[1]);
16150 if (insn_length > 2) {
16151 vex_printf(" %02x%02x", bytes[2], bytes[3]);
16152 }
16153 if (insn_length > 4) {
16154 vex_printf(" %02x%02x", bytes[4], bytes[5]);
16155 }
16156 vex_printf("\n");
sewardj2019a972011-03-07 16:04:07 +000016157 }
16158
sewardj2019a972011-03-07 16:04:07 +000016159 return 0; /* Failed */
16160}
16161
16162
sewardj2019a972011-03-07 16:04:07 +000016163/* Disassemble a single instruction INSN into IR. */
16164static DisResult
florian420c5012011-07-22 02:12:28 +000016165disInstr_S390_WRK(UChar *insn)
sewardj2019a972011-03-07 16:04:07 +000016166{
16167 UChar byte;
16168 UInt insn_length;
16169 DisResult dres;
16170
16171 /* ---------------------------------------------------- */
16172 /* --- Compute instruction length -- */
16173 /* ---------------------------------------------------- */
16174
16175 /* Get the first byte of the insn. */
16176 byte = insn[0];
16177
16178 /* The leftmost two bits (0:1) encode the length of the insn in bytes.
16179 00 -> 2 bytes, 01 -> 4 bytes, 10 -> 4 bytes, 11 -> 6 bytes. */
16180 insn_length = ((((byte >> 6) + 1) >> 1) + 1) << 1;
16181
16182 guest_IA_next_instr = guest_IA_curr_instr + insn_length;
16183
16184 /* ---------------------------------------------------- */
16185 /* --- Initialise the DisResult data -- */
16186 /* ---------------------------------------------------- */
16187 dres.whatNext = Dis_Continue;
16188 dres.len = insn_length;
16189 dres.continueAt = 0;
florian8844a632012-04-13 04:04:06 +000016190 dres.jk_StopHere = Ijk_INVALID;
sewardj2019a972011-03-07 16:04:07 +000016191
floriana99f20e2011-07-17 14:16:41 +000016192 /* fixs390: consider chasing of conditional jumps */
16193
sewardj2019a972011-03-07 16:04:07 +000016194 /* Normal and special instruction handling starts here. */
16195 if (s390_decode_and_irgen(insn, insn_length, &dres) == 0) {
16196 /* All decode failures end up here. The decoder has already issued an
16197 error message.
16198 Tell the dispatcher that this insn cannot be decoded, and so has
florian342e01a2012-07-26 02:37:49 +000016199 not been executed, and (is currently) the next to be executed.
16200 The insn address in the guest state needs to be set to
16201 guest_IA_curr_instr, otherwise the complaint will report an
16202 incorrect address. */
16203 put_IA(mkaddr_expr(guest_IA_curr_instr));
sewardj2019a972011-03-07 16:04:07 +000016204
florian8844a632012-04-13 04:04:06 +000016205 dres.whatNext = Dis_StopHere;
16206 dres.jk_StopHere = Ijk_NoDecode;
16207 dres.continueAt = 0;
16208 dres.len = 0;
16209 } else {
16210 /* Decode success */
16211 switch (dres.whatNext) {
16212 case Dis_Continue:
florian8559e412012-04-19 14:23:48 +000016213 put_IA(mkaddr_expr(guest_IA_next_instr));
florian8844a632012-04-13 04:04:06 +000016214 break;
16215 case Dis_ResteerU:
16216 case Dis_ResteerC:
16217 put_IA(mkaddr_expr(dres.continueAt));
16218 break;
16219 case Dis_StopHere:
florian4b8efad2012-09-02 18:07:08 +000016220 if (dres.jk_StopHere == Ijk_EmWarn ||
16221 dres.jk_StopHere == Ijk_EmFail) {
16222 /* We assume here, that emulation warnings are not given for
16223 insns that transfer control. There is no good way to
16224 do that. */
16225 put_IA(mkaddr_expr(guest_IA_next_instr));
16226 }
florian8844a632012-04-13 04:04:06 +000016227 break;
16228 default:
16229 vassert(0);
16230 }
sewardj2019a972011-03-07 16:04:07 +000016231 }
16232
16233 return dres;
16234}
16235
16236
16237/*------------------------------------------------------------*/
16238/*--- Top-level fn ---*/
16239/*------------------------------------------------------------*/
16240
16241/* Disassemble a single instruction into IR. The instruction
16242 is located in host memory at &guest_code[delta]. */
16243
16244DisResult
16245disInstr_S390(IRSB *irsb_IN,
sewardj2019a972011-03-07 16:04:07 +000016246 Bool (*resteerOkFn)(void *, Addr64),
16247 Bool resteerCisOk,
16248 void *callback_opaque,
16249 UChar *guest_code,
16250 Long delta,
16251 Addr64 guest_IP,
16252 VexArch guest_arch,
16253 VexArchInfo *archinfo,
16254 VexAbiInfo *abiinfo,
sewardj442e51a2012-12-06 18:08:04 +000016255 Bool host_bigendian,
16256 Bool sigill_diag_IN)
sewardj2019a972011-03-07 16:04:07 +000016257{
16258 vassert(guest_arch == VexArchS390X);
16259
16260 /* The instruction decoder requires a big-endian machine. */
16261 vassert(host_bigendian == True);
16262
16263 /* Set globals (see top of this file) */
16264 guest_IA_curr_instr = guest_IP;
sewardj2019a972011-03-07 16:04:07 +000016265 irsb = irsb_IN;
florian420c5012011-07-22 02:12:28 +000016266 resteer_fn = resteerOkFn;
16267 resteer_data = callback_opaque;
sewardj442e51a2012-12-06 18:08:04 +000016268 sigill_diag = sigill_diag_IN;
sewardj2019a972011-03-07 16:04:07 +000016269
florian420c5012011-07-22 02:12:28 +000016270 return disInstr_S390_WRK(guest_code + delta);
sewardj2019a972011-03-07 16:04:07 +000016271}
16272
16273/*---------------------------------------------------------------*/
16274/*--- end guest_s390_toIR.c ---*/
16275/*---------------------------------------------------------------*/